تصفّح الأقسام
الـ Webhooks
يصل طلب HTTP إلى خادمك لحظة تغيّر محادثة أو رسالة أو جهة اتصال، وتتحقّق أنه منّا.
في هذا المقال
الـ Webhook يرسل طلب POST إلى رابط على خادمك كلما وقع حدث اخترته في مساحة عملك، مثل رسالة جديدة. بهذا لا تحتاج أن تسأل الـ API كل قليل عن الجديد.
أضف Webhook
تحتاج دور المدير.
- افتح الإعدادات ثم خيارات الربط.
- في بطاقة Webhook (1) اضغط تهيئة (2).
- اضغط إضافة webhook جديد.
- اكتب رابط Webhook (1)، ويجب أن يكون عنوان
httpsعاماً على خادمك. - اكتب إن شئت اسم الويب هوك (2) لتميّز كل Webhook عن غيره.
- تحت الأحداث (3) اختر الأحداث التي تريدها.
- اضغط إنشاء webhook (4).
- يظهر المفتاح السري الخاص به. انسخه إلى إعدادات خادمك ثم اضغط تم. تجده لاحقاً في نموذج تعديل الـ Webhook.
الأحداث
الاسم الذي يصل في الحقل event، واسمه في النموذج:
conversation_created: تم إنشاء المحادثةconversation_status_changed: تم تغيير حالة المحادثة (مفتوحة، محلولة، معلّقة، مؤجّلة)conversation_updated: تم تحديث المحادثة (مثل الوسوم أو الموظف المسؤول أو السمات)message_created: تم إنشاء رسالة (الرسائل الواردة والصادرة، والملاحظات الخاصة ومعها"private": true؛ سطور النشاط لا تُرسل)message_updated: تم تحديث الرسالة (مثل تغيّر حالة التسليم)webwidget_triggered: أداة الدردشة المباشرة مفتوحة من قبل المستخدمcontact_created: إنشاء جهة اتصالcontact_updated: تحديث جهة اتصالconversation_typing_onوconversation_typing_off: بدء الكتابة في محادثة، وإيقاف الكتابة في محادثة
ماذا يصلك؟
المحتوى JSON، ويُرسل مع Content-Type: application/json. فيه دائماً event وكائن account، والباقي حسب الحدث. مثال مختصر لـ message_created:
{
"event": "message_created",
"id": 9876,
"content": "وين طلبي؟",
"message_type": "incoming",
"private": false,
"created_at": "2026-10-29T08:15:02Z",
"account": { "id": 12, "name": "My Store" },
"inbox": { "id": 29, "name": "Store WhatsApp" },
"sender": { "id": 42, "name": "Sara", "phone_number": "+966500000000" },
"conversation": { "id": 123, "status": "open", "labels": [], "meta": { "assignee": null } }
}conversation.idهو الرقم الذي يظهر في صندوق الوارد، نفسه الذي يستخدمه الـ API.account.idهنا هو الرقم التسلسلي لمساحة العمل، لا معرّفacc_الذي في الرابط.- أحداث
…_updatedوconversation_status_changedتضيفchanged_attributes، وفيها القيمة السابقة والحالية لكل حقل تغيّر.
تحقّق من التوقيع
كل طلب يحمل ثلاث ترويسات:
X-Hadir-Delivery: معرّف فريد لهذا الإرسال.X-Hadir-Timestamp: وقت الإرسال بثواني يونكس.X-Hadir-Signature:sha256=ثم قيمة HMAC SHA256 بالصيغة الست عشرية لـ: الوقت، ثم نقطة، ثم المحتوى الخام كما هو، بمفتاح الـ Webhook السري.
احسب القيمة نفسها على خادمك من المحتوى الخام قبل تحليله، وقارن. في Node.js:
const crypto = require('crypto');
function isFromHadir(rawBody, headers, secret) {
const ts = headers['x-hadir-timestamp'];
const expected = 'sha256=' + crypto.createHmac('sha256', secret)
.update(`${ts}.${rawBody}`).digest('hex');
const given = String(headers['x-hadir-signature'] || '');
const fresh = Math.abs(Date.now() / 1000 - Number(ts)) < 300;
return fresh && given.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected));
}في PHP: hash_equals('sha256=' . hash_hmac('sha256', $ts . '.' . $rawBody, $secret), $signature). رفض الأوقات القديمة، كما في المثال، يمنع أحداً من إعادة إرسال طلب التقطه.
المهلة وإعادة المحاولة
- أمام خادمك 5 ثوانٍ للرد. ردّ بأي رمز
2xxبسرعة، وأكمل العمل الطويل بعدها. - الإرسال الذي تنتهي مهلته أو يأتيه رد غير
2xxلا يُعاد، ولوحة التحكم لا تعرض الإرسالات الفاشلة. إن كان فوات أي حدث مشكلة عندك، راجع الـ API بين حين وآخر أيضاً. - قد تصل الأحداث بغير ترتيبها. اعتمد على
created_atوالمعرّفات، لا على ترتيب الوصول.
ملاحظة: تبقى الـ Webhooks تعمل حتى لو صارت باقتك لاحقاً لا تشمل الـ API؛ المرفوض فقط هو إضافتها أو تعديلها. احذف ما لا تحتاجه من الصفحة نفسها.
شكراً لملاحظتك ✓
وصلتنا ملاحظتك، وسنراجع المقال على ضوئها.