الهندسة · 21 سبتمبر 2026

تصميم webhooks البريد الإلكتروني للتسليم مرة واحدة على الأقل

تعلّم كيف تبني مستهلكي webhook متينين لأحداث البريد الإلكتروني باستخدام إعادة المحاولة ومفاتيح عدم التكرار والتحقق من التوقيع، لضمان ألا يضيع أي حدث تسليم.

تحدي تسليم الأحداث بموثوقية

لتحقيق التسليم مرة واحدة على الأقل (at-least-once) لـ webhooks البريد الإلكتروني، عليك تطبيق نظام يعيد فيه المُرسِل الطلبات الفاشلة بتراجع أُسّي (exponential backoff) ويضمن فيه المستلِم عدم التكرار. ولأن الشبكات غير موثوقة والخوادم تتعطل، لا يمكنك افتراض أن استجابة HTTP 200 OK واحدة تضمن معالجة الحدث. وتُبنى الموثوقية بالجمع بين طابور إعادة محاولة دائم من جهة المُرسِل وطبقة إزالة تكرار من جهة المستلِم.

عندما تدمج واجهة API للبريد الإلكتروني مثل SendHQ، يحتاج تطبيقك إلى معرفة متى سُلِّمت الرسالة أو ارتدت أو صُنِّفت بريدًا مزعجًا. وهذه الأحداث غير متزامنة. فإذا تعطلت نقطة نهاية webhook لديك خمس دقائق أثناء ذروة حركة، فقد تفقد آلاف إشارات التسليم الحرجة. وهذا يخلق فجوة في بيانات التحليلات ويمنع نظامك من التفاعل مع الارتدادات (وهو أمر حاسم للحفاظ على سمعة المُرسِل).

تشريح webhook موثوق

تتكون بنية webhook المتينة من ثلاث ركائز أساسية: التحقق من التوقيع، والمعالجة غير المكرّرة، واستراتيجية إعادة المحاولة.

1. التحقق من التوقيع

لا تثق أبدًا بطلب POST إلى نقطة نهاية webhook لديك بالاعتماد على عنوان IP وحده أو على وجود مفتاح API في الجسم. فالمهاجمون يستطيعون انتحال هذه. بدلًا من ذلك، استخدم توقيع HMAC (رمز مصادقة الرسائل المبني على التجزئة).

يوقّع المُرسِل الحمولة (payload) باستخدام سر مشترك ويرفق التوقيع في ترويسة (مثل X-SendHQ-Signature). ويعيد المستلِم حساب التجزئة باستخدام السر نفسه ويقارنها بالترويسة.

const crypto = require('crypto'); function verifySignature(payload, signature, secret) { const expectedSignature = crypto .createHmac('sha256', secret) .update(payload) .digest('hex'); // Use timingSafeEqual to prevent timing attacks return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expectedSignature)); }

2. عدم التكرار وإزالة التكرار

يعني التسليم مرة واحدة على الأقل أن المُرسِل سيواصل إرسال الحدث إلى أن يتلقى استجابة نجاح. فإذا عالج خادمك الحدث ثم تعطل قبل إرسال 200 OK، فسيرسل المُرسِل الحدث مرة أخرى. وبدون معالجة غير مكرّرة، قد تحتسب تسليمًا واحدًا كتسليمين في قاعدة بياناتك.

يجب أن يحمل كل حدث event_id فريدًا. وينبغي أن تستخدم نمط مفتاح عدم التكرار (idempotency key) لتتبع الأحداث التي عولجت.

سير العمل:

  1. استلم حمولة webhook.
  2. تحقق مما إذا كان event_id موجودًا في جدول processed_events لديك.
  3. إذا كان موجودًا، فأعد 200 OK فورًا وتجاهل الجسم.
  4. إذا لم يكن موجودًا، فعالج الحدث وسجّل event_id في معاملة واحدة.

3. استراتيجية إعادة المحاولة

من منظور المُرسِل، سياسة إعادة المحاولة إلزامية. والنمط المعتاد هو التراجع الأُسّي مع عشوائية (jitter). مثلًا: أعد المحاولة بعد دقيقة واحدة، ثم 5 دقائق، ثم 30 دقيقة، ثم ساعتين، ثم 12 ساعة.

إذا أعاد المستلِم خطأ 4xx (باستثناء 429)، فهذا يشير عادةً إلى خطأ من جهة العميل (مثل توقيع غير صالح)، ولن تفيد إعادة المحاولة. أما خطأ 5xx أو انتهاء المهلة فيدل على فشل عابر تكون فيه إعادة المحاولة ضرورية.

مثال ملموس على الحمولة

فيما يلي حمولة نموذجية لحدث تسليم قد تتلقاه من SendHQ:

{ "event_id": "evt_12345abcde", "event_type": "delivered", "timestamp": "2026-09-15T10:00:00Z", "message_id": "msg_98765xyz", "recipient": "user@example.com", "metadata": { "order_id": "ord_5544" } }

التعامل مع الإخفاقات والحالات الحدّية

مشكلة «المستهلك البطيء»

إذا كان معالج webhook لديك ينفّذ عمليات كتابة ثقيلة في قاعدة البيانات أو يستدعي واجهات API خارجية أخرى بشكل متزامن، فستنتهي مهلة نقطة النهاية. وهذا يُطلق منطق إعادة المحاولة لدى المُرسِل، فتنشأ «عاصفة إعادة محاولات» قد تُسقط خادمك.

الحل: افصل القبول عن المعالجة.

  1. استلم webhook.
  2. تحقق من التوقيع.
  3. ادفع الحمولة الخام إلى طابور رسائل (مثل RabbitMQ أو SQS أو Redis).
  4. أعد 200 OK فورًا.
  5. تستهلك عملية عامل منفصلة الطابور وتحدّث قاعدة بياناتك.

مشكلة جاهزية الوكلاء

عندما تُشغَّل وكلاء الذكاء الاصطناعي بواسطة webhooks، يزداد خطر الحلقات اللانهائية. فإذا تلقى وكيل حدث «delivered» وردّ بإرسال رسالة أخرى تُطلق بدورها حدث «delivered» آخر، فأنت أمام حلقة.

تعامل مع إرسال البريد كأثر جانبي خارجي. ينبغي ألا ترسل الوكلاء رسائل تلقائيًا بناءً على webhook دون موافقة إنسان في الحلقة أو فحص صارم لآلة الحالات يؤكد أن الإجراء ضروري.

مقارنة المنظومة

عند اختيار مزوّد، غالبًا ما ترتبط الموثوقية بطريقة تعامله مع هذه الأحداث وبما يتقاضاه مقابل حجم البريد الذي يولّد هذه الأحداث.

بالنسبة إلى البريد المعاملاتي عالي الحجم، فالفرق في التكلفة صارخ. ووفقًا لـ أسعار Amazon SES، يكلّف الإرسال بنموذج a la carte ما مقداره 0.10 USD لكل 1,000 رسالة. في المقابل، تبدأ أسعار Postmark من 15 USD شهريًا لـ 10,000 رسالة، مع رسوم تجاوز بين 1.20 و1.80 USD لكل 1,000. ولحجم 50,000 رسالة، تكلّف SES بنموذج a la carte نحو 5 USD تقريبًا، بينما تبلغ تكلفة باقات Postmark نحو 66 USD.

ومن الخيارات الأخرى Resend التي تقدّم باقة مجانية بـ 3,000 رسالة شهريًا (بحد أقصى 100 يوميًا) وباقة Pro بـ 20 USD شهريًا لـ 50,000 رسالة. وتبدأ Mailgun من 15 USD شهريًا لـ 10,000 رسالة. أما SendGrid فقد حوّلت باقتها المجانية إلى فترة تجريبية مدتها 60 يومًا، مع بدء Essentials من 19.95 USD شهريًا.

وأيًّا كان المزوّد، فإن موثوقية استهلاكك لهذه الأحداث هي ما يحدد سلامة بياناتك.

قائمة التحقق للتنفيذ للمهندسين

  • التحقق من التوقيع: هل جرى التحقق من الحمولة (payload) باستخدام سر مشترك ودالة مقارنة بزمن ثابت؟
  • المعالجة غير المتزامنة: هل تُرجع نقطة النهاية 200 OK قبل تنفيذ منطق أعمال ثقيل؟
  • عدم التكرار: هل يوجد قيد فريد على event_id لمنع المعالجة المكررة؟
  • إدارة المهلة: هل ضُبطت المهلة لتكون أقل من مهلة المزوّد لتجنب تداخل عمليات إعادة المحاولة؟
  • المراقبة: هل لديك تنبيهات لارتفاع مفاجئ في استجابات 5xx عند نقطة نهاية webhook لديك؟
  • سلامة DNS: هل خوادم الاستقبال لديك مُهيأة بشكل صحيح؟ استخدم أدوات مثل أداة SendHQ لفحص DNS للبريد الإلكتروني للتأكد من إمكانية الوصول إلى بنيتك التحتية ومن إعدادها بشكل صحيح.
  • معايير المصادقة: هل نفذت DKIM وSPF وDMARC لضمان قبول بريدك الصادر، مما يقلل عدد webhooks «الارتداد» التي عليك معالجتها؟

ملخص المفاضلات

النهج | المزايا | العيوب

المعالجة المتزامنة | سهلة التنفيذ، واتساق فوري | خطر كبير لانتهاء المهلة، وعُرضة لعواصف إعادة المحاولة

المعالجة القائمة على الطابور | قابلة للتوسع بدرجة عالية، ومتينة أمام الذروات | تعقيد أكبر في البنية التحتية، واتساق نهائي (eventual consistency)

التسجيل البسيط | تكلفة إضافية منخفضة | لا سبيل لاسترداد الأحداث الفائتة دون سجلات يدوية

جدول عدم التكرار | سلامة بيانات مضمونة | عملية كتابة إضافية في قاعدة البيانات لكل حدث

الخلاصة

الموثوقية في webhooks البريد الإلكتروني لا تعني منع الإخفاقات بل التصميم لها. فبافتراض أن الشبكة ستفشل وأن الأحداث ستُسلَّم أكثر من مرة، تبني نظامًا متينًا حقًا. وسواء كنت تدير سجلات SPF لمشروع صغير أو توسّع نظامًا معاملاتيًا ضخمًا، تظل أنماط التحقق من التوقيع وعدم التكرار هي المعيار الذهبي.

ابنِ بنيتك التحتية للبريد الإلكتروني مع SendHQ.