Panoramica
DBestChatBot invia webhook in uscita quando accadono eventi significativi sui tuoi chatbot (viene acquisito un lead, inizia o termina una conversazione, viene inviato o ricevuto un messaggio). Configuri un URL di destinazione nella dashboard e noi inviamo via POST un envelope JSON entro pochi secondi da ogni evento.
Webhooks are a Pro / Agency feature. Free-tier accounts can still view conversations and leads in the dashboard but can't pipe them to external systems.
Eventi
Ogni webhook si iscrive a uno o più di questi tipi di evento:
| Evento | Quando si attiva |
|---|---|
lead.captured | Un visitatore invia il modulo pre-chat, OPPURE un messaggio WhatsApp in entrata avvia una conversazione (abbiamo sempre il suo numero). Consigliato per il collegamento al CRM. |
conversation.started | Inizia una nuova conversazione. Utile per le analisi di marketing o per avviare subito flussi di follow-up. |
conversation.ended | Il visitatore chiude la chat o resta inattivo per oltre 5 minuti. Utile per attivare email di follow-up. |
message.received | Il visitatore ha inviato un messaggio. Volume elevato — abbonati solo se hai un'esigenza specifica. |
message.sent | L'AI ha risposto a un visitatore. Volume elevato — abbonati solo se hai un'esigenza specifica. |
Formato del payload
Ogni webhook invia un envelope JSON con gli stessi campi di primo livello. Il data l'oggetto varia in base al tipo di evento. Esempio per 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"
}
}Header della richiesta
Ogni richiesta include:
Content-Type: application/jsonUser-Agent: DBestChatBot-Webhook/1.0X-DBestChatBot-Event: lead.captured— il nome dell'eventoX-DBestChatBot-Delivery: evt_abc123— ID di consegna univoco, da usare per la deduplicazioneX-DBestChatBot-Signature: t=1747490400,v1=<hex_hmac>— firma di verifica
Verifica delle firme (consigliato)
Verifica sempre i payload dei webhook per assicurarti che provengano davvero da DBestChatBot. Il formato della firma è compatibile con Stripe: un timestamp Unix t e un digest esadecimale HMAC-SHA-256 v1, uniti da una virgola.
Algoritmo:
- Estrai
tandv1dall'intestazione - Rifiuta se
tè superiore a 5 minuti rispetto all'ora corrente (protezione replay) - Calcola
expected = HMAC_SHA256(signing_secret, "t.raw_request_body") - Confronto a tempo costante
expectedwithv1 - Se corrispondono, il payload è autentico. Altrimenti rifiuta.
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';Nuovi tentativi e garanzie di consegna
Riproviamo fino a 5 volte with exponential backoff if your endpoint doesn't return a 2xx response within 30 seconds:
| Tentativo | Ritardo rispetto al precedente |
|---|---|
| 1 | immediate |
| 2 | +1 minuto |
| 3 | +5 minuti |
| 4 | +30 minuti |
| 5 | +2 ore |
Dopo il 5° tentativo fallito, la consegna viene contrassegnata come failed e interrompiamo i tentativi. Puoi vedere il log completo delle consegne (inclusi stato HTTP, messaggio di errore e numero di tentativi) nella pagina di dettaglio del webhook nella tua dashboard.
Restituisci sempre rapidamente uno stato 2xx. Se devi fare elaborazioni pesanti, rispondi prima con 200 ed elabora in modo asincrono.
Idempotenza
Ogni consegna ha un id campo (inviato anche come 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.
Allowlist IP
I webhook in uscita provengono dai nostri server di produzione su 15.204.199.41. Se usi una allowlist per IP, consenti questo indirizzo. Le firme sono comunque il percorso di verifica più affidabile — l'IP può essere falsificato, HMAC no (senza il segreto).
Per iniziare
- Vai a Webhooks nella tua dashboard
- Clicca Aggiungi endpoint — incolla il tuo URL, scegli gli eventi
- Copia il signing secret mostrato dopo la creazione
- Invia un evento di test per verificare che il tuo endpoint lo riceva e lo convalidi
- Osserva gli eventi reali scorrere mentre i visitatori usano i tuoi chatbot
Connessione a 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 nel tuo CRM, in Sheets o dove preferisci da lì.
HubSpot — guida completa
Questa è la configurazione più comune. Cattura ogni lead del chatbot come Contatto HubSpot:
- In Zapier, clicca Crea Zap → Trigger: Webhooks by Zapier → evento Catch Hook → continua. Zapier ti mostra un URL personalizzato come
https://hooks.zapier.com/hooks/catch/12345/abc/ - In DBestChatBot, vai a Webhooks → Aggiungi endpoint. Paste the Zapier URL, name it "HubSpot via Zapier," subscribe to
lead.captured, salva. - Torna in Zapier: clicca Test trigger. Poi nella pagina webhook del tuo DBestChatChatBot, clicca Invia evento di test. Zapier dovrebbe ricevere un payload di esempio — l'esempio include
data.visitor.name,data.visitor.email,data.visitor.phone, e qualsiasi campo personalizzato pre-chat che hai definito. - In Zapier, aggiungi un Azione → HubSpot → evento Crea o aggiorna contatto. Autorizza il tuo account HubSpot.
- Mappa i campi:
- HubSpot
email← Zapierdata.visitor.email - HubSpot
firstname← Zapierdata.visitor.name(separa nome/cognome se necessario) - 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→ inserisci manualmente in Lead or Subscriber - HubSpot
website← Zapierdata.source_url
- HubSpot
- Facoltativo ma consigliato: aggiungi una seconda azione → HubSpot → Crea nota su quel contatto con l'URL della trascrizione della chat
data.transcript_urlcome corpo della nota. Il tuo team di vendita clicca il link e vede l'intera conversazione che ha portato alla cattura. - Attiva lo Zap. Ogni futura
lead.capturedl'evento crea / aggiorna automaticamente un contatto HubSpot in pochi secondi.
Consiglio: 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.
Altri CRM: lo stesso schema funziona per Pipedrive (azione: Create Deal), Salesforce (azione: Create/Update Lead), Close (azione: Create Lead), monday.com (azione: Create Item) e Airtable (azione: Create Record). Il lato DBestChatBot è identico — basta indirizzare uno Zap diverso allo stesso URL del webhook.
FAQ
Why isn't my endpoint receiving events?
- Verifica che il webhook sia active nella dashboard
- Check you're subscribed to the right event type
- Controlla il registro di consegna nella pagina di dettaglio del webhook per gli errori HTTP
- Usa il Invia evento di test button to bypass real-world triggers
Come posso smettere temporaneamente di ricevere eventi?
Toggle the webhook off — no events are queued or buffered, they're simply dropped.
Posso recuperare eventi più vecchi già svolti?
No, i webhook sono fire-and-forget. Per i dati storici, usa la dashboard Conversazioni esporta (CSV) o contattaci per un backfill una tantum.