2022-05-20|閱讀時間 ‧ 約 8 分鐘

Laravel Notifications

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){
}

發送通知
通知有兩種方式可以發送。
  1. 使用Notifiable的notify method發送通知:
  • 在Model設定use Notifiable。
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表中。
  • 想要延遲發送通知的話,可以用-delay():
$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找出通知:
$user = (new User)->find(1);
foreach ($user->notifications as $notification) {
  //$notification->type
  //$notification->data
  ...
}
$user-notifications就可以找出這個user所有的通知: 預設會按照created_at最新到最舊排序:
  • 只想找未讀通知:
$user->unreadNotifications
  • 將user通知標記為已讀:
$user = (new User)->find(1);
$user->unreadNotifications->markAsRead();
  • 一個user可能有多則通知,想指定已讀某一則通知:
$user->unreadNotifications[0]->markAsRead();

分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.