Webhooks de eventos, assinados
Sete eventos, um endpoint por conta, e toda entrega é assinada como as do Stripe. Cada payload diz em qual número aquilo aconteceu, então uma URL só atende quantos números você tiver.
Registre uma vez
import { Whatsapi } from "@whatsapi.sh/sdk";
const wa = new Whatsapi({ apiKey: "wa_your_key" });
const data = await wa.setWebhook({ url: "https://api.yourapp.com/webhooks/whatsapp" });{
"data": {
"secret": "whsec_…", // shown ONCE, store it
"record": { "url": "…", "events": ["message.created", "…"], "enabled": true }
}
}Eventos: message.created, message.sent, message.failed, message.status, number.connected, number.disconnected, number.logged_out, number.history_synced. Os dois do meio são o desfecho de uma mensagem que esperou na fila de envio. O último chega uma vez por pareamento, quando o celular terminou de enviar as conversas antigas ou ficou 10 minutos sem enviar nada. Para rotacionar o segredo, salve o endpoint com "rotateSecret": true.
Confira a assinatura
Toda entrega carrega x-whatsapi-signature: t=<unix>,v1=<hmac>, um HMAC-SHA256 de <t>.<body> com o seu segredo. Confira antes de confiar em qualquer coisa:
import { verifyWebhook, WebhookSignatureError } from "@whatsapi.sh/sdk";
// Signature, replay window and constant-time compare, in one call. Anything
// that does not check out throws WebhookSignatureError. Answer 400.
const event = await verifyWebhook({
payload: rawBody, // the raw bytes, not the parsed body
signature: req.header("x-whatsapi-signature"),
secret: process.env.WHATSAPI_WEBHOOK_SECRET,
});Espere retentativas e deduplique
Cada evento tem até 5 tentativas de entrega. Tentamos de novo se não vier resposta ou se ela for 5xx, 408, 425 ou 429. A espera entre tentativas é de 30, 60, 120 e 240 segundos. Se o Retry-After pedir mais tempo, esperamos esse tempo, limitado a 1 hora por tentativa. Outros códigos 4xx e redirecionamentos encerram a entrega sem nova tentativa. Cadastre a URL final, sem redirecionamento. Todas as tentativas usam o mesmo id x-whatsapi-delivery. Use esse id para não processar o evento duas vezes. Depois de 10 entregas que falharam seguidas, desativamos o endpoint. Tentativas que ainda serão repetidas não entram nessa conta. Salve o endpoint corrigido ou envie um teste bem-sucedido para reativá-lo. POST /v1/webhooks/test envia um único teste e mostra o que o seu endpoint respondeu.
Leia o histórico de uma conversa
Se o seu endpoint ficou fora do ar, ou você quer contexto antes de responder, leia a própria conversa. As mensagens vêm da mais recente para a mais antiga, cada uma no mesmo formato do message.created. Um número guarda as últimas 100 mensagens de cada conversa, a não ser que você mude o historyPerChat pelo PATCH /v1/numbers/:id. Com 0, nada fica guardado.
import { Whatsapi } from "@whatsapi.sh/sdk";
const wa = new Whatsapi({ apiKey: "wa_your_key" });
const data = await wa.getChatHistory({ chat: "+5511987654321" });Ainda não sabe quais conversas existem? O GET /v1/chats lista as conversas que um número guardou, da mais recente para a mais antiga. Depois, leia cada uma como acima.
import { Whatsapi } from "@whatsapi.sh/sdk";
const wa = new Whatsapi({ apiKey: "wa_your_key" });
const data = await wa.listChats();