Webhook: eventi al Suo server
Webhook firmati e REST hook di reactive.chat: eventi, intestazioni, corpo, verifica HMAC-SHA256, tentativi, timeout, disattivazione ed esempi di verifica in PHP, Node e Python.
I webhook comunicano al Suo server che cosa accade nella chat: una nuova conversazione, un messaggio, un passaggio al team, una valutazione. Esistono due modalità:
- Webhook firmato: un indirizzo di destinazione per spazio di lavoro, configurato nell’account, ogni consegna firmata con HMAC-SHA256. La modalità adatta ai Suoi sistemi.
- REST hook: destinazioni che uno strumento di automazione (Zapier, Make, n8n) sottoscrive e annulla autonomamente tramite l’API server.
Eventi
- conversation.created: è stata creata una conversazione. Canale in
channel(web,whatsapp,email…). - message.created: è stato memorizzato un messaggio (del visitatore, dell’assistente, di un operatore o del sistema).
- handoff.requested: la conversazione deve passare a una persona; con
reasonetarget. - csat.submitted: il visitatore ha dato una valutazione;
score(1o-1) ecomment(con dati personali mascherati). - fehlerfall.erstellt: è stato rilevato un nuovo caso di errore JavaScript sul sito (vedere Manuale).
Le conversazioni dalla ricerca nel sito (Smart Answer) attivano eventi solo quando diventano visibili come chat.
Configurare il webhook firmato
Nell’account, in Impostazioni → Integrazioni → Webhook (permesso: gestire integrazioni):
- URL:
https://, massimo 1000 caratteri, raggiungibile pubblicamente. Un indirizzo per spazio di lavoro. - Eventi: una selezione; nessuna selezione significa tutti.
- Segreto di firma: mostrato sulla pagina (64 caratteri esadecimali). Rigenera invalida quello precedente immediatamente; pianifichi il cambio affinché il ricevitore accetti brevemente entrambi.
Al salvataggio non viene inviata alcuna chiamata di prova. Dopo l’attivazione possono servire fino a circa 15 secondi prima che arrivino gli eventi; quelli precedenti non vengono consegnati retroattivamente.
La consegna
POST /rc-webhook HTTP/1.1
Host: hooks.your-company.com
Content-Type: application/json; charset=utf-8
User-Agent: reactive.chat-webhook/1.0
X-RC-Event: csat.submitted
X-RC-Delivery: 01JAB3C4D5E6F7G8H9JKMNPQRS
X-RC-Timestamp: 1792503600
X-RC-Signature: sha256=3f0a1c...
{"id":"01JAB3C4D5E6F7G8H9JKMNPQRS","event":"csat.submitted","ts":1792503600,"site_key":"ABCDEFGHJKLMNPQRSTUVWX12","conversation_id":"01JAB2...","session_id":"s_...","visitor_id":"v_...","data":{"score":5,"comment":"Very helpful"}}
Intestazioni:
- X-RC-Event: nome dell’evento.
- X-RC-Delivery: ID della consegna; resta uguale nei tentativi successivi. Lo usi per rilevare duplicati.
- X-RC-Timestamp: secondi Unix.
- X-RC-Signature:
sha256=+hex(HMAC_SHA256(secret, X-RC-Timestamp + "." + raw_body)). La chiave è la stessa stringa esadecimale mostrata.
Corpo:
- id (stringa): uguale a
X-RC-Delivery. - event (stringa).
- ts (intero): secondi Unix.
- site_key, conversation_id, session_id, visitor_id (stringa o
null). - data (oggetto): dati specifici dell’evento. Per
fehlerfall.erstellt:fall_id,project_id,signatur,meldung,datei,zeile,spalte,seite,browser,os,stack,erste_ms,url(link al caso nell’account). Permessage.created:messageconid,seq,kind,direction,author_type,author_name(solo per operatore e assistente),via,body(mascherato sul server),redacted,ts(millisecondi). Perhandoff.requested:reasonetarget. Percsat.submitted:scoreecomment. Perconversation.created:channel.
Verificare la firma
Verifichi prima di qualsiasi elaborazione: timestamp non più vecchio di 300 secondi, firma sul corpo grezzo, confronto a tempo costante.
PHP:
<?php
$geheim = getenv('RC_WEBHOOK_SECRET');
$body = file_get_contents('php://input');
$ts = $_SERVER['HTTP_X_RC_TIMESTAMP'] ?? '';
$sig = $_SERVER['HTTP_X_RC_SIGNATURE'] ?? '';
if (!ctype_digit($ts) || abs(time() - (int) $ts) > 300) { http_response_code(401); exit; }
$soll = 'sha256=' . hash_hmac('sha256', $ts . '.' . $body, $geheim);
if (!hash_equals($soll, $sig)) { http_response_code(401); exit; }
$ereignis = json_decode($body, true);
// detect duplicates: remember $ereignis['id']
http_response_code(204);
Node.js (Express):
const crypto = require('crypto');
app.post('/rc-webhook', express.raw({ type: 'application/json' }), (req, res) => {
const ts = req.get('X-RC-Timestamp') || '';
const sig = req.get('X-RC-Signature') || '';
if (!/^\d+$/.test(ts) || Math.abs(Date.now() / 1000 - Number(ts)) > 300) return res.sendStatus(401);
const soll = 'sha256=' + crypto.createHmac('sha256', process.env.RC_WEBHOOK_SECRET)
.update(ts + '.' + req.body.toString('utf8')).digest('hex');
if (sig.length !== soll.length || !crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(soll))) {
return res.sendStatus(401);
}
const ereignis = JSON.parse(req.body.toString('utf8'));
res.sendStatus(204);
verarbeiteSpaeter(ereignis); // respond quickly, work afterwards
});
Python (Flask):
import hmac, hashlib, os, time
from flask import request, abort
@app.post("/rc-webhook")
def rc_webhook():
ts = request.headers.get("X-RC-Timestamp", "")
sig = request.headers.get("X-RC-Signature", "")
body = request.get_data() # raw bytes
if not ts.isdigit() or abs(time.time() - int(ts)) > 300:
abort(401)
soll = "sha256=" + hmac.new(os.environ["RC_WEBHOOK_SECRET"].encode(),
ts.encode() + b"." + body, hashlib.sha256).hexdigest()
if not hmac.compare_digest(soll, sig):
abort(401)
return "", 204
Risposte, nuovi tentativi e disattivazione
Risponda rapidamente con un 2xx ed elabori in seguito. Timeout: 4 secondi per stabilire la connessione, 10 secondi totali. I reindirizzamenti non vengono seguiti.
- 2xx: consegnato.
- 408, 429, 5xx, timeout, errore di rete: nuovo tentativo dopo 1 s, 5 s, 25 s, 125 s e 625 s (fino a sei tentativi complessivi), poi viene scartato.
- 410 Gone: l’integrazione viene disattivata. Usi 410 solo se davvero non desidera più webhook.
- altri 4xx: nessun nuovo tentativo.
Gli eventi più vecchi di un’ora non vengono più consegnati. Se gli errori si accumulano (5 in 60 secondi), la consegna alla destinazione si sospende per 30 secondi; gli incarichi vengono poi ritentati. La chat non attende mai il Suo webhook.
L’ordine delle consegne non è garantito. Se necessario, ordini per ts o per il seq dei messaggi dell’API.
REST hook (Zapier, Make, n8n)
Gli strumenti di automazione sottoscrivono autonomamente le destinazioni tramite l’API server. Può farlo anche direttamente:
curl -X POST https://reactive.chat/v1/hooks \
-H "Authorization: Bearer rc_live_..." \
-H "Content-Type: application/json" \
-d '{"event":"message.created","target_url":"https://hooks.your-company.com/rc","source":"n8n"}'
- POST /v1/hooks: un ambito con permesso di scrittura.
event(uno degli eventi sopra),target_url(https://, massimo 500 caratteri, pubblico),source(zapier,makeon8n, predefinitozapier). Risposta 201 conid. La stessa combinazione di evento e destinazione non viene creata due volte. Massimo 200 sottoscrizioni per spazio di lavoro. - GET /v1/hooks: elenco con
id,event,target_url,source,failures,created_at,last_ok_at. - DELETE /v1/hooks/{id}: annulla la sottoscrizione.
Consegna di un REST hook:
POST https://hooks.your-company.com/rc
Content-Type: application/json
User-Agent: reactive.chat-n8n/1.0
X-RC-Event: message.created
X-RC-Delivery: 01JAB3...
{"event":"message.created","delivery_id":"01JAB3...","data":{"name":"message.created","ts":1792503600123,"site_key":"...","conversation_id":"...","session_id":"...","visitor_id":"...","message":{"id":"...","seq":7,"kind":"text","direction":"in","author_type":"bot","author_name":"Assistant","via":null,"body":"…","redacted":false,"ts":1792503600120}}}
- Non firmata. Usi un indirizzo di destinazione difficile da indovinare e verifichi
X-RC-Deliveryper i duplicati. Per i Suoi sistemi, il webhook firmato è la modalità migliore. dataè l’evento completo: inoltreworkspace_id,delivery_ideattempt(numero del tentativo). Quidata.tsè in millisecondi.- Il
datadimessage.createdcontienemessageconid,seq,kind,direction,author_type,author_name(solo per operatore e assistente),via,body(mascherato sul server),redacted,ts.handoff.requestedcontienereasonetarget,csat.submittedcontienescoreecomment,conversation.createdcontienechannel. - Un 410 annulla solo questa singola sottoscrizione. Gli hook di una chiave API revocata non vengono più serviti.
- Allo stato attuale, la consegna richiede che l’integrazione corrispondente (Zapier, Make o n8n) sia attivata nello spazio di lavoro, in Integrazioni.
Che cosa non esiste
- Nessun webhook in entrata con cui il server inserisca messaggi dei visitatori in una conversazione. Le risposte in nome del team si inviano tramite l’API server o MCP.
- Nessun periodo di transizione al rinnovo del segreto di firma.
- Nessun evento all’eliminazione di una conversazione.
Successivo: API server
Posledná aktualizácia: