آنچه در این مقاله میخوانید [پنهانسازی]
اگر می خواهید اعلان های ایمیل، پیامک و داخل برنامه را به شکلی تمیز و قابل گسترش پیاده سازی کنید، بهترین نقطه شروع استفاده از Notification در لاراول است. در این راهنما از ساخت اولین اعلان تا صف بندی، کانال ها، قالب ها و تست خودکار را پوشش می دهیم تا بتوانید یک سیستم اعلان پایدار و حرفه ای بسازید.
مبانی و معماری اعلان در پروژه لاراول
لاراول یک لایه استاندارد برای اعلان ها فراهم می کند که حول سه مفهوم می چرخد: کلاس های اعلان، کانال ها و مدل های قابل اعلان. هر اعلان به صورت یک کلاس مستقل تعریف می شود و مشخص می کند از چه کانال هایی ارسال شود و چه داده ای منتقل گردد.
برای اینکه یک مدل بتواند اعلان دریافت کند، کافی است Trait مربوط به آن را اضافه کنید. متداول ترین گیرنده کاربر است، اما هر مدل دلخواه می تواند باشد. کانال ها مسیرهای ارسال مانند ایمیل، دیتابیس، پیامک یا بروکست را مدیریت می کنند و شما می توانید همزمان چند کانال را به کار بگیرید.
طراحی ماژولار باعث می شود منطق اعلان از منطق دامنه جدا بماند. این جداسازی به شما اجازه می دهد قالب ها را مستقل توسعه دهید، صف ها را فعال کنید و بدون تغییر هسته سیستم، کانال های جدید اضافه نمایید. نتیجه کار، کدی خوانا، قابل تست و مقیاس پذیر خواهد بود.
الگوی کلی این است: رویدادی در سیستم رخ می دهد، اعلان مناسب ایجاد می شود، کانال ها تعیین می شوند و ارسال آغاز می گردد. هر کانال متد خاص خود را در کلاس اعلان مصرف می کند و داده را به فرمت مورد انتظار تبدیل می کند.
پیاده سازی گام به گام با ایمیل و دیتابیس
برای پروژه های تجاری، ترکیب ایمیل و دیتابیس هم اطلاع رسانی بیرونی را پوشش می دهد و هم سابقه قابل جستجو در پنل کاربر می سازد. در ادامه مسیر عملی پیاده سازی را می بینید.
- ایجاد کلاس اعلان:
php artisan make:notification InvoicePaidاین دستور کلاس InvoicePaid را در مسیر app/Notifications می سازد.
- تکمیل کلاس اعلان برای ایمیل و دیتابیس:
<?php namespace App\Notifications; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Notification; class InvoicePaid extends Notification implements ShouldQueue { use Queueable; public function __construct(public $invoice) { // } public function via($notifiable) { return ['mail', 'database']; } public function toMail($notifiable) { return (new MailMessage) ->subject('پرداخت فاکتور ثبت شد') ->greeting('سلام ' . $notifiable->name) ->line('فاکتور شماره ' . $this->invoice->id . ' با موفقیت پرداخت شد.') ->action('مشاهده فاکتور', url('/invoices/' . $this->invoice->id)) ->line('از همراهی شما سپاسگزاریم.'); } public function toDatabase($notifiable) { return [ 'invoice_id' => $this->invoice->id, 'amount' => $this->invoice->amount, 'paid_at' => now(), ]; } }در این پیاده سازی از ایمیل برای اطلاع رسانی فوری و از دیتابیس برای نمایش اعلان در داشبورد استفاده می کنیم. پیاده سازی ShouldQueue نیز ارسال را صف بندی می کند.
- فعال کردن قابلیت اعلان روی مدل کاربر:
<?php namespace App\Models; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; class User extends Authenticatable { use Notifiable; }با این کار، متد notify روی نمونه های کاربر در دسترس قرار می گیرد.
- ساخت جدول اعلان ها و اجرای مهاجرت:
php artisan notifications:table php artisan migrateاین جدول برای ذخیره اعلان های دیتابیس مورد استفاده قرار می گیرد.
- ارسال اعلان از کنترلر یا سرویس:
<?php use App\Models\User; use App\Models\Invoice; use App\Notifications\InvoicePaid; class PaymentController { public function store() { $invoice = Invoice::findOrFail(request('invoice_id')); // منطق تایید پرداخت... $user = $invoice->user; $user->notify(new InvoicePaid($invoice)); return response()->json(['ok' => true]); } }با اجرای این کد، ایمیل ارسال و رکورد اعلان در دیتابیس ذخیره می شود.
در سمت رابط کاربری، خواندن اعلان های خوانده نشده و علامت گذاری به عنوان خوانده شده بسیار ساده است. این قابلیت تجربه کاربری بهتری می سازد و تعداد اعلان های معوق را کنترل می کند.
// دریافت اعلان های خوانده نشده
$unread = auth()->user()->unreadNotifications;
// علامت گذاری همه به عنوان خوانده شده
auth()->user()->unreadNotifications->markAsRead();
// علامت گذاری یک اعلان
$notification = auth()->user()->notifications()->first();
$notification?->markAsRead();
اگر نیاز دارید داده بیشتری در اعلان نگهداری کنید، آن را در متد toDatabase برگردانید. چون این داده به صورت آرایه ذخیره می شود، سبک است و در لیست اعلان ها سریع بازیابی می گردد.
افزودن کانال ها، صف و بهترین روش ها
فراتر از ایمیل و دیتابیس، می توانید کانال های پیامک، بروکست و حتی وب هوک را طبق نیاز پروژه اضافه کنید. برای نمونه، افزودن بروکست به شما اجازه می دهد اعلان را بی درنگ به کلاینت ارسال کنید و بدون رفرش، نشانگر اعلان ها را به روز سازید. همچنین برای پروژه های پرکاربر، تلفیق صف ها حیاتی است. در این بخش چند الگو و نکته کلیدی را می بینید و یک بار دیگر اهمیت استفاده از Notification در لاراول را می سنجیم.
- افزودن کانال بروکست: کافی است مقدار ‘broadcast’ را به آرایه via بیفزایید و متد toBroadcast را پیاده سازی کنید. فراموش نکنید سرویس دهنده را برای Echo و کانکشن انتخاب نمایید.
- پیامک یا پیام فوری: پس از نصب پکیج مربوط، نام کانال را در via اضافه کنید و متد متناظر مانند toVonage را بنویسید. این روش برای اعلان های حساس به زمان مناسب است.
- صف ها و تحمل بار: اعلان ها را با ShouldQueue صف بندی کنید تا پردازش درخواست اصلی سریع بماند. می توانید برای هر کانال تاخیر مجزا تعیین کنید.
// نمونه ای از تاخیر در ارسال اعلان
$user->notify((new InvoicePaid($invoice))->delay(now()->addMinutes(5)));
برای پردازش صف ها اجراگر صف را راه اندازی کنید. انتخاب درایور مناسب مانند Redis برای محیط های سنگین توصیه می شود و مانیتورینگ صف در تولید الزامی است.
php artisan queue:work --tries=3 --backoff=5
قالب ایمیل ها را می توانید با Markdown داخلی لاراول یکپارچه کنید تا طراحی استانداردتر و نگهداری ساده تری داشته باشید. این قالب ها قابل شخصی سازی و ترجمه هستند و با داده پویا به راحتی پر می شوند.
return (new MailMessage)
->subject('پرداخت فاکتور ثبت شد')
->markdown('mail.invoices.paid', [
'user' => $notifiable,
'invoice' => $this->invoice,
]);
برای انتخاب کانال مناسب، نیازمندی های تاخیر، تعاملی بودن و ردیابی را در نظر بگیرید. جدول زیر گزیده ای از تصمیم گیری عملی را نشان می دهد.
| کانال | کاربرد پیشنهادی |
|---|---|
| ایمیل | اطلاع رسانی رسمی، رسید پرداخت، پیام های طولانی |
| دیتابیس | نمایش اعلان در پنل، تاریخچه قابل جستجو |
| پیامک | هشدار فوری، کد ورود یکبار مصرف |
| بروکست | به روزرسانی بی درنگ در رابط کاربری |
در پروژه های حرفه ای، مدیریت ترجیحات کاربر کلیدی است. ساخت جدولی برای تنظیمات اعلان به شما اجازه می دهد کاربر مشخص کند از چه کانالی و درباره چه رویدادهایی اعلان بگیرد. این کار هم تجربه کاربری را ارتقا می دهد و هم هزینه کانال هایی مانند پیامک را کنترل می کند.
- نکته امنیتی: پیوندهای حساس در اعلان ایمیل باید دارای تاریخ انقضا و توکن امن باشند. از Signed URL برای لینک های تایید استفاده کنید.
- نکته عملیاتی: برای جلوگیری از بمباران کاربر، نرخ ارسال را محدود کنید. می توانید شمار اعلان های یک رویداد را تجمیع کنید و به صورت دوره ای ارسال نمایید.
- نکته تحلیل: هر اعلان را با یک شناسه زمینه ای ذخیره کنید تا بعدا بتوانید نرخ باز شدن، کلیک یا تعامل را تحلیل کنید.
تست خودکار اعلان ها با امکانات داخلی فریم ورک ساده است. با فیک کردن سیستم اعلان، بدون ارسال واقعی کانال ها، منطق خود را بررسی کنید و از وقوع رگرسیون جلوگیری نمایید.
<?php
use App\Models\User;
use App\Notifications\InvoicePaid;
use Illuminate\Support\Facades\Notification;
it('sends invoice paid notification', function () {
Notification::fake();
$user = User::factory()->create();
$invoice = \App\Models\Invoice::factory()->create(['user_id' => $user->id]);
$user->notify(new InvoicePaid($invoice));
Notification::assertSentTo($user, InvoicePaid::class, function ($n, $channels) use ($invoice) {
return in_array('database', $channels) && $n->invoice->id === $invoice->id;
});
});
- خطاهای رایج: فراموشی اجرای notifications:table و عدم وجود ستون data در جدول اعلان ها.
- اشتباه پیکربندی: فعال نکردن صف در تولید و مشاهده کندی پاسخ هنگام ارسال انبوه.
- اشتباه طراحی: قرار دادن منطق تجاری در کلاس اعلان به جای سرویس یا Listener رویداد.
جمع بندی
با تعریف یک کلاس اعلان مستقل، انتخاب کانال های مناسب و صف بندی ارسال، می توانید یک سیستم اعلان تمیز، سریع و قابل اطمینان بسازید. ایمیل برای پیام های رسمی، دیتابیس برای تاریخچه درون برنامه، پیامک و بروکست برای موقعیت های فوری مناسب اند. با شخصی سازی قالب ها، مدیریت ترجیحات کاربر و نوشتن تست های خودکار، هزینه نگهداری کاهش می یابد و کیفیت تجربه کاربر افزایش پیدا می کند. این رویکرد شما را برای توسعه ویژگی های آینده آماده و پروژه را در برابر رشد مقیاس پذیر می کند.






