Webhook’lar: sunucunuza olaylar
reactive.chat imzalı webhook’ları ve REST hook’ları: olaylar, başlıklar, gövde, HMAC-SHA256 imza doğrulaması, yeniden denemeler, zaman aşımları, devre dışı bırakma; PHP, Node ve Python doğrulama örnekleri.
Webhook’lar sohbette olanları sunucunuza bildirir: yeni sohbet, yeni mesaj, ekibe aktarma, değerlendirme. İki yol vardır:
- İmzalı webhook – çalışma alanı başına hesabınızda ayarlanan tek hedef adres; her iletim HMAC-SHA256 ile imzalanır. Kendi sistemleriniz için uygun yol.
- REST hook’ları – otomasyon aracının (Zapier, Make, n8n) sunucu API’si üzerinden kendisinin abone olup abonelikten çıktığı hedefler.
Olaylar
- conversation.created – sohbet oluşturuldu. Kanal
channeliçinde (web,whatsapp,email…). - message.created – mesaj saklandı (ziyaretçiden, asistandan, temsilciden veya sistemden).
- handoff.requested – sohbet bir insana aktarılacak;
reasonvetargetile. - csat.submitted – ziyaretçi değerlendirme verdi;
score(1veya-1) vecomment(kişisel verileri maskelenmiş). - fehlerfall.erstellt – web sitenizde yeni JavaScript hata olayı algılandı (El kitabı bölümüne bakın).
Site içi aramadan gelen sohbetler (Smart Answer) yalnızca sohbet olarak görünür olduklarında olay tetikler.
İmzalı webhook kurulumu
Hesabınızda Ayarlar → Entegrasyonlar → Webhook’lar altında (yetki: entegrasyonları yönetme):
- URL –
https://, en fazla 1.000 karakter, genel erişime açık. Çalışma alanı başına tek adres. - Olaylar – seçim; seçim yapılmazsa tümü.
- İmzalama gizli anahtarı – sayfada gösterilir (64 onaltılık karakter). Yeniden oluştur, önceki anahtarı hemen geçersiz kılar; geçişi, alıcınız kısa süreliğine ikisini de kabul edecek şekilde planlayın.
Kaydederken test çağrısı gönderilmez. Açıldıktan sonra olayların gelmeye başlaması yaklaşık 15 saniyeyi bulabilir; açılmadan önceki olaylar sonradan iletilmez.
İletim
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"}}
Başlıklar:
- X-RC-Event – olayın adı.
- X-RC-Delivery – iletimin kimliği; yeniden denemelerde aynı kalır. Yinelenenleri saptamak için kullanın.
- X-RC-Timestamp – Unix saniyesi.
- X-RC-Signature –
sha256=+hex(HMAC_SHA256(secret, X-RC-Timestamp + "." + raw_body)). Anahtar, gösterilen onaltılık dizenin kendisidir.
Gövde:
- id (dize) –
X-RC-Deliveryile aynı. - event (dize).
- ts (tam sayı) – Unix saniyesi.
- site_key, conversation_id, session_id, visitor_id (dize veya
null). - data (nesne) – olaya özgü veriler.
fehlerfall.erstelltiçin:fall_id,project_id,signatur,meldung,datei,zeile,spalte,seite,browser,os,stack,erste_ms,url(hesabınızdaki hata olayına bağlantı).message.creatediçin:id,seq,kind,direction,author_type,author_name(yalnızca temsilci ve asistan için),via,body(sunucuda maskelenmiş),redacted,ts(milisaniye) içerenmessage.handoff.requestediçin:reasonvetarget.csat.submittediçin:scorevecomment.conversation.creatediçin:channel.
İmzayı doğrulama
Herhangi bir işlemden önce doğrulayın: zaman damgası en fazla 300 saniye eski, imza ham gövde üzerinden, sabit süreli karşılaştırma.
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
Yanıtlar, yeniden denemeler, devre dışı bırakma
Hızlıca 2xx yanıtı verip ardından işleyin. Zaman aşımları: bağlantı kurulumu için 4 saniye, toplam 10 saniye. Yönlendirmeler izlenmez.
- 2xx – iletildi.
- 408, 429, 5xx, zaman aşımı, ağ hatası – 1 sn, 5 sn, 25 sn, 125 sn ve 625 sn sonra yeniden denenir (toplam en fazla altı deneme), ardından atılır.
- 410 Gone – entegrasyon devre dışı bırakılır. Yalnızca gerçekten artık webhook istemiyorsanız 410 kullanın.
- diğer 4xx – yeniden denenmez.
Bir saatten eski olaylar artık iletilmez. Hatalar birikirse (60 saniyede 5) hedefinize iletim 30 saniye duraklar; ardından işler yeniden denenir. Sohbet webhook’unuzu asla beklemez.
İletim sırası garanti edilmez. Gerekirse ts veya API’den gelen mesajların seq değerine göre sıralayın.
REST hook’ları (Zapier, Make, n8n)
Otomasyon araçları sunucu API’si üzerinden hedeflerine kendileri abone olur. Bunu doğrudan da kullanabilirsiniz:
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 – yazma yetkisi içeren kapsam.
event(yukarıdaki olaylardan biri),target_url(https://, en fazla 500 karakter, genel erişime açık),source(zapier,makeveyan8n, varsayılanzapier).idile 201 yanıtı. Aynı olay ve hedef kombinasyonu iki kez oluşturulmaz. Çalışma alanı başına en fazla 200 abonelik. - GET /v1/hooks –
id,event,target_url,source,failures,created_at,last_ok_atiçeren liste. - DELETE /v1/hooks/{id} – abonelikten çıkma.
REST hook iletimi:
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}}}
- İmzalı değildir. Tahmin edilmesi zor hedef adres kullanın ve yinelenenler için
X-RC-Deliverydeğerini kontrol edin. Kendi sistemleriniz için imzalı webhook daha uygun yoldur. datatam olaydır: ayrıcaworkspace_id,delivery_idveattempt(deneme sayısı).data.tsburada milisaniye cinsindendir.message.createdolayınındataalanı,id,seq,kind,direction,author_type,author_name(yalnızca temsilci ve asistan için),via,body(sunucu tarafında maskelenmiş),redacted,tsiçerenmessagebarındırır.handoff.requested,reasonvetarget;csat.submitted,scorevecomment;conversation.created,channeltaşır.- 410 yalnızca bu tek aboneliği kaldırır. İptal edilmiş API anahtarının hook’larına artık iletim yapılmaz.
- Mevcut durumda iletim için ilgili entegrasyonun (Zapier, Make veya n8n) çalışma alanında Entegrasyonlar altında açık olması gerekir.
Bulunmayan özellikler
- Sunucunuzun bir sohbete ziyaretçi mesajı aktarmasını sağlayan gelen webhook yoktur. Ekibiniz adına yanıtları sunucu API’si veya MCP üzerinden gönderirsiniz.
- İmzalama gizli anahtarını yenilerken geçiş süresi yoktur.
- Sohbet silindiğinde olay gönderilmez.
Sonraki: Sunucu API’si
చివరిగా నవీకరించినది: