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.
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 (allpara 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,instagramoumessenger. É 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 comchanges[].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
200antes 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
idda 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átisPerguntas 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
API de Instagram e Messenger na mesma API do WhatsApp: uma instância, um padrão
API de Instagram Direct e Messenger oficiais na mesma API do WhatsApp: uma instância, um padrão Meta, o campo provider escolhe o canal. Sem criar app na Meta.
API não oficial do WhatsApp: recursos que a oficial não tem (com exemplos)
Recursos da API não oficial do WhatsApp (QR Code): botões, listas, enquete, figurinha, reação, grupos, status e Pix — com exemplos em cURL e Node.js.
Bot de IA no WhatsApp, Instagram e Messenger com n8n (template pronto)
Monte um bot de IA (GPT/OpenAI) que responde no WhatsApp, Instagram e Messenger num único fluxo do n8n. Template pronto WAME, com memória por contato.