مهندسی · 21 سپتامبر 2026
طراحی وبهوکهای ایمیل برای تحویل حداقل یکباره (at-least-once)
یاد بگیرید چگونه با تلاش مجدد، کلیدهای idempotency و تأیید امضا، مصرفکنندههای وبهوک مقاوم برای رویدادهای ایمیل بسازید تا هیچ رویداد تحویلی از دست نرود.
چالش تحویل قابلاعتماد رویدادها
برای دستیابی به تحویل حداقل یکباره (at-least-once) در وبهوکهای ایمیل، باید سیستمی پیادهسازی کنید که در آن فرستنده درخواستهای ناموفق را با exponential backoff دوباره تلاش کند و گیرنده idempotency را تضمین کند. چون شبکهها غیرقابلاعتمادند و سرورها از کار میافتند، نمیتوانید فرض کنید یک پاسخ HTTP 200 OK بهتنهایی تضمین میکند رویداد پردازش شده است. قابلیت اطمینان از ترکیب یک صف تلاش مجدد ماندگار در سمت فرستنده با یک لایه حذف موارد تکراری در سمت گیرنده به دست میآید.
وقتی یک API ایمیل مانند SendHQ را یکپارچه میکنید، برنامه شما باید بداند چه زمانی ایمیلی تحویل داده شده، برگشت خورده یا اسپم علامت خورده است. این رویدادها ناهمگاماند. اگر endpoint وبهوک شما در یک اوج ترافیک پنج دقیقه از دسترس خارج شود، ممکن است هزاران سیگنال تحویل حیاتی را از دست بدهید. این کار شکافی در دادههای analytics شما ایجاد میکند و مانع واکنش سیستم به برگشتها میشود (که برای حفظ اعتبار فرستنده حیاتی است).
ساختار یک وبهوک قابلاعتماد
یک معماری وبهوک مستحکم بر سه ستون اصلی استوار است: تأیید امضا، پردازش idempotent و راهبرد تلاش مجدد.
1. تأیید امضا
هرگز به یک درخواست POST به endpoint وبهوک خود فقط بر اساس نشانی IP یا وجود کلید API در بدنه اعتماد نکنید. مهاجمان میتوانند اینها را جعل کنند. بهجای آن از امضای HMAC (کد احراز اصالت پیام مبتنی بر هش) استفاده کنید.
فرستنده payload را با یک secret مشترک امضا میکند و امضا را در یک هدر (مثلاً X-SendHQ-Signature) قرار میدهد. گیرنده هش را با همان secret دوباره محاسبه میکند و با هدر مقایسه میکند.
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. Idempotency و حذف موارد تکراری
تحویل حداقل یکباره یعنی فرستنده تا زمانی که پاسخ موفق دریافت نکند، ارسال رویداد را ادامه میدهد. اگر سرور شما رویداد را پردازش کند اما پیش از ارسال 200 OK از کار بیفتد، فرستنده رویداد را دوباره ارسال میکند. بدون idempotency ممکن است یک تحویل واحد را در پایگاه داده خود دو تحویل حساب کنید.
هر رویداد باید یک event_id یکتا داشته باشد. برای پیگیری رویدادهای پردازششده باید از الگوی کلید idempotency استفاده کنید.
گردشکار:
- payload وبهوک را دریافت کنید.
- بررسی کنید آیا
event_idدر جدولprocessed_eventsشما وجود دارد. - اگر وجود دارد، فوراً 200 OK برگردانید و بدنه را نادیده بگیرید.
- اگر وجود ندارد، رویداد را پردازش کنید و
event_idرا در همان تراکنش ثبت کنید.
3. راهبرد تلاش مجدد
از دید فرستنده، سیاست تلاش مجدد الزامی است. یک الگوی استاندارد، exponential backoff همراه با jitter است. برای مثال: تلاش مجدد پس از 1 دقیقه، 5 دقیقه، 30 دقیقه، 2 ساعت و 12 ساعت.
اگر گیرنده خطای 4xx برگرداند (بهجز 429)، معمولاً نشاندهنده خطای سمت کلاینت (مانند امضای نادرست) است و تلاش مجدد کمکی نمیکند. خطای 5xx یا timeout نشاندهنده خطایی گذراست که تلاش مجدد در آن ضروری است.
نمونه عینی payload
این یک payload معمول رویداد تحویل است که ممکن است از 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"
}
}
مدیریت خطاها و حالتهای مرزی
مسئله "مصرفکننده کند"
اگر handler وبهوک شما نوشتنهای سنگین در پایگاه داده انجام دهد یا APIهای خارجی دیگری را بهصورت همگام فراخوانی کند، endpoint شما دچار timeout میشود. این کار منطق تلاش مجدد فرستنده را فعال میکند و به یک "طوفان تلاش مجدد" میانجامد که میتواند سرور شما را از کار بیندازد.
راهحل: پذیرش را از پردازش جدا کنید.
- وبهوک را دریافت کنید.
- امضا را تأیید کنید.
- payload خام را در یک صف پیام (مانند RabbitMQ، SQS یا Redis) قرار دهید.
- فوراً 200 OK برگردانید.
- یک فرایند worker جداگانه صف را مصرف میکند و پایگاه داده شما را بهروز میکند.
مسئله آمادگی ایجنتها
وقتی ایجنتهای هوش مصنوعی با وبهوک فعال میشوند، خطر حلقههای بیپایان افزایش مییابد. اگر ایجنتی رویداد "delivered" را دریافت کند و در پاسخ ایمیل دیگری بفرستد که خود رویداد "delivered" دیگری ایجاد میکند، با یک حلقه روبهرو هستید.
ارسال ایمیل را یک اثر جانبی خارجی در نظر بگیرید. ایجنتها هرگز نباید بر اساس یک وبهوک و بدون تأیید انسان در حلقه یا بررسی دقیق ماشین حالت برای اطمینان از ضروری بودن اقدام، بهطور خودکار ایمیل بفرستند.
مقایسه اکوسیستم
هنگام انتخاب ارائهدهنده، قابلیت اطمینان اغلب به نحوه مدیریت این رویدادها و هزینهای که برای حجم ایمیلی که این رویدادها را تولید میکند دریافت میکنند، گره خورده است.
برای ایمیل تراکنشی پرحجم، تفاوت هزینه چشمگیر است. طبق قیمتگذاری 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 با استفاده از یک secret مشترک و تابع مقایسه با زمان ثابت تأیید میشود؟
- پردازش ناهمگام: آیا endpoint پیش از اجرای منطق سنگین کسبوکار، 200 OK برمیگرداند؟
- Idempotency: آیا روی
event_idیک محدودیت یکتا وجود دارد تا از پردازش تکراری جلوگیری شود؟ - مدیریت timeout: آیا برای جلوگیری از تلاشهای مجدد همپوشان، timeout پایینتر از timeout ارائهدهنده تنظیم شده است؟
- پایش: آیا برای جهش پاسخهای 5xx در endpoint وبهوک خود هشدار دارید؟
- سلامت DNS: آیا سرورهای دریافتکننده شما بهدرستی پیکربندی شدهاند؟ برای اطمینان از دسترسپذیری و پیکربندی درست زیرساخت، از ابزارهایی مانند بررسیکننده DNS ایمیل SendHQ استفاده کنید.
- استانداردهای احراز هویت: آیا DKIM، SPF و DMARC را پیادهسازی کردهاید تا ایمیل خروجی شما پذیرفته شود و تعداد وبهوکهای «bounce» که باید مدیریت کنید کاهش یابد؟
خلاصه بدهبستانها
رویکرد | مزایا | معایب
پردازش همگام | پیادهسازی ساده، سازگاری فوری | خطر بالای timeout، مستعد طوفان تلاش مجدد
پردازش مبتنی بر صف | بسیار مقیاسپذیر، مقاوم در برابر اوجها | پیچیدگی بیشتر زیرساخت، سازگاری نهایی (eventual consistency)
ثبت لاگ ساده | سربار کم | بدون لاگهای دستی، راهی برای بازیابی رویدادهای ازدسترفته نیست
جدول idempotency | تضمین یکپارچگی داده | یک نوشتن اضافه در پایگاه داده بهازای هر رویداد
جمعبندی
قابلیت اطمینان در وبهوکهای ایمیل به معنای جلوگیری از خطا نیست، بلکه به معنای طراحی برای آن است. با این فرض که شبکه از کار میافتد و رویدادها بیش از یک بار تحویل داده میشوند، سیستمی میسازید که واقعاً مقاوم است. چه رکوردهای SPF را برای یک پروژه کوچک مدیریت کنید و چه یک سیستم تراکنشی عظیم را مقیاس دهید، الگوهای تأیید امضا و idempotency همچنان استاندارد طلایی هستند.
زیرساخت ایمیل خود را با SendHQ بسازید.