الـ Webhook رابط تملكه أنت. تخبر لينوميا تشات بالأحداث التي تهمّك، وفي كل مرة يحدث واحد منها نرسل إلى ذلك الرابط طلب POST بجسم JSON. وهو الطريقة التي يتفاعل بها نظام خارج المنتج مع ما يحدث داخله.
متى تستخدمه
عندما يحتاج نظام آخر أن يعرف: أداة تذاكر تفتح حالة عند إنشاء محادثة، أو لوحة تحصي الرسائل الواردة، أو أداة أتمتة تبدأ سلسلة عمل عند إضافة جهة اتصال.
متى لا تستخدمه
- لإرسال رسائل أو تغيير أي شيء. فالـ Webhook صادر فقط. استخدم الواجهة البرمجية للكتابة.
- للرد على محادثة فوراً. فما يعيده رابطك يُهمَل. ولا شيء يعيده يدخل المحادثة.
- لقاعدة واحدة بعينها. إن أردت طلب POST عند تحقّق شرط معيّن فقط، فإجراء الـ Webhook داخل قاعدة أتمتة أو تدفق أضيق وأرخص من الاشتراك بكل رسالة في الحساب.
ما تحتاجه أولاً
حساب مدير، ورابط يمكن الوصول إليه من الإنترنت العام عبر HTTP أو HTTPS ويجيب في ثوانٍ قليلة. وفي بعض الخطط تعرض صفحة الـ Webhook إشعار ترقية بدلاً من القائمة.
الخطوات
- اذهب إلى الإعدادات ← خيارات الربط ← Webhook واختر إضافة Webhook جديد.
- أدخل الرابط، وأعطه اسماً، وأشّر على الأحداث التي تريدها. وحدث واحد على الأقل مطلوب.
- احفظ. ويُعرض الـ Secret مرة واحدة في شاشة التأكيد، فانسخه حينها. ويمكنك كشفه لاحقاً من نموذج تعديل الـ Webhook.
الأحداث
يعرض النموذج عشرة أحداث. وحدث حادي عشر، inbox_updated، لا يظهر إلا إذا كانت أحداث قنوات التواصل مفعّلة على
تثبيتك.
| الحدث | يُطلق عند |
|---|---|
conversation_created |
فتح محادثة |
conversation_updated |
تغيّر أي خاصية في محادثة |
conversation_status_changed |
تغيّر حالتها |
message_created |
إضافة رسالة |
message_updated |
تغيّر رسالة |
contact_created |
إضافة جهة اتصال |
contact_updated |
تغيّر خصائص جهة اتصال |
webwidget_triggered |
فتح زائر أداة الدردشة المباشرة |
conversation_typing_on / conversation_typing_off |
بدء أحدهم الكتابة أو توقفه |
inbox_updated |
تغيّر إعدادات قناة تواصل |
وتوقّع أمرين. conversation_updated كثير الضجيج — فهو يُطلق على تغييرات لا تسمّيها تحديثاً، فرشّح على
changed_attributes بدلاً من اعتبار كل واحد خبراً. ولا تُرسل إلا الرسائل الواردة والصادرة ورسائل القوالب؛ أما
الملاحظات الخاصة وأسطر النشاط فلا.
الحمولة
كل جسم كائن JSON فيه مفتاح event يسمّي الحدث، ومعه الكائن الذي يتعلق به الحدث.
| مجموعة الأحداث | يحمل الجسم |
|---|---|
| أحداث الرسائل | الرسالة — id وcontent وcontent_type وmessage_type وprivate وsource_id والمرفقات إن وُجدت — ومعها conversation وinbox وsender وaccount |
| أحداث المحادثات | المحادثة — id وstatus وpriority وlabels وinbox_id وmeta بالمُرسل والمُسند إليه والفريق، وcustom_attributes والأوقات — وأحدث رسالة فيها، وaccount |
| أحداث جهات الاتصال | جهة الاتصال — id وname وemail وphone_number وidentifier وavatar وcustom_attributes وadditional_attributes وblocked — وaccount |
والأحداث الثلاثة التي تعني تغيّراً — conversation_updated وconversation_status_changed
وcontact_updated — تضيف مصفوفة changed_attributes تصف ما تحرّك. وcontact_updated وinbox_updated لا
تُرسل أصلاً إن لم يتغيّر شيء.
التحقق من الإرسال
لكل Webhook سِرّ خاص به، ويحمل الإرسال الموقَّع ثلاث ترويسات طلب: معرّف الإرسال، والوقت، والتوقيع. وقيمة
التوقيع هي sha256= يتبعها HMAC-SHA256 للوقت ثم نقطة ثم جسم الطلب الخام، بمفتاح السِرّ:
sha256=HMAC_SHA256(secret, "<timestamp>.<raw body>")
احسبه على البايتات التي وصلتك، لا على نسخة أعدت تحويلها إلى نص، وقارن بزمن ثابت. ارفض كل ما لا يتطابق، واستخدم معرّف الإرسال مفتاحاً لتجاهل الإرسال المتكرر.
وأسماء الترويسات الثلاث بدقة:
| الترويسة | ما تحمله |
|---|---|
X-Chatwoot-Signature |
sha256= يتبعها HMAC أعلاه |
X-Chatwoot-Timestamp |
الوقت الذي حُسب التوقيع عليه |
X-Chatwoot-Delivery |
معرّف الإرسال، حين يتوفّر |
وهذه الأسماء جزء من صيغة البروتوكول، ولا تتغيّر بتغيّر الهوية البصرية للتثبيت.
عند فشل الإرسال
هذا الجزء يستحق قراءتين. فإرسال الـ Webhook يُحاوَل مرة واحدة.
| ما يحدث | |
|---|---|
| رابطك بطيء | يُترك الطلب بعد مهلة الـ Webhook في تثبيتك، وهي خمس ثوانٍ افتراضاً |
| رابطك يجيب 4xx أو 5xx | يُحسب الإرسال فاشلاً |
| رابطك متوقف | يُحسب الإرسال فاشلاً |
| أي ممّا سبق | يُكتب الفشل في سجل الخادم. ولا شيء يُعاد، ولا شيء يُحفظ في طابور، ولا شيء يُعرض لك |
فالأحداث التي تقع أثناء تعطّل رابطك تضيع. وإن كنت لا تستطيع تحمّل فقدانها، فاستقبل طلب POST في طابور خاص بك، وأجب فوراً، ثم عالجه بعد ذلك.
من يستطيع ذلك
المديرون وحدهم. فقائمة صلاحيات الدور المخصص لا تحتوي بنداً للـ Webhook، فلا يمكن تفويضه — راجع الأدوار والصلاحيات.
الحدود
- لا إعادة محاولة، ولا سجل إرسال، ولا إعادة إرسال، ولا زر اختبار. فالتحقق من Webhook يكون بإطلاق حدث حقيقي.
- لا يتكرر الرابط نفسه في الحساب الواحد. ولتصل الأحداث مرتين، استخدم رابطين مختلفين.
- العناوين الخاصة والداخلية مرفوضة. فالرابط الذي يُترجم إلى localhost أو إلى شبكة خاصة لا يُرسل إليه. ويجب أن يكون رابطك متاحاً للعموم.
inbox_createdلا يمكن الاشتراك به من النموذج. فهو موجود في قائمة أحداث الواجهة البرمجية وحدها.- جسم الرد لا يُقرأ أبداً، ونوع محتوى الرد لا يُفحَص.
- الحمولة غير قابلة للتهيئة. فلا تضيف حقولاً ولا تحذف حقولاً ولا تختار صيغة.
- الاشتراكات على مستوى الحساب. فلا تشترك برسائل قناة تواصل واحدة فقط؛ رشّح على
inboxفي كودك.
أشياء أخرى ترسل إلى رابط
الـ Webhook واحد من عدة. وهي غير متكافئة، والموقَّع منها بعضها فقط.
| يرسله | event في الجسم |
موقَّع |
|---|---|---|
| اشتراك Webhook | الحدث الذي اشتركت به | نعم، بسِرّ الـ Webhook |
| إجراء الـ Webhook في قاعدة أتمتة | automation_event.<trigger>، ومعه كتلة commerce على مُطلِق المتجر |
لا |
| إجراء الـ Webhook في ماكروس | macro.executed |
لا |
| عقدة الـ Webhook في تدفق | flow_webhook، ومعه التدفق والجلسة والقيم التي جمعها |
نعم، بسِرّ روبوت التدفق |
مواضيع ذات صلة
إن لم ينجح الأمر
لا يصل شيء. تحقق بهذا الترتيب: الرابط متاح للعموم، ويجيب في أقل من خمس ثوانٍ، والحدث الذي تتوقعه مؤشَّر فعلاً. والرابط على شبكة خاصة لا يستقبل شيئاً أبداً.
بعض الأحداث تصل وبعضها لا. فالملاحظات الخاصة وأسطر النشاط لا تُرسل كرسائل، وcontact_updated يُمنع إن لم
يتغيّر شيء.
فحص التوقيع عندي يفشل. أنت تُجزّئ جسماً أعدت تحويله إلى نص على الأغلب. جزّئ البايتات الخام، وضمّن الوقت والنقطة قبلها.
فقدت أحداثاً أثناء انقطاع. لا يوجد تعويض. اقرأ الواجهة البرمجية للفترة التي فاتتك.
صفحة الـ Webhook تعرض إشعار ترقية. فالواجهة البرمجية والـ Webhook غير مشمولين في خطتك.