dm dm-chat

Webhooks

Receba eventos do dm-chat em tempo real no seu sistema. Use webhooks para integrar com n8n, Zapier, CRMs próprios, dashboards ou qualquer endpoint HTTPS.

Cadastre seus endpoints em Configurações → Webhooks após fazer login.

Eventos disponíveis

Evento Quando dispara
message.received Mensagem recebida (inbound)
message.sent Mensagem enviada (outbound)
conversation.assigned Conversa atribuída a atendente
conversation.closed Conversa encerrada
campaign.finished Campanha finalizada

Formato do payload

Todos os eventos enviam POST JSON com a estrutura:

json
{
  "event": "message.received",
  "tenant_id": 42,
  "created_at": "2026-05-05T20:30:00-03:00",
  "data": {
    "...": "campos específicos do evento"
  }
}

Exemplo: message.received

json
{
  "event": "message.received",
  "tenant_id": 42,
  "created_at": "2026-05-05T20:30:00-03:00",
  "data": {
    "conversation_id": 123,
    "message_id": 9876,
    "wa_account_id": 5,
    "from": "5511999998888",
    "contact_name": "Maria",
    "type": "text",
    "text": "Oi, quero saber sobre o curso",
    "received_at": "2026-05-05T20:29:58-03:00"
  }
}

Exemplo: conversation.assigned

json
{
  "event": "conversation.assigned",
  "tenant_id": 42,
  "created_at": "2026-05-05T20:31:10-03:00",
  "data": {
    "conversation_id": 123,
    "assigned_to": { "id": 7, "name": "Atendente João" },
    "assigned_by": { "id": 1, "name": "Admin" }
  }
}

Headers HTTP

Header Valor
Content-Typeapplication/json
User-Agentdm-chat-webhook/1.0
X-DmChat-EventNome do evento (ex.: message.received)
X-DmChat-Signaturesha256=<hex> — HMAC do body com seu secret
X-DmChat-DeliveryID único da entrega (idempotência)

Verificação HMAC

Cada endpoint tem um secret exibido apenas uma vez no momento da criação. O dm-chat assina o body bruto da requisição com HMAC-SHA256 e envia em X-DmChat-Signature no formato sha256=<hex>.

Sempre valide o body bruto (antes de qualquer parse), e use comparação constant-time (hash_equals, crypto.timingSafeEqual) para evitar ataques de timing.

Exemplos de implementação

PHP (Laravel)

php
Route::post('/dmchat-webhook', function (Request $request) {
    $secret = env('DMCHAT_WEBHOOK_SECRET');
    $body = $request->getContent();
    $sig = $request->header('X-DmChat-Signature', '');
    $expected = 'sha256=' . hash_hmac('sha256', $body, $secret);

    if (! hash_equals($expected, $sig)) {
        abort(401, 'Invalid signature');
    }

    $payload = json_decode($body, true);
    Log::info('dm-chat event', $payload);

    // Idempotência: armazenar X-DmChat-Delivery e ignorar duplicatas.
    return response()->json(['ok' => true]);
});

Node.js / Express

js
import express from 'express';
import crypto from 'node:crypto';

const app = express();
const SECRET = process.env.DMCHAT_WEBHOOK_SECRET;

// IMPORTANTE: usar raw body para o HMAC bater.
app.post('/dmchat-webhook',
    express.raw({ type: 'application/json' }),
    (req, res) => {
        const sig = req.header('X-DmChat-Signature') || '';
        const expected = 'sha256=' + crypto
            .createHmac('sha256', SECRET)
            .update(req.body)
            .digest('hex');

        const a = Buffer.from(sig);
        const b = Buffer.from(expected);
        if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) {
            return res.status(401).send('Invalid signature');
        }

        const payload = JSON.parse(req.body.toString('utf8'));
        console.log('dm-chat event', payload.event, payload.data);
        res.json({ ok: true });
    }
);

app.listen(3000);

cURL (simular entrega para testar)

Útil para reproduzir um payload no ambiente local:

bash
BODY='{"event":"message.received","tenant_id":42,"created_at":"2026-05-05T20:30:00-03:00","data":{"text":"oi"}}'
SECRET="seu_secret_aqui"
SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$SECRET" -hex | awk '{print $2}')

curl -X POST https://seu-endpoint.com/webhook \
  -H "Content-Type: application/json" \
  -H "X-DmChat-Event: message.received" \
  -H "X-DmChat-Signature: sha256=$SIG" \
  -H "X-DmChat-Delivery: test-123" \
  -d "$BODY"

n8n

  1. Crie um workflow com nó Webhook (HTTP Method: POST).
  2. Copie a URL do n8n (formato https://n8n.dominio/webhook/<id>).
  3. No dm-chat, cadastre o endpoint apontando para essa URL e copie o secret.
  4. No n8n, adicione um nó Code antes do fluxo principal:
js
// n8n Code node — valida HMAC do dm-chat
const crypto = require('crypto');
const SECRET = $env.DMCHAT_WEBHOOK_SECRET;

const raw = JSON.stringify($input.first().json);
const sig = $input.first().headers['x-dmchat-signature'] || '';
const expected = 'sha256=' + crypto.createHmac('sha256', SECRET).update(raw).digest('hex');

if (sig !== expected) {
    throw new Error('Invalid signature');
}
return $input.all();

Atenção: o n8n parseia o JSON antes do Code node. Para validação 100% precisa, use o nó Webhook com opção Raw Body ativada e re-serialize com a mesma chave/ordem do remetente, ou prefira validar por IP allowlist + token em query.

Zapier

  1. Crie um Zap com trigger Webhooks by Zapier → Catch Raw Hook.
  2. Copie a URL fornecida e cadastre como endpoint no dm-chat.
  3. Adicione um passo Code by Zapier (Run JavaScript) para validar:
js
// Zapier Code — valida HMAC
const crypto = require('crypto');
const SECRET = 'cole_seu_secret_aqui'; // ou use Storage by Zapier
const raw = inputData.rawBody;
const sig = inputData.signature;
const expected = 'sha256=' + crypto.createHmac('sha256', SECRET).update(raw).digest('hex');

if (sig !== expected) callback(new Error('Invalid signature'));
else callback(null, JSON.parse(raw));

No mapeamento do passo Code, defina rawBody = {{Raw Body}} e signature = {{X-DmChat-Signature}}.

Retries e timeouts

  • Timeout: 15 segundos por entrega.
  • Sucesso: qualquer status HTTP 2xx.
  • Retries: até 5 tentativas com backoff exponencial (10s, 1min, 10min, 1h, 6h).
  • Auto-desativação: após muitas falhas consecutivas o endpoint pode ser pausado automaticamente.
  • Idempotência: use X-DmChat-Delivery como chave para evitar processar duplicatas.

Boas práticas

  • Responda rápido (< 2s). Enfileire o processamento em background.
  • Sempre valide o HMAC antes de processar o conteúdo.
  • Armazene o X-DmChat-Delivery e ignore IDs já processados.
  • Não confie no IP de origem — confie no HMAC.
  • Use HTTPS com certificado válido (não aceitamos endpoints HTTP).