Laravel Notifications(通知),是用來通知使用者應用程式訊息的功能,比如付款完成發送email或簡訊通知使用者,文章被訂閱通知等等。Notifications甚至還可以把通知訊息塞進DB,可以用來顯示在後台報表頁面中。
以下以發送email通知來舉例用法。
建立通知
$ php artisan make:notification ArticleSubscription
新的通知類別會建立在這個路徑: app/Notifications。
預設範例是要透過email通知的,via method裡面定義要通過什麼來通知,由於是要通過email來進行通知,因此要定義toMail method,裡面實作寄信功能。如果是要通知到DB則要定義toDatabase method。
假如除了email也要通過DB來通知,via method可以改成這樣:
return ['mail','database'];
則需要有toDatabase method:
public function toDatabase($notifiable){
}
發送通知
通知有兩種方式可以發送。
- 使用Notifiable的notify method發送通知:
use Illuminate\Notifications\Notifiable;
use Notifiable;
- 在程式中觸發通知的方式: 如此則會觸發ArticleSubscription中的toMail method。
use App\Notifications\ArticleSubscription;
use App\Models\User;
$user = (new User)->find(1);
$user->notify(new ArticleSubscription());
- Note: 為了方便測試寄信功能,已先將google帳號的「兩步驟驗證」關閉與開啟「低安全性應用程式存取權」。
- .env中mail設定如下:
- 資料庫中user table第一筆資料如下: 收信者會自動從user table中抓email欄位來寄信。
收到的信長這樣:
2. 通過Notification facade發送通知:
如下範例,這種方式可以一次發給多個user。
use App\Models\User;
use Notification;
use App\Notifications\ArticleSubscription;
$users = (new User)->get();
Notification::send($users, new ArticleSubscription());
注意,這種方式Model中還是一樣要use Notifiable;
結合Queue
在某些需要時間處理的狀況下,把job加入Queue中會是比較好的做法,通知想要結合Queue,可以在class中添加ShouldQueue界面和Queueable特徵:
建立Notification的時候就已經引用Queueable跟ShouldQueue了,需再加入implements ShouldQueue。
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
implements ShouldQueue
use Queueable;
- 記得要設定Queue跟啟動Queue listener,可參考之前寫的這篇:
- 如果是使用database driver的話,一樣會塞進jobs表中。
$user = (new User)->find(1);
$when = now()->addMinutes(10);
$user->notify((new ArticleSubscription())->delay($when));
- 想指定通知要塞到哪個queue,需在Notification class中定義viaQueues method:
public function viaQueues()
{
return[
'mail' => 'mail-queue'
];
}
經過設定後,job不再是塞到default queue中而是指定的mail-queue了!
客製化郵件
一般為了呈現給user專業的感覺,會使用view method來寄信,在blade模板中可以自由寫html/css,達到客製化的目的,第二個參數則是把變數往下帶。
這樣的mail看起來專業多了!
補充: subject看起來是預設的,可以加上-subject() method來自定義,把Code改成這樣:
public function toMail($notifiable)
{
return (new MailMessage)
->subject('Notification Subject')
->view(
'example_mail', ['name' => 'Vic']
);
}
資料庫通知
$ php artisan notifications:table
這會建立CreateNotificationsTable migration:
$ php artisan migrate
接著把ArticleSubscription 通知code改成這樣:
接著程式trigger通知後,就會把資料塞進DB:
- 塞到db的json data其實就是被儲存在data欄位。
- notifiable_id其實就是user_id(因為是用User Model來通知的)。
- 若是要結合Queue跟toMail一樣用法,不再贅述。
$user = (new User)->find(1);
foreach ($user->notifications as $notification) {
//$notification->type
//$notification->data
...
}
$user-notifications就可以找出這個user所有的通知: 預設會按照created_at最新到最舊排序:
$user->unreadNotifications
$user = (new User)->find(1);
$user->unreadNotifications->markAsRead();
- 一個user可能有多則通知,想指定已讀某一則通知:
$user->unreadNotifications[0]->markAsRead();