نوتیفیکیشنهای هوشمند تو Laravel با اولویت و ارسال با تأخیر
خلاصهٔ کاملتر
نویسنده تو تنظیمات Linear یه گزینه دیده: ایمیلهای کماهمیت بیرون از ساعت کاری تا روز کاری بعد عقب بیفتن. به گفتهٔ اون، تو یه اپ B2B منطقیه که کسی ساعت ۷ عصر بهخاطر اینکه یه همتیمی از یه منطقهٔ زمانی دیگه بهش issue داده، ایمیل نگیره. برای همین با سیستم notification داخلی Laravel یه نسخهٔ مشابه ساخته، بدون اینکه API ارسال نوتیفیکیشن عوض بشه.
قدم اول کانالهای پویاست. یه ستون email_notifications به جدول users اضافه میشه که مشخص میکنه کاربر برای کدوم نوع اعلان ایمیل میخواد. همهٔ نوتیفیکیشنها از یه کلاس abstract به اسم UserNotification ارث میبرن که صفدار (ShouldQueue) هست و متد via() اون کانالها رو بر اساس ترجیح کاربر برمیگردونه. کانال database همیشه هست، چون اعلان باید داخل اپ دیده بشه و نمیشه خاموشش کرد.
قدم دوم اولویته. نویسنده بهجای override کردن via() تو هر کلاس، یه اینترفیس خالی به اسم HighPriorityNotification ساخته. همون الگویی که Laravel با ShouldQueue و ShouldBeUnique استفاده میکنه:
if ($this instanceof HighPriorityNotification) {
return ['mail', 'database'];
}
$wantsEmail = $notifiable->email_notifications[$this::class] ?? true;مثلاً «یه نفر به سازمانت اضافه شد» اولویت بالاست و همیشه ایمیل میشه، ولی «یه issue بهت داده شد» کماهمیته و کاربر میتونه ایمیلش رو خاموش کنه.
قدم سوم ارسال با تأخیره. یه ستون boolean به اسم delay_low_priority_notifications (پیشفرض true) اضافه شده و فرض شده هر کاربر یه timezone داره و ساعت کاریش دوشنبه تا جمعه ۹ تا ۵ هست. اولین ایده استفاده از withDelay() بود، ولی نویسنده میگه مشکلش اینه که کاربر ساعت ۹ صبح زیر یه عالمه ایمیل دفن میشه و سرویس ایمیل هم از این حجم خوشش نمیاد.
راهحل یه نوتیفیکیشن جدید به اسم NotificationSummary هست که فقط از کانال mail میره. این کلاس همهٔ اعلانهای نخوندهٔ بعد از زمان queuedAt رو که کاربر براشون ایمیل خواسته جمع میکنه و تو یه ایمیل میفرسته. متد shouldSend() هم چک میکنه اگه چیزی نمونده (مثلاً کاربر همه رو تو اپ خونده)، اصلاً ایمیلی نره.
نکات کلیدی:
- همهٔ اعلانها با کانال database تو اپ ثبت میشن و قابل خاموش کردن نیستن.
- ترجیح ایمیل هر نوع اعلان تو ستون آرایهای email_notifications ذخیره میشه.
- اینترفیس خالی HighPriorityNotification اعلانهایی رو مشخص میکنه که همیشه ایمیل میشن.
- withDelay() بهتنهایی کافی نیست چون صبحها کلی ایمیل یهجا میرسه.
- NotificationSummary فقط اعلانهای نخونده رو تو یه ایمیل خلاصه میفرسته و اگه چیزی نباشه، ارسال نمیشه.




