Webhooks: händelser till din server
Signerade webhooks och REST-hooks från reactive.chat – händelser, huvuden, meddelandekropp, signaturverifiering med HMAC-SHA256, nya försök, tidsgränser, inaktivering och verifieringsexempel i PHP, Node och Python.
Webhooks meddelar din server vad som händer i chatten: en ny konversation, ett nytt meddelande, en överlämning till teamet, ett omdöme. Det finns två sätt:
- Signerad webhook – en måladress per arbetsyta, inställd i kontot, där varje leverans signeras med HMAC-SHA256. Rätt väg för dina egna system.
- REST-hooks – mål som ett automatiseringsverktyg (Zapier, Make, n8n) självt registrerar och avregistrerar via server-API:et.
Händelser
- conversation.created – en konversation har skapats. Kanalen anges i
channel(web,whatsapp,email…). - message.created – ett meddelande har sparats (från besökaren, assistenten, en agent eller systemet).
- handoff.requested – konversationen ska gå till en människa; med
reasonochtarget. - csat.submitted – besökaren har lämnat ett omdöme;
score(1eller-1) ochcomment(med maskerade personuppgifter). - fehlerfall.erstellt – ett nytt JavaScript-felfall har upptäckts på din webbplats (se Handbok).
Konversationer från webbplatssökningen (Smart Answer) utlöser händelser först när de blir synliga som chatt.
Ställa in den signerade webhooken
I kontot under Inställningar → Integrationer → Webhooks (behörighet: hantera integrationer):
- URL –
https://, högst 1 000 tecken, offentligt tillgänglig. En adress per arbetsyta. - Händelser – ett urval; inget val innebär alla.
- Signeringshemlighet – visas på sidan (64 hexadecimala tecken). Generera ny gör den tidigare omedelbart ogiltig; planera därför bytet så att mottagaren accepterar båda en kort stund.
Inget testanrop skickas när du sparar. Efter aktivering kan det ta upp till cirka 15 sekunder innan händelser börjar skickas; händelser från tiden före aktiveringen levereras inte i efterhand.
Leveransen
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"}}
Huvuden:
- X-RC-Event – händelsens namn.
- X-RC-Delivery – leveransens ID; är oförändrat vid nya försök. Använd det för att upptäcka dubbletter.
- X-RC-Timestamp – Unix-tid i sekunder.
- X-RC-Signature –
sha256=+hex(HMAC_SHA256(secret, X-RC-Timestamp + "." + raw_body)). Nyckeln är själva den hexadecimala sträng som visas.
Meddelandekropp:
- id (sträng) – samma som
X-RC-Delivery. - event (sträng).
- ts (heltal) – Unix-tid i sekunder.
- site_key, conversation_id, session_id, visitor_id (sträng eller
null). - data (objekt) – händelsespecifika data. För
fehlerfall.erstellt:fall_id,project_id,signatur,meldung,datei,zeile,spalte,seite,browser,os,stack,erste_ms,url(länk till ärendet i kontot). Förmessage.created:messagemedid,seq,kind,direction,author_type,author_name(bara för agent och assistent),via,body(maskerad på servern),redacted,ts(millisekunder). Förhandoff.requested:reasonochtarget. Förcsat.submitted:scoreochcomment. Förconversation.created:channel.
Verifiera signaturen
Kontrollera före all bearbetning: tidsstämpeln är högst 300 sekunder gammal, signaturen beräknas över den råa meddelandekroppen och jämförelsen sker i konstant tid.
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
Svar, nya försök och inaktivering
Svara snabbt med 2xx och bearbeta därefter. Tidsgränser: 4 sekunder för att upprätta anslutningen, totalt 10 sekunder. Omdirigeringar följs inte.
- 2xx – levererat.
- 408, 429, 5xx, överskriden tidsgräns, nätverksfel – nytt försök efter 1 s, 5 s, 25 s, 125 s och 625 s (upp till sex försök totalt), därefter kasseras händelsen.
- 410 Gone – integrationen inaktiveras. Använd 410 bara om du verkligen inte vill ha fler webhooks.
- andra 4xx – inga nya försök.
Händelser som är äldre än en timme levereras inte längre. Om fel samlas på hög (5 på 60 sekunder) pausas leveransen till ditt mål i 30 sekunder; jobben körs därefter på nytt. En chatt väntar aldrig på din webhook.
Leveransordningen garanteras inte. Sortera vid behov efter ts eller meddelandenas seq från API:et.
REST-hooks (Zapier, Make, n8n)
Automatiseringsverktygen registrerar själva sina mål via server-API:et. Du kan också använda detta direkt:
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 – en omfattning med skrivbehörighet.
event(en av händelserna ovan),target_url(https://, högst 500 tecken, offentlig),source(zapier,makeellern8n, standardzapier). Svar 201 medid. Samma kombination av händelse och mål skapas inte två gånger. Högst 200 registreringar per arbetsyta. - GET /v1/hooks – lista med
id,event,target_url,source,failures,created_at,last_ok_at. - DELETE /v1/hooks/{id} – avregistrera.
Leverans av en 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}}}
- Inte signerad. Använd en måladress som är svår att gissa och kontrollera
X-RC-Deliveryför att upptäcka dubbletter. För egna system är den signerade webhooken den bättre vägen. dataär den fullständiga händelsen: dessutomworkspace_id,delivery_idochattempt(antal försök).data.tsanges här i millisekunder.dataförmessage.createdinnehållermessagemedid,seq,kind,direction,author_type,author_name(bara för agent och assistent),via,body(maskerad på serversidan),redacted,ts.handoff.requestedinnehållerreasonochtarget,csat.submittedinnehållerscoreochcomment,conversation.createdinnehållerchannel.- Ett 410 avregistrerar bara den aktuella registreringen. Hooks för en återkallad API-nyckel levereras inte längre.
- I nuläget kräver leveransen att respektive integration (Zapier, Make eller n8n) är påslagen i arbetsytan under Integrationer.
Vad som inte finns
- Ingen inkommande webhook genom vilken din server matar in besökarmeddelanden i en konversation. Svar för teamets räkning skickar du via server-API:et eller MCP.
- Ingen övergångsperiod när signeringshemligheten förnyas.
- Ingen händelse när en konversation raderas.
Nästa: Server-API
Senast uppdaterad: