Webhooks · v1
Webhooks — يدفعها CD4CD، يستقبلها سيرفرك.
سجّل endpoint مرة واحدة، واستقبل تدفّق أحداث منظّم. توقيع HMAC على كل payload، إعادة محاولة ذكية، JSON بسيط.
التسجيل
سجّل عبر /dashboard/api → New webhook أو عبر REST API:
POST /v1/webhooks
Authorization: Bearer cd_live_xxx
{
"endpoint": "https://hooks.aljazera.sa/cd4cd",
"events": ["link.clicked", "link.created"],
"secret": "auto"
}
→ 201 Created
{ "id": "wh_8f3c", "endpoint": "...", "secret": "whsec_xyz" }الأحداث المتاحة
| الحدث | الوصف |
|---|---|
| link.created | عند إنشاء رابط جديد. |
| link.updated | عند تعديل الوجهة أو الـ alias. |
| link.deleted | عند حذف رابط. |
| link.clicked | في كل نقرة (مع breakdown). |
| qr.created | عند إنشاء QR جديد. |
| qr.scanned | كل فحص QR. |
| bio.visited | كل زيارة لصفحة Bio. |
| security.flagged | عند تعليم رابط بطل بالطبقات الأمنية. |
مثال: link.clicked
POST https://hooks.aljazera.sa/cd4cd
CD4CD-Signature: t=1715583720,v1=8f3c…a91
Content-Type: application/json
{
"id": "evt_18f3c_a91",
"type": "link.clicked",
"createdAt": "2026-05-13T05:42:00.123Z",
"data": {
"linkId": "lnk_8f3c_a91",
"shortCode": "promo-2026",
"longUrl": "https://example.com/long/path",
"country": "SA",
"device": "mobile",
"os": "iOS",
"referrer": "https://t.co/abc"
}
}التحقق من التوقيع
كل webhook يحمل header CD4CD-Signature. احسب HMAC_SHA256(secret, t + "." + body) وقارن مع v1.
// Node.js
import crypto from 'node:crypto';
const sig = req.headers['cd4cd-signature']; // t=..,v1=..
const [tPart, vPart] = sig.split(',');
const t = tPart.slice(2);
const v1 = vPart.slice(3);
const expected = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(`${t}.${req.rawBody}`)
.digest('hex');
if (expected !== v1) return res.status(401).end();إعادة المحاولة
إذا لم نستلم 2xx خلال ١٠ ثوانٍ، نُعيد المحاولة بـ exponential backoff:
- 1m → 5m → 15m → 1h → 6h → 24h
- بعد ٦ محاولات فاشلة، نُعطّل الـ webhook ونرسل بريداً.
الـ Idempotency
كل حدث له id. احفظ آخر ٧ أيام منها لتجاهل التكرار.