لتشغيل خطافات الويب (webhooks) في واتساب بأمان، افصل أولًا بين ثلاثة اتجاهات: ميتا إلى Wats، وWats إلى أنظمة شركتك، ونظام خارجي إلى Wats. لكل اتجاه سر ورؤوس وصلاحيات مختلفة. تحقق من التوقيع على الجسم الخام، وخزّن الحدث بمعرف ثابت، وامنع التكرار، وأعد 2xx بسرعة، ثم عالج العمل غير المتزامن مع إعادة محاولة ومراقبة وتدوير أسرار.
خطاف الويب إشعار حدث، لا ضمانًا بأن العملية التجارية اكتملت فورًا. قد يتأخر الطلب أو يتكرر أو يصل بعد حدث أحدث، وقد يكون النظام المستقبل متوقفًا مؤقتًا. لذلك تكون الاعتمادية نتيجة تصميم المستقبل والسجل والصف وسياسة الاستعادة، لا نتيجة وجود نقطة نهاية (endpoint) عامة فقط.
افصل اتجاهات الأحداث قبل تصميمها
عبارة «خطاف ويب لواتساب» قد تشير إلى عقود مختلفة:
الاتجاه | المرسل | المستقبل | طريقة الثقة الأساسية | مثال |
|---|---|---|---|---|
Meta → Wats | WhatsApp Business Platform لدى Meta | endpoint الوارد في Wats | verify token للمصافحة ثم | رسالة واردة أو تحديث حالة رسالة |
Wats → نظام الشركة | Wats | CRM أو ERP أو برمجية وسيطة (middleware) | سر خطاف الويب ورأس |
|
نظام خارجي → Wats | CRM أو ERP أو خدمة تكامل | API أو endpoint مخصص في Wats | API token محدود الصلاحيات والقنوات، وعقد idempotency | طلب إرسال مؤهل أو تحديث سياق |
لا تستخدم سر تطبيق ميتا لتوقيع خطاف ويب صادر من Wats، ولا تضع رمز API في الحمولة (payload). السر يثبت هوية المرسل، والرمز يمنح صلاحية لاستدعاء واجهة؛ لكل منهما دورة حياة مستقلة.
إذا لم يكتمل ربط الرقم والأصول لدى Meta، ابدأ بدليل تكامل واتساب للأعمال مع Meta قبل بناء مستهلك الأحداث.
مسار Meta إلى Wats: المصافحة ثم الأحداث
توضح وثائق ميتا الرسمية لخطافات Cloud API الاشتراك في الأحداث وبنية الاستقبال. يبدأ تفعيل نقطة النهاية عادةً بطلب GET للتحقق، ثم تستخدم الأحداث طلبات POST.
1. مصافحة GET
يصل الطلب بمعاملات:
المعامل | الغرض |
|---|---|
| يجب أن يطابق وضع الاشتراك المتوقع |
| قيمة مشتركة تختارها أنت وتقارنها بأمان |
| قيمة يعيدها endpoint كما هي عند نجاح التحقق |
إذا تطابق الوضع والرمز، يعيد المستقبل hub.challenge مع استجابة ناجحة. verify token ليس توقيع كل حدث ولا بديلًا عن app secret.
2. POST للأحداث
عند وصول الحمولة، يجب التحقق من X-Hub-Signature-256 باستخدام HMAC SHA-256 وسر تطبيق ميتا على بايتات الجسم الخام. تشرح وثائق ميتا للتحقق من الحمولات نموذج التوقيع. بعد النجاح، استخرج معرفات الرسالة والحالة والقناة، وسجل الحدث قبل تنفيذ عمل خارجي طويل.
Meta Wats endpoint Event store / worker
| GET verification | |
|---------------------->| compare verify token |
|<----------------------| 200 + challenge |
| | |
| POST event + signature| |
|---------------------->| verify raw body |
| | persist + deduplicate ------>|
|<----------------------| 2xx after safe acceptance |
| | process async |الـ2xx هنا يعني أن الحدث قُبل بأمان، وليس أن كل API لاحق اكتمل. إذا ربطت استجابة Meta بانتظار CRM بطيء، تزيد احتمالات انتهاء المهلة وإعادة التسليم والتكرار.
مسار Wats إلى CRM أو ERP
يستطيع Wats إرسال أحداث صادرة مثل message.inbound وmessage.outbound وconversation.assigned وconversation.escalated وcampaign.completed، مع فلترة نوع الحدث والقنوات. يحتوي الطلب على رؤوس سياقية مثل:
X-Wats-Event
X-Wats-Webhook-Id
X-Wats-Company-Id
X-Wats-Timestamp
X-Wats-Signature: sha256=<hex-hmac-of-raw-body>يحسب المستقبل HMAC باستخدام السر المضبوط لهذا الخطاف، لا سر ميتا. ثم يستخدم معرف الخطاف ونوع الحدث ومعرفًا ثابتًا من الحمولة لبناء مفتاح منع تكرار، ويخزن الحدث ويعيد 2xx قبل تشغيل تحديثات ثقيلة.
Wats event → event/channel filter → sign raw payload → HTTPS POST
↓
CRM receiver ← 2xx ← verify → deduplicate → persist → queue
↓
update CRM/ERP asyncراجع دليل تكامل واتساب مع CRM وERP لتحديد مصدر الحقيقة والمعرفات واتجاه التحديث قبل اختيار الأحداث.
مسار النظام الخارجي إلى Wats
عندما يريد ERP أو CRM بدء إجراء داخل Wats، فهذا غالبًا استدعاء API أو سير عمل وارد مصمم لهذا الغرض، لا «إعادة خطاف ويب» بلا عقد. استخدم رمزًا له أقل الصلاحيات المطلوبة واقصره على القنوات اللازمة، مع انتهاء وإلغاء. أرسل مفتاح عدم التكرار (idempotency) أو معرف الحدث الخارجي حتى لا تنشئ إعادة المحاولة رسالتين أو إجراءين.
مثال: يرسل ERP حدث shipment.updated إلى خدمة التكامل. تتحقق الخدمة من الحدث وتخزنه، ثم تقرر بوابة السياسة هل التحديث داخلي فقط أم مؤهل لإرسال واتساب. إذا كان مؤهلًا، تستدعي Wats بمعرف العملية نفسه. لا تسمح لكل نظام خلفي بإرسال نص حر مباشرة إلى العميل.
يمكن أن ينسق سير عمل أتمتة واتساب هذا المسار، لكن يجب أن تبقى المصادقة ومنع التكرار وبوابة السياسة صريحة خارج الموجّه (prompt) أو النص الحر.
مثال حمولة (payload) آمنة ومحدودة
المثال التالي توضيحي لشكل حدث موحد داخل طبقة التكامل، وليس وعدًا بأن كل مزود يستخدم أسماء الحقول نفسها:
{
"event": "message.inbound",
"eventId": "evt_demo_01",
"occurredAt": "2026-05-31T06:05:12Z",
"companyId": "cmp_demo",
"channelId": "chn_demo",
"data": {
"messageId": "wamid.demo_123",
"conversationId": "conv_demo_45",
"direction": "inbound",
"contentType": "text"
}
}لا تضع app secret أو access token أو بيانات عميل لا يحتاجها المستهلك في payload. وإذا احتاج CRM نص الرسالة فعلًا، طبّق تقليل البيانات وسياسة الاحتفاظ والحجب في logs.
مثال HMAC صحيح على الجسم الخام
المثال التالي في Node.js يصلح لفحص رأس بالشكل sha256=<hex>. يجب تمرير rawBody كما وصل قبل JSON parsing، وقراءة السر من secret manager أو متغير بيئة آمن:
import crypto from "node:crypto";
export function validSignature(rawBody, signatureHeader, secret) {
if (!signatureHeader?.startsWith("sha256=")) return false;
const received = Buffer.from(signatureHeader.slice(7), "hex");
const expected = crypto
.createHmac("sha256", secret)
.update(rawBody)
.digest();
return received.length === expected.length &&
crypto.timingSafeEqual(received, expected);
}استخدم سر تطبيق ميتا مع X-Hub-Signature-256 للأحداث الواردة من ميتا، واستخدم سر خطاف الويب مع X-Wats-Signature للأحداث الصادرة من Wats. ارفض الرأس المفقود أو القيمة السداسية غير الصالحة أو عدم التطابق، وسجل سببًا غير حساس دون طباعة السر أو التوقيع الكامل أو الحمولة الشخصية.
وجود X-Wats-Timestamp يسمح بإضافة سياسة رفض للطلبات القديمة للحد من replay، لكن نفذ هامشًا معقولًا لاختلاف الساعات، ولا تستخدم timestamp بدل مفتاح deduplication.
دورة حياة حدث تتحمل الفشل
اعتمد حالات واضحة بدل تنفيذ كل شيء داخل request:
received → verified → persisted → queued → processing → processed
└────→ failed → retry / review
duplicate → acknowledge without repeating the business actionReceived: التقط raw body والرؤوس اللازمة فقط.
Verified: تحقق من التوقيع والوقت والعقد المتوقع.
Persisted: خزّن معرف الحدث وhash ومصدره وحالة أولية.
Deduplicated: احجز مفتاحًا فريدًا ذريًا قبل الأثر التجاري.
Queued: أعد 2xx ثم مرر المهمة إلى worker.
Processed: سجل المعرف الناتج، مثل سجل CRM أو رسالة واتساب.
Failed: صنف الخطأ إلى مؤقت أو دائم، مع عدد المحاولات وموعد التالي.
استخدم exponential backoff مع jitter للأخطاء المؤقتة، وحدًا للمحاولات، ثم dead-letter queue أو مراجعة بشرية. لا تعِد المحاولة تلقائيًا عند أخطاء دائمة مثل payload غير صالح أو صلاحية مفقودة قبل تصحيح السبب.
يعيد Wats معالجة أحداث ميتا الواردة التي سُجل فشلها ضمن مسار إعادة محاولة داخلي. أما خطاف الويب الصادر إلى نظام الشركة، فلا تفترض سياسة إعادة محاولة أو ترتيبًا أو تنفيذًا مرة واحدة فقط (exactly-once) إلا إذا كانت موثقة في عقد النسخة التي تستخدمها؛ اختبر السلوك واجعل المستقبل آمنًا عند التكرار وراقب الفجوات في كل الأحوال.
كيف تتعامل مع التكرار والترتيب؟
مفتاح dedup الجيد يعتمد على معرف مستقر من المصدر ونوع الحدث، مثل:
meta + message_id + status_type
wats + webhook_id + event_id
erp + source_event_id + requested_actionنفذ حجز المفتاح بقيد unique أو معاملة ذرية، لا بفحص ثم إنشاء منفصلين قد يتسابقان. احتفظ بالنتيجة النهائية حتى تستطيع إعادة 2xx للنسخة المكررة.
أما الأحداث خارج الترتيب فتحتاج قواعد مجال. إذا وصل read ثم وصل تحديث أقدم، فلا تعد الحالة إلى الوراء. وإذا وصل تحديث طلب بإصدار أقل من الإصدار المخزن، سجله للتدقيق وتجاهل أثره. الوقت وحده قد لا يكفي؛ استخدم sequence أو version من المصدر عندما يكون متاحًا.
تدوير الأسرار والمراقبة
للتدوير بلا توقف، أضف السر الجديد إلى المستقبل، واقبل القديم والجديد خلال نافذة قصيرة، ثم حدّث المرسل، وراقب أي استخدام للقديم، وألغِه بعد التأكد. لا تجعل النافذة مفتوحة بلا نهاية. في Meta قد تحتاج إلى دعم app secrets النشطة أثناء الانتقال، وفي Wats حدّث secret الخاص بتكوين webhook والمستقبل وفق ترتيب منسق.
راقب مؤشرات تشغيلية لا تحتوي بيانات عميل:
عدد الأحداث المقبولة والمرفوضة بسبب التوقيع.
نسبة التكرار وأسباب الفشل حسب endpoint.
عمر أقدم حدث في queue وأقدم حدث failed.
عدد المحاولات ووقت المعالجة من الاستلام إلى الاكتمال.
فجوات sequence أو اختلاف العد بين المصدر والمستقبل.
لا تعد العميل بـ«real-time مضمون». الوصف الأدق هو معالجة مدفوعة بالأحداث وقريبة من الزمن الحقيقي، تتأثر بالشبكة والصفوف وإعادة المحاولة. صمم تجربة المستخدم لتتحمل حالة «قيد التحديث» وتوفر reconciliation للحالات المهمة.
كيف يستخدم Wats هذه العقود؟
في اتجاه Meta الوارد، يتحقق Wats من مصافحة GET ومن توقيع POST، ويسجل الأحداث ويمنع التكرار ثم يتابع حالات المعالجة والفشل وإعادة المعالجة. وفي الاتجاه الصادر، يتيح تكوين URL وsecret وفلاتر أحداث وقنوات واختبار endpoint، ويرسل رؤوس Wats والتوقيع المبني على الجسم الخام.
وفي اتجاه الأنظمة الخارجية، توفر رموز API صلاحيات محددة وقصرًا على القنوات وانتهاءً وإلغاءً. إذا أضفت وكيلًا ذكيًا إلى التدفق، فلا تعطه السر أو سلطة قبول خطاف الويب؛ اجعل التحقق والحفظ قواعد بنية تحتية قبل وصول الحدث إليه. يشرح دليل القواعد والوكيل الذكي أين يجب أن تبقى الحدود الحتمية.
الخلاصة: صمم للاستلام أكثر من مرة
خطاف الويب الموثوق هو عقد أمني وسجل حالة ومسار استعادة، وليس طلب POST ناجحًا في اختبار واحد. افصل الاتجاهات والأسرار، وتحقق من الجسم الخام، واحجز مفتاح التكرار، وأعد 2xx بعد القبول الآمن، ثم نفذ العمل خارج الطلب. اختبر التكرار والتأخير والوصول خارج الترتيب وتعطل النظام وتدوير السر؛ عندها يصبح الحدث جزءًا يمكن تشغيله ومراجعته بدل نقطة اتصال هشة.


