Webhooks (Server)
Esta página descreve o que sua aplicação recebe nos webhooks configurados quando a Sendeasy processa eventos de canal e mensagem, e quando repassa eventos brutos recebidos da Meta (WhatsApp Business, Facebook, Instagram).
A referência oficial dos eventos da Meta está em developers.facebook.com — WhatsApp Cloud API Webhooks e em Graph API — WhatsApp Business Account.
Escopos: geral e por canal
Webhooks têm dois escopos possíveis:
- Geral: recebe eventos de todos os canais da empresa. Pense nele como o webhook "global" da conta.
- Por canal específico: recebe eventos apenas do canal ao qual está amarrado.
Os dois escopos coexistem. Para cada evento, a Sendeasy dispara a união: todos os webhooks gerais ativos da empresa mais o(s) webhook(s) por canal específico daquele canal. Configure quantos webhooks quiser de cada escopo.
A configuração é feita em Configurações → Integrações.
Fluxo resumido
- A Sendeasy recebe um evento da Meta (ou processa um evento interno).
- O payload é enfileirado em BullMQ e normalizado conforme o contrato público.
- A Sendeasy busca todos os webhooks
enabled=trueamarrados ao canal de origem do evento (mais os webhooks de escopo geral). - Para cada webhook encontrado, é criado um registro
WebhookDeliveryno histórico e enfileirada uma entrega. - O worker faz
POSTna URL configurada com o payload no body. Se houver bearer token configurado, ele é enviado no headerAuthorization. - Cada tentativa é registrada em
WebhookDeliveryAttempt(HTTP status, duração, response body, erro). O histórico fica visível em Configurações → Integrações → Webhook → Histórico de envios.
Payload base
Todos os eventos seguem o mesmo envelope:
| Campo | Tipo | Descrição |
|---|---|---|
event | string | nome do evento processado |
channel | string | tipo do canal: "whatsapp", "waba", "email", "sms", "facebook", "instagram" |
data | object | payload específico do evento |
channelId | string | number | identificador do canal — UUID (WhatsApp/WABA/FB/IG) ou id numérico (Email/SMS) |
{
"event": "messaging",
"channel": "whatsapp",
"data": {},
"channelId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
Tabela de eventos suportados
Cada evento que a Sendeasy emite hoje, com sua origem e link para a documentação Meta correspondente quando aplicável.
event | Canais | Origem |
|---|---|---|
messaging | whatsapp, waba, email, sms, facebook, instagram | Mensagem recebida (qualquer canal). Para WABA: campo Meta messages com messages[]. |
message_status | waba | Atualização de entrega/leitura. Campo Meta messages com statuses[]. docs |
comments | facebook, instagram | Comentário em post. Campos Meta comments e live_comments. |
account_alerts | waba | Alertas da conta WABA. docs |
phone_number_quality_update | waba | Mudança na qualidade do número. docs |
template_category_update | waba | Categoria de template alterada. docs |
message_template_status_update | waba | Aprovação/rejeição de template. docs |
message_template_quality_update | waba | Qualidade do template. docs |
business_capability_update | waba | Novas capacidades habilitadas. docs |
account_review_update | waba | Resultado de revisão da conta. docs |
account_update | waba | Atualização geral da conta. |
flows | waba | Eventos de Flows (WhatsApp). |
partner_solutions | waba | Eventos de partner solutions. |
security | waba | Eventos de segurança da conta. |
ticket.queue | interno | Mudança de fila do ticket (SendEasy). |
ticket.sector | interno | Mudança de setor do ticket (SendEasy). |
connection | whatsapp | Mudança de status da conexão (SendEasy). |
Eventos repassados da Meta: todo campo (change.field) que a Sendeasy
recebe da Meta e não processa internamente é encaminhado automaticamente
ao seu webhook como event=<change.field>. Se a Meta lançar um campo novo
(ex: xyz_update), você o receberá com event="xyz_update" sem precisar
esperar suporte oficial. O data do evento contém também metaField com
o nome original do campo Meta para referência.
Eventos por canal
WhatsApp Cloud API / WABA — channel: "waba"
messaging — mensagem recebida
{
"event": "messaging",
"channel": "waba",
"channelId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"data": {
"object": "whatsapp_business_account",
"entry": [
{
"id": "WABA_ID",
"changes": [
{
"field": "messages",
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "5511999999999",
"phone_number_id": "PHONE_ID"
},
"contacts": [{ "profile": { "name": "Cliente" }, "wa_id": "5511999999999" }],
"messages": [
{
"from": "5511999999999",
"id": "wamid.HBg...",
"timestamp": "1713800000",
"type": "text",
"text": { "body": "Olá, preciso de ajuda" }
}
]
}
}
]
}
]
}
}
message_status — status de entrega
{
"event": "message_status",
"channel": "waba",
"channelId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"data": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "5511999999999",
"phone_number_id": "PHONE_ID"
},
"statuses": [
{
"id": "wamid.HBg...",
"status": "read",
"timestamp": "1713800010",
"recipient_id": "5511999999999"
}
],
"metaField": "messages"
}
}
status pode ser sent, delivered, read, failed. Em failed há
errors[] com code, title, message, error_data.details.
account_alerts, phone_number_quality_update, template_category_update, etc. (passthrough)
{
"event": "phone_number_quality_update",
"channel": "waba",
"channelId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"data": {
"display_phone_number": "5511999999999",
"event": "FLAGGED",
"current_limit": "TIER_1K",
"metaField": "phone_number_quality_update"
}
}
O data é o change.value original da Meta, com um campo extra metaField
contendo o nome do campo Meta original.
WhatsApp clássico (Baileys/Evolution) — channel: "whatsapp"
connection
{
"event": "connection",
"channel": "whatsapp",
"channelId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"data": { "state": "open" }
}
Valores comuns: open, close.
messaging — mensagem recebida (formato Baileys)
{
"event": "messaging",
"channel": "whatsapp",
"channelId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"data": {
"key": {
"remoteJid": "5511999999999@s.whatsapp.net",
"fromMe": false,
"id": "3EB0XXXXXX"
},
"message": { "conversation": "Olá, preciso de ajuda" },
"messageTimestamp": "1634567890",
"pushName": "Cliente"
}
}
Email — channel: "email"
{
"event": "messaging",
"channel": "email",
"channelId": 7,
"data": {
"email": {
"direction": "inbound",
"mailbox": "suporte@empresa.com",
"from": { "email": "cliente@dominio.com", "name": "Cliente" },
"to": ["suporte@empresa.com"],
"subject": "Dúvida sobre o pedido #1234",
"text": "Olá, gostaria de saber...",
"html": "<p>...</p>",
"messageId": "<abc@dominio.com>",
"receivedAt": "2026-04-28T13:45:00.000Z"
}
}
}
SMS — channel: "sms"
{
"event": "messaging",
"channel": "sms",
"channelId": 15,
"data": {
"sms": {
"direction": "inbound",
"from": "+5511999999999",
"body": "Confirmar agendamento",
"providerPayload": { "...": "raw provider data" }
}
}
}
Facebook / Instagram — channel: "facebook" | "instagram"
comments
{
"event": "comments",
"channel": "facebook",
"channelId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"data": {
"from": { "id": "USER_ID", "name": "Cliente" },
"post_id": "PAGE_ID_POST_ID",
"comment_id": "COMMENT_ID",
"message": "Texto do comentário",
"created_time": 1713800000
}
}
Eventos internos do SendEasy
ticket.queue / ticket.sector
{
"event": "ticket.queue",
"channel": "whatsapp",
"channelId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"data": {
"ticketId": 123,
"previousQueueId": 5,
"newQueueId": 8
}
}
Histórico de envios
Cada disparo cria um registro persistido em WebhookDeliveries. Você pode
inspecionar o histórico em Configurações → Integrações → Webhook → Histórico
de envios, onde é possível:
- Filtrar por evento, status (
pending,processing,retrying,success,failed), e intervalo de datas. - Ver detalhes de cada tentativa: HTTP status, duração, response body, erro.
- Reenviar uma entrega manualmente (replay).
Os eventos repassados da Meta (account_alerts,
phone_number_quality_update, etc.) também ficam armazenados no histórico —
basta filtrar pelo nome do evento.
Boas práticas de consumo
- Trate o processamento como assíncrono e idempotente. A Sendeasy faz retry automático em falhas (BullMQ).
- Use idempotência por
event+ identificadores (data.entry[].changes[].value.messages[].id,data.email.messageId, etc.). - Armazene o payload bruto para troubleshooting.
- Valide o header
Authorizationquando configurado no webhook. - Timeout: a Sendeasy aguarda até 30s pela resposta do seu endpoint
(configurável via
OUTBOUND_WEBHOOK_TIMEOUT_MS). Se exceder, a entrega é marcada comoretryinge reprocessada pelo BullMQ. Devolva2xxo quanto antes; faça processamento pesado em background no seu lado. - Para eventos novos da Meta ainda não documentados acima, inspecione o
campo
data.metaField(e/oudata.entry[].changes[].field) para saber qual campo Meta gerou o evento.
Onde gerenciar
A configuração e ativação de webhooks é feita em Configurações → Integrações na plataforma.