لماذا يكون مزوّد البريد الشكل الخطأ لضمان الجودة
جُرِّبت كل طريقة لإعطاء مجموعة اختبارات عناوين بريد إلكتروني، وكل واحدة منها تتسرب من مكان مختلف:
| الأسلوب | ما تكلفته | أين يتعطل |
|---|---|---|
صندوق وارد مشترك واحد (qa@company.com) | لا شيء يجب إعداده. | كل اختبار يقرأ بريد كل اختبار آخر. وأول استطلاع لتشغيلة جديدة يجد رمز التشغيلة السابقة. والتشغيلات المتوازية مستحيلة. |
العنونة بعلامة + (qa+run42@company.com) | لا شيء يجب إعداده، إن كان المزوّد يدعمها. | يظل صندوق بريد واحدًا: حصة واحدة، وتسجيل دخول IMAP واحد يتشاركه الفريق كله، ونموذج تسجيل يزيل الوسم أو يرفض علامة +. |
| صندوق بريد لكل مختبِر من المزوّد | مقعد لكل واحد، وتذكرة دعم لإنشائه. | لا أحد يجهِّز صندوق بريد لكل تشغيلة اختبار. فيعيد المختبِرون استخدام صناديقهم، وتعود مشكلة الصندوق المشترك شخصًا واحدًا في كل مرة. |
| نطاق catch-all موجَّه إلى هنا | سجل DNS واحد، مرة واحدة. | صندوق البريد عام لأي شخص يعرف العنوان، والبريد يعيش 5 يومًا. وكلا الأمرين مقبول لرمز لا تهم صلاحيته سوى إحدى عشرة ثانية؛ ولا واحد منهما مقبول لبريد عملاء حقيقي. |
الصف الرابع هو موضوع هذا الدليل. وهو الآلية نفسها التي تعمل عليها النطاقات المؤقتة العامة — خادم يقبل كل عنوان على نطاق بدل قائمة من صناديق البريد — مطبَّقة على اسم لا يستخدمه أحد غيرك.
سجل DNS الواحد
لدى مزوّد DNS الخاص بك، أضف سجل MX واحدًا على جذر نطاق تملكه. لا سجل آخر هنا، ولا سجل TXT لإثبات أي شيء، ولا حساب على هذا الموقع:
سجل MX للنطاق10 smtp.grabmail.io
- انشر سجل MX. بأولوية 10، يشير إلى
smtp.grabmail.io. واحذف أي سجل MX آخر على النطاق — فالبريد لا يمكن تسليمه إلا إلى مكان واحد، وأي سجل متبقٍّ يرسل جزءًا منه إلى مكان آخر. - انتظر DNS. عادةً دقائق؛ وأحيانًا مدة TTL الخاصة بأي سجل كان موجودًا من قبل. ويُظهر أمر
dig MX qa-example.comمتى بدأ نفاذه. - أرسل رسالة واحدة إلى أي عنوان عليه. فأول عملية تسليم هي ما يربط النطاق: يبحث الخادم عن سجل MX في تلك اللحظة، ويرى نفسه، ويقبل الرسالة. ومن تلك اللحظة يصبح كل عنوان على النطاق صندوق بريد.
مخطط تسمية يوضح مَن أنشأ صندوق البريد
بما أن كل عنوان صالح، يصبح الجزء المحلي حرًا في حمل معلومات — وفي الساعة الثانية صباحًا، أمام تشغيلة فاشلة وصندوق بريد مفتوح، ستتمنى لو أنه يحمل هذه المعلومات. ثلاثة أجزاء، مفصولة بشرطات، بهذا الترتيب:
| الجزء | مثال | ما الذي يمنحك إياه |
|---|---|---|
| ما الذي أنشأه | signup، reset، e2e، alice | نظرة واحدة تخبرك بالمسار أو الشخص الذي يخص صندوق البريد. |
| أي تشغيلة | 1234567890 (معرِّف تشغيلة CI)، أو اسم فرع، أو تاريخ | كل صندوق بريد من تشغيلة خط أنابيب واحدة يتشارك رمزًا يمكنك البحث عنه. |
| العشوائية | 3f9a1c2e | ثمانية أحرف منها. وهذا هو الجزء الذي يجعل اختبارين، أو قسمي تنفيذ متوازيين (shards)، أو محاولتي إعادة، لا يتشاركون صندوق بريد أبدًا. |
| أبدًا: أي شيء حقيقي | اسم عميل، أو معرِّف مستخدم حقيقي، أو رقم تذكرة يذكر اسم عميل | صندوق البريد عام لأي شخص يعرف العنوان. ولا ينبغي أن يحمل العنوان أي شيء يستحق معرفته. |
// one helper, every runner: who made it, which run, and eight random characters
export const testAddress = (who: string, run = process.env.GITHUB_RUN_ID ?? 'local') =>
`${who}-${run}-${crypto.randomUUID().slice(0, 8)}@qa-example.com`;
testAddress('signup'); // signup-1234567890-3f9a1c2e@qa-example.comقراءة أي عنوان، بالاستدعاءات الثلاثة نفسها
لا شيء في API يتغيّر من أجل نطاقك الخاص. استدعاء السرد نفسه، واستدعاء الرسالة نفسه، والحذف نفسه — بلا مفتاح في المستوى العام، والنطاق في العنوان هو الشيء الوحيد الذي يختلف:
$ curl -sG https://grabmail.io/api/v1/mailbox --data-urlencode "address=signup-1234567890-3f9a1c2e@qa-example.com"وهذا يعني أن كل أداة مساعدة على هذا الموقع تعمل دون تغيير بعد تعديل ثابت واحد: fixture الخاصة بـPlaywright، ومهمة Cypress، ووحدتا Python وNode. وثمة ثلاثة أشياء تستحق معرفتها لا تضطرك النطاقات العامة إلى التفكير فيها:
- الرمز
404يعني أن سجل MX غير موجود بعد - يجيب السرد بـ
404لنطاق غير مستضاف هنا. وعلى نطاقك الخاص يكون ذلك مشكلة DNS — إذ لم ينتشر السجل بعد، أو أنه يشير إلى مكان آخر — لا مشكلة في API. جرِّبdig MXأولاً. - المستعار يعمل على نطاقك أيضًا
- لكل صندوق بريد، على أي نطاق، عنوان ثانٍ على نطاق منفصل يسلِّم إليه ولا يستطيع قراءته. أعطِ ذلك العنوان لموقع حين تفضِّل ألا يستطيع فتح صندوق الوارد؛ واستطلع أنت عنوانك الخاص.
- العنوان المزدحم يُقسَّم إلى صفحات
- عنوان catch-all يجمع الارتدادات أو إشعارات يوم كامل قد يحمل أكثر من صفحة واحدة من 200. مرِّر
nextمجددًا كـbeforeإلى أن تصبحnull.
إبقاء نطاق الاختبار صالحًا للاستخدام
النطاق الذي تملكه غير مدرج في أي قائمة حظر بريد مؤقت، وهذا غالبًا هو سبب استخدامه من الأساس: فالتطبيق قيد الاختبار يرفض grabmail.io وكل نطاق عام آخر، كما ينبغي له بالضبط. وأربع عادات تُبقيه كذلك:
- استخدم نطاقًا مخصصًا — مثل
qa-example.com، لا نطاقًا فرعيًا من الإنتاج ولا النطاق الذي يكتب إليه العملاء. والخدمة تقبل النطاقات القابلة للتسجيل فقط (example.com، وليس أبدًاmail.example.com)، ولا ينبغي أن يكون لنطاق الاختبار أي وظيفة أخرى. - لا تنشره. فالقوائم تُبنى مما يظهر على مواقع البريد المؤقت العامة وفي مقالب العناوين المشتركة. والنطاق الذي لا يظهر إلا في مجموعة اختباراتك الخاصة ليس أمامه طريقة للوصول إليها.
- اقفله بـSPF وDMARC. فالنطاق المخصص للاستقبال فقط بلا SPF نطاق يستطيع أي شخص انتحال البريد الصادر منه؛ وسجلان اثنان يغلقان هذه الثغرة، دون أي تكلفة.
- لا توجِّه إليه بريدًا حقيقيًا. فبمجرد أن يرسل نظام staging إشعارات عملاء إلى عنوان catch-all، يصبح صندوق بريد عام يحمل بيانات عملاء. ونطاقات الاختبار تحمل بريد اختبار فقط.
وإذا كان التطبيق يرفض كل نطاقات catch-all — كما تفعل بعض فحوصات الاحتيال، بفحص ما إذا كان عنوان عشوائي على النطاق مقبولاً — فتوجد مجموعة مدفوعة من نطاقات .com ذات مظهر عادي تُبقى بعيدة عن القوائم، موصوفة في صفحة الأسعار. ويشرح دليل لماذا تحظر نماذج التسجيل البريد المؤقت ما الذي يراه كل نوع من الفحوصات.
لفريق: نطاق واحد، ومختبِرون كثيرون، وخطوط أنابيب كثيرة
نطاق catch-all واحد يخدم الجميع، لأن الجزء المحلي هو الشيء الوحيد الذي يجب أن يختلف، وهو مجاني. وما يحتاجه الفريق هو الاتفاق على مخطط التسمية أعلاه وثلاث قواعد صغيرة:
- بادئة لكل خط أنابيب ولكل شخص
e2e-،nightly-،alice-. البحث عن البادئة في سجل مهمة يجد كل صندوق بريد أنشأته؛ والبحث عن بادئة زميل يجد العلة التي يبحث فيها.- لا شيء مشترك، أبدًا
- لا يوجد «صندوق وارد للفريق» على النطاق ولا fixture توزّع عنوانًا ثابتًا. وإذا احتاج شخصان إلى صندوق البريد نفسه، يرسل أحدهما العنوان إلى الآخر.
- حدود المعدل لكل عميل
- قراءة واحدة في الثانية لكل عنوان، و1200 طلب في الدقيقة لكل عميل — فمُشغِّل CI عميل واحد، والحاسوب المحمول عميل آخر. وفريق من عشرة أشخاص يشغِّلون مجموعات اختبار في الوقت نفسه هم عشرة عملاء، لا عميل واحد.
الحدود المطبَّقة
يحصل نطاقك الخاص على الخدمة نفسها التي تحصل عليها النطاقات العامة، بالسقوف نفسها. ولا واحد منها قابل للتعديل، ولا واحد منها مشكلة لمجموعة اختبارات:
| الحد | القيمة | ماذا يعني ذلك لضمان الجودة |
|---|---|---|
| الاحتفاظ | 5 يومًا لكل رسالة | كل تشغيلة تنشئ بريدها الخاص؛ ولا يُجلب شيء أبدًا من أسبوع سابق. القواعد الدقيقة. |
| المرفقات | 5 MB لكل رسالة | يكفي لملف PDF لفاتورة أو تصدير CSV؛ وتُرفض الرسالة الأكبر وقت SMTP، بحيث يُخبَر المرسِل بذلك. |
| القراءات | 1 في الثانية لكل عنوان، و1200 في الدقيقة لكل عميل | عشرون صندوق بريد يُستطلَع كل واحد منها مرة في الثانية من مُشغِّل واحد. وبعد تجاوز ذلك، 429 مع Retry-After. |
| الخصوصية | لا شيء — يستطيع أي شخص يعرف عنوانًا قراءته | أجزاء محلية عشوائية، ونطاق غير منشور، ولا بريد عملاء حقيقي. |
| الإرسال | لا شيء | النطاق يستقبل فقط. ويرسل تطبيقك عبر مزوّده الخاص، كما في الإنتاج. |
قبل أن تعتبر الأمر منتهيًا
- نطاق مخصص قابل للتسجيل، بسجل MX واحد:
10 smtp.grabmail.io، وبلا أي سجل MX آخر. - رسالة واحدة أُرسلت إلى أي عنوان عليه، وقُرئت عبر API.
- سجلا SPF وDMARC منشوران، بحيث لا يستطيع أحد الإرسال باسم النطاق.
- أداة تسمية مساعدة — مَن، وأي تشغيلة، وثمانية أحرف عشوائية — تستخدمها كل مجموعة اختبارات.
- النطاق محفوظ في إعداد بيئة التشغيل، لا في الكود أو لقطات الشاشة أو التذاكر أبدًا.
- لا شيء يرسل بريد عملاء حقيقيًا موجَّه إليه.
ومن هنا فمجموعات الاختبار هي تلك المكتوبة أصلاً: Playwright مع النطاق في fixture الخاصة به، والمنهج المستقل عن أداة التشغيل، ومسار عمل GitHub Actions مع النطاق في متغير.
أسئلة
هل يمكنني استخدام نطاق فرعي، مثل test.company.com؟
لا — فالخدمة تقبل النطاقات القابلة للتسجيل فقط (company.com، أو company.co.uk)، لأن من يتحكم بنطاق يتحكم بكل اسم تحته، ويجب ألا يستطيع طرفان الاحتفاظ بنصفين متداخلين من مساحة أسماء واحدة. سجِّل نطاقًا مخصصًا رخيصًا للاختبار؛ فهذه هي الممارسة الأفضل على أي حال.
كم من الوقت حتى يعمل سجل MX؟
بمجرد أن يقدِّمه DNS، وهذا عادةً دقائق. وإن كان هناك سجل MX سابق، تُطبَّق مدة TTL الخاصة به. ويُربَط النطاق بأول رسالة تصل بعد ذلك — ولا يجب أن يحدث أي شيء آخر، ويخبرك أمر dig MX بموعد نفاذ السجل.
هل يكلِّف هذا أي شيء؟
لا. فربط نطاق، وكل عنوان عليه، وAPI، كلها مجانية، بلا حساب. والشيء المدفوع الوحيد على هذا الموقع هو مجموعة من النطاقات تُبقى بعيدة عن قوائم حظر البريد المؤقت، لمن لا يستطيعون استخدام نطاق يملكونه.
هل يستطيع شخص آخر قراءة البريد على نطاقي؟
يستطيع ذلك أي شخص يعرف عنوانًا، تمامًا كما على النطاقات العامة. وما يغيّره نطاقك الخاص هو إمكانية التخمين: فعناوينه على اسم لا يستخدمه أحد غيرك. والأجزاء المحلية العشوائية والنطاق غير المنشور يجعلان التخمين غير عملي؛ لكنهما لا يجعلان صندوق البريد خاصًا، ولا شيء هنا يفعل ذلك.
ماذا يحدث للبريد المرسَل إلى النطاق قبل أن تربطه؟
لا شيء يصل إلى هنا إلى أن يشير سجل MX إلى هنا. والبريد المرسَل بينما كان السجل القديم نافذًا ذهب إلى الخادم القديم، أو ارتد؛ والبريد المرسَل بعد تبديل DNS يصل ويربط النطاق.
كيف أفصل النطاق؟
احذف سجل MX. يتوقف وصول البريد الجديد فورًا؛ وما هو موجود بالفعل في صناديق البريد تنتهي صلاحيته من تلقاء نفسه خلال 5 يومًا. ولا يُحفظ عن النطاق شيء بعد ذلك.
التطبيق يرفض نطاق الاختبار الخاص بي أيضًا. ماذا الآن؟
بعض فحوصات الاحتيال ترفض أي نطاق يقبل عنوانًا عشوائيًا — فحص catch-all — بدل التحقق من قائمة. ولهذه الحالات، يُحتاج إلى نطاق يتصرف كمزوّد صناديق بريد عادي، وهذا ما توفره المجموعة المدفوعة؛ ويشرح دليل لماذا تحظر نماذج التسجيل البريد المؤقت أي نوع من الفحص تواجهه.


