Webhook
Buluthat invia i risultati al Suo indirizzo senza aspettare che li chiediate POST invia: risultati della chiamata automatica, riepiloghi delle conversazioni dell'assistente vocale, stato dei codici di verifica vocale. Stessa busta, stessa firma, stessa politica di ripetizione.
Busta
POST https://sizin-adresiniz/buluthat
Content-Type: application/json
X-Buluthat-Event: call_finished
X-Buluthat-Delivery: 4471
X-Buluthat-Signature: sha256=9f2b…
{
"event": "call_finished",
"sent_at": "2026-09-18T10:12:35+03:00",
"tenant_id": 1,
"data": { }
}
| Intestazione | Descrizione |
|---|---|
X-Buluthat-Event | Nome dell'evento |
X-Buluthat-Delivery | ID di consegna; resta invariato nei nuovi tentativi (utilizzatelo come chiave di idempotenza) |
X-Buluthat-Signature | sha256= + firma HMAC-SHA256 del corpo; nel record webhook_secret viene inviato se indicato |
Verifica della firma
Firma corpo grezzo si calcola su; non ricalcolate serializzando di nuovo il JSON.
$raw = file_get_contents('php://input');
$given = $_SERVER['HTTP_X_BULUTHAT_SIGNATURE'] ?? '';
$expect = 'sha256=' . hash_hmac('sha256', $raw, $secret);
if (!hash_equals($expect, $given)) { http_response_code(401); exit; }
$event = json_decode($raw, true);
// Node.js (express, raw body ile)
const crypto = require('crypto');
const expect = 'sha256=' + crypto.createHmac('sha256', secret).update(req.rawBody).digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(expect), Buffer.from(req.get('X-Buluthat-Signature') || ''))) return res.sendStatus(401);
Risposta e ripetizione
Il Suo interlocutore 2xx deve rispondere; il corpo non viene letto. Il più sicuro è mettere l'elaborazione in coda e rispondere subito 200 (timeout di 10 sec).
2xx se non arriva, la consegna viene ritentata ai seguenti intervalli: 1 min, 5 min, 15 min, 1 h, 3 h, 6 h. Dopo il sesto tentativo viene abbandonato e nel pannello failed compare come. Lo stesso evento può arrivare più volte; X-Buluthat-Delivery elimini i duplicati con.
Eventi
Chiamata automatica
| Evento | Quando | data |
|---|---|---|
call_finished | Chiamata terminata, esito definitivo (una volta per numero) | results gli stessi campi di: phone, external_id, status, dtmf, dtmf_label, amd_result, talk_seconds, custom_fields… |
dtmf | Nel momento in cui viene premuto il tasto | phone, external_id, digit, label |
campaign_finished | Tutti i numeri completati | campaign_id, conteggi di riepilogo |
Quali eventi inviare nella campagna webhook_events si seleziona con (call_finished,dtmf).
Assistente vocale
| Evento | Quando | data |
|---|---|---|
session_ended | Conversazione terminata, riepilogo generato | session_id, bot_id, caller_number, direction, duration_seconds, summary, intent, sentiment_label, outcome, tools (strumenti richiamati), task_id (se è una chiamata per un incarico) e i campi del risultato |
L'indirizzo webhook e il segreto dell'assistente si definiscono nel modulo dell'assistente.
Codice di verifica vocale
| Evento | Quando |
|---|---|
voice_otp.delivered | Codice letto |
voice_otp.verified | Codice verificato |
voice_otp.no_answer, voice_otp.busy, voice_otp.failed, voice_otp.expired | Risultati non riusciti |
data invece di request si utilizza la chiave: { "id", "status", "reference", "phone" }.
Consigli di sicurezza
- Indichi solo indirizzi HTTPS; non si consegna a indirizzi con certificato errato.
webhook_secretdefinitelo sempre e verificate la firma.- Se desidera limitare il destinatario per IP, richieda l'IP del server del pannello Buluthat al Centro Assistenza.
- Trattate i dati nel corpo dell'evento come "dati" e non come "istruzioni"; il testo pronunciato dal chiamante compare nei riepiloghi.
