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

  1. A Sendeasy recebe um evento da Meta (ou processa um evento interno).
  2. O payload é enfileirado em BullMQ e normalizado conforme o contrato público.
  3. A Sendeasy busca todos os webhooks enabled=true amarrados ao canal de origem do evento (mais os webhooks de escopo geral).
  4. Para cada webhook encontrado, é criado um registro WebhookDelivery no histórico e enfileirada uma entrega.
  5. O worker faz POST na URL configurada com o payload no body. Se houver bearer token configurado, ele é enviado no header Authorization.
  6. 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:

CampoTipoDescrição
eventstringnome do evento processado
channelstringtipo do canal: "whatsapp", "waba", "email", "sms", "facebook", "instagram"
dataobjectpayload específico do evento
channelIdstring | numberidentificador 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.

eventCanaisOrigem
messagingwhatsapp, waba, email, sms, facebook, instagramMensagem recebida (qualquer canal). Para WABA: campo Meta messages com messages[].
message_statuswabaAtualização de entrega/leitura. Campo Meta messages com statuses[]. docs
commentsfacebook, instagramComentário em post. Campos Meta comments e live_comments.
account_alertswabaAlertas da conta WABA. docs
phone_number_quality_updatewabaMudança na qualidade do número. docs
template_category_updatewabaCategoria de template alterada. docs
message_template_status_updatewabaAprovação/rejeição de template. docs
message_template_quality_updatewabaQualidade do template. docs
business_capability_updatewabaNovas capacidades habilitadas. docs
account_review_updatewabaResultado de revisão da conta. docs
account_updatewabaAtualização geral da conta.
flowswabaEventos de Flows (WhatsApp).
partner_solutionswabaEventos de partner solutions.
securitywabaEventos de segurança da conta.
ticket.queueinternoMudança de fila do ticket (SendEasy).
ticket.sectorinternoMudança de setor do ticket (SendEasy).
connectionwhatsappMudança de status da conexão (SendEasy).

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 failederrors[] 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

  1. Trate o processamento como assíncrono e idempotente. A Sendeasy faz retry automático em falhas (BullMQ).
  2. Use idempotência por event + identificadores (data.entry[].changes[].value.messages[].id, data.email.messageId, etc.).
  3. Armazene o payload bruto para troubleshooting.
  4. Valide o header Authorization quando configurado no webhook.
  5. Timeout: a Sendeasy aguarda até 30s pela resposta do seu endpoint (configurável via OUTBOUND_WEBHOOK_TIMEOUT_MS). Se exceder, a entrega é marcada como retrying e reprocessada pelo BullMQ. Devolva 2xx o quanto antes; faça processamento pesado em background no seu lado.
  6. Para eventos novos da Meta ainda não documentados acima, inspecione o campo data.metaField (e/ou data.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.

Essa informação foi útil?