Webhooks: gebeurtenissen naar uw server
Ondertekende webhooks en REST-hooks van reactive.chat: gebeurtenissen, headers, body, HMAC-SHA256-verificatie, herhalingen, time-outs, deactivering en voorbeelden in PHP, Node en Python.
Webhooks vertellen uw server wat er in de chat gebeurt: een nieuw gesprek, een nieuw bericht, een overdracht aan het team, een beoordeling. Er zijn twee routes:
- Ondertekende webhook — één doeladres per werkruimte, ingesteld in uw account, elke aflevering ondertekend met HMAC-SHA256. De juiste route voor uw eigen systemen.
- REST-hooks — doelen die een automatiseringstool (Zapier, Make, n8n) zelf via de server-API aan- en afmeldt.
Gebeurtenissen
- conversation.created — er is een gesprek aangemaakt. Kanaal in
channel(web,whatsapp,email…). - message.created — er is een bericht opgeslagen (van de bezoeker, de assistent, een medewerker of het systeem).
- handoff.requested — het gesprek moet naar een mens; met
reasonentarget. - csat.submitted — de bezoeker heeft een beoordeling gegeven;
score(1of-1) encomment(met gemaskeerde persoonsgegevens). - fehlerfall.erstellt — op uw website is een nieuwe JavaScript-foutzaak gevonden (zie Handboek).
Gesprekken uit de websitezoekfunctie (Smart Answer) veroorzaken pas gebeurtenissen zodra ze zichtbaar worden als chat.
De ondertekende webhook instellen
In uw account onder Instellingen → Integraties → Webhooks (recht: integraties beheren):
- URL —
https://, maximaal 1000 tekens, openbaar bereikbaar. Eén adres per werkruimte. - Gebeurtenissen — een selectie; geen selectie betekent alles.
- Ondertekeningsgeheim — wordt op de pagina getoond (64 hextekens). Opnieuw genereren maakt het vorige direct ongeldig; plan de omschakeling zo dat uw ontvanger kort beide accepteert.
Bij het opslaan wordt geen testaanroep verstuurd. Na het inschakelen kan het ongeveer 15 seconden duren voordat gebeurtenissen worden afgeleverd; eerdere gebeurtenissen worden niet achteraf afgeleverd.
De aflevering
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"}}
Headers:
- X-RC-Event — naam van de gebeurtenis.
- X-RC-Delivery — ID van de aflevering; blijft gelijk bij herhaalde pogingen. Gebruik deze om duplicaten te herkennen.
- X-RC-Timestamp — Unix-seconden.
- X-RC-Signature —
sha256=+hex(HMAC_SHA256(secret, X-RC-Timestamp + "." + raw_body)). De sleutel is de getoonde hexstring zelf.
Body:
- id (string) — gelijk aan
X-RC-Delivery. - event (string).
- ts (integer) — Unix-seconden.
- site_key, conversation_id, session_id, visitor_id (string of
null). - data (object) — gegevens per gebeurtenis. Voor
fehlerfall.erstellt:fall_id,project_id,signatur,meldung,datei,zeile,spalte,seite,browser,os,stack,erste_ms,url(link naar de zaak in uw account). Voormessage.created:messagemetid,seq,kind,direction,author_type,author_name(alleen voor medewerker en assistent),via,body(op de server gemaskeerd),redacted,ts(milliseconden). Voorhandoff.requested:reasonentarget. Voorcsat.submitted:scoreencomment. Voorconversation.created:channel.
De handtekening verifiëren
Verifieer vóór elke verwerking: tijdstempel maximaal 300 seconden oud, handtekening over de ruwe body, vergelijking in constante tijd.
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
Antwoorden, herhalingen, deactivering
Antwoord snel met een 2xx en verwerk daarna. Time-outs: 4 seconden voor het opbouwen van de verbinding, 10 seconden in totaal. Omleidingen worden niet gevolgd.
- 2xx — afgeleverd.
- 408, 429, 5xx, time-out, netwerkfout — opnieuw proberen na 1 s, 5 s, 25 s, 125 s en 625 s (maximaal zes pogingen in totaal), daarna verworpen.
- 410 Gone — de integratie wordt gedeactiveerd. Gebruik 410 alleen als u werkelijk geen webhooks meer wilt.
- andere 4xx — geen nieuwe poging.
Gebeurtenissen ouder dan één uur worden niet meer afgeleverd. Als fouten zich opstapelen (5 in 60 seconden), pauzeert de aflevering naar uw doel 30 seconden; de taken worden daarna opnieuw geprobeerd. Een chat wacht nooit op uw webhook.
De volgorde van afleveringen is niet gegarandeerd. Sorteer zo nodig op ts of op seq van de berichten uit de API.
REST-hooks (Zapier, Make, n8n)
Automatiseringstools melden hun doelen zelf via de server-API aan. U kunt dit ook rechtstreeks gebruiken:
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 — een scope met schrijfrecht.
event(een van de bovenstaande gebeurtenissen),target_url(https://, maximaal 500 tekens, openbaar),source(zapier,makeofn8n, standaardzapier). Antwoord 201 metid. Dezelfde combinatie van gebeurtenis en doel wordt niet tweemaal aangemaakt. Maximaal 200 abonnementen per werkruimte. - GET /v1/hooks — lijst met
id,event,target_url,source,failures,created_at,last_ok_at. - DELETE /v1/hooks/{id} — afmelden.
Aflevering van een 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}}}
- Niet ondertekend. Gebruik een moeilijk te raden doeladres en controleer
X-RC-Deliveryop duplicaten. Voor eigen systemen is de ondertekende webhook de betere route. datais de volledige gebeurtenis: daarnaastworkspace_id,delivery_idenattempt(aantal pogingen).data.tsis hier in milliseconden.datavanmessage.createdbevatmessagemetid,seq,kind,direction,author_type,author_name(alleen voor medewerker en assistent),via,body(op de server gemaskeerd),redacted,ts.handoff.requestedbevatreasonentarget,csat.submittedbevatscoreencomment,conversation.createdbevatchannel.- Een 410 meldt alleen dit ene abonnement af. Hooks van een ingetrokken API-sleutel worden niet meer bediend.
- Momenteel vereist aflevering dat de betreffende integratie (Zapier, Make of n8n) onder Integraties in de werkruimte is ingeschakeld.
Wat niet bestaat
- Geen inkomende webhook waarmee uw server bezoekersberichten in een gesprek invoert. Antwoorden namens uw team verstuurt u via de server-API of MCP.
- Geen overgangsperiode bij het vernieuwen van het ondertekeningsgeheim.
- Geen gebeurtenis wanneer een gesprek wordt verwijderd.
Volgende: Server-API
Последна актуализация: