WHATSAPP SEND INTERACTIVE - Enviar Mensagens Interativas
O que é este Node?
O WHATSAPP SEND INTERACTIVE é o node responsável por enviar mensagens com botões, listas e elementos interativos que permitem ao usuário responder de forma estruturada.
Por que este Node existe?
Usuários precisam de opções claras para interagir. O SEND INTERACTIVE existe para:
- Menus estruturados: Oferecer opções organizadas em botões ou listas
- Experiência guiada: Conduzir usuário por opções predefinidas
- Reduzir erros: Eliminar digitação livre (usuário clica em vez de digitar)
- Capturar escolhas: Obter resposta estruturada para processar no flow
- Melhor UX: Interface visual mais amigável que texto livre
- Automação eficiente: Respostas padronizadas facilitam processamento
Como funciona internamente?
Quando o SEND INTERACTIVE é executado, o sistema:
- Valida credenciais: Verifica accessToken e phoneNumberId
- Valida tipo interativo: Confirma interactiveType (button ou list)
- Valida body: Garante que interactiveBody.text existe
- Monta estrutura: Cria JSON com header, body, footer, action
- Formata botões/listas: Estrutura buttons ou sections conforme tipo
- Envia requisição: POST para WhatsApp Graph API
- Retorna resultado: Confirma envio com ID da mensagem
Código interno (whatsapp-meta-executor.service.ts:595-632):
private async sendInteractive(data: WhatsAppMetaNodeData): Promise<any> {
const interactive: any = {
type: data.interactiveType,
body: data.interactiveBody
};
if (data.interactiveHeader) {
interactive.header = data.interactiveHeader;
}
if (data.interactiveFooter) {
interactive.footer = data.interactiveFooter;
}
if (data.interactiveAction) {
interactive.action = data.interactiveAction;
}
const payload = {
messaging_product: 'whatsapp',
to: data.recipientPhone,
type: 'interactive',
interactive
};
const response: AxiosResponse = await axios.post(
`${this.WHATSAPP_API_BASE}/${data.phoneNumberId}/messages`,
payload,
{
headers: {
'Authorization': `Bearer ${data.accessToken}`,
'Content-Type': 'application/json'
}
}
);
return response.data;
}
Quando você DEVE usar este Node?
Use SEND INTERACTIVE sempre que precisar de respostas estruturadas do usuário:
Casos de uso:
- Menu principal: "Escolha uma opção: Vendas, Suporte, Financeiro"
- Confirmações: "Sim" / "Não" como botões
- Avaliação: "Ruim", "Regular", "Bom", "Excelente"
- Categorias: Listar departamentos, produtos, serviços
- Agendamento: Escolher horários disponíveis
- FAQ: Menu de perguntas frequentes
- Checkout: Confirmar pedido, cancelar, editar
Quando NÃO usar SEND INTERACTIVE:
- Resposta livre: Use INPUT para texto livre
- Mais de 10 opções em botões: Use list em vez de buttons
- Conteúdo dinâmico muito variável: Botões são fixos no envio
Tipos de Mensagens Interativas
1. Button (Botões)
- Até 3 botões
- Resposta rápida
- Ideal para sim/não, confirmações
2. List (Lista)
- Até 10 seções
- Cada seção pode ter até 10 itens
- Ideal para menus extensos
Parâmetros Detalhados
interactiveType (string, obrigatório)
O que é: Tipo de mensagem interativa.
Valores aceitos: - button - Mensagem com até 3 botões - list - Mensagem com lista expansível
Flow completo para testar:
{
"name": "Teste WhatsApp Interactive - Type Button",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "whatsapp_1",
"type": "whatsapp_meta",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Menu com Botões",
"parameters": {
"operation": "send_interactive",
"accessToken": "SEU_TOKEN",
"phoneNumberId": "SEU_PHONE_ID",
"recipientPhone": "5511999999999",
"interactiveType": "button",
"interactiveBody": {
"text": "Como podemos ajudar você hoje?"
},
"interactiveAction": {
"buttons": [
{
"type": "reply",
"reply": {
"id": "vendas",
"title": "Vendas"
}
},
{
"type": "reply",
"reply": {
"id": "suporte",
"title": "Suporte"
}
},
{
"type": "reply",
"reply": {
"id": "financeiro",
"title": "Financeiro"
}
}
]
}
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "✅ Menu enviado!"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 700, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "whatsapp_1" },
{ "source": "whatsapp_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: Mensagem aparece com 3 botões clicáveis no WhatsApp!
interactiveBody (object, obrigatório)
O que é: Corpo principal da mensagem interativa.
Estrutura:
{
"text": "Texto da mensagem (obrigatório, até 1024 caracteres)"
}
interactiveHeader (object, opcional)
O que é: Cabeçalho da mensagem (pode ser texto, imagem, vídeo ou documento).
Tipos suportados: - text - Texto curto (até 60 caracteres) - image - Imagem - video - Vídeo - document - Documento
Flow completo para testar:
{
"name": "Teste WhatsApp Interactive - Header",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "whatsapp_1",
"type": "whatsapp_meta",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Mensagem com Header",
"parameters": {
"operation": "send_interactive",
"accessToken": "SEU_TOKEN",
"phoneNumberId": "SEU_PHONE_ID",
"recipientPhone": "5511999999999",
"interactiveType": "button",
"interactiveHeader": {
"type": "text",
"text": "🛍️ LOJA VIRTUAL"
},
"interactiveBody": {
"text": "Bem-vindo à nossa loja! O que você gostaria de fazer?"
},
"interactiveFooter": {
"text": "Estamos aqui para ajudar!"
},
"interactiveAction": {
"buttons": [
{
"type": "reply",
"reply": {
"id": "ver_produtos",
"title": "Ver Produtos"
}
},
{
"type": "reply",
"reply": {
"id": "meus_pedidos",
"title": "Meus Pedidos"
}
},
{
"type": "reply",
"reply": {
"id": "suporte",
"title": "Suporte"
}
}
]
}
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 500, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "whatsapp_1" },
{ "source": "whatsapp_1", "target": "end_1" }
]
}
Teste: Mensagem aparece com header destacado no topo!
interactiveFooter (object, opcional)
O que é: Rodapé da mensagem (texto pequeno abaixo do body).
Estrutura:
{
"text": "Texto do rodapé (até 60 caracteres)"
}
interactiveAction (object, obrigatório)
O que é: Define os botões ou lista que o usuário verá.
Para type=button:
{
"buttons": [
{
"type": "reply",
"reply": {
"id": "identificador_unico",
"title": "Texto do Botão"
}
}
]
}
Para type=list:
{
"button": "Texto do botão que abre a lista",
"sections": [
{
"title": "Título da Seção",
"rows": [
{
"id": "identificador_unico",
"title": "Título da Opção",
"description": "Descrição opcional"
}
]
}
]
}
Flow completo para testar (List):
{
"name": "Teste WhatsApp Interactive - List",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "whatsapp_1",
"type": "whatsapp_meta",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Menu Lista",
"parameters": {
"operation": "send_interactive",
"accessToken": "SEU_TOKEN",
"phoneNumberId": "SEU_PHONE_ID",
"recipientPhone": "5511999999999",
"interactiveType": "list",
"interactiveHeader": {
"type": "text",
"text": "📋 MENU DE OPÇÕES"
},
"interactiveBody": {
"text": "Escolha uma das opções abaixo para continuar:"
},
"interactiveFooter": {
"text": "Atendimento 24/7"
},
"interactiveAction": {
"button": "Ver Opções",
"sections": [
{
"title": "Serviços",
"rows": [
{
"id": "servico_1",
"title": "Consulta",
"description": "Agendar uma consulta"
},
{
"id": "servico_2",
"title": "Exames",
"description": "Solicitar exames"
}
]
},
{
"title": "Informações",
"rows": [
{
"id": "info_1",
"title": "Horários",
"description": "Ver horários de atendimento"
},
{
"id": "info_2",
"title": "Localização",
"description": "Como chegar"
}
]
}
]
}
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 500, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "whatsapp_1" },
{ "source": "whatsapp_1", "target": "end_1" }
]
}
Teste: Usuário clica em "Ver Opções" e lista expansível aparece!
Parâmetros
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| operation | string | Sim | Deve ser "send_interactive" |
| accessToken | string | Sim | Token da WhatsApp Business API |
| phoneNumberId | string | Sim | ID do número de telefone WhatsApp |
| recipientPhone | string | Sim | Telefone do destinatário (formato: 5511999999999) |
| interactiveType | string | Sim | "button" ou "list" |
| interactiveBody | object | Sim | { text: "mensagem" } |
| interactiveHeader | object | Não | Cabeçalho (texto, imagem, vídeo, documento) |
| interactiveFooter | object | Não | { text: "rodapé" } |
| interactiveAction | object | Sim | Botões (button) ou Lista (list) |
Limites
| Elemento | Limite |
|---|---|
| Botões (button) | Máximo 3 botões |
| Título do botão | Máximo 20 caracteres |
| Seções (list) | Máximo 10 seções |
| Itens por seção | Máximo 10 itens |
| Título do item | Máximo 24 caracteres |
| Descrição do item | Máximo 72 caracteres |
| Header text | Máximo 60 caracteres |
| Body text | Máximo 1024 caracteres |
| Footer text | Máximo 60 caracteres |
Exemplo 1: Menu de Atendimento com Botões
Objetivo: Menu principal de atendimento com 3 opções
JSON para Importar
{
"name": "WhatsApp Interactive - Menu Atendimento",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "whatsapp_1",
"type": "whatsapp_meta",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Menu Principal",
"parameters": {
"operation": "send_interactive",
"accessToken": "SEU_TOKEN",
"phoneNumberId": "SEU_PHONE_ID",
"recipientPhone": "5511999999999",
"interactiveType": "button",
"interactiveHeader": {
"type": "text",
"text": "🏢 ATENDIMENTO"
},
"interactiveBody": {
"text": "Olá! Bem-vindo ao nosso atendimento.\n\nComo podemos ajudar você hoje?"
},
"interactiveFooter": {
"text": "Responda em até 24h"
},
"interactiveAction": {
"buttons": [
{
"type": "reply",
"reply": {
"id": "opcao_vendas",
"title": "💰 Vendas"
}
},
{
"type": "reply",
"reply": {
"id": "opcao_suporte",
"title": "🔧 Suporte"
}
},
{
"type": "reply",
"reply": {
"id": "opcao_financeiro",
"title": "📊 Financeiro"
}
}
]
}
}
}
},
{
"id": "switch_1",
"type": "switch",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Processar Resposta",
"parameters": {
"variable": "user_choice",
"cases": [
{ "value": "opcao_vendas", "targetNodeId": "msg_vendas" },
{ "value": "opcao_suporte", "targetNodeId": "msg_suporte" },
{ "value": "opcao_financeiro", "targetNodeId": "msg_financeiro" }
]
}
}
},
{
"id": "msg_vendas",
"type": "message",
"position": { "x": 700, "y": 50 },
"data": {
"label": "Vendas",
"parameters": {
"message": "💰 Você escolheu VENDAS. Em instantes um vendedor entrará em contato!"
}
}
},
{
"id": "msg_suporte",
"type": "message",
"position": { "x": 700, "y": 150 },
"data": {
"label": "Suporte",
"parameters": {
"message": "🔧 Você escolheu SUPORTE. Nossa equipe técnica já foi notificada!"
}
}
},
{
"id": "msg_financeiro",
"type": "message",
"position": { "x": 700, "y": 250 },
"data": {
"label": "Financeiro",
"parameters": {
"message": "📊 Você escolheu FINANCEIRO. O departamento foi acionado!"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 900, "y": 150 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "whatsapp_1" },
{ "source": "whatsapp_1", "target": "switch_1" },
{ "source": "msg_vendas", "target": "end_1" },
{ "source": "msg_suporte", "target": "end_1" },
{ "source": "msg_financeiro", "target": "end_1" }
]
}
Saída esperada:
[WhatsApp Interactive enviado]
Usuário: [Clica em "💰 Vendas"]
Sistema: 💰 Você escolheu VENDAS. Em instantes um vendedor entrará em contato!
Exemplo 2: Catálogo de Produtos com Lista
Objetivo: Menu expansível com categorias de produtos
JSON para Importar
{
"name": "WhatsApp Interactive - Catálogo Lista",
"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 à nossa loja virtual!"
}
}
},
{
"id": "delay_1",
"type": "delay",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Aguardar",
"parameters": {
"duration": 1,
"unit": "seconds"
}
}
},
{
"id": "whatsapp_1",
"type": "whatsapp_meta",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Catálogo",
"parameters": {
"operation": "send_interactive",
"accessToken": "SEU_TOKEN",
"phoneNumberId": "SEU_PHONE_ID",
"recipientPhone": "5511999999999",
"interactiveType": "list",
"interactiveHeader": {
"type": "text",
"text": "🛍️ NOSSOS PRODUTOS"
},
"interactiveBody": {
"text": "Confira nosso catálogo completo de produtos organizados por categoria:"
},
"interactiveFooter": {
"text": "Frete grátis acima de R$ 200"
},
"interactiveAction": {
"button": "📋 Ver Catálogo",
"sections": [
{
"title": "Eletrônicos",
"rows": [
{
"id": "eletro_smartphone",
"title": "Smartphones",
"description": "iPhone, Samsung, Xiaomi"
},
{
"id": "eletro_notebook",
"title": "Notebooks",
"description": "Dell, Lenovo, Asus"
},
{
"id": "eletro_fone",
"title": "Fones de Ouvido",
"description": "Bluetooth, In-ear, Over-ear"
}
]
},
{
"title": "Moda",
"rows": [
{
"id": "moda_camiseta",
"title": "Camisetas",
"description": "Básicas, estampadas"
},
{
"id": "moda_calca",
"title": "Calças",
"description": "Jeans, sociais, esportivas"
},
{
"id": "moda_tenis",
"title": "Tênis",
"description": "Esportivos, casuais"
}
]
},
{
"title": "Casa",
"rows": [
{
"id": "casa_decoracao",
"title": "Decoração",
"description": "Quadros, vasos, almofadas"
},
{
"id": "casa_cozinha",
"title": "Cozinha",
"description": "Utensílios, panelas"
}
]
}
]
}
}
}
},
{
"id": "message_2",
"type": "message",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Aguardar Escolha",
"parameters": {
"message": "Você escolheu: {{user_choice}}\n\nVou buscar os produtos dessa categoria..."
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1100, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "message_1" },
{ "source": "message_1", "target": "delay_1" },
{ "source": "delay_1", "target": "whatsapp_1" },
{ "source": "whatsapp_1", "target": "message_2" },
{ "source": "message_2", "target": "end_1" }
]
}
Saída esperada:
Sistema: 👋 Bem-vindo à nossa loja virtual!
[1 segundo]
[WhatsApp Lista enviada]
Usuário: [Clica em "📋 Ver Catálogo"]
Usuário: [Escolhe "Notebooks" da categoria Eletrônicos]
Sistema: Você escolheu: eletro_notebook
Sistema: Vou buscar os produtos dessa categoria...
Resposta do Node
{
"success": true,
"data": {
"messaging_product": "whatsapp",
"contacts": [
{
"input": "5511999999999",
"wa_id": "5511999999999"
}
],
"messages": [
{
"id": "wamid.HBgNNTUxMTk5OTk5OTk5ORUCABIYFjNBMDhBRjg3QTQyRjI2RTFCNDFBAA=="
}
]
},
"executionTime": 1678,
"logs": ["WhatsApp Meta send_interactive operation completed successfully"]
}
Capturando Resposta do Usuário
Quando o usuário clica em um botão ou item da lista, o WhatsApp envia um webhook com:
{
"interactive": {
"type": "button_reply", // ou "list_reply"
"button_reply": {
"id": "opcao_vendas",
"title": "Vendas"
}
}
}
Use o id para processar a escolha no flow (via SWITCH, CONDITION, etc.).
Boas Práticas
✅ SIM:
- Use botões para 2-3 opções simples
- Use lista para 4+ opções ou opções categorizadas
- Mantenha títulos curtos e objetivos (max 20 chars em botões)
- Use emojis para destacar opções
- Agrupe itens em seções lógicas nas listas
- Sempre inclua header para contexto visual
- Use footer para informações adicionais (horários, políticas)
- Capture o ID da resposta para processar escolha
❌ NÃO:
- Não use mais de 3 botões (não é suportado)
- Não ultrapasse limites de caracteres (causará erro)
- Não use botões para menus extensos (use lista)
- Não esqueça de processar a resposta do usuário
- Não crie listas com mais de 10 seções
- Não use descrições muito longas (max 72 chars)
Dicas
💡 Botões vs Lista: Use botões para escolhas simples, lista para catálogos e menus 💡 IDs únicos: Use IDs descritivos para facilitar processamento (ex: "opcao_vendas") 💡 Emojis: Tornam botões mais atrativos e fáceis de identificar 💡 Sections: Agrupe itens relacionados em seções para melhor organização 💡 Header: Sempre use header para dar contexto à mensagem 💡 Footer: Ótimo para políticas, horários, avisos importantes 💡 Descrições: Use para dar mais contexto em itens de lista 💡 Timeout: Mensagens interativas não expiram, usuário pode responder a qualquer momento
Próximo Node
→ SEND_MESSAGE - Enviar texto simples → SEND_TEMPLATE - Templates pré-aprovados → SWITCH - Processar resposta do usuário