Visão geral
O DBestChatBot dispara webhooks de saída quando eventos relevantes acontecem nos seus chatbots (um lead é capturado, uma conversa começa ou termina, uma mensagem é enviada ou recebida). Você configura uma URL de destino no dashboard e nós enviamos um envelope JSON via POST para ela em segundos após cada evento.
Os webhooks são um recurso Pro / Agency. Free-tier accounts can still view conversations and leads in the dashboard but can't pipe them to external systems.
Eventos
Cada webhook subscreve um ou mais destes tipos de evento:
| Evento | Quando é acionado |
|---|---|
lead.captured | Um visitante submete o formulário de pré-chat, OU uma mensagem recebida no WhatsApp inicia uma conversa (temos sempre o telefone dele). Recomendado para integração com CRM. |
conversation.started | Começa uma nova conversa. Útil para análises de marketing ou para iniciar fluxos de acompanhamento de imediato. |
conversation.ended | O visitante fecha o chat ou ele fica inativo por mais de 5 minutos. Bom para disparar e-mails de acompanhamento. |
message.received | O visitante enviou uma mensagem. Alto volume — subscreva apenas se tiver uma necessidade específica. |
message.sent | A IA respondeu a um visitante. Alto volume — subscreva apenas se tiver uma necessidade específica. |
Formato do payload
Cada webhook envia um envelope JSON com os mesmos campos de nível superior. O data o objeto varia conforme o tipo de evento. Exemplo para lead.captured:
{
"event": "lead.captured",
"id": "evt_abc123def456",
"created_at": "2026-05-17T15:30:00+00:00",
"data": {
"conversation_id": "conv_xyz789",
"chatbot": {
"id": 42,
"name": "Acme Support"
},
"visitor": {
"name": "Jane Doe",
"email": "jane@acme.com",
"phone": "+15551234567"
},
"source_url": "https://acme.com/pricing",
"message_count": 4,
"transcript_url": "https://dbestchatbot.com/app/conversations/conv_xyz789",
"capture_method": "prechat_form"
}
}Cabeçalhos do pedido
Cada pedido inclui:
Content-Type: application/jsonUser-Agent: DBestChatBot-Webhook/1.0X-DBestChatBot-Event: lead.captured— o nome do eventoX-DBestChatBot-Delivery: evt_abc123— ID de entrega único, use para deduplicaçãoX-DBestChatBot-Signature: t=1747490400,v1=<hex_hmac>— assinatura de verificação
Verificando assinaturas (recomendado)
Verifique sempre os payloads dos webhooks para garantir que vieram realmente do DBestChatBot. O formato da assinatura é compatível com Stripe: um timestamp Unix t e um digest hexadecimal HMAC-SHA-256 v1, unidos por uma vírgula.
Algoritmo:
- Extrair
tandv1no cabeçalho - Rejeitar se
testá mais de 5 minutos distante do horário atual (proteção contra replay) - Calcular
expected = HMAC_SHA256(signing_secret, "t.raw_request_body") - Comparação em tempo constante
expectedwithv1 - Se coincidirem, o payload é autêntico. Caso contrário, rejeita.
Node.js / Express
// Node.js / Express example — verify the signature header
import express from 'express';
import crypto from 'crypto';
const app = express();
const SIGNING_SECRET = process.env.DBESTCHATBOT_SIGNING_SECRET;
// IMPORTANT: use raw body, not parsed JSON, for signature verification
app.post('/webhooks/dbestchatbot',
express.raw({ type: 'application/json' }),
(req, res) => {
const header = req.header('X-DBestChatBot-Signature') || '';
const match = header.match(/t=(\d+),v1=([a-f0-9]+)/);
if (!match) return res.status(400).send('bad signature header');
const [, ts, signature] = match;
// 5-minute replay window
if (Math.abs(Date.now() / 1000 - parseInt(ts)) > 300) {
return res.status(400).send('stale timestamp');
}
const expected = crypto
.createHmac('sha256', SIGNING_SECRET)
.update(`${ts}.${req.body}`)
.digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature))) {
return res.status(401).send('signature mismatch');
}
const event = JSON.parse(req.body.toString());
console.log('Verified event:', event.event, event.data);
// Always respond 2xx quickly — we'll retry up to 5x with backoff if you don't
res.status(200).send('ok');
},
);PHP
<?php
// PHP example — verify the signature header
$signingSecret = getenv('DBESTCHATBOT_SIGNING_SECRET');
$rawBody = file_get_contents('php://input');
$header = $_SERVER['HTTP_X_DBESTCHATBOT_SIGNATURE'] ?? '';
if (! preg_match('/t=(\d+),v1=([a-f0-9]+)/', $header, $m)) {
http_response_code(400); exit('bad signature header');
}
[, $ts, $signature] = $m;
if (abs(time() - (int) $ts) > 300) {
http_response_code(400); exit('stale timestamp');
}
$expected = hash_hmac('sha256', "{$ts}.{$rawBody}", $signingSecret);
if (! hash_equals($expected, $signature)) {
http_response_code(401); exit('signature mismatch');
}
$event = json_decode($rawBody, true);
// process $event['event'], $event['data'] ...
http_response_code(200);
echo 'ok';Novas tentativas e garantias de entrega
Tentamos novamente até 5 vezes with exponential backoff if your endpoint doesn't return a 2xx response within 30 seconds:
| Tentativa | Atraso desde o anterior |
|---|---|
| 1 | immediate |
| 2 | +1 minuto |
| 3 | +5 minutos |
| 4 | +30 minutos |
| 5 | +2 horas |
Após a 5ª tentativa falhada, a entrega é marcada como failed e paramos de tentar novamente. Você pode ver o registro completo de entregas (incluindo status HTTP, mensagem de erro e número de tentativas) na página de detalhes do webhook no seu painel.
Retorne sempre um status 2xx rapidamente. Se precisar fazer processamento pesado, confirme com 200 primeiro e processe de forma assíncrona.
Idempotência
Cada entrega tem um único id campo (também enviado como X-DBestChatBot-Delivery). Because we retry on failure, your endpoint may receive the same event more than once. Store the IDs you've already processed and skip duplicates.
Lista de permissões de IP
Os webhooks de saída têm origem nos nossos servidores de produção em 15.204.199.41. Se você usar allowlist por IP, permita este endereço. No entanto, as assinaturas são o caminho de verificação mais confiável — o IP pode ser falsificado, o HMAC não (sem o segredo).
Primeiros passos
- Ir para Webhooks no seu painel
- Clique Adicionar endpoint — cole o seu URL, escolha eventos
- Copiar o segredo de assinatura exibido após a criação
- Envie um evento de teste para verificar se o seu endpoint o recebe e valida
- Veja eventos reais fluindo enquanto os visitantes usam seus chatbots
Conectando ao Zapier / Make / n8n
All three tools have a generic "Catch Hook" or "Webhook Trigger" action — paste the URL they generate into a new endpoint here, subscribe to the events you want, done. Map fields from data.visitor para o seu CRM, Sheets ou para onde quiser a partir daí.
HubSpot — guia completo
Esta é a configuração mais comum. Captura cada lead do chatbot como um Contato do HubSpot:
- No Zapier, clique Criar Zap → Gatilho: Webhooks by Zapier → evento Catch Hook → continuar. O Zapier mostra uma URL personalizada como
https://hooks.zapier.com/hooks/catch/12345/abc/ - No DBestChatBot, vá a Webhooks → Adicionar endpoint. Paste the Zapier URL, name it "HubSpot via Zapier," subscribe to
lead.captured, salvar. - De volta ao Zapier: clique Testar gatilho. Depois, na página de webhook do DBestChatBot, clique em Enviar evento de teste. O Zapier deve receber um payload de exemplo — o exemplo inclui
data.visitor.name,data.visitor.email,data.visitor.phone, e quaisquer campos personalizados de pré-chat que tenha definido. - No Zapier, adicione um Ação → HubSpot → evento Criar ou atualizar contato. Autorize sua conta HubSpot.
- Mapeie os campos:
- HubSpot
email← Zapierdata.visitor.email - HubSpot
firstname← Zapierdata.visitor.name(separe nome/sobrenome se precisar) - HubSpot
phone← Zapierdata.visitor.phone - HubSpot
company← Zapierdata.visitor.company(if you added a custom "Company" field in your chatbot's pre-chat form) - HubSpot
lifecycle_stage→ codificar para Lead or Subscritor - HubSpot
website← Zapierdata.source_url
- HubSpot
- Opcional, mas recomendado: adicione uma segunda ação → HubSpot → Criar nota nesse contacto com o URL da transcrição do chat
data.transcript_urlcomo corpo da nota. Sua equipe de vendas clica no link e vê a conversa completa que levou à captura. - Ative o Zap. Cada futuro
lead.capturedo evento cria / atualiza automaticamente um Contato do HubSpot em segundos.
Dica Pro: if you want to route HIGH-VALUE leads differently (e.g. enterprise pricing inquiries) from FAQ-style chats, add a custom field to your pre-chat form like "What are you looking to do?" with options "Just browsing / Buying / Sales question." Then in Zapier add a Filter step that only continues to HubSpot if the answer is "Sales question" — your CRM stays clean.
Outros CRMs: o mesmo padrão funciona para Pipedrive (ação: Create Deal), Salesforce (ação: Create/Update Lead), Close (ação: Create Lead), monday.com (ação: Create Item) e Airtable (ação: Create Record). O lado do DBestChatBot é idêntico — basta apontar um Zap diferente para a mesma URL de webhook.
FAQ
Why isn't my endpoint receiving events?
- Verifique se o webhook está active no painel
- Check you're subscribed to the right event type
- Verifique o registo de entregas na página de detalhe do webhook para erros HTTP
- Use o Enviar evento de teste button to bypass real-world triggers
Como posso parar de receber eventos temporariamente?
Toggle the webhook off — no events are queued or buffered, they're simply dropped.
Posso obter eventos mais antigos que já aconteceram?
Não, os webhooks são disparados sem confirmação. Para dados históricos, use o painel Conversas exportação (CSV) ou fale connosco sobre um backfill pontual.