Pular para conteúdo

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:

  1. Menus estruturados: Oferecer opções organizadas em botões ou listas
  2. Experiência guiada: Conduzir usuário por opções predefinidas
  3. Reduzir erros: Eliminar digitação livre (usuário clica em vez de digitar)
  4. Capturar escolhas: Obter resposta estruturada para processar no flow
  5. Melhor UX: Interface visual mais amigável que texto livre
  6. Automação eficiente: Respostas padronizadas facilitam processamento

Como funciona internamente?

Quando o SEND INTERACTIVE é executado, o sistema:

  1. Valida credenciais: Verifica accessToken e phoneNumberId
  2. Valida tipo interativo: Confirma interactiveType (button ou list)
  3. Valida body: Garante que interactiveBody.text existe
  4. Monta estrutura: Cria JSON com header, body, footer, action
  5. Formata botões/listas: Estrutura buttons ou sections conforme tipo
  6. Envia requisição: POST para WhatsApp Graph API
  7. 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:

  1. Menu principal: "Escolha uma opção: Vendas, Suporte, Financeiro"
  2. Confirmações: "Sim" / "Não" como botões
  3. Avaliação: "Ruim", "Regular", "Bom", "Excelente"
  4. Categorias: Listar departamentos, produtos, serviços
  5. Agendamento: Escolher horários disponíveis
  6. FAQ: Menu de perguntas frequentes
  7. 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