تخطَّ إلى المحتوى

Webhooks

يسلّم RolChat الأحداث إلى أنظمتك كطلبات HTTP POST موقّعة. تصف هذه الصفحة webhooks الإضافات؛ أما webhooks التي ترسلها قاعدة الأتمتة فتختلف في إعادة المحاولة ومدة الانتظار وتدوير السر، انظر Webhooks الأتمتة. وتنطبق القواعد نفسها في الاتجاه المعاكس عندما يرسل نظامك أو إضافة أو مزوّد إلى RolChat. تحقق من كل تسليم بالترتيب أدناه قبل أن تتصرف بناءً عليه.

POST /your/endpoint HTTP/1.1
Content-Type: application/json
User-Agent: RolChat-Webhook/1.0
X-RolChat-Timestamp: 1713615825
X-RolChat-Signature: sha256=a1b2c3…
X-RolChat-Nonce: nonce_01HKQN9…
X-RolChat-Event-Id: evt_01HKQN9…
{ "id": "evt_01HKQN9…", "type": "conversation.created", "occurred_at": "…", "data": { … } }
الترويسة المعنى
X-RolChat-Timestamp ثوانٍ بتوقيت Unix عند الإرسال. جزء من الرسالة الموقّعة.
X-RolChat-Signature sha256=<hex>. تسمّي البادئة الخوارزمية كي يمكن تغييرها لاحقًا.
X-RolChat-Nonce ULID فريد لطلب HTTP هذا. إعادة المحاولة تحصل على nonce جديد.
X-RolChat-Event-Id معرّف الحدث نفسه. ثابت عبر إعادات المحاولة؛ استخدمه لإزالة التكرار.

تذهب عمليات التسليم الصادرة إلى نقاط نهاية HTTPS فقط. يُرفض عنوان URL بصيغة HTTP عند إنشاء الاشتراك.

الرسالة الموقّعة هي الطابع الزمني، ثم نقطة حرفية، ثم جسم الطلب الخام، بايتًا ببايت:

canonical = "<timestamp>.<body>"
signature = hex( HMAC-SHA256( secret, canonical ) )

وقّع البايتات التي تلقيتها، لا نسخة أُعيد تسلسلها من JSON المحلَّل. تغييرات المسافات البيضاء أو ترتيب المفاتيح تكسر التوقيع. SHA-256 هي الخوارزمية الوحيدة المقبولة.

أجرِ هذه الفحوص الخمسة بالترتيب. أمثلة بلغات Python وNode.js وGo وRuby وPHP موجودة في صفحة أمثلة التحقق.

  1. الحداثة. ارفض إذا كان |now − X-RolChat-Timestamp| > 300 ثانية (400). خمس دقائق تتسامح مع انحراف الساعة وتجعل الطلب الملتقط عديم القيمة بعدها. أبقِ خادمك متزامنًا عبر NTP.
  2. التوقيع. احسب القيمة المتوقعة وقارن باستخدام مقارنة ثابتة الزمن (hmac.compare_digest، crypto.timingSafeEqual، hash_equals). ارفض بـ 401 عند عدم التطابق. المقارنة النصية العادية تسرّب معلومات التوقيت وغير مقبولة.
  3. Nonce. خزّن X-RolChat-Nonce مع TTL مدته 10 دقائق باستخدام عملية ذرية “اضبط إن لم يوجد” (SET NX EX 600). إذا كان موجودًا بالفعل، ارفض بـ 409: الطلب إعادة إرسال. إذا تعطّل مخزن nonce لديك، افشل بشكل مغلق بـ 503 كي يعيد RolChat المحاولة؛ ولا تنتقل أبدًا إلى “القبول”.
  4. حلّل الجسم الآن فقط.
  5. أزل التكرار حسب معرّف الحدث. تحمل إعادات المحاولة nonce جديدًا لكن X-RolChat-Event-Id نفسه. إذا عالجت ذلك المعرّف خلال الأيام السبعة الأخيرة، أجب بـ 200 دون معالجة مجددًا.

أجب بـ 2xx بمجرد قبول التسليم بأمان؛ ونفّذ العمل بشكل غير متزامن. ينتظر RolChat الاستجابة 15 ثانية.

  • سر webhook هو 64 بايت عشوائية بترميز base64url (نحو 86 حرفًا). يُولَّد عند إنشاء الاشتراك أو الإضافة ويُعرض مرة واحدة.
  • خزّنه في خزنتك أو بيئتك الخاصة؛ ولا يحتفظ RolChat إلا بنسخة مشفرة.
  • يُوصى بالتدوير بعد 90 يومًا؛ يعرض المنتج تذكيرًا لكنه لا يعطّل الاشتراك أبدًا بسبب عدم التدوير.
  • يستخدم التدوير نافذة تداخل: بعد POST /api/v1/plugins/{id}/webhook-secret/rotate يتحقق السر القديم والجديد كلاهما لمدة سبعة أيام، وتُوقَّع عمليات التسليم الجديدة بالسر الجديد، ويُحذف القديم بعد النافذة. لا شيء يتعطل لحظة التدوير.
  • إذا تسرّب سر، فإن POST /api/v1/plugins/{id}/webhook-secret/revoke يبطله فورًا، ويصدر سرًا جديدًا، ويراسل مسؤولي الحساب بالبريد الإلكتروني، ويكتب إدخالًا في سجل التدقيق.

إعادات المحاولة والرسائل الميتة

Section titled “إعادات المحاولة والرسائل الميتة”

الاستجابة غير 2xx أو فشل الشبكة يجدول إعادة محاولة:

المحاولة التأخير بعد المحاولة السابقة
1 فورًا
2 15 ثانية
3 دقيقة واحدة
4 5 دقائق
5 30 دقيقة
6 ساعتان
7 8 ساعات
8 24 ساعة

تُعاد محاولة 408 و429 و5xx وأخطاء الشبكة. أما 400 و401 و403 و404 و410 فلا: يذهب التسليم مباشرة إلى قائمة انتظار الرسائل الميتة، لأن إعادة محاولة توقيع مرفوض أو نقطة نهاية مفقودة لا يمكن أن تفيد. بعد ثماني محاولات فاشلة يُنقل التسليم إلى الرسائل الميتة أيضًا.

تُحفظ الرسائل الميتة لمدة 30 يومًا وتظهر في الإعدادات ← الإضافات ← {plugin} ← سجل Webhook ← DLQ، حيث يستطيع المسؤول إعادة تشغيل إحداها (POST /api/v1/plugins/{id}/webhook-dlq/{entry_id}/replay).

  • الجسم الصادر: 1 MB افتراضيًا (قابل للضبط لكل إضافة). الجسم الوارد إلى RolChat: 5 MB. ما هو أكبر يعطي 413.
  • يمكن للإضافة الإعلان عن allowed_source_ips؛ ويطبّق RolChat قائمة السماح هذه قبل التحقق.
  • يمكنك الاعتماد على وكيل المستخدم RolChat-Webhook/1.0 كفحص إضافي للمعقولية. إنه ليس ضابطًا أمنيًا.

يرسل المزوّدون إلى RolChat على /api/v1/webhooks/{category}/{adapter} باستخدام مخططات التوقيع الخاصة بهم (Twilio وTelnyx وBandwidth وMeta لـ WhatsApp وStripe). يتحقق كل محوّل من توقيع مزوّده، ويوحّد الحمولة، ويعيد نشرها على ناقل الأحداث الداخلي بتوقيع RolChat. يستطيع نظامك الخاص الإرسال إلى RolChat بترويسات X-RolChat-* نفسها الموضحة أعلاه، موقّعة بسر الإضافة التي تملك نقطة النهاية.

لإجراء إرسال طلب HTTP في وحدة الأتمتة قواعد تسليم خاصة به:

  • سر واحد لكل حساب. اعرضه أو دوّره في شاشة الأتمتة (المالك والمسؤول). يسري التدوير فورًا: لا توجد فترة تداخل، ويتوقف السر القديم عن النجاح في التحقق على الفور، فحدّث المستقبِل لديك أولًا أو اقبل فجوة قصيرة.
  • مدة الانتظار: ينتظر RolChat الرد 10 ثوانٍ.
  • إعادة المحاولة: حتى 6 محاولات في المجموع. الفاصل قبل المحاولة 2 هو 30 ثانية، ثم نحو دقيقتين و8 دقائق و32 دقيقة وساعتين و8 دقائق، ويتفاوت كل منها بما يصل إلى 20 %. ولا يتجاوز أي فاصل واحد 6 ساعات.
  • ما يُعاد محاولته: أخطاء الشبكة وانتهاء المهلة و5xx و408 و425 و429. أما الردود 4xx الأخرى أو العنوان المحظور أو الجسم الأكبر من الحد فلا تُعاد: ينتقل التسليم مباشرة إلى طابور الرسائل الميتة، كما يحدث بعد آخر محاولة فاشلة.
  • الترويسات: X-RolChat-Signature وX-RolChat-Signature-V2 وX-RolChat-Timestamp وX-RolChat-Delivery-Id وX-RolChat-Attempt.

POST /api/v1/webhooks/test-signature يرسل حدثًا اصطناعيًا موقّعًا إلى نقطة نهاية الإضافة المستدعية كي تتحقق من تطبيقك من البداية إلى النهاية قبل وصول الحركة الحقيقية.

  • التحقق مقابل JSON المحلَّل والمعاد ترميزه بدلًا من البايتات الخام.
  • استخدام == لمقارنة التوقيعات.
  • إزالة التكرار حسب nonce (لكل إعادة محاولة nonce جديد) بدلًا من معرّف الحدث.
  • ساعة منحرفة بأكثر من خمس دقائق.
  • تنفيذ عمل بطيء قبل الإجابة، ثم انتهاء المهلة عند 15 ثانية وتلقي الحدث نفسه مجددًا.