Documentação
Webhooks
Cadastre um endpoint HTTPS com POST /webhooks e os eventos que quer. Cada evento vira uma entrega: um POST com corpo JSON e três headers. O segredo de assinatura é devolvido uma vez, na criação. A URL precisa ser https e apontar para um host público: endereço de rede privada, loopback e link-local são recusados, e para testar na sua máquina use um túnel.
Eventos
- message.received: um cliente mandou mensagem. Traz wamid, from, phoneNumberId, type, text, os campos de mídia, replyPayload, flowResponse, order e o messageId da Zaiped para GET /media.
- message.status: uma mensagem sua foi entregue, lida ou falhou, com error e pricing.
- template.status: o veredito da Meta sobre um modelo.
- number.update: mudanças de qualidade, limite de envio ou nome de exibição.
- account.notice: avisos da WABA, inclusive acesso perdido.
- call.event: eventos e status de chamada de voz.
O corpo
{
"id": "YOUR_DELIVERY_ID",
"event": "message.received",
"createdAt": 1757160000000,
"data": { "wamid": "wamid.HBg...", "from": "+5511999999999", "type": "text", "text": "Oi", "messageId": "..." }
}Headers e assinatura
- X-Zaiped-Event: o nome do evento.
- X-Zaiped-Delivery: o id da entrega, o mesmo em todas as tentativas dela. Use para deduplicar.
- X-Zaiped-Signature: t=TIMESTAMP,v1=HEX, onde v1 é HMAC-SHA256(secret, "TIMESTAMP.CORPO_CRU").
// Node.js
import { createHmac, timingSafeEqual } from "node:crypto";
function verify(rawBody, header, secret) {
const [t, v1] = header.split(",").map((part) => part.slice(part.indexOf("=") + 1));
const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
return timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
}Uma entrega por evento
A Meta reentrega o mesmo evento quando não tem certeza de que o recebemos, e nós absorvemos isso: um evento de origem gera UMA entrega por endpoint, com um X-Zaiped-Delivery só. O que se repete é a tentativa da MESMA entrega, quando o seu endpoint não responde 2xx, e aí o id é o mesmo. Guarde o id que já processou e ignore repetição: é a rede que sobra para o caso raro de um evento sem identidade estável, que preferimos entregar duas vezes a engolir.
Retentativa
Responda 2xx rápido. Qualquer outra coisa, ou um timeout de dez segundos, agenda uma retentativa depois de um minuto, depois cinco, trinta, duas horas e doze horas. São seis tentativas ao todo (a primeira mais as cinco esperas); depois delas a entrega é marcada como failed e fica no registro por trinta dias. GET /webhooks/{webhookId}/deliveries lista as recentes; POST .../test manda um evento de teste.