إرسال تنبيهات البريد الإلكتروني عبر SNS: لماذا لا تصل الرسائل؟
أنشأت موضوع SNS وربطت به بريدك الإلكتروني، لكن التنبيهات لا تصل — هذا السيناريو يتكرر كثيراً، والسبب في معظم الحالات ليس خطأً في الكود أو السياسة، بل خطوة واحدة يتجاهلها المهندسون: تأكيد الاشتراك عبر الرابط الذي أرسله SNS إلى البريد الإلكتروني.
ملخص سريع (TL;DR) — إرسال تنبيهات البريد الإلكتروني عبر SNS
| الخطوة | الإجراء المطلوب | الحالة الشائعة للفشل |
|---|---|---|
| 1. إنشاء موضوع SNS | إنشاء موضوع من نوع Standard أو FIFO | استخدام نوع FIFO مع بريد إلكتروني — غير مدعوم |
| 2. إضافة اشتراك بريد إلكتروني | تحديد البروتوكول email أو email-json | كتابة عنوان البريد بشكل خاطئ |
| 3. تأكيد الاشتراك | النقر على رابط التأكيد في البريد الوارد | تجاهل الرسالة أو انتهاء صلاحية الرابط |
| 4. اختبار النشر | نشر رسالة تجريبية عبر CLI أو Console | عدم التحقق من حالة الاشتراك قبل الاختبار |
كيف يعمل SNS مع البريد الإلكتروني
Amazon SNS هو خدمة نشر/اشتراك مُدارة. عندما تضيف بريداً إلكترونياً كنقطة نهاية (endpoint)، لا يبدأ SNS في إرسال الرسائل فوراً — بل يُرسل أولاً رسالة تأكيد إلى ذلك البريد. يجب على المستلم النقر على رابط التأكيد داخل تلك الرسالة حتى ينتقل الاشتراك من حالة PendingConfirmation إلى حالة Confirmed. أي رسالة تُنشر على الموضوع قبل اكتمال هذه الخطوة لن تصل إلى البريد الإلكتروني.
فكر في الأمر كبريد مادي: SNS يضع ورقة في صندوق بريدك يقول 'هل تريد أن تستقبل رسائلنا؟' — حتى لا تُجيب بنعم، لا يُرسل شيئاً.
على رابط التأكيد؟"} C -- لا --> D["الحالة: PendingConfirmation
لا تصل أي رسائل"] C -- نعم --> E["الحالة: Confirmed"] E --> F["الرسائل المنشورة تصل
إلى البريد الإلكتروني"] D -- "إعادة الاشتراك" --> B
- إنشاء الاشتراك: يُسجّل SNS الاشتراك بحالة PendingConfirmation ويُرسل رسالة تأكيد.
- انتظار التأكيد: الاشتراك معلّق — لا تصل أي رسائل منشورة خلال هذه المرحلة.
- تأكيد الاشتراك: بعد النقر على الرابط، تنتقل الحالة إلى Confirmed.
- النشر الفعّال: أي رسالة تُنشر على الموضوع تصل الآن إلى البريد الإلكتروني.
التشخيص خطوة بخطوة — إرسال تنبيهات البريد الإلكتروني عبر SNS
الخطوة 1: التحقق من حالة الاشتراك
أول شيء يجب فعله هو التحقق من حالة الاشتراك مباشرة. معظم المهندسين يفترضون أن الاشتراك مؤكد لأنهم أضافوه من الـ Console — لكن الإضافة وحدها لا تعني التأكيد. الأمر التالي يُظهر جميع الاشتراكات المرتبطة بالموضوع وحالة كل منها.
aws sns list-subscriptions-by-topic \
--topic-arn arn:aws:sns:us-east-1:123456789012:MyAlertTopic \
--region us-east-1
ابحث في الناتج عن حقل SubscriptionArn. إذا كانت قيمته PendingConfirmation، فهذا هو السبب الجذري — الاشتراك لم يُؤكَّد بعد.
الخطوة 2: إعادة إرسال رسالة التأكيد
إذا انتهت صلاحية رابط التأكيد الأصلي أو ضاعت الرسالة في مجلد الـ Spam، يمكنك طلب إعادة إرسالها. لاحظ أن هذا الأمر يتطلب معرفة SubscriptionArn — لكن في حالة PendingConfirmation لن يكون لديك ARN حقيقي. الحل هو حذف الاشتراك وإعادة إنشائه.
aws sns subscribe \
--topic-arn arn:aws:sns:us-east-1:123456789012:MyAlertTopic \
--protocol email \
--notification-endpoint your-email@example.com \
--region us-east-1
بعد تنفيذ هذا الأمر، تحقق من بريدك الإلكتروني فوراً — بما في ذلك مجلد الـ Spam — وانقر على رابط التأكيد.
الخطوة 3: التحقق من نوع الموضوع
مواضيع SNS من نوع FIFO لا تدعم بروتوكول البريد الإلكتروني. إذا أنشأت موضوعاً بنهاية .fifo، فلن تتمكن من إضافة اشتراك بريد إلكتروني إليه أصلاً. تحقق من نوع الموضوع بالأمر التالي.
aws sns get-topic-attributes \
--topic-arn arn:aws:sns:us-east-1:123456789012:MyAlertTopic \
--region us-east-1 \
--query 'Attributes.FifoTopic'
إذا أعاد الأمر true، فأنت تستخدم موضوع FIFO. يجب إنشاء موضوع Standard منفصل لاشتراكات البريد الإلكتروني.
الخطوة 4: التحقق من سياسة الوصول للموضوع
حتى لو كان الاشتراك مؤكداً، قد تمنع سياسة الموضوع (Topic Policy) عملية النشر إذا كانت تقيّد من يملك صلاحية sns:Publish. هذا يظهر عادةً عندما تحاول CloudWatch أو خدمة أخرى النشر على الموضوع.
aws sns get-topic-attributes \
--topic-arn arn:aws:sns:us-east-1:123456789012:MyAlertTopic \
--region us-east-1 \
--query 'Attributes.Policy'
تحقق من أن الكيان الذي يُنشر (مثل cloudwatch.amazonaws.com) مدرج في قسم Principal مع صلاحية sns:Publish. مثال على سياسة تسمح لـ CloudWatch بالنشر:
🔽 عرض مثال سياسة SNS لـ CloudWatch
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCloudWatchPublish",
"Effect": "Allow",
"Principal": {
"Service": "cloudwatch.amazonaws.com"
},
"Action": "sns:Publish",
"Resource": "arn:aws:sns:us-east-1:123456789012:MyAlertTopic"
}
]
}
الخطوة 5: اختبار النشر المباشر
بعد تأكيد الاشتراك والتحقق من السياسة، انشر رسالة تجريبية مباشرة على الموضوع. هذا يُعزل المشكلة — إذا وصلت الرسالة التجريبية ولم تصل تنبيهات CloudWatch، فالمشكلة في إعداد التنبيه وليس في SNS.
aws sns publish \
--topic-arn arn:aws:sns:us-east-1:123456789012:MyAlertTopic \
--message "رسالة اختبار من SNS" \
--subject "اختبار تنبيه SNS" \
--region us-east-1
إذا وصلت هذه الرسالة إلى بريدك، فالموضوع والاشتراك يعملان بشكل صحيح.
خطأ شائع: الاشتراك مؤكد لكن الرسائل لا تصل
هذا هو السيناريو المُربك: تُظهر list-subscriptions-by-topic حالة Confirmed، وتنجح عملية النشر التجريبية، لكن تنبيهات CloudWatch لا تصل.
الافتراض الأول عادةً: 'المشكلة في SNS'. الافتراض الخاطئ تماماً.
السبب الفعلي في معظم الحالات: إجراء CloudWatch Alarm مرتبط بموضوع SNS مختلف، أو أن حالة التنبيه لم تتغير بعد (CloudWatch لا يُرسل إشعاراً إلا عند تغيير الحالة، وليس عند بقائها في حالة ALARM).
تحقق من الموضوع المرتبط بالتنبيه مباشرة:
aws cloudwatch describe-alarms \
--alarm-names "MyAlarm" \
--region us-east-1 \
--query 'MetricAlarms[*].{Name:AlarmName,SNS:AlarmActions,State:StateValue}'
قارن قيمة AlarmActions مع ARN الموضوع الذي تتوقع استخدامه. ARN واحد مختلف يُفسّر ساعات من التشخيص.
وأكّد الرابط"] Q1 -- Confirmed --> Q2{"نوع الموضوع؟"} Q2 -- FIFO --> Fix2["أنشئ موضوع Standard
جديداً"] Q2 -- Standard --> Q3{"سياسة الموضوع
تسمح بالنشر؟"} Q3 -- لا --> Fix3["أضف صلاحية sns:Publish
للخدمة الناشرة"] Q3 -- نعم --> Q4{"AlarmActions يشير
للموضوع الصحيح؟"} Q4 -- لا --> Fix4["صحّح ARN الموضوع
في إعداد التنبيه"] Q4 -- نعم --> Fix5["انشر رسالة تجريبية
وتحقق من السجلات"]
- تحقق من حالة الاشتراك: PendingConfirmation تعني أن الرسائل لن تصل بغض النظر عن أي إعداد آخر.
- تحقق من نوع الموضوع: FIFO لا يدعم البريد الإلكتروني.
- تحقق من سياسة الموضوع: الخدمة الناشرة يجب أن تملك صلاحية sns:Publish.
- تحقق من إعداد CloudWatch Alarm: تأكد أن AlarmActions يشير إلى الموضوع الصحيح.
الصلاحيات المطلوبة (IAM)
إذا كنت تُدير هذا الإعداد برمجياً أو عبر CI/CD، فالمستخدم أو الدور يحتاج الصلاحيات التالية كحد أدنى:
🔽 عرض سياسة IAM المطلوبة
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SNSManagement",
"Effect": "Allow",
"Action": [
"sns:CreateTopic",
"sns:Subscribe",
"sns:ListSubscriptionsByTopic",
"sns:GetTopicAttributes",
"sns:Publish"
],
"Resource": "arn:aws:sns:us-east-1:123456789012:MyAlertTopic"
},
{
"Sid": "CloudWatchAlarmRead",
"Effect": "Allow",
"Action": [
"cloudwatch:DescribeAlarms"
],
"Resource": "*"
}
]
}
لاحظ أن cloudwatch:DescribeAlarms يتطلب Resource: * — هذا متطلب موثّق في مرجع تفويض خدمة CloudWatch، وليس تساهلاً في السياسة.
الخلاصة والخطوات التالية
إعداد تنبيهات البريد الإلكتروني عبر SNS بسيط من الناحية التقنية، لكن خطوة تأكيد الاشتراك هي نقطة الفشل الأكثر شيوعاً. إذا كنت تُعدّ هذا الإعداد في بيئة إنتاجية، فكّر في أتمتة التحقق من حالة الاشتراك كجزء من pipeline الإعداد بدلاً من الاعتماد على خطوة يدوية.
- راجع توثيق SNS الرسمي لإشعارات البريد الإلكتروني للتفاصيل الكاملة.
- إذا كنت تستخدم CloudWatch Alarms، راجع إعداد تنبيهات CloudWatch مع SNS.
- للبيئات متعددة الحسابات، تحقق من سياسة الموضوع للتأكد من السماح بالنشر عبر الحسابات.
مسرد المصطلحات
| المصطلح | التعريف |
|---|---|
| SNS Topic | قناة اتصال في Amazon SNS تستقبل الرسائل وتوزعها على المشتركين |
| PendingConfirmation | حالة الاشتراك قبل تأكيده — لا تصل أي رسائل في هذه الحالة |
| Topic Policy | سياسة مبنية على الموارد تتحكم في من يملك صلاحية النشر أو الاشتراك في الموضوع |
| AlarmActions | قائمة ARNs تُنفَّذ عند تغيير حالة تنبيه CloudWatch، عادةً تشمل موضوع SNS |
| FIFO Topic | نوع من مواضيع SNS يضمن الترتيب وعدم التكرار، لكنه لا يدعم بروتوكول البريد الإلكتروني |
تعليقات
إرسال تعليق