الويبهوك الصادر
تُرسل اشتراكات الويبهوك الصادر طلب HTTP من نوع POST بجسم JSON إلى عنوانك
عند وقوع حدث تختاره. افتح الإعدادات ← التكاملات ← ربط واتساب والأدوات والتطبيقات
(/settings?area=connections&goal=connect)، ثم وسّع متقدّم للوصول إلى
اشتراكات Webhook. اختر إضافة اشتراك أو عدّل اشتراكاً موجوداً. اختر من
أنواع الأحداث، ثم وسّع عرض تفاصيل الطلب للاطلاع على الحقول والمثال.
عيّن سر التوقيع (اختياري) لتفعيل توقيع الطلبات، واحتفظ بالسر نفسه لدى المستقبِل. عند عدم تعيين سر، لا يرسل كسبلي ترويسة التوقيع. سر التوقيع مستقل عن مصادقة Bearer أو Basic الاختيارية.
ترويسات الطلب
Section titled “ترويسات الطلب”| الترويسة | القيمة |
|---|---|
Content-Type |
application/json |
X-Kasbly-Event |
اسم الحدث المختار، مثل conversation.started، أو test عند إرسال اختبار. |
X-Kasbly-Signature |
تُرسل فقط عند تعيين سر: توقيع HMAC-SHA256 لبايتات جسم JSON الخام كاملاً، بترميز سداسي عشري من 64 محرفاً بأحرف صغيرة، دون بادئة sha256=. |
X-Retry-Attempt |
لا تُرسل في المحاولة الأولى أو الاختبار. تحمل رقم محاولة التسليم الإجمالي: 2 في أول إعادة و3 في الثانية. تستخدم الإعادة اليدوية رقم محاولة سجل التسليم المختار مضافاً إليه 1. |
Authorization |
عند تفعيل المصادقة فقط: Bearer <token> أو Basic <base64(username:password)>. |
أسماء ترويسات HTTP لا تتأثر بحالة الأحرف؛ قد يعرضها إطار الخادم بأحرف صغيرة،
مثل x-kasbly-signature.
تحقّق من التوقيع قبل تحليل JSON
Section titled “تحقّق من التوقيع قبل تحليل JSON”استخدم بايتات الطلب الأصلية قبل أن تغيّرها برمجيات تحليل JSON. تحليل الجسم ثم تحويله إلى JSON مجدداً قد يغيّر المسافات أو ترتيب المفاتيح فيُبطل التوقيع. احسب التوقيع على الجسم كاملاً، بما فيه الغلاف إن وُجد.
المثال التالي لـ Node.js يرفض التوقيع المفقود أو غير الصالح، ويتحقّق من الطول قبل المقارنة، ويستخدم مقارنة ثابتة الزمن:
import { createHmac, timingSafeEqual } from 'node:crypto';
// rawBody is the original request Buffer, before JSON parsing.export function verifyWebhookSignature(rawBody, signature, secret) { if ( typeof signature !== 'string' || signature.length !== 64 || !/^[0-9a-f]{64}$/.test(signature) ) { return false; } const expected = createHmac('sha256', secret).update(rawBody).digest(); const received = Buffer.from(signature, 'hex'); return received.length === expected.length && timingSafeEqual(received, expected);}مرّر السر المحفوظ وقيمة X-Kasbly-Signature إلى الدالة. ارفض الطلب عند فشل
التحقّق قبل معالجة الحدث. بعد نجاحه، حلّل rawBody.toString('utf8') باستخدام
JSON.parse. إذا كنت تشترط توثيق مصدر الطلب، فعيّن سراً وارفض الطلبات غير
الموقّعة أيضاً.
أشكال البيانات
Section titled “أشكال البيانات”تستخدم الأحداث المرسلة عبر ناقل الأحداث هذا الغلاف (القيم توضيحية):
{ "event": "conversation.started", "eventId": "evt_example", "timestamp": "2026-10-19T12:00:00.000Z", "data": { "conversationId": "conv_example", "customerId": "cust_example", "channel": "WHATSAPP" }, "tenantId": "tenant_example", "entityType": "conversation", "entityId": "conv_example"}يطابق event ترويسة X-Kasbly-Event، ويحدّد eventId الحدث، ويمثل timestamp
وقت إصداره. تحتوي data على حقول الحدث. يحدّد tenantId مساحة العمل، فيما
يحدّد entityType وentityId السجل المتأثر.
لا يوجد غلاف موحّد لجميع الأحداث. قد تضع الأحداث المرسلة مباشرةً حقولها
في المستوى الأعلى. مثلاً، يرسل survey.submitted:
{ "tenantId": "tenant_example", "eventType": "survey.submitted", "occurredAt": "2026-10-19T12:00:00.000Z", "surveyId": "survey_example", "conversationId": "conv_example", "customerId": "cust_example", "rating": 5, "feedbackText": "Helpful support"}قد تحتوي أحداث الطلبات على tenantId وtimestamp وorder في المستوى الأعلى.
وجّه المعالجة بحسب X-Kasbly-Event وتعامل مع حقول الحدث المحدد، دون افتراض
وجود data أو eventId دائماً. تصف أمثلة نافذة الاشتراك حقول الحدث؛ وتُغلَّف
هذه الحقول داخل data عندما يأتي التسليم عبر ناقل الأحداث.
لإرسال اختبار Webhook جسم خاص، ويُرسل مرة واحدة بترويسة
X-Kasbly-Event: test ودون ترويسة إعادة المحاولة:
{ "event": "test", "timestamp": "2026-10-19T12:00:00.000Z", "message": "This is a test webhook from Kasbly"}يستخدم الاختبار خوارزمية التوقيع نفسها عند تقديم سر. نجاحه يتحقّق من الاتصال ومعالجة التوقيع؛ جرّب حدثاً حقيقياً مختاراً للتحقّق من معالجة بياناته أيضاً.
التسليم وإعادة المحاولة
Section titled “التسليم وإعادة المحاولة”أعد استجابة 2xx لتأكيد الاستلام. مهلة طلبات التسليم التلقائي 10 ثوانٍ.
تؤدي الاستجابات الأخرى وانتهاء المهلة وأخطاء الشبكة المؤقتة إلى إعادة المحاولة
حتى بلوغ الحد. لا تُعاد الطلبات التي يرفض التحقّق الأمني عنوانها. مهلة
الاختبار 30 ثانية ولا يُعاد تلقائياً.
يضبط حقل الحد الأقصى لإعادة المحاولة (حقل API باسم maxRetries) فعلياً
إجمالي المحاولات من 1 إلى 10، بما فيها الطلب الأول. الافتراضي 3
محاولات: التسليم الأول ثم إعادتان كحد أقصى، بانتظار ثانية واحدة ثم
3 ثوانٍ بعد فشل المحاولة السابقة. القيمة 1 تعطّل الإعادة التلقائية.
للحدود الأعلى، فترات الانتظار المتتالية هي 1 و3 و10 و30 و60 و120 و300 و600 و900 ثانية، أي 9 إعادات كحد أقصى عند ضبط 10 محاولات. هذه فترات انتظار بعد الفشل وليست مواعيد دقيقة منذ وقوع الحدث؛ يضاف إليها زمن الطلب وحمل الطابور. تضع الإعادة اليدوية محاولة إضافية واحدة في الطابور.
صمّم المستقبِل بحيث يتحمّل وصول الحدث أكثر من مرة. عند وجود eventId، استخدمه
مع نوع الحدث لمنع تكرار المعالجة؛ تحتاج الأشكال الأخرى إلى استراتيجية ملائمة
لحقول الحدث. احفظ الحدث بشكل دائم، وأكّد استلامه بسرعة، ونفّذ الأعمال البطيئة
لاحقاً. راجع سجلات تسليم الاشتراك لتشخيص الإخفاقات.
