MENU - Menu Interativo WhatsApp
O que é este Node?
O MENU é o node responsável por criar menus interativos nativos do WhatsApp com múltiplas seções e opções, permitindo que usuários selecionem entre até 10 opções organizadas em categorias. É a forma mais elegante e profissional de oferecer escolhas complexas em conversas WhatsApp.
Por que este Node existe?
Quando você precisa apresentar múltiplas opções ao usuário de forma organizada e profissional, botões simples não são suficientes. O MENU existe para:
- Organização Visual: Agrupar opções relacionadas em seções nomeadas, criando uma hierarquia clara de informações
- Suporte a Múltiplas Opções: Permitir até 10 opções (versus 3 botões), ideal para catálogos, categorias e escolhas complexas
- Descrições Detalhadas: Cada opção pode ter uma descrição adicional, ajudando o usuário a entender melhor cada escolha
- Experiência Nativa WhatsApp: Usa a interface interativa oficial do WhatsApp, garantindo familiaridade e confiança do usuário
Como funciona internamente?
Quando o MENU é executado, o sistema:
- Valida Seções: Verifica se há pelo menos uma seção com opções configuradas
- Conta Total de Opções: Soma todas as opções de todas as seções (limite: 10 opções no total)
- Gera IDs Únicos: Cria IDs automáticos para opções sem ID definido
- Constrói Estrutura WhatsApp: Monta o payload no formato
interactiveesperado pela API WhatsApp - Adiciona Elementos Opcionais: Inclui header e footer se fornecidos
- Retorna Menu Pronto: Envia estrutura completa aguardando seleção do usuário
- Aguarda Resposta: Sistema espera que usuário selecione uma opção para continuar
Código interno (whatsapp-ui-executor.service.ts:42-98):
private async executeMenu(parameters: any, context: any): Promise<any> {
const { header, body, footer, sections, buttonText } = parameters;
this.logger.log(`📱 MENU - Creating WhatsApp menu with ${sections?.length || 0} sections`);
// Validate sections
if (!sections || sections.length === 0) {
throw new Error('Menu requires at least one section with options');
}
// Validate total options limit (WhatsApp limit: 10 options per menu)
const totalOptions = sections.reduce((total, section) => total + (section.rows?.length || 0), 0);
if (totalOptions > 10) {
throw new Error(`WhatsApp menu supports maximum 10 options, got ${totalOptions}`);
}
// Build WhatsApp menu structure
const whatsappMenu = {
type: 'interactive',
body: {
text: body || 'Please select an option:'
},
action: {
button: buttonText || 'Select',
sections: sections.map(section => ({
title: section.title || 'Options',
rows: section.rows?.map(row => ({
id: row.id || `option_${Math.random().toString(36).substr(2, 9)}`,
title: row.title || row.text || 'Option',
description: row.description || ''
})) || []
}))
}
};
if (header) {
whatsappMenu['header'] = {
type: 'text',
text: header
};
}
if (footer) {
whatsappMenu['footer'] = {
text: footer
};
}
return {
success: true,
action: 'whatsapp_menu_created',
messageType: 'interactive_menu',
payload: whatsappMenu,
awaitingUserSelection: true,
timestamp: new Date().toISOString()
};
}
Quando você DEVE usar este Node?
Use MENU sempre que precisar de apresentar 4 ou mais opções organizadas em categorias:
Casos de uso
- Catálogo de Produtos: "Selecione uma categoria: Eletrônicos, Roupas, Alimentos, etc."
- Menu de Serviços: "Escolha um departamento: Vendas, Suporte, Financeiro, RH"
- Opções de Agendamento: "Selecione um horário disponível" com múltiplos dias/horários
- Seleção de Especialidade: "Qual especialidade médica você precisa?" com descrições de cada uma
- Configurações de Conta: Múltiplas opções de configuração agrupadas por tipo
Quando NÃO usar MENU
- 3 ou menos opções: Use BUTTONS para escolhas rápidas (mais visual e direto)
- Resposta Livre: Use INPUT quando o usuário precisa digitar algo (não escolher)
- Confirmação Sim/Não: Use BUTTONS com apenas 2 botões
- Lista Linear Simples: Use LIST se não precisa de seções/categorias
Parâmetros Detalhados
header (string, opcional)
O que é: Título principal exibido no topo do menu, destacado em negrito.
Padrão: Nenhum (menu sem header)
Flow completo para testar:
{
"name": "Teste MENU - Header",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "menu_1",
"type": "menu",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Menu com Header",
"parameters": {
"header": "🛍️ Catálogo de Produtos",
"body": "Selecione a categoria desejada:",
"buttonText": "Ver Categorias",
"sections": [
{
"title": "Produtos",
"rows": [
{ "id": "eletronicos", "title": "Eletrônicos", "description": "TVs, celulares, notebooks" },
{ "id": "roupas", "title": "Roupas", "description": "Moda masculina e feminina" }
]
}
]
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Confirmar Seleção",
"parameters": {
"message": "Você selecionou: {{menu_selection}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 700, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "menu_1" },
{ "source": "menu_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: 1. Inicie o flow 2. Verá menu com header "🛍️ Catálogo de Produtos" em destaque 3. Clique em "Ver Categorias" 4. Selecione uma opção 5. Confirmação mostra o que foi selecionado
body (string, obrigatório)
O que é: Texto principal da mensagem, explicando o que o usuário deve fazer. É o conteúdo central do menu.
Padrão: "Please select an option:"
Flow completo para testar:
{
"name": "Teste MENU - Body",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "menu_1",
"type": "menu",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Menu Body Personalizado",
"parameters": {
"body": "👋 Olá! Para qual departamento você gostaria de falar?\n\nSelecione abaixo:",
"buttonText": "Selecionar Departamento",
"sections": [
{
"title": "Departamentos",
"rows": [
{ "id": "vendas", "title": "Vendas", "description": "Informações sobre produtos" },
{ "id": "suporte", "title": "Suporte", "description": "Ajuda técnica" },
{ "id": "financeiro", "title": "Financeiro", "description": "Cobranças e pagamentos" }
]
}
]
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "Conectando você ao departamento: {{menu_selection}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 700, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "menu_1" },
{ "source": "menu_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: 1. Inicie o flow 2. Verá mensagem personalizada com saudação e instruções 3. Texto body aceita múltiplas linhas e emojis 4. Selecione um departamento 5. Confirmação usa o ID selecionado
footer (string, opcional)
O que é: Texto adicional exibido abaixo do menu, ideal para informações complementares ou avisos.
Padrão: Nenhum (menu sem footer)
Flow completo para testar:
{
"name": "Teste MENU - Footer",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "menu_1",
"type": "menu",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Menu com Footer",
"parameters": {
"header": "📅 Agendamento",
"body": "Selecione o melhor horário para sua consulta:",
"footer": "⏰ Horário de Brasília | Consultas duram 30min",
"buttonText": "Ver Horários",
"sections": [
{
"title": "Manhã",
"rows": [
{ "id": "09h", "title": "09:00", "description": "Disponível" },
{ "id": "10h", "title": "10:00", "description": "Disponível" }
]
},
{
"title": "Tarde",
"rows": [
{ "id": "14h", "title": "14:00", "description": "Disponível" },
{ "id": "15h", "title": "15:00", "description": "Disponível" }
]
}
]
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Confirmar Horário",
"parameters": {
"message": "✅ Consulta agendada para {{menu_selection}}!"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 700, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "menu_1" },
{ "source": "menu_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: 1. Inicie o flow 2. Menu mostra footer com informações sobre fuso horário 3. Footer aparece em cinza claro abaixo das opções 4. Selecione um horário 5. Confirmação usa o horário selecionado
sections (array, obrigatório)
O que é: Array de seções do menu. Cada seção tem um título e uma lista de opções (rows). É a estrutura principal do menu.
Estrutura de cada seção:
{
title: string, // Nome da seção
rows: [ // Array de opções
{
id: string, // ID único da opção
title: string, // Texto da opção (max 24 chars)
description: string // Descrição opcional
}
]
}
Limite: Máximo de 10 opções no total (somando todas as seções)
Flow completo para testar:
{
"name": "Teste MENU - Sections Múltiplas",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "menu_1",
"type": "menu",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Menu Multi-Seção",
"parameters": {
"header": "🏥 Clínica Médica",
"body": "Selecione a especialidade que você precisa:",
"buttonText": "Ver Especialidades",
"sections": [
{
"title": "🩺 Clínica Geral",
"rows": [
{ "id": "clinico", "title": "Clínico Geral", "description": "Consultas gerais e check-ups" },
{ "id": "pediatra", "title": "Pediatra", "description": "Especialista em crianças" }
]
},
{
"title": "🦷 Odontologia",
"rows": [
{ "id": "dentista", "title": "Dentista", "description": "Limpeza e tratamentos" },
{ "id": "ortodontia", "title": "Ortodontia", "description": "Aparelhos e alinhamento" }
]
},
{
"title": "🧠 Especialidades",
"rows": [
{ "id": "cardio", "title": "Cardiologista", "description": "Saúde do coração" },
{ "id": "dermato", "title": "Dermatologista", "description": "Problemas de pele" }
]
}
]
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Confirmar Especialidade",
"parameters": {
"message": "Especialidade selecionada: {{menu_selection}}\n\nAgora vamos agendar sua consulta!"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 700, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "menu_1" },
{ "source": "menu_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: 1. Inicie o flow 2. Menu mostra 3 seções bem organizadas com títulos com emojis 3. Cada seção agrupa opções relacionadas 4. Descrições ajudam usuário a entender cada opção 5. Selecione qualquer especialidade 6. ID da especialidade é capturado para próxima ação
buttonText (string, opcional)
O que é: Texto do botão que abre o menu. Usuário precisa clicar neste botão para ver as opções.
Padrão: "Select"
Flow completo para testar:
{
"name": "Teste MENU - ButtonText Personalizado",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "menu_1",
"type": "menu",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Menu ButtonText Custom",
"parameters": {
"header": "🎓 Cursos Online",
"body": "Escolha a área de conhecimento que mais te interessa:",
"buttonText": "📚 Ver Todos os Cursos",
"sections": [
{
"title": "Tecnologia",
"rows": [
{ "id": "programacao", "title": "Programação", "description": "Python, JavaScript, etc" },
{ "id": "design", "title": "Design", "description": "UI/UX, Figma, Adobe" }
]
},
{
"title": "Negócios",
"rows": [
{ "id": "marketing", "title": "Marketing Digital", "description": "SEO, ads, redes sociais" },
{ "id": "vendas", "title": "Vendas", "description": "Técnicas de vendas" }
]
}
]
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Mostrar Curso",
"parameters": {
"message": "Ótima escolha! Você selecionou: {{menu_selection}}\n\n🎯 Vamos te mostrar os cursos disponíveis!"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 700, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "menu_1" },
{ "source": "menu_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: 1. Inicie o flow 2. Veja botão com texto "📚 Ver Todos os Cursos" (personalizado) 3. Clique no botão para abrir menu 4. Selecione uma área 5. Mensagem confirma seleção
Parâmetros
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| header | string | Não | Título principal destacado no topo |
| body | string | Sim | Texto explicativo da mensagem (padrão: "Please select an option:") |
| footer | string | Não | Texto adicional abaixo das opções |
| sections | array | Sim | Array de seções com opções (máx 10 opções total) |
| buttonText | string | Não | Texto do botão que abre menu (padrão: "Select") |
Exemplo 1: Cardápio de Restaurante com Categorias
Objetivo: Criar menu organizado de restaurante com múltiplas categorias de pratos
JSON para Importar
{
"name": "Cardápio de Restaurante - Menu Interativo",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "message_1",
"type": "message",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Boas-vindas",
"parameters": {
"message": "🍽️ Bem-vindo ao Restaurante Sabor Brasileiro!\n\nVamos fazer seu pedido?"
}
}
},
{
"id": "menu_1",
"type": "menu",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Menu Cardápio",
"parameters": {
"header": "🍽️ Cardápio Completo",
"body": "Selecione o prato que deseja pedir:\n\nTodos os pratos acompanham arroz, feijão e salada.",
"footer": "🚚 Entrega em 40-50 minutos | Pedido mínimo: R$ 25",
"buttonText": "Ver Cardápio Completo",
"sections": [
{
"title": "🥩 Carnes",
"rows": [
{
"id": "picanha",
"title": "Picanha Grelhada",
"description": "300g - R$ 45,90"
},
{
"id": "frango",
"title": "Frango à Parmegiana",
"description": "Com molho e queijo - R$ 32,90"
}
]
},
{
"title": "🐟 Peixes",
"rows": [
{
"id": "salmao",
"title": "Salmão Grelhado",
"description": "Com legumes - R$ 52,90"
},
{
"id": "tilapia",
"title": "Tilápia na Manteiga",
"description": "Com molho de ervas - R$ 38,90"
}
]
},
{
"title": "🥗 Vegetarianos",
"rows": [
{
"id": "lasanha_veg",
"title": "Lasanha Vegetariana",
"description": "Camadas de legumes - R$ 29,90"
},
{
"id": "risoto",
"title": "Risoto de Cogumelos",
"description": "Cremoso e saboroso - R$ 34,90"
}
]
}
]
}
}
},
{
"id": "message_2",
"type": "message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Confirmar Pedido",
"parameters": {
"message": "🎉 Excelente escolha!\n\nVocê pediu: {{menu_selection}}\n\n✅ Pedido confirmado!\n🚚 Tempo estimado: 40-50 minutos\n📱 Você receberá atualizações via WhatsApp"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 900, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "message_1" },
{ "source": "message_1", "target": "menu_1" },
{ "source": "menu_1", "target": "message_2" },
{ "source": "message_2", "target": "end_1" }
]
}
Saída esperada:
Sistema: 🍽️ Bem-vindo ao Restaurante Sabor Brasileiro!
Vamos fazer seu pedido?
[Menu interativo aparece]
Header: 🍽️ Cardápio Completo
Body: Selecione o prato que deseja pedir:
Todos os pratos acompanham arroz, feijão e salada.
Botão: [Ver Cardápio Completo]
Usuário: [Clica no botão, abre menu com 3 seções]
- 🥩 Carnes (Picanha, Frango)
- 🐟 Peixes (Salmão, Tilápia)
- 🥗 Vegetarianos (Lasanha, Risoto)
Usuário: [Seleciona "Salmão Grelhado"]
Sistema: 🎉 Excelente escolha!
Você pediu: salmao
✅ Pedido confirmado!
🚚 Tempo estimado: 40-50 minutos
📱 Você receberá atualizações via WhatsApp
Exemplo 2: Sistema de Suporte Técnico Multi-Nível
Objetivo: Menu de atendimento com diferentes departamentos e tipos de suporte
JSON para Importar
{
"name": "Suporte Técnico - Menu Departamentos",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "menu_1",
"type": "menu",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Menu Suporte",
"parameters": {
"header": "🛠️ Central de Suporte",
"body": "Olá! 👋\n\nPara melhor atendê-lo, selecione o tipo de suporte que você precisa:",
"footer": "⏰ Atendimento 24/7 | Tempo médio de resposta: 5min",
"buttonText": "🎯 Selecionar Área",
"sections": [
{
"title": "💻 Técnico",
"rows": [
{
"id": "bug",
"title": "Reportar Bug",
"description": "Algo não está funcionando"
},
{
"id": "lentidao",
"title": "Sistema Lento",
"description": "Problemas de performance"
},
{
"id": "erro",
"title": "Mensagem de Erro",
"description": "Recebeu um erro específico"
}
]
},
{
"title": "💳 Financeiro",
"rows": [
{
"id": "cobranca",
"title": "Dúvida sobre Cobrança",
"description": "Valores e faturas"
},
{
"id": "pagamento",
"title": "Problema no Pagamento",
"description": "Pagamento não processado"
}
]
},
{
"title": "📚 Dúvidas Gerais",
"rows": [
{
"id": "como_usar",
"title": "Como usar o Sistema",
"description": "Tutorial e documentação"
},
{
"id": "novidade",
"title": "Novidades",
"description": "Novas funcionalidades"
}
]
}
]
}
}
},
{
"id": "switch_1",
"type": "switch",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Direcionar Atendimento",
"parameters": {
"variable": "{{menu_selection}}",
"cases": [
{ "value": "bug", "label": "Bug" },
{ "value": "lentidao", "label": "Lentidão" },
{ "value": "erro", "label": "Erro" },
{ "value": "cobranca", "label": "Cobrança" },
{ "value": "pagamento", "label": "Pagamento" },
{ "value": "como_usar", "label": "Tutorial" },
{ "value": "novidade", "label": "Novidades" }
]
}
}
},
{
"id": "message_bug",
"type": "message",
"position": { "x": 700, "y": 0 },
"data": {
"label": "Resposta Bug",
"parameters": {
"message": "🐛 Entendido! Vamos resolver esse bug.\n\nPor favor, descreva detalhadamente o problema:\n- O que você estava fazendo?\n- O que aconteceu?\n- Já tentou reiniciar o sistema?"
}
}
},
{
"id": "message_financeiro",
"type": "message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Resposta Financeiro",
"parameters": {
"message": "💳 Equipe financeira!\n\nVou te conectar com nosso time financeiro.\n\nPor favor, tenha em mãos:\n- CPF/CNPJ\n- Número do pedido\n- Data da transação"
}
}
},
{
"id": "message_tutorial",
"type": "message",
"position": { "x": 700, "y": 200 },
"data": {
"label": "Resposta Tutorial",
"parameters": {
"message": "📚 Ótimo! Vou te ajudar.\n\n📖 Documentação: https://docs.exemplo.com\n🎥 Vídeos: https://youtube.com/exemplo\n💬 Comunidade: https://forum.exemplo.com\n\nQual desses recursos prefere?"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 900, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "menu_1" },
{ "source": "menu_1", "target": "switch_1" },
{ "source": "switch_1", "target": "message_bug", "label": "Bug/Lentidão/Erro" },
{ "source": "switch_1", "target": "message_financeiro", "label": "Cobrança/Pagamento" },
{ "source": "switch_1", "target": "message_tutorial", "label": "Tutorial/Novidades" },
{ "source": "message_bug", "target": "end_1" },
{ "source": "message_financeiro", "target": "end_1" },
{ "source": "message_tutorial", "target": "end_1" }
]
}
Saída esperada:
[Menu aparece automaticamente]
Header: 🛠️ Central de Suporte
Body: Olá! 👋
Para melhor atendê-lo, selecione o tipo de suporte que você precisa:
Footer: ⏰ Atendimento 24/7 | Tempo médio de resposta: 5min
Usuário: [Clica em "🎯 Selecionar Área"]
[Vê 3 seções organizadas]
Usuário: [Seleciona "Reportar Bug" da seção Técnico]
Sistema: 🐛 Entendido! Vamos resolver esse bug.
Por favor, descreva detalhadamente o problema:
- O que você estava fazendo?
- O que aconteceu?
- Já tentou reiniciar o sistema?
[Flow continua com coleta de informações do bug]
Exemplo 3: Agendamento de Consultas com Múltiplos Horários
Objetivo: Sistema completo de agendamento usando menu para selecionar dia e horário
JSON para Importar
{
"name": "Agendamento Médico - Menu Horários",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "message_1",
"type": "message",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Boas-vindas Clínica",
"parameters": {
"message": "🏥 Clínica Saúde Total\n\nOlá! Vamos agendar sua consulta com Dr. Silva.\n\n📋 Consulta: Cardiologia\n⏱️ Duração: 30 minutos\n💰 Valor: R$ 250,00"
}
}
},
{
"id": "menu_1",
"type": "menu",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Menu Horários",
"parameters": {
"header": "📅 Horários Disponíveis",
"body": "Selecione o melhor dia e horário para sua consulta:\n\n✅ = Disponível\n⏰ = Últimas vagas",
"footer": "🕐 Horário de Brasília | Confirme com 24h de antecedência",
"buttonText": "Ver Horários",
"sections": [
{
"title": "Segunda-feira 15/01",
"rows": [
{ "id": "seg_09", "title": "09:00", "description": "✅ Disponível" },
{ "id": "seg_14", "title": "14:00", "description": "⏰ Última vaga" }
]
},
{
"title": "Terça-feira 16/01",
"rows": [
{ "id": "ter_10", "title": "10:00", "description": "✅ Disponível" },
{ "id": "ter_15", "title": "15:00", "description": "✅ Disponível" }
]
},
{
"title": "Quarta-feira 17/01",
"rows": [
{ "id": "qua_09", "title": "09:00", "description": "✅ Disponível" },
{ "id": "qua_11", "title": "11:00", "description": "✅ Disponível" },
{ "id": "qua_16", "title": "16:00", "description": "⏰ Última vaga" }
]
}
]
}
}
},
{
"id": "message_2",
"type": "message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Confirmar Dados",
"parameters": {
"message": "📋 Confirme os dados do agendamento:\n\n👤 Paciente: {{patient_name}}\n🏥 Médico: Dr. Silva - Cardiologia\n📅 Data/Hora: {{menu_selection}}\n💰 Valor: R$ 250,00\n\nOs dados estão corretos?"
}
}
},
{
"id": "buttons_1",
"type": "buttons",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Confirmar Agendamento",
"parameters": {
"body": "Confirmar agendamento?",
"buttons": [
{ "id": "confirmar", "text": "✅ Sim, confirmar" },
{ "id": "alterar", "text": "📝 Alterar horário" },
{ "id": "cancelar", "text": "❌ Cancelar" }
]
}
}
},
{
"id": "message_3",
"type": "message",
"position": { "x": 1100, "y": 100 },
"data": {
"label": "Confirmação Final",
"parameters": {
"message": "✅ Consulta agendada com sucesso!\n\n📅 Horário: {{menu_selection}}\n🏥 Local: Clínica Saúde Total\n📍 Endereço: Rua das Flores, 123\n\n📱 Você receberá um lembrete 24h antes.\n🚗 Reserve 10 minutos para estacionamento.\n\n🎉 Até lá! Cuide-se bem!"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1300, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "message_1" },
{ "source": "message_1", "target": "menu_1" },
{ "source": "menu_1", "target": "message_2" },
{ "source": "message_2", "target": "buttons_1" },
{ "source": "buttons_1", "target": "message_3" },
{ "source": "message_3", "target": "end_1" }
]
}
Saída esperada:
Sistema: 🏥 Clínica Saúde Total
Olá! Vamos agendar sua consulta com Dr. Silva.
📋 Consulta: Cardiologia
⏱️ Duração: 30 minutos
💰 Valor: R$ 250,00
[Menu aparece]
Header: 📅 Horários Disponíveis
Botão: [Ver Horários]
Usuário: [Clica e vê menu organizado por dias]
- Segunda-feira 15/01 (09:00, 14:00)
- Terça-feira 16/01 (10:00, 15:00)
- Quarta-feira 17/01 (09:00, 11:00, 16:00)
Usuário: [Seleciona "Terça-feira 16/01 - 10:00"]
Sistema: 📋 Confirme os dados do agendamento:
👤 Paciente: João Silva
🏥 Médico: Dr. Silva - Cardiologia
📅 Data/Hora: ter_10
💰 Valor: R$ 250,00
Os dados estão corretos?
[Botões aparecem: Sim/Alterar/Cancelar]
Usuário: [Clica "✅ Sim, confirmar"]
Sistema: ✅ Consulta agendada com sucesso!
📅 Horário: ter_10
🏥 Local: Clínica Saúde Total
📍 Endereço: Rua das Flores, 123
📱 Você receberá um lembrete 24h antes.
🚗 Reserve 10 minutos para estacionamento.
🎉 Até lá! Cuide-se bem!
Resposta do Node
{
"success": true,
"action": "whatsapp_menu_created",
"messageType": "interactive_menu",
"payload": {
"type": "interactive",
"header": {
"type": "text",
"text": "🛍️ Catálogo de Produtos"
},
"body": {
"text": "Selecione a categoria desejada:"
},
"footer": {
"text": "Todos os preços incluem frete"
},
"action": {
"button": "Ver Categorias",
"sections": [
{
"title": "Eletrônicos",
"rows": [
{
"id": "smartphones",
"title": "Smartphones",
"description": "iPhones e Androids"
},
{
"id": "notebooks",
"title": "Notebooks",
"description": "Dell, Lenovo, Apple"
}
]
}
]
}
},
"awaitingUserSelection": true,
"timestamp": "2025-01-15T10:30:00.000Z"
}
Boas Práticas
✅ SIM:
- Use seções bem nomeadas para agrupar opções relacionadas logicamente
- Adicione descrições às opções para ajudar usuário a decidir (especialmente em escolhas complexas)
- Mantenha títulos curtos e claros (máx 24 caracteres por opção)
- Use emojis estrategicamente nos títulos das seções para identificação visual rápida
- Personalize buttonText para ficar intuitivo ("Ver Produtos", "Selecionar Horário")
- Use footer para informações importantes (limites, horários, condições)
- Garanta que IDs sejam únicos e descritivos (facilita lógica posterior)
- Organize opções por relevância (mais populares primeiro)
❌ NÃO:
- Não coloque mais de 10 opções no total (limite do WhatsApp)
- Não use títulos muito longos que serão cortados
- Não crie seções com apenas 1 opção (use LIST simples)
- Não esqueça de validar se sections existe antes de acessar
- Não use IDs com espaços ou caracteres especiais (dificulta processamento)
- Não crie menus sem contexto (sempre explique o que usuário está escolhendo)
- Não use linguagem ambígua nas descrições (seja claro e direto)
Dicas
💡 Organização por Contexto: Agrupe opções que fazem sentido juntas. Ex: "Manhã/Tarde/Noite" para horários, "Norte/Sul/Leste/Oeste" para localização.
💡 Descrições Informativas: Use descrições para diferenciar opções similares. Ex: "Básico - R$ 49/mês" vs "Premium - R$ 99/mês com mais recursos".
💡 Fallback Inteligente: Sempre capture a resposta do menu em uma variável para usar em SWITCH ou CONDITION posteriormente, direcionando o flow de acordo com a escolha.
💡 Validação de Limite: Sistema valida automaticamente o limite de 10 opções. Se precisar de mais, divida em múltiplos menus ou use estratégia de navegação hierárquica.
💡 IDs Estratégicos: Use IDs que façam sentido no código (ex: "seg_09h" para segunda 9h), facilitando debug e lógica condicional.
💡 Responsividade Visual: Header e Footer aparecem em destaque. Use header para contexto principal (ex: "📅 Agendamento") e footer para informações secundárias (ex: "Horário de Brasília").
💡 Testes de Usabilidade: Teste o menu com usuários reais. Títulos claros e descrições úteis reduzem confusão e melhoram conversão.
💡 Combinação com Outros Nodes: Menu funciona perfeitamente com SWITCH para rotear diferentes escolhas, e com VARIABLE para armazenar seleção e usar depois.
Próximo Node
→ BUTTONS - Botões rápidos de resposta (até 3 opções simples) → LIST - Lista de seleção alternativa (sem múltiplas seções) → SWITCH - Direcione flow baseado na seleção do menu → VARIABLE - Armazene a seleção do usuário para uso posterior