Webhooks
Verificacao e recebimento de eventos da Meta Cloud API — mensagens, status e templates
Webhooks
Endpoints para verificacao e recebimento de eventos do WhatsApp via Meta Cloud API. Ambos sao publicos (sem autenticacao por header).
A seguranca e garantida pela validacao do hub.verify_token (GET) e da assinatura x-hub-signature-256 (POST).
GET /webhooks/whatsapp
Verificacao do webhook pela Meta. Quando voce configura a URL do webhook no painel do Meta App, a Meta envia um GET para validar que voce controla o endpoint.
Auth: Publico.
Query Parameters:
| Parametro | Tipo | Descricao |
|---|---|---|
hub.mode | string | Sempre subscribe |
hub.verify_token | string | Token configurado na variavel META_VERIFY_TOKEN |
hub.challenge | string | String aleatoria que deve ser retornada como resposta |
Curl (simulando a verificacao):
curl "http://localhost:8200/webhooks/whatsapp?hub.mode=subscribe&hub.verify_token=seu-verify-token&hub.challenge=challenge123"Resposta (200 OK):
challenge123Se o verify_token nao bater, retorna 403 Forbidden.
Configuracao: Defina a variavel de ambiente
META_VERIFY_TOKENcom o mesmo valor configurado no painel do Meta App em Webhooks > Callback URL > Verify Token.
POST /webhooks/whatsapp
Recebe eventos da Meta (mensagens recebidas, status de entrega, atualizacoes de templates).
Auth: Publico. Validacao via header x-hub-signature-256.
Header de Seguranca:
| Header | Descricao |
|---|---|
x-hub-signature-256 | HMAC-SHA256 do body usando META_APP_SECRET como chave |
O connector valida automaticamente a assinatura. Se a assinatura for invalida, retorna 401 Unauthorized.
Curl (exemplo de envio manual para teste):
curl -X POST http://localhost:8200/webhooks/whatsapp \
-H "Content-Type: application/json" \
-H "x-hub-signature-256: sha256=abc123..." \
-d '{
"object": "whatsapp_business_account",
"entry": [
{
"id": "WABA_ID",
"changes": [
{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "5511999998888",
"phone_number_id": "123456789"
},
"messages": [
{
"from": "5511888887777",
"id": "wamid.HBgNNTUxMTk...",
"timestamp": "1712188800",
"type": "text",
"text": {
"body": "Ola, quero simular FGTS"
}
}
]
},
"field": "messages"
}
]
}
]
}'Resposta (200 OK):
{
"status": "ok"
}Importante: Sempre retorne
200 OKrapidamente. O processamento da mensagem ocorre em background. A Meta reenvia webhooks que nao recebem 200 em ate 5 segundos.
Tipos de Evento
messages
Mensagens recebidas dos usuarios. O campo type indica o tipo de mensagem.
Payload value.messages[]:
{
"from": "5511888887777",
"id": "wamid.HBgNNTUxMTk...",
"timestamp": "1712188800",
"type": "text",
"text": {
"body": "Quero simular FGTS"
}
}Tipos de mensagem suportados:
| type | Descricao | Campo com conteudo |
|---|---|---|
text | Texto simples | text.body |
image | Imagem | image.id, image.caption |
video | Video | video.id, video.caption |
audio | Audio/voz | audio.id |
document | Documento | document.id, document.filename |
sticker | Sticker | sticker.id |
location | Localizacao | location.latitude, location.longitude |
contacts | Contato | contacts[].name, contacts[].phones |
interactive | Resposta de botao/lista | interactive.type, interactive.button_reply ou interactive.list_reply |
button | Resposta de botao de template | button.text, button.payload |
reaction | Reacao com emoji | reaction.message_id, reaction.emoji |
Contexto de resposta (quando usuario responde a mensagem):
{
"from": "5511888887777",
"id": "wamid.NEW...",
"context": {
"from": "5511999998888",
"id": "wamid.ORIGINAL..."
},
"type": "text",
"text": {
"body": "Sim, quero prosseguir"
}
}statuses
Status de entrega de mensagens enviadas.
Payload value.statuses[]:
{
"id": "wamid.HBgNNTUxMTk...",
"status": "delivered",
"timestamp": "1712188810",
"recipient_id": "5511888887777",
"conversation": {
"id": "CONVERSATION_ID",
"origin": {
"type": "service"
},
"expiration_timestamp": "1712275200"
},
"pricing": {
"billable": true,
"pricing_model": "CBP",
"category": "service"
}
}Ciclo de vida do status:
| Status | Descricao |
|---|---|
sent | Mensagem enviada ao servidor da Meta |
delivered | Entregue no dispositivo do destinatario |
read | Lida pelo destinatario |
failed | Falha no envio (ver errors[]) |
Exemplo de status failed:
{
"id": "wamid.HBgNNTUxMTk...",
"status": "failed",
"timestamp": "1712188810",
"recipient_id": "5511888887777",
"errors": [
{
"code": 131047,
"title": "Re-engagement message",
"message": "More than 24 hours have passed since the recipient last replied",
"error_data": {
"details": "Message failed to send because more than 24 hours have passed since the customer last replied to this number."
}
}
]
}message_template_status_update
Notificacoes sobre mudancas de status de templates.
Payload value:
{
"event": "APPROVED",
"message_template_id": 123456789,
"message_template_name": "fgts_simulacao_pronta",
"message_template_language": "pt_BR",
"reason": null
}| Event | Descricao |
|---|---|
APPROVED | Template aprovado pela Meta |
REJECTED | Template rejeitado |
PENDING_DELETION | Template sera deletado |
DISABLED | Template desabilitado por baixa qualidade |
PAUSED | Template pausado por baixa qualidade |
REINSTATED | Template reativado apos melhoria de qualidade |
Estrutura Completa do Payload
{
"object": "whatsapp_business_account",
"entry": [
{
"id": "WABA_ID",
"changes": [
{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "5511999998888",
"phone_number_id": "123456789"
},
"contacts": [
{
"profile": {
"name": "Joao Silva"
},
"wa_id": "5511888887777",
"user_id": "USER_ID"
}
],
"messages": [],
"statuses": []
},
"field": "messages"
}
]
}
]
}BSUID 2026
A partir de 2026, payloads de webhook incluem o campo user_id dentro de contacts[]. Este campo identifica unicamente o usuario do WhatsApp e pode ser usado para rastreamento cross-device.
{
"contacts": [
{
"profile": { "name": "Joao Silva" },
"wa_id": "5511888887777",
"user_id": "ABCdef123..."
}
]
}Fluxo de Processamento
- Meta envia POST para
/webhooks/whatsapp - Connector valida
x-hub-signature-256comMETA_APP_SECRET - Identifica a instancia pelo
phone_number_idno payload - Retorna
200 OKimediatamente - Processa a mensagem em background:
- Verifica idempotencia (deduplicacao por
message_id) - Armazena no buffer de mensagens (aguarda delay configuravel)
- Encaminha para o Agente IA (
AGENT_MODULE_URL) - Envia resposta do agente via Meta Cloud API
- Verifica idempotencia (deduplicacao por
Configuracao do buffer: A variavel
MESSAGE_BUFFER_DELAY(padrao: 8 segundos) controla o tempo de espera para agrupar mensagens consecutivas do mesmo usuario antes de enviar ao agente.