Pular para o conteúdo

Receber mensagens com webhooks

Webhooks são o jeito recomendado de receber eventos em produção: entregas persistentes, assinadas e com retry por 24 horas.

  1. Escreva o receptor

    Ele precisa: ler o corpo bruto, validar a assinatura, deduplicar pelo id do evento, responder 2xx rápido e processar depois.

    import http from "node:http";
    import crypto from "node:crypto";
    const SECRET = process.env.LITEZAP_WEBHOOK_SECRET;
    const seen = new Set(); // em produção: Redis/banco com expiração
    function verify(header, rawBody) {
    const parts = Object.fromEntries((header || "").split(",").map((p) => p.split("=", 2)));
    const t = Number(parts.t);
    if (!parts.v1 || !Number.isFinite(t) || Math.abs(Date.now() / 1000 - t) > 300) return false;
    const want = crypto.createHmac("sha256", SECRET).update(`${parts.t}.${rawBody}`).digest("hex");
    const a = Buffer.from(parts.v1, "hex"), b = Buffer.from(want, "hex");
    return a.length === b.length && crypto.timingSafeEqual(a, b);
    }
    http.createServer((req, res) => {
    let body = "";
    req.setEncoding("utf8");
    req.on("data", (c) => (body += c)).on("end", () => {
    if (!verify(req.headers["x-litezap-signature"], body)) return res.writeHead(401).end();
    const id = req.headers["x-litezap-event-id"];
    res.writeHead(204).end(); // responda antes de processar
    if (seen.has(id)) return;
    seen.add(id);
    const evt = JSON.parse(body);
    if (evt.type === "message.received") console.log(evt.data.chat, evt.data.text);
    });
    }).listen(9000);
  2. Exponha o receptor

    Em produção, uma URL https:// pública. Para testar no seu PC, rode o receptor em 127.0.0.1:9000 e libere destinos locais no LiteZap (webhook_allow_private_urls: true no litezap.yaml, ou LITEZAP_WEBHOOK_ALLOW_PRIVATE_URLS=true) e reinicie o serve. Em servidores, deixe essa opção desligada.

  3. Cadastre o webhook e guarde o segredo

    Janela do terminal
    curl -s -X POST localhost:8787/v1/webhooks -H "Authorization: Bearer $TOK" \
    -d '{"url":"https://seu-app.com/litezap","events":["message.*","instance.status"]}'

    A resposta traz secret (whsec_...) uma única vez. Guarde-o como LITEZAP_WEBHOOK_SECRET. Com token de instância, o webhook é daquela instância; com token admin e sem instance_id, recebe eventos de todas.

  4. Teste

    Mande uma mensagem para o número conectado: o receptor recebe message.received. Envie pela API: chegam message.sent e message.status.

events aceita tipos exatos (message.status), famílias (message.*) ou *. Assine só o que você usa: menos tráfego e menos entregas na fila. A lista de tipos está no catálogo.

  • Cada entrega tem 10s para receber um 2xx. Falhas são repetidas com backoff (1s, 2s, 4s… até 1h) por 24 horas.

  • Um endpoint que falha segura as outras entregas dele pelo mesmo backoff; outros webhooks seguem normalmente.

  • Depois de 24 horas, a entrega vai para a dead-letter:

    Janela do terminal
    curl -s "localhost:8787/v1/webhooks/$WH/deliveries?status=failed" -H "Authorization: Bearer $TOK"
    curl -s -X POST "localhost:8787/v1/webhooks/$WH/deliveries/$DLV/retry" -H "Authorization: Bearer $TOK"

PATCH /v1/webhooks/{id} com {"secret": ""} gera um segredo novo (devolvido na resposta), ou passe o seu (16 a 256 caracteres). A troca vale para as próximas entregas: atualize o receptor logo em seguida.

Veja também: entrega e retentativas · referência de webhooks.