Raphael Serafim· Publicado em 07 de agosto de 2026· 9 min de leitura

Um webhook para WhatsApp, Instagram e Messenger: o padrão Meta na prática

Receba WhatsApp, Instagram e Messenger em um único webhook no formato da Meta Cloud API, reusando um só parser. O campo provider diz o canal.

Ver como Markdown

Você pode receber mensagens e eventos de WhatsApp, Instagram e Messenger em um único webhook, no mesmo envelope da Meta Cloud API — reaproveitando um só parser. A WAME entrega os três canais na estrutura oficial da Meta; o que muda de um para o outro é apenas o campo provider. O resultado: um endpoint, um parser, três canais.

Neste guia você configura o webhook no formato meta, entende o envelope campo a campo, trata os eventos com os SDKs de Node.js e PHP (ou com Express puro) e responde à mensagem recebida dentro do próprio handler.

Por que webhooks

Sem webhook, você teria que ficar perguntando à API se chegou algo novo (polling) — desperdício de requisições e atraso. Com webhook, é o contrário: a WAME empurra o evento para o seu servidor no instante em que ele acontece. Mensagem recebida, status de entrega, presença ("digitando"), conexão da instância, QR code, chamadas — tudo chega em tempo real, no seu endpoint.

Para quem atende clientes, isso é a base de um chatbot, de um CRM ou de uma central omnichannel: o evento chega, seu código decide o que fazer e responde na hora.

Passo 1 — Configurar o webhook na instância

O webhook é configurado por instância, com um PUT /{key}/instance. O campo-chave aqui é o webhookFormat:

curl -X PUT "https://us.api-wa.me/YOUR_KEY/instance" \
  -H "Content-Type: application/json" \
  -d '{"allowWebhook":true,"allowNumber":"all","webhookFormat":"meta","webhookMessage":"https://seu-servidor.com/webhook"}'

O que cada campo faz:

  • allowWebhook — liga o envio de eventos para o seu endpoint.
  • allowNumber — quais números geram eventos (all para todos).
  • webhookMessage — a URL que vai receber os eventos.
  • webhookFormat — o formato do payload. É aqui que a mágica acontece.

Sobre o webhookFormat, há três opções:

  • native — payload no formato interno da WAME. Mais enxuto, mas específico da plataforma.
  • meta — payload no envelope oficial da Meta Cloud API. É o que permite reaproveitar os parsers oficiais e tratar WhatsApp, Instagram e Messenger com o mesmo código.
  • both — envia os dois formatos, útil em migrações ou testes.

Para o cenário deste post — um webhook, três canais — use meta. Assim seu parser já entende a estrutura que a própria Meta documenta, e o campo provider diferencia o canal.

Passo 2 — O envelope

Independentemente do canal, o corpo entregue no formato meta tem sempre a mesma forma. Só muda o provider (e o messaging_product interno):

{
  "object": "wame",
  "provider": "whatsapp",
  "instance": "YOUR_INSTANCE_ID",
  "official": true,
  "entry": [{ "id": "YOUR_INSTANCE_ID", "changes": [{ "field": "messages", "value": {
    "messaging_product": "whatsapp",
    "metadata": { "display_phone_number": "5511999990000", "phone_number_id": "YOUR_INSTANCE_ID" },
    "contacts": [{ "profile": { "name": "Fulano" }, "wa_id": "5511988887777" }],
    "messages": [{ "from": "5511988887777", "id": "wamid.XXX", "timestamp": "1700000000", "type": "text", "text": { "body": "Olá!" } }]
  }}]}]
}

Os campos que importam:

  • object — identifica a origem do evento (wame).
  • provider — o canal: whatsapp, instagram ou messenger. É o campo que o seu código lê para saber por onde responder.
  • instance — o identificador da instância que gerou o evento.
  • official — se a instância é oficial (API Cloud da Meta) ou não.
  • entry[] — a lista de entradas, cada uma com changes[].
  • entry[].changes[].field — o tipo de evento (messages, presence, etc.).
  • entry[].changes[].value — o conteúdo do evento, no formato oficial da Meta.

Para trocar de canal, imagine o mesmo JSON com "provider": "instagram" — a estrutura de leitura do seu código continua idêntica. É esse o ganho de usar o padrão Meta.

Passo 3 — Tratar os eventos

Você não precisa navegar o entry[].changes[].value na mão. Os SDKs oficiais têm um parser que achata o envelope em uma lista de eventos tipados, já expondo provider, official, fromUserId e profile.

Node.js / TypeScript

Com o SDK @raphaelvserafim/client-api-whatsapp, use parseWebhook:

import express from 'express';
import { Wame, TypeMessage, parseWebhook } from '@raphaelvserafim/client-api-whatsapp';
const wa = new Wame({ server: "https://us.api-wa.me", key: "YOUR_KEY" });
const app = express();
app.use(express.json());
app.post('/webhook', async (req, res) => {
  res.sendStatus(200);
  const events = parseWebhook(req.body);
  for (const ev of events) {
    if (ev.type === 'text') {
      await wa.message.send({ type: TypeMessage.TEXT, body: { to: ev.from, text: "Recebi: " + ev.text, provider: ev.provider } });
    }
  }
});
app.listen(3000);

Repare em dois pontos: o res.sendStatus(200) vem antes do processamento, e o ev.provider é repassado no envio — assim a resposta volta pelo mesmo canal de onde a mensagem chegou.

PHP

No SDK raphaelvserafim/client-php-api-wa-me, o método equivalente é parseMeta:

use Api\Wame\Wame;
$wa = new Wame(['server' => 'https://us.api-wa.me', 'key' => 'YOUR_KEY']);
$body = json_decode(file_get_contents('php://input'), true);
$events = $wa->webhook->parseMeta($body);
foreach ($events as $e) {
  if ($e['type'] === 'text') {
    $wa->message->sendText($e['from'], 'Recebi: ' . $e['text']['body'], $e['provider']);
  }
}

Sem SDK — lendo o envelope cru com Express

Se preferir não usar SDK, dá para navegar o envelope diretamente. É útil para entender a estrutura por trás do parser:

import express from 'express';
const app = express();
app.use(express.json());
app.post('/webhook', (req, res) => {
  res.sendStatus(200);
  const body = req.body;
  const provider = body.provider;
  for (const entry of body.entry || []) {
    for (const change of entry.changes || []) {
      if (change.field !== 'messages') continue;
      for (const msg of change.value.messages || []) {
        if (msg.type === 'text') {
          console.log(provider, msg.from, msg.text.body);
        }
      }
    }
  }
});
app.listen(3000);

O caminho é sempre o mesmo: body.entry[].changes[], filtrando por field e lendo o value. Trocar de WhatsApp para Instagram ou Messenger não muda esse percurso — só o provider.

Passo 4 — Tipos de field

O campo field de cada change diz que tipo de evento chegou. Trate cada um conforme sua necessidade:

  • messages — mensagens recebidas e status de entrega (enviado, entregue, lido, falha). É o mais usado.
  • presence — presença do contato ("digitando", online).
  • connection — mudanças de estado da conexão da instância.
  • qrcode — novo QR code disponível (para instâncias não oficiais).
  • call — eventos de chamada.
  • groups — eventos de grupo (entrada, saída, alterações).
  • health — saúde da instância.

Sobre os status de entrega: eles chegam dentro de field: "messages", no array statuses do value (em vez de messages). É assim que você acompanha se a mensagem que você enviou foi entregue e lida — essencial para métricas e reenvio.

Passo 5 — Responder à mensagem no próprio handler

Como visto nos exemplos, responder é só chamar o send com o provider do evento. O ponto importante é repassar ev.provider: sem isso, o envio pode ir pelo canal errado. Como o parser já entrega esse campo, basta encaminhá-lo.

Esse padrão fecha o ciclo: chegou uma mensagem no Instagram, seu código responde no Instagram; chegou no WhatsApp, responde no WhatsApp — tudo no mesmo handler, sem if por canal para montar a chamada de envio.

Passo 6 — Boas práticas

  • Responda 200 rápido. Envie o 200 antes de processar a lógica. Se o seu endpoint demora, a WAME pode considerar falha e reentregar o evento, gerando duplicidade. Processe de forma assíncrona (fila, worker) quando a lógica for pesada.
  • Seja idempotente. Use o id da mensagem (wamid.XXX) para ignorar reentregas do mesmo evento.
  • Monitore a entrega. Consulte as estatísticas do webhook para ver se está tudo chegando:
curl "https://us.api-wa.me/YOUR_KEY/instance/webhook/statistics"
  • Trate os três estados. No handler, considere sempre o caminho de erro (payload inesperado), o vazio (evento sem messages) e o feliz — não só o último.

Conclusão

Um único endpoint, um único parser e o campo provider para diferenciar o canal: é assim que a WAME transforma WhatsApp, Instagram e Messenger em uma superfície só, usando o envelope oficial da Meta. Você escreve o parser uma vez e ele serve para os três.

Comece configurando a instância com webhookFormat: "meta" e aponte seu endpoint. Para aprofundar, veja a documentação de webhooks, o SDK de TypeScript e o SDK de PHP. E se quiser entender como um só conjunto de endpoints atende os três canais, leia Instagram e Messenger na mesma API do WhatsApp.

Pronto para automatizar seu WhatsApp?

Crie sua conta gratuita e comece a enviar mensagens pela API em minutos.

Começar grátis

Perguntas frequentes

Como recebo mensagens dos três canais em um só webhook?+

Configure a instância com webhookFormat "meta". A WAME entrega os eventos de WhatsApp, Instagram e Messenger no mesmo envelope da Meta Cloud API, mudando apenas o campo provider. Assim você usa um único endpoint e um único parser para os três canais.

O que é o campo provider no envelope?+

É o campo que identifica de qual canal veio o evento: "whatsapp", "instagram" ou "messenger". Como o restante da estrutura é idêntica, seu código lê provider para saber por onde responder, sem precisar de webhooks separados.

Qual a diferença entre webhookFormat native, meta e both?+

native entrega o payload no formato interno da WAME; meta entrega no envelope oficial da Meta Cloud API, reaproveitando os parsers oficiais; both envia os dois formatos. Use meta para padronizar WhatsApp, Instagram e Messenger com o mesmo parser.

Preciso responder algo ao webhook?+

Sim, responda HTTP 200 o mais rápido possível para confirmar o recebimento. Processe a lógica de negócio depois, de forma assíncrona, para evitar timeouts e reentregas. Nos SDKs isso é feito enviando o 200 antes de processar os eventos.

Como sei se meu webhook está recebendo os eventos?+

Consulte GET /{key}/instance/webhook/statistics para ver estatísticas de entrega, incluindo sucessos e falhas. Isso ajuda a diagnosticar endpoints fora do ar, respostas lentas ou URLs mal configuradas.

Continue lendo