コンテンツへスキップ

通知

イントロダクション

メール送信のサポートに加え、Laravelはメール、SMS(Vonage、旧Nexmo経由)、Slackなど、さまざまな配信チャネルでの通知送信をサポートしています。さらに、コミュニティで構築されたさまざまな通知チャネルが作成されており、数十種類のチャネルで通知を送信できます!通知はデータベースに保存し、Webインターフェイスに表示することもできます。

通常、通知は、アプリケーションで発生した出来事をユーザーに知らせる、短く情報量の多いメッセージであるべきです。たとえば、請求アプリケーションを作成している場合、メールやSMSチャネルを介して「請求書支払い済み」の通知をユーザーに送信できます。

通知の生成

Laravelでは、各通知は単一のクラスで表現され、通常はapp/Notificationsディレクトリに保存されます。アプリケーションにこのディレクトリが表示されなくても心配ありません。make:notification Artisanコマンドを実行すると作成されます。

1php artisan make:notification InvoicePaid

このコマンドは、app/Notificationsディレクトリに新しい通知クラスを配置します。各通知クラスには、viaメソッドと、通知を特定のチャネルに合わせたメッセージに変換するtoMailtoDatabaseなど、可変数のメッセージ構築メソッドが含まれています。

通知の送信

Notifiableトレイトの使用

通知は、Notifiableトレイトのnotifyメソッドを使用する方法と、Notification ファサードを使用する方法の2つの方法で送信できます。Notifiableトレイトは、デフォルトでアプリケーションのApp\Models\Userモデルに含まれています。

1<?php
2 
3namespace App\Models;
4 
5use Illuminate\Foundation\Auth\User as Authenticatable;
6use Illuminate\Notifications\Notifiable;
7 
8class User extends Authenticatable
9{
10 use Notifiable;
11}

このトレイトが提供するnotifyメソッドは、通知インスタンスを受け取ることを想定しています。

1use App\Notifications\InvoicePaid;
2 
3$user->notify(new InvoicePaid($invoice));

Notifiableトレイトは、どのモデルでも使用できることを覚えておいてください。Userモデルにのみ含める必要はありません。

Notificationファサードの使用

または、Notification ファサードを介して通知を送信することもできます。このアプローチは、ユーザーのコレクションなど、複数の通知可能なエンティティに通知を送信する必要がある場合に役立ちます。ファサードを使用して通知を送信するには、すべての通知可能なエンティティと通知インスタンスをsendメソッドに渡します。

1use Illuminate\Support\Facades\Notification;
2 
3Notification::send($users, new InvoicePaid($invoice));

sendNowメソッドを使用して、通知を即座に送信することもできます。このメソッドは、通知がShouldQueueインターフェイスを実装している場合でも、通知をすぐに送信します。

1Notification::sendNow($developers, new DeploymentCompleted($deployment));

配信チャネルの指定

すべての通知クラスには、通知が配信されるチャネルを決定するviaメソッドがあります。通知は、maildatabasebroadcastvonageslackチャネルで送信できます。

TelegramやPusherなどの他の配信チャネルを使用したい場合は、コミュニティ主導のLaravel Notification Channelsウェブサイトをご覧ください。

viaメソッドは$notifiableインスタンスを受け取ります。これは通知が送信される先のクラスのインスタンスになります。$notifiableを使用して、通知をどのチャネルで配信するかを決定できます。

1/**
2 * Get the notification's delivery channels.
3 *
4 * @return array<int, string>
5 */
6public function via(object $notifiable): array
7{
8 return $notifiable->prefers_sms ? ['vonage'] : ['mail', 'database'];
9}

通知のキュー投入

通知をキューに入れる前に、キューを設定し、ワーカを起動する必要があります。

通知の送信には時間がかかる場合があります。特に、チャネルが通知を配信するために外部API呼び出しを行う必要がある場合はそうです。アプリケーションの応答時間を短縮するために、ShouldQueueインターフェイスとQueueableトレイトをクラスに追加して、通知をキューに入れるようにしましょう。インターフェイスとトレイトは、make:notificationコマンドを使用して生成されたすべての通知にすでにインポートされているため、すぐに通知クラスに追加できます。

1<?php
2 
3namespace App\Notifications;
4 
5use Illuminate\Bus\Queueable;
6use Illuminate\Contracts\Queue\ShouldQueue;
7use Illuminate\Notifications\Notification;
8 
9class InvoicePaid extends Notification implements ShouldQueue
10{
11 use Queueable;
12 
13 // ...
14}

ShouldQueueインターフェイスが通知に追加されると、通常どおり通知を送信できます。LaravelはクラスのShouldQueueインターフェイスを検出し、通知の配信を自動的にキューに入れます。

1$user->notify(new InvoicePaid($invoice));

通知をキューに入れると、受信者とチャネルの組み合わせごとにキュージョブが作成されます。たとえば、通知に3つの受信者と2つのチャネルがある場合、6つのジョブがキューにディスパッチされます。

通知の遅延

通知の配信を遅らせたい場合は、通知のインスタンス化にdelayメソッドをチェーンできます。

1$delay = now()->addMinutes(10);
2 
3$user->notify((new InvoicePaid($invoice))->delay($delay));

delayメソッドに配列を渡して、特定のチャネルの遅延量を指定できます。

1$user->notify((new InvoicePaid($invoice))->delay([
2 'mail' => now()->addMinutes(5),
3 'sms' => now()->addMinutes(10),
4]));

あるいは、通知クラス自体にwithDelayメソッドを定義することもできます。withDelayメソッドは、チャネル名と遅延値の配列を返す必要があります。

1/**
2 * Determine the notification's delivery delay.
3 *
4 * @return array<string, \Illuminate\Support\Carbon>
5 */
6public function withDelay(object $notifiable): array
7{
8 return [
9 'mail' => now()->addMinutes(5),
10 'sms' => now()->addMinutes(10),
11 ];
12}

通知キュー接続のカスタマイズ

デフォルトでは、キューに入れられた通知は、アプリケーションのデフォルトのキュー接続を使用してキューに入れられます。特定の通知に使用する別の接続を指定したい場合は、通知のコンストラクタからonConnectionメソッドを呼び出すことができます。

1<?php
2 
3namespace App\Notifications;
4 
5use Illuminate\Bus\Queueable;
6use Illuminate\Contracts\Queue\ShouldQueue;
7use Illuminate\Notifications\Notification;
8 
9class InvoicePaid extends Notification implements ShouldQueue
10{
11 use Queueable;
12 
13 /**
14 * Create a new notification instance.
15 */
16 public function __construct()
17 {
18 $this->onConnection('redis');
19 }
20}

または、通知がサポートする各通知チャネルに使用する特定のキュー接続を指定したい場合は、通知にviaConnectionsメソッドを定義できます。このメソッドは、チャネル名とキュー接続名のペアの配列を返す必要があります。

1/**
2 * Determine which connections should be used for each notification channel.
3 *
4 * @return array<string, string>
5 */
6public function viaConnections(): array
7{
8 return [
9 'mail' => 'redis',
10 'database' => 'sync',
11 ];
12}

通知チャネルキューのカスタマイズ

通知がサポートする各通知チャネルに使用する特定のキューを指定したい場合は、通知にviaQueuesメソッドを定義できます。このメソッドは、チャネル名とキュー名のペアの配列を返す必要があります。

1/**
2 * Determine which queues should be used for each notification channel.
3 *
4 * @return array<string, string>
5 */
6public function viaQueues(): array
7{
8 return [
9 'mail' => 'mail-queue',
10 'slack' => 'slack-queue',
11 ];
12}

キュー投入済み通知ミドルウェア

キュー投入済み通知は、キュー投入済みジョブと同様にミドルウェアを定義できます。まず、通知クラスにmiddlewareメソッドを定義します。middlewareメソッドは$notifiable$channel変数を受け取り、これにより通知の宛先に基づいて返されるミドルウェアをカスタマイズできます。

1use Illuminate\Queue\Middleware\RateLimited;
2 
3/**
4 * Get the middleware the notification job should pass through.
5 *
6 * @return array<int, object>
7 */
8public function middleware(object $notifiable, string $channel)
9{
10 return match ($channel) {
11 'email' => [new RateLimited('postmark')],
12 'slack' => [new RateLimited('slack')],
13 default => [],
14 };
15}

キュー投入済み通知とデータベーストランザクション

キューに入れられた通知がデータベーストランザクション内でディスパッチされると、データベーストランザクションがコミットされる前にキューによって処理される可能性があります。この場合、データベーストランザクション中に行ったモデルやデータベースレコードへの更新が、まだデータベースに反映されていない可能性があります。さらに、トランザクション内で作成されたモデルやデータベースレコードがデータベースに存在しない可能性もあります。通知がこれらのモデルに依存している場合、キューに入れられた通知を送信するジョブが処理されるときに予期しないエラーが発生する可能性があります。

キュー接続のafter_commit設定オプションがfalseに設定されている場合でも、通知を送信するときにafterCommitメソッドを呼び出すことで、開いているすべてのデータベーストランザクションがコミットされた後に特定のキューに入れられた通知をディスパッチするように指示できます。

1use App\Notifications\InvoicePaid;
2 
3$user->notify((new InvoicePaid($invoice))->afterCommit());

あるいは、通知のコンストラクタからafterCommitメソッドを呼び出すこともできます。

1<?php
2 
3namespace App\Notifications;
4 
5use Illuminate\Bus\Queueable;
6use Illuminate\Contracts\Queue\ShouldQueue;
7use Illuminate\Notifications\Notification;
8 
9class InvoicePaid extends Notification implements ShouldQueue
10{
11 use Queueable;
12 
13 /**
14 * Create a new notification instance.
15 */
16 public function __construct()
17 {
18 $this->afterCommit();
19 }
20}

これらの問題の回避策の詳細については、キュー投入するジョブとデータベーストランザクションに関するドキュメントを確認してください。

キュー投入済み通知を送信すべきかどうかの判断

キューに入れられた通知がバックグラウンド処理のためにキューにディスパッチされた後、通常はキューワーカに受け入れられ、意図した受信者に送信されます。

ただし、キューに入れられた通知がキューワーカによって処理された後で、その通知を送信するかどうかを最終的に決定したい場合は、通知クラスにshouldSendメソッドを定義できます。このメソッドがfalseを返した場合、通知は送信されません。

1/**
2 * Determine if the notification should be sent.
3 */
4public function shouldSend(object $notifiable, string $channel): bool
5{
6 return $this->invoice->isPaid();
7}

オンデマンド通知

アプリケーションの「ユーザー」として保存されていない誰かに通知を送信する必要がある場合があります。Notificationファサードのrouteメソッドを使用すると、通知を送信する前にアドホックな通知ルーティング情報を指定できます。

1use Illuminate\Broadcasting\Channel;
2use Illuminate\Support\Facades\Notification;
3 
4Notification::route('mail', '[email protected]')
5 ->route('vonage', '5555555555')
6 ->route('slack', '#slack-channel')
7 ->route('broadcast', [new Channel('channel-name')])
8 ->notify(new InvoicePaid($invoice));

mailルートにオンデマンド通知を送信する際に受信者の名前を指定したい場合は、メールアドレスをキー、名前を配列の最初の要素の値として含む配列を渡すことができます。

1Notification::route('mail', [
2 '[email protected]' => 'Barrett Blair',
3])->notify(new InvoicePaid($invoice));

routesメソッドを使用すると、複数の通知チャネルのアドホックなルーティング情報を一度に提供できます。

1Notification::routes([
2 'mail' => ['[email protected]' => 'Barrett Blair'],
3 'vonage' => '5555555555',
4])->notify(new InvoicePaid($invoice));

メール通知

メールメッセージのフォーマット

通知がメールとして送信されることをサポートする場合、通知クラスにtoMailメソッドを定義する必要があります。このメソッドは$notifiableエンティティを受け取り、Illuminate\Notifications\Messages\MailMessageインスタンスを返す必要があります。

MailMessageクラスには、トランザクションメールメッセージの構築に役立ついくつかの簡単なメソッドが含まれています。メールメッセージには、テキストの行と「コールトゥアクション」を含めることができます。toMailメソッドの例を見てみましょう。

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 $url = url('/invoice/'.$this->invoice->id);
7 
8 return (new MailMessage)
9 ->greeting('Hello!')
10 ->line('One of your invoices has been paid!')
11 ->lineIf($this->amount > 0, "Amount paid: {$this->amount}")
12 ->action('View Invoice', $url)
13 ->line('Thank you for using our application!');
14}

toMailメソッドで$this->invoice->idを使用していることに注意してください。通知がメッセージを生成するために必要なデータを、通知のコンストラクタに渡すことができます。

この例では、挨拶、テキストの行、コールトゥアクション、そして別のテキストの行を登録しています。MailMessageオブジェクトが提供するこれらのメソッドにより、小さなトランザクションメールを簡単かつ迅速にフォーマットできます。メールチャネルは、メッセージコンポーネントを、プレーンテキストの対応物を持つ、美しくレスポンシブなHTMLメールテンプレートに変換します。以下は、mailチャネルによって生成されたメールの例です。

メール通知を送信する際は、config/app.php設定ファイルのname設定オプションを必ず設定してください。この値は、メール通知メッセージのヘッダーとフッターで使用されます。

エラーメッセージ

一部の通知は、請求書の支払いが失敗したなど、エラーをユーザーに通知します。メッセージを構築する際にerrorメソッドを呼び出すことで、メールメッセージがエラーに関するものであることを示すことができます。メールメッセージでerrorメソッドを使用すると、コールトゥアクションボタンが黒ではなく赤になります。

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 return (new MailMessage)
7 ->error()
8 ->subject('Invoice Payment Failed')
9 ->line('...');
10}

その他のメール通知のフォーマットオプション

通知クラスでテキストの「行」を定義する代わりに、viewメソッドを使用して、通知メールのレンダリングに使用するカスタムテンプレートを指定できます。

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 return (new MailMessage)->view(
7 'mail.invoice.paid', ['invoice' => $this->invoice]
8 );
9}

viewメソッドに渡される配列の2番目の要素としてビュー名を渡すことで、メールメッセージのプレーンテキストビューを指定できます。

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 return (new MailMessage)->view(
7 ['mail.invoice.paid', 'mail.invoice.paid-text'],
8 ['invoice' => $this->invoice]
9 );
10}

または、メッセージにプレーンテキストビューしかない場合は、textメソッドを利用できます。

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 return (new MailMessage)->text(
7 'mail.invoice.paid-text', ['invoice' => $this->invoice]
8 );
9}

送信者のカスタマイズ

デフォルトでは、メールの送信者/fromアドレスはconfig/mail.php設定ファイルで定義されています。ただし、fromメソッドを使用して、特定の通知のfromアドレスを指定できます。

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 return (new MailMessage)
7 ->from('[email protected]', 'Barrett Blair')
8 ->line('...');
9}

受信者のカスタマイズ

mailチャネルを介して通知を送信する場合、通知システムは自動的に通知可能なエンティティのemailプロパティを探します。通知可能なエンティティにrouteNotificationForMailメソッドを定義することで、通知の配信に使用されるメールアドレスをカスタマイズできます。

1<?php
2 
3namespace App\Models;
4 
5use Illuminate\Foundation\Auth\User as Authenticatable;
6use Illuminate\Notifications\Notifiable;
7use Illuminate\Notifications\Notification;
8 
9class User extends Authenticatable
10{
11 use Notifiable;
12 
13 /**
14 * Route notifications for the mail channel.
15 *
16 * @return array<string, string>|string
17 */
18 public function routeNotificationForMail(Notification $notification): array|string
19 {
20 // Return email address only...
21 return $this->email_address;
22 
23 // Return email address and name...
24 return [$this->email_address => $this->name];
25 }
26}

件名のカスタマイズ

デフォルトでは、メールの件名は通知のクラス名を「タイトルケース」にフォーマットしたものです。したがって、通知クラス名がInvoicePaidの場合、メールの件名はInvoice Paidになります。メッセージに別の件名を指定したい場合は、メッセージを構築する際にsubjectメソッドを呼び出すことができます。

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 return (new MailMessage)
7 ->subject('Notification Subject')
8 ->line('...');
9}

メーラーのカスタマイズ

デフォルトでは、メール通知はconfig/mail.php設定ファイルで定義されたデフォルトのメーラーを使用して送信されます。ただし、メッセージを構築する際にmailerメソッドを呼び出すことで、実行時に別のメーラーを指定できます。

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 return (new MailMessage)
7 ->mailer('postmark')
8 ->line('...');
9}

テンプレートのカスタマイズ

通知パッケージのリソースを公開することで、メール通知で使用されるHTMLおよびプレーンテキストのテンプレートを変更できます。このコマンドを実行すると、メール通知のテンプレートはresources/views/vendor/notificationsディレクトリに配置されます。

1php artisan vendor:publish --tag=laravel-notifications

添付ファイル

メール通知に添付ファイルを追加するには、メッセージを構築する際にattachメソッドを使用します。attachメソッドは、ファイルの絶対パスを最初の引数として受け入れます。

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 return (new MailMessage)
7 ->greeting('Hello!')
8 ->attach('/path/to/file');
9}

通知メールメッセージが提供するattachメソッドは、添付可能オブジェクトも受け入れます。詳細については、包括的な添付可能オブジェクトのドキュメントを参照してください。

メッセージにファイルを添付する際、attachメソッドの2番目の引数としてarrayを渡すことで、表示名やMIMEタイプを指定することもできます。

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 return (new MailMessage)
7 ->greeting('Hello!')
8 ->attach('/path/to/file', [
9 'as' => 'name.pdf',
10 'mime' => 'application/pdf',
11 ]);
12}

Mailableオブジェクトでのファイル添付とは異なり、attachFromStorageを使用してストレージディスクから直接ファイルを添付することはできません。代わりに、ストレージディスク上のファイルの絶対パスを指定してattachメソッドを使用する必要があります。あるいは、toMailメソッドからMailableを返すこともできます。

1use App\Mail\InvoicePaid as InvoicePaidMailable;
2 
3/**
4 * Get the mail representation of the notification.
5 */
6public function toMail(object $notifiable): Mailable
7{
8 return (new InvoicePaidMailable($this->invoice))
9 ->to($notifiable->email)
10 ->attachFromStorage('/path/to/file');
11}

必要に応じて、attachManyメソッドを使用して複数のファイルをメッセージに添付できます。

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 return (new MailMessage)
7 ->greeting('Hello!')
8 ->attachMany([
9 '/path/to/forge.svg',
10 '/path/to/vapor.svg' => [
11 'as' => 'Logo.svg',
12 'mime' => 'image/svg+xml',
13 ],
14 ]);
15}

生データ添付

attachDataメソッドを使用して、生のバイト列を添付ファイルとして添付できます。attachDataメソッドを呼び出すときは、添付ファイルに割り当てるファイル名を指定する必要があります。

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 return (new MailMessage)
7 ->greeting('Hello!')
8 ->attachData($this->pdf, 'name.pdf', [
9 'mime' => 'application/pdf',
10 ]);
11}

タグとメタデータの追加

MailgunやPostmarkなどの一部のサードパーティメールプロバイダは、アプリケーションから送信されたメールをグループ化および追跡するために使用できるメッセージの「タグ」と「メタデータ」をサポートしています。tagメソッドとmetadataメソッドを介して、メールメッセージにタグとメタデータを追加できます。

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 return (new MailMessage)
7 ->greeting('Comment Upvoted!')
8 ->tag('upvote')
9 ->metadata('comment_id', $this->comment->id);
10}

アプリケーションでMailgunドライバを使用している場合は、Mailgunのドキュメントでタグメタデータに関する詳細情報を参照できます。同様に、Postmarkのドキュメントも、タグメタデータのサポートに関する詳細情報を参照できます。

アプリケーションでAmazon SESを使用してメールを送信している場合は、metadataメソッドを使用して、メッセージにSES「タグ」を添付する必要があります。

Symfonyメッセージのカスタマイズ

MailMessageクラスのwithSymfonyMessageメソッドを使用すると、メッセージを送信する前にSymfony Messageインスタンスとともに呼び出されるクロージャを登録できます。これにより、配信前にメッセージを深くカスタマイズする機会が得られます。

1use Symfony\Component\Mime\Email;
2 
3/**
4 * Get the mail representation of the notification.
5 */
6public function toMail(object $notifiable): MailMessage
7{
8 return (new MailMessage)
9 ->withSymfonyMessage(function (Email $message) {
10 $message->getHeaders()->addTextHeader(
11 'Custom-Header', 'Header Value'
12 );
13 });
14}

Mailableの使用

必要に応じて、通知のtoMailメソッドから完全なMailableオブジェクトを返すことができます。MailMessageの代わりにMailableを返す場合、Mailableオブジェクトのtoメソッドを使用してメッセージの受信者を指定する必要があります。

1use App\Mail\InvoicePaid as InvoicePaidMailable;
2use Illuminate\Mail\Mailable;
3 
4/**
5 * Get the mail representation of the notification.
6 */
7public function toMail(object $notifiable): Mailable
8{
9 return (new InvoicePaidMailable($this->invoice))
10 ->to($notifiable->email);
11}

Mailableとオンデマンド通知

オンデマンド通知を送信している場合、toMailメソッドに渡される$notifiableインスタンスはIlluminate\Notifications\AnonymousNotifiableのインスタンスになります。これには、オンデマンド通知を送信すべきメールアドレスを取得するために使用できるrouteNotificationForメソッドがあります。

1use App\Mail\InvoicePaid as InvoicePaidMailable;
2use Illuminate\Notifications\AnonymousNotifiable;
3use Illuminate\Mail\Mailable;
4 
5/**
6 * Get the mail representation of the notification.
7 */
8public function toMail(object $notifiable): Mailable
9{
10 $address = $notifiable instanceof AnonymousNotifiable
11 ? $notifiable->routeNotificationFor('mail')
12 : $notifiable->email;
13 
14 return (new InvoicePaidMailable($this->invoice))
15 ->to($address);
16}

メール通知のプレビュー

メール通知テンプレートを設計する際、典型的なBladeテンプレートのように、レンダリングされたメールメッセージをブラウザで素早くプレビューできると便利です。このため、Laravelでは、ルートクロージャやコントローラから直接、メール通知によって生成された任意のメールメッセージを返すことができます。MailMessageが返されると、ブラウザでレンダリングおよび表示され、実際のメールアドレスに送信することなく、そのデザインを素早くプレビューできます。

1use App\Models\Invoice;
2use App\Notifications\InvoicePaid;
3 
4Route::get('/notification', function () {
5 $invoice = Invoice::find(1);
6 
7 return (new InvoicePaid($invoice))
8 ->toMail($invoice->user);
9});

Markdownメール通知

Markdownメール通知を使用すると、事前に構築されたメール通知のテンプレートを活用しながら、より長く、カスタマイズされたメッセージを自由に記述できます。メッセージはMarkdownで記述されているため、Laravelは美しくレスポンシブなHTMLテンプレートをレンダリングできると同時に、プレーンテキストの対応物も自動的に生成できます。

メッセージの生成

対応するMarkdownテンプレートを持つ通知を生成するには、make:notification Artisanコマンドの--markdownオプションを使用できます。

1php artisan make:notification InvoicePaid --markdown=mail.invoice.paid

他のすべてのメール通知と同様に、Markdownテンプレートを使用する通知は、通知クラスにtoMailメソッドを定義する必要があります。ただし、lineメソッドやactionメソッドを使用して通知を構築する代わりに、markdownメソッドを使用して、使用するMarkdownテンプレートの名前を指定します。テンプレートで利用できるようにしたいデータの配列を、メソッドの2番目の引数として渡すことができます。

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 $url = url('/invoice/'.$this->invoice->id);
7 
8 return (new MailMessage)
9 ->subject('Invoice Paid')
10 ->markdown('mail.invoice.paid', ['url' => $url]);
11}

メッセージの記述

Markdownメール通知は、BladeコンポーネントとMarkdown構文の組み合わせを使用しており、Laravelの事前に作成された通知コンポーネントを活用しながら、簡単に通知を構築できます。

1<x-mail::message>
2# Invoice Paid
3 
4Your invoice has been paid!
5 
6<x-mail::button :url="$url">
7View Invoice
8</x-mail::button>
9 
10Thanks,<br>
11{{ config('app.name') }}
12</x-mail::message>

ボタンコンポーネント

ボタンコンポーネントは、中央に配置されたボタンリンクをレンダリングします。コンポーネントは、urlとオプションのcolorの2つの引数を受け入れます。サポートされている色はprimarygreenredです。通知には、好きなだけボタンコンポーネントを追加できます。

1<x-mail::button :url="$url" color="green">
2View Invoice
3</x-mail::button>

パネルコンポーネント

パネルコンポーネントは、指定されたテキストブロックを、通知の他の部分とは少し異なる背景色のパネルにレンダリングします。これにより、特定のテキストブロックに注意を引くことができます。

1<x-mail::panel>
2This is the panel content.
3</x-mail::panel>

テーブルコンポーネント

テーブルコンポーネントを使用すると、MarkdownテーブルをHTMLテーブルに変換できます。コンポーネントは、Markdownテーブルをコンテンツとして受け入れます。テーブルの列の配置は、デフォルトのMarkdownテーブルの配置構文を使用してサポートされます。

1<x-mail::table>
2| Laravel | Table | Example |
3| ------------- | :-----------: | ------------: |
4| Col 2 is | Centered | $10 |
5| Col 3 is | Right-Aligned | $20 |
6</x-mail::table>

コンポーネントのカスタマイズ

すべてのMarkdown通知コンポーネントを、カスタマイズのために独自のアプリケーションにエクスポートできます。コンポーネントをエクスポートするには、vendor:publish Artisanコマンドを使用してlaravel-mailアセットタグを公開します。

1php artisan vendor:publish --tag=laravel-mail

このコマンドは、Markdownメールコンポーネントをresources/views/vendor/mailディレクトリに公開します。mailディレクトリにはhtmlディレクトリとtextディレクトリが含まれ、それぞれに利用可能なすべてのコンポーネントの表現が含まれています。これらのコンポーネントは、好きなように自由にカスタマイズできます。

CSSのカスタマイズ

コンポーネントをエクスポートした後、resources/views/vendor/mail/html/themesディレクトリにdefault.cssファイルができます。このファイルでCSSをカスタマイズでき、スタイルはMarkdown通知のHTML表現に自動的にインライン化されます。

LaravelのMarkdownコンポーネント用に全く新しいテーマを作成したい場合は、html/themesディレクトリ内にCSSファイルを配置できます。CSSファイルに名前を付けて保存した後、mail設定ファイルのthemeオプションを新しいテーマの名前に合わせて更新してください。

個々の通知のテーマをカスタマイズするには、通知のメールメッセージを構築する際にthemeメソッドを呼び出すことができます。themeメソッドは、通知を送信する際に使用するテーマの名前を受け入れます。

1/**
2 * Get the mail representation of the notification.
3 */
4public function toMail(object $notifiable): MailMessage
5{
6 return (new MailMessage)
7 ->theme('invoice')
8 ->subject('Invoice Paid')
9 ->markdown('mail.invoice.paid', ['url' => $url]);
10}

データベース通知

事前準備

database通知チャネルは、通知情報をデータベーステーブルに保存します。このテーブルには、通知タイプや通知を説明するJSONデータ構造などの情報が含まれます。

テーブルをクエリして、アプリケーションのユーザーインターフェイスに通知を表示できます。しかし、その前に、通知を保持するためのデータベーステーブルを作成する必要があります。make:notifications-tableコマンドを使用して、適切なテーブルスキーマを持つマイグレーションを生成できます。

1php artisan make:notifications-table
2 
3php artisan migrate

通知可能なモデルがUUIDまたはULID主キーを使用している場合は、通知テーブルマイグレーションのmorphsメソッドをuuidMorphsまたはulidMorphsに置き換える必要があります。

データベース通知のフォーマット

通知がデータベーステーブルへの保存をサポートしている場合、通知クラスにtoDatabaseまたはtoArrayメソッドを定義する必要があります。このメソッドは$notifiableエンティティを受け取り、プレーンなPHP配列を返す必要があります。返された配列はJSONとしてエンコードされ、notificationsテーブルのdata列に保存されます。toArrayメソッドの例を見てみましょう。

1/**
2 * Get the array representation of the notification.
3 *
4 * @return array<string, mixed>
5 */
6public function toArray(object $notifiable): array
7{
8 return [
9 'invoice_id' => $this->invoice->id,
10 'amount' => $this->invoice->amount,
11 ];
12}

通知がアプリケーションのデータベースに保存されるとき、typeカラムには通知のクラス名が格納されます。しかし、通知クラスにdatabaseTypeメソッドを定義することで、この動作をカスタマイズできます。

1/**
2 * Get the notification's database type.
3 *
4 * @return string
5 */
6public function databaseType(object $notifiable): string
7{
8 return 'invoice-paid';
9}

toDatabase vs. toArray

toArrayメソッドは、JavaScriptで動くフロントエンドにブロードキャストするデータを決定するために、broadcastチャネルでも使用されます。databaseチャネルとbroadcastチャネルで異なる配列表現を持たせたい場合は、toArrayメソッドの代わりにtoDatabaseメソッドを定義する必要があります。

通知へのアクセス

通知がデータベースに保存されたら、通知可能なエンティティからそれらに便利にアクセスする方法が必要です。LaravelのデフォルトのApp\Models\Userモデルに含まれているIlluminate\Notifications\Notifiableトレイトには、エンティティの通知を返すnotifications Eloquentリレーションシップが含まれています。通知を取得するには、他のEloquentリレーションシップと同様にこのメソッドにアクセスできます。デフォルトでは、通知はcreated_atタイムスタンプでソートされ、最新の通知がコレクションの先頭になります。

1$user = App\Models\User::find(1);
2 
3foreach ($user->notifications as $notification) {
4 echo $notification->type;
5}

「未読」の通知のみを取得したい場合は、unreadNotificationsリレーションシップを使用できます。ここでも、これらの通知はcreated_atタイムスタンプでソートされ、最新の通知がコレクションの先頭になります。

1$user = App\Models\User::find(1);
2 
3foreach ($user->unreadNotifications as $notification) {
4 echo $notification->type;
5}

JavaScriptクライアントから通知にアクセスするには、現在のユーザーなど、通知可能なエンティティの通知を返す通知コントローラをアプリケーション用に定義する必要があります。その後、JavaScriptクライアントからそのコントローラのURLにHTTPリクエストを送信できます。

通知を既読にする

通常、ユーザーが通知を表示したときに、その通知を「既読」としてマークしたいでしょう。Illuminate\Notifications\Notifiableトレイトは、通知のデータベースレコードのread_at列を更新するmarkAsReadメソッドを提供します。

1$user = App\Models\User::find(1);
2 
3foreach ($user->unreadNotifications as $notification) {
4 $notification->markAsRead();
5}

ただし、各通知をループ処理する代わりに、通知のコレクションで直接markAsReadメソッドを使用できます。

1$user->unreadNotifications->markAsRead();

データベースから通知を取得せずに、一括更新クエリを使用してすべての通知を既読としてマークすることもできます。

1$user = App\Models\User::find(1);
2 
3$user->unreadNotifications()->update(['read_at' => now()]);

通知をdeleteして、テーブルから完全に削除することができます。

1$user->notifications()->delete();

ブロードキャスト通知

事前準備

ブロードキャスト通知を送信する前に、Laravelのイベントブロードキャストサービスを設定し、理解しておく必要があります。イベントブロードキャストは、JavaScriptで動くフロントエンドからサーバーサイドのLaravelイベントに反応する方法を提供します。

ブロードキャスト通知のフォーマット

broadcastチャネルは、Laravelのイベントブロードキャストサービスを使用して通知をブロードキャストし、JavaScriptで動くフロントエンドがリアルタイムで通知をキャッチできるようにします。通知がブロードキャストをサポートしている場合、通知クラスにtoBroadcastメソッドを定義できます。このメソッドは$notifiableエンティティを受け取り、BroadcastMessageインスタンスを返す必要があります。toBroadcastメソッドが存在しない場合、toArrayメソッドがブロードキャストするデータを収集するために使用されます。返されたデータはJSONとしてエンコードされ、JavaScriptで動くフロントエンドにブロードキャストされます。toBroadcastメソッドの例を見てみましょう。

1use Illuminate\Notifications\Messages\BroadcastMessage;
2 
3/**
4 * Get the broadcastable representation of the notification.
5 */
6public function toBroadcast(object $notifiable): BroadcastMessage
7{
8 return new BroadcastMessage([
9 'invoice_id' => $this->invoice->id,
10 'amount' => $this->invoice->amount,
11 ]);
12}

ブロードキャストキューの設定

すべてのブロードキャスト通知は、ブロードキャスト用にキューに入れられます。ブロードキャスト操作のキューに使用されるキュー接続またはキュー名を設定したい場合は、BroadcastMessageonConnectionおよびonQueueメソッドを使用できます。

1return (new BroadcastMessage($data))
2 ->onConnection('sqs')
3 ->onQueue('broadcasts');

通知タイプのカスタマイズ

指定したデータに加えて、すべてのブロードキャスト通知には、通知の完全なクラス名を含むtypeフィールドもあります。通知のtypeをカスタマイズしたい場合は、通知クラスにbroadcastTypeメソッドを定義できます。

1/**
2 * Get the type of the notification being broadcast.
3 */
4public function broadcastType(): string
5{
6 return 'broadcast.message';
7}

通知のリッスン

通知は、{notifiable}.{id}の規則でフォーマットされたプライベートチャネルでブロードキャストされます。したがって、IDが1App\Models\Userインスタンスに通知を送信している場合、通知はApp.Models.User.1プライベートチャネルでブロードキャストされます。Laravel Echoを使用している場合、notificationメソッドを使用してチャネル上の通知を簡単にリッスンできます。

1Echo.private('App.Models.User.' + userId)
2 .notification((notification) => {
3 console.log(notification.type);
4 });

通知チャネルのカスタマイズ

エンティティのブロードキャスト通知がブロードキャストされるチャネルをカスタマイズしたい場合は、通知可能なエンティティにreceivesBroadcastNotificationsOnメソッドを定義できます。

1<?php
2 
3namespace App\Models;
4 
5use Illuminate\Broadcasting\PrivateChannel;
6use Illuminate\Foundation\Auth\User as Authenticatable;
7use Illuminate\Notifications\Notifiable;
8 
9class User extends Authenticatable
10{
11 use Notifiable;
12 
13 /**
14 * The channels the user receives notification broadcasts on.
15 */
16 public function receivesBroadcastNotificationsOn(): string
17 {
18 return 'users.'.$this->id;
19 }
20}

SMS通知

事前準備

LaravelでのSMS通知の送信は、Vonage(旧Nexmo)によって提供されています。Vonage経由で通知を送信する前に、laravel/vonage-notification-channelパッケージとguzzlehttp/guzzleパッケージをインストールする必要があります。

1composer require laravel/vonage-notification-channel guzzlehttp/guzzle

このパッケージには設定ファイルが含まれています。ただし、この設定ファイルを自分のアプリケーションにエクスポートする必要はありません。VONAGE_KEYVONAGE_SECRET環境変数を使用して、Vonageの公開鍵と秘密鍵を定義するだけです。

キーを定義した後、VONAGE_SMS_FROM環境変数を設定して、SMSメッセージがデフォルトで送信される電話番号を定義する必要があります。この電話番号はVonageのコントロールパネル内で生成できます。

1VONAGE_SMS_FROM=15556666666

SMS通知のフォーマット

通知がSMSとして送信されることをサポートする場合、通知クラスにtoVonageメソッドを定義する必要があります。このメソッドは$notifiableエンティティを受け取り、Illuminate\Notifications\Messages\VonageMessageインスタンスを返す必要があります。

1use Illuminate\Notifications\Messages\VonageMessage;
2 
3/**
4 * Get the Vonage / SMS representation of the notification.
5 */
6public function toVonage(object $notifiable): VonageMessage
7{
8 return (new VonageMessage)
9 ->content('Your SMS message content');
10}

Unicodeコンテンツ

SMSメッセージにUnicode文字が含まれる場合は、VonageMessageインスタンスを構築する際にunicodeメソッドを呼び出す必要があります。

1use Illuminate\Notifications\Messages\VonageMessage;
2 
3/**
4 * Get the Vonage / SMS representation of the notification.
5 */
6public function toVonage(object $notifiable): VonageMessage
7{
8 return (new VonageMessage)
9 ->content('Your unicode message')
10 ->unicode();
11}

「From」番号のカスタマイズ

VONAGE_SMS_FROM環境変数で指定された電話番号とは異なる電話番号から一部の通知を送信したい場合は、VonageMessageインスタンスでfromメソッドを呼び出すことができます。

1use Illuminate\Notifications\Messages\VonageMessage;
2 
3/**
4 * Get the Vonage / SMS representation of the notification.
5 */
6public function toVonage(object $notifiable): VonageMessage
7{
8 return (new VonageMessage)
9 ->content('Your SMS message content')
10 ->from('15554443333');
11}

クライアント参照の追加

ユーザー、チーム、またはクライアントごとのコストを追跡したい場合は、通知に「クライアント参照」を追加できます。Vonageでは、このクライアント参照を使用してレポートを生成できるため、特定の顧客のSMS使用状況をよりよく理解できます。クライアント参照は、最大40文字の任意の文字列にできます。

1use Illuminate\Notifications\Messages\VonageMessage;
2 
3/**
4 * Get the Vonage / SMS representation of the notification.
5 */
6public function toVonage(object $notifiable): VonageMessage
7{
8 return (new VonageMessage)
9 ->clientReference((string) $notifiable->id)
10 ->content('Your SMS message content');
11}

SMS通知のルーティング

Vonage通知を適切な電話番号にルーティングするには、通知可能なエンティティにrouteNotificationForVonageメソッドを定義します。

1<?php
2 
3namespace App\Models;
4 
5use Illuminate\Foundation\Auth\User as Authenticatable;
6use Illuminate\Notifications\Notifiable;
7use Illuminate\Notifications\Notification;
8 
9class User extends Authenticatable
10{
11 use Notifiable;
12 
13 /**
14 * Route notifications for the Vonage channel.
15 */
16 public function routeNotificationForVonage(Notification $notification): string
17 {
18 return $this->phone_number;
19 }
20}

Slack通知

事前準備

Slack通知を送信する前に、Composer経由でSlack通知チャネルをインストールする必要があります。

1composer require laravel/slack-notification-channel

さらに、Slackワークスペース用にSlackアプリを作成する必要があります。

アプリが作成されたのと同じSlackワークスペースにのみ通知を送信する必要がある場合は、アプリにchat:writechat:write.publicchat:write.customizeスコープがあることを確認してください。Slackアプリとしてメッセージを送信したい場合は、アプリにchat:write:botスコープもあることを確認してください。これらのスコープは、Slack内の「OAuth & Permissions」アプリ管理タブから追加できます。

次に、アプリの「Bot User OAuth Token」をコピーし、アプリケーションのservices.php設定ファイルのslack設定配列内に配置します。このトークンは、Slack内の「OAuth & Permissions」タブにあります。

1'slack' => [
2 'notifications' => [
3 'bot_user_oauth_token' => env('SLACK_BOT_USER_OAUTH_TOKEN'),
4 'channel' => env('SLACK_BOT_USER_DEFAULT_CHANNEL'),
5 ],
6],

アプリ配布

アプリケーションが、アプリケーションのユーザーが所有する外部のSlackワークスペースに通知を送信する場合は、Slack経由でアプリを「配布」する必要があります。アプリの配布は、Slack内のアプリの「Manage Distribution」タブから管理できます。アプリが配布されたら、Socialiteを使用して、アプリケーションのユーザーに代わってSlackボットトークンを取得できます。

Slack通知のフォーマット

通知がSlackメッセージとして送信されることをサポートする場合、通知クラスにtoSlackメソッドを定義する必要があります。このメソッドは$notifiableエンティティを受け取り、Illuminate\Notifications\Slack\SlackMessageインスタンスを返す必要があります。SlackのBlock Kit APIを使用して、リッチな通知を作成できます。次の例は、SlackのBlock Kitビルダーでプレビューできます。

1use Illuminate\Notifications\Slack\BlockKit\Blocks\ContextBlock;
2use Illuminate\Notifications\Slack\BlockKit\Blocks\SectionBlock;
3use Illuminate\Notifications\Slack\BlockKit\Composites\ConfirmObject;
4use Illuminate\Notifications\Slack\SlackMessage;
5 
6/**
7 * Get the Slack representation of the notification.
8 */
9public function toSlack(object $notifiable): SlackMessage
10{
11 return (new SlackMessage)
12 ->text('One of your invoices has been paid!')
13 ->headerBlock('Invoice Paid')
14 ->contextBlock(function (ContextBlock $block) {
15 $block->text('Customer #1234');
16 })
17 ->sectionBlock(function (SectionBlock $block) {
18 $block->text('An invoice has been paid.');
19 $block->field("*Invoice No:*\n1000")->markdown();
20 $block->field("*Invoice Recipient:*\n[email protected]")->markdown();
21 })
22 ->dividerBlock()
23 ->sectionBlock(function (SectionBlock $block) {
24 $block->text('Congratulations!');
25 });
26}

SlackのBlock Kitビルダーテンプレートの使用

流暢なメッセージビルダーメソッドを使用してBlock Kitメッセージを構築する代わりに、SlackのBlock Kitビルダーによって生成された生のJSONペイロードをusingBlockKitTemplateメソッドに提供することができます。

1use Illuminate\Notifications\Slack\SlackMessage;
2use Illuminate\Support\Str;
3 
4/**
5 * Get the Slack representation of the notification.
6 */
7public function toSlack(object $notifiable): SlackMessage
8{
9 $template = <<<JSON
10 {
11 "blocks": [
12 {
13 "type": "header",
14 "text": {
15 "type": "plain_text",
16 "text": "Team Announcement"
17 }
18 },
19 {
20 "type": "section",
21 "text": {
22 "type": "plain_text",
23 "text": "We are hiring!"
24 }
25 }
26 ]
27 }
28 JSON;
29 
30 return (new SlackMessage)
31 ->usingBlockKitTemplate($template);
32}

Slackの対話性

SlackのBlock Kit通知システムは、ユーザーの操作を処理するための強力な機能を提供します。これらの機能を利用するには、Slackアプリで「Interactivity」を有効にし、アプリケーションが提供するURLを指す「Request URL」を設定する必要があります。これらの設定は、Slack内の「Interactivity & Shortcuts」アプリ管理タブから管理できます。

次の例では、actionsBlockメソッドを利用しており、SlackはボタンをクリックしたSlackユーザー、クリックされたボタンのIDなどを含むペイロードとともに、あなたの「Request URL」にPOSTリクエストを送信します。あなたのアプリケーションは、ペイロードに基づいて実行するアクションを決定できます。また、リクエストがSlackによって行われたことを確認する必要があります。

1use Illuminate\Notifications\Slack\BlockKit\Blocks\ActionsBlock;
2use Illuminate\Notifications\Slack\BlockKit\Blocks\ContextBlock;
3use Illuminate\Notifications\Slack\BlockKit\Blocks\SectionBlock;
4use Illuminate\Notifications\Slack\SlackMessage;
5 
6/**
7 * Get the Slack representation of the notification.
8 */
9public function toSlack(object $notifiable): SlackMessage
10{
11 return (new SlackMessage)
12 ->text('One of your invoices has been paid!')
13 ->headerBlock('Invoice Paid')
14 ->contextBlock(function (ContextBlock $block) {
15 $block->text('Customer #1234');
16 })
17 ->sectionBlock(function (SectionBlock $block) {
18 $block->text('An invoice has been paid.');
19 })
20 ->actionsBlock(function (ActionsBlock $block) {
21 // ID defaults to "button_acknowledge_invoice"...
22 $block->button('Acknowledge Invoice')->primary();
23 
24 // Manually configure the ID...
25 $block->button('Deny')->danger()->id('deny_invoice');
26 });
27}

確認モーダル

ユーザーにアクションを実行する前に確認を求めたい場合は、ボタンを定義する際にconfirmメソッドを呼び出すことができます。confirmメソッドは、メッセージと、ConfirmObjectインスタンスを受け取るクロージャを受け入れます。

1use Illuminate\Notifications\Slack\BlockKit\Blocks\ActionsBlock;
2use Illuminate\Notifications\Slack\BlockKit\Blocks\ContextBlock;
3use Illuminate\Notifications\Slack\BlockKit\Blocks\SectionBlock;
4use Illuminate\Notifications\Slack\BlockKit\Composites\ConfirmObject;
5use Illuminate\Notifications\Slack\SlackMessage;
6 
7/**
8 * Get the Slack representation of the notification.
9 */
10public function toSlack(object $notifiable): SlackMessage
11{
12 return (new SlackMessage)
13 ->text('One of your invoices has been paid!')
14 ->headerBlock('Invoice Paid')
15 ->contextBlock(function (ContextBlock $block) {
16 $block->text('Customer #1234');
17 })
18 ->sectionBlock(function (SectionBlock $block) {
19 $block->text('An invoice has been paid.');
20 })
21 ->actionsBlock(function (ActionsBlock $block) {
22 $block->button('Acknowledge Invoice')
23 ->primary()
24 ->confirm(
25 'Acknowledge the payment and send a thank you email?',
26 function (ConfirmObject $dialog) {
27 $dialog->confirm('Yes');
28 $dialog->deny('No');
29 }
30 );
31 });
32}

Slackブロックの検査

構築中のブロックを素早く検査したい場合は、SlackMessageインスタンスでddメソッドを呼び出すことができます。ddメソッドは、SlackのBlock KitビルダーへのURLを生成してダンプし、ブラウザでペイロードと通知のプレビューを表示します。ddメソッドにtrueを渡して、生のペイロードをダンプすることもできます。

1return (new SlackMessage)
2 ->text('One of your invoices has been paid!')
3 ->headerBlock('Invoice Paid')
4 ->dd();

Slack通知のルーティング

Slack通知を適切なSlackチームとチャネルに送信するには、通知可能なモデルにrouteNotificationForSlackメソッドを定義します。このメソッドは、次の3つの値のいずれかを返すことができます。

  • null - ルーティングを通知自体で設定されたチャネルに委ねます。SlackMessageを構築する際にtoメソッドを使用して、通知内のチャネルを設定できます。
  • 通知を送信するSlackチャネルを指定する文字列。例:#support-channel
  • OAuthトークンとチャネル名を指定できるSlackRouteインスタンス。例:SlackRoute::make($this->slack_channel, $this->slack_token)。このメソッドは、外部ワークスペースに通知を送信するために使用する必要があります。

たとえば、routeNotificationForSlackメソッドから#support-channelを返すと、アプリケーションのservices.php設定ファイルにあるボットユーザーOAuthトークンに関連付けられたワークスペースの#support-channelチャネルに通知が送信されます。

1<?php
2 
3namespace App\Models;
4 
5use Illuminate\Foundation\Auth\User as Authenticatable;
6use Illuminate\Notifications\Notifiable;
7use Illuminate\Notifications\Notification;
8 
9class User extends Authenticatable
10{
11 use Notifiable;
12 
13 /**
14 * Route notifications for the Slack channel.
15 */
16 public function routeNotificationForSlack(Notification $notification): mixed
17 {
18 return '#support-channel';
19 }
20}

外部Slackワークスペースへの通知

外部のSlackワークスペースに通知を送信する前に、Slackアプリを配布する必要があります。

もちろん、多くの場合、アプリケーションのユーザーが所有するSlackワークスペースに通知を送信したいでしょう。そのためには、まずユーザーのSlack OAuthトークンを取得する必要があります。幸いにも、Laravel SocialiteにはSlackドライバが含まれており、アプリケーションのユーザーをSlackで簡単に認証し、ボットトークンを取得できます。

ボットトークンを取得し、アプリケーションのデータベースに保存したら、SlackRoute::makeメソッドを利用して、ユーザーのワークスペースに通知をルーティングできます。さらに、アプリケーションは、ユーザーが通知を送信するチャネルを指定する機会を提供する必要があるでしょう。

1<?php
2 
3namespace App\Models;
4 
5use Illuminate\Foundation\Auth\User as Authenticatable;
6use Illuminate\Notifications\Notifiable;
7use Illuminate\Notifications\Notification;
8use Illuminate\Notifications\Slack\SlackRoute;
9 
10class User extends Authenticatable
11{
12 use Notifiable;
13 
14 /**
15 * Route notifications for the Slack channel.
16 */
17 public function routeNotificationForSlack(Notification $notification): mixed
18 {
19 return SlackRoute::make($this->slack_channel, $this->slack_token);
20 }
21}

通知のローカライズ

Laravelでは、HTTPリクエストの現在のロケール以外のロケールで通知を送信でき、通知がキューに入れられた場合でもこのロケールを記憶します。

これを実現するために、Illuminate\Notifications\Notificationクラスは、希望の言語を設定するためのlocaleメソッドを提供しています。アプリケーションは、通知が評価されるときにこのロケールに切り替わり、評価が完了すると以前のロケールに戻ります。

1$user->notify((new InvoicePaid($invoice))->locale('es'));

複数の通知可能なエントリのローカライズは、Notificationファサードを介して達成することもできます。

1Notification::locale('es')->send(
2 $users, new InvoicePaid($invoice)
3);

ユーザーの優先ロケール

アプリケーションによっては、各ユーザーの優先ロケールを保存している場合があります。通知可能なモデルにHasLocalePreferenceコントラクトを実装することで、通知を送信する際にこの保存されたロケールを使用するようにLaravelに指示できます。

1use Illuminate\Contracts\Translation\HasLocalePreference;
2 
3class User extends Model implements HasLocalePreference
4{
5 /**
6 * Get the user's preferred locale.
7 */
8 public function preferredLocale(): string
9 {
10 return $this->locale;
11 }
12}

インターフェイスを実装すると、Laravelはモデルに通知やMailableを送信する際に自動的に優先ロケールを使用します。したがって、このインターフェイスを使用する場合、localeメソッドを呼び出す必要はありません。

1$user->notify(new InvoicePaid($invoice));

テスト

Notificationファサードのfakeメソッドを使用して、通知が送信されないようにすることができます。通常、通知の送信は、実際にテストしているコードとは無関係です。ほとんどの場合、Laravelに特定の通知を送信するように指示されたことをアサートするだけで十分です。

Notificationファサードのfakeメソッドを呼び出した後、ユーザーに通知が送信されるように指示されたことをアサートし、通知が受け取ったデータを検査することもできます。

1<?php
2 
3use App\Notifications\OrderShipped;
4use Illuminate\Support\Facades\Notification;
5 
6test('orders can be shipped', function () {
7 Notification::fake();
8 
9 // Perform order shipping...
10 
11 // Assert that no notifications were sent...
12 Notification::assertNothingSent();
13 
14 // Assert a notification was sent to the given users...
15 Notification::assertSentTo(
16 [$user], OrderShipped::class
17 );
18 
19 // Assert a notification was not sent...
20 Notification::assertNotSentTo(
21 [$user], AnotherNotification::class
22 );
23 
24 // Assert that a given number of notifications were sent...
25 Notification::assertCount(3);
26});
1<?php
2 
3namespace Tests\Feature;
4 
5use App\Notifications\OrderShipped;
6use Illuminate\Support\Facades\Notification;
7use Tests\TestCase;
8 
9class ExampleTest extends TestCase
10{
11 public function test_orders_can_be_shipped(): void
12 {
13 Notification::fake();
14 
15 // Perform order shipping...
16 
17 // Assert that no notifications were sent...
18 Notification::assertNothingSent();
19 
20 // Assert a notification was sent to the given users...
21 Notification::assertSentTo(
22 [$user], OrderShipped::class
23 );
24 
25 // Assert a notification was not sent...
26 Notification::assertNotSentTo(
27 [$user], AnotherNotification::class
28 );
29 
30 // Assert that a given number of notifications were sent...
31 Notification::assertCount(3);
32 }
33}

assertSentToまたはassertNotSentToメソッドにクロージャを渡して、特定の「真理値テスト」に合格する通知が送信されたことをアサートできます。指定された真理値テストに合格する通知が少なくとも1つ送信された場合、アサーションは成功します。

1Notification::assertSentTo(
2 $user,
3 function (OrderShipped $notification, array $channels) use ($order) {
4 return $notification->order->id === $order->id;
5 }
6);

オンデマンド通知

テスト対象のコードがオンデマンド通知を送信する場合、assertSentOnDemandメソッドを介してオンデマンド通知が送信されたことをテストできます。

1Notification::assertSentOnDemand(OrderShipped::class);

assertSentOnDemandメソッドの2番目の引数としてクロージャを渡すことで、オンデマンド通知が正しい「ルート」アドレスに送信されたかどうかを判断できます。

1Notification::assertSentOnDemand(
2 OrderShipped::class,
3 function (OrderShipped $notification, array $channels, object $notifiable) use ($user) {
4 return $notifiable->routes['mail'] === $user->email;
5 }
6);

通知イベント

通知送信イベント

通知が送信されるとき、Illuminate\Notifications\Events\NotificationSendingイベントが通知システムによってディスパッチされます。これには、「通知可能」エンティティと通知インスタンス自体が含まれます。アプリケーション内でこのイベントのイベントリスナを作成できます。

1use Illuminate\Notifications\Events\NotificationSending;
2 
3class CheckNotificationStatus
4{
5 /**
6 * Handle the given event.
7 */
8 public function handle(NotificationSending $event): void
9 {
10 // ...
11 }
12}

NotificationSendingイベントのイベントリスナがhandleメソッドからfalseを返した場合、通知は送信されません。

1/**
2 * Handle the given event.
3 */
4public function handle(NotificationSending $event): bool
5{
6 return false;
7}

イベントリスナ内では、イベントのnotifiablenotificationchannelプロパティにアクセスして、通知の受信者や通知自体について詳しく知ることができます。

1/**
2 * Handle the given event.
3 */
4public function handle(NotificationSending $event): void
5{
6 // $event->channel
7 // $event->notifiable
8 // $event->notification
9}

通知送信済みイベント

通知が送信されると、Illuminate\Notifications\Events\NotificationSent イベントが通知システムによってディスパッチされます。これには、「通知可能」エンティティと通知インスタンス自体が含まれます。アプリケーション内でこのイベントのイベントリスナを作成できます。

1use Illuminate\Notifications\Events\NotificationSent;
2 
3class LogNotification
4{
5 /**
6 * Handle the given event.
7 */
8 public function handle(NotificationSent $event): void
9 {
10 // ...
11 }
12}

イベントリスナ内では、イベントのnotifiablenotificationchannelresponseプロパティにアクセスして、通知の受信者や通知自体について詳しく知ることができます。

1/**
2 * Handle the given event.
3 */
4public function handle(NotificationSent $event): void
5{
6 // $event->channel
7 // $event->notifiable
8 // $event->notification
9 // $event->response
10}

カスタムチャネル

Laravelにはいくつかの通知チャネルが同梱されていますが、他のチャネルを介して通知を配信するために独自のドライバを作成したい場合があるでしょう。Laravelはそれを簡単にします。まず、sendメソッドを含むクラスを定義します。このメソッドは、$notifiable$notificationの2つの引数を受け取る必要があります。

sendメソッド内で、通知のメソッドを呼び出してチャネルが理解できるメッセージオブジェクトを取得し、その後、好きな方法で$notifiableインスタンスに通知を送信できます。

1<?php
2 
3namespace App\Notifications;
4 
5use Illuminate\Notifications\Notification;
6 
7class VoiceChannel
8{
9 /**
10 * Send the given notification.
11 */
12 public function send(object $notifiable, Notification $notification): void
13 {
14 $message = $notification->toVoice($notifiable);
15 
16 // Send notification to the $notifiable instance...
17 }
18}

通知チャネルクラスが定義されたら、任意の通知のviaメソッドからそのクラス名を返すことができます。この例では、通知のtoVoiceメソッドは、音声メッセージを表すために選択した任意のオブジェクトを返すことができます。たとえば、これらのメッセージを表すために独自のVoiceMessageクラスを定義することができます。

1<?php
2 
3namespace App\Notifications;
4 
5use App\Notifications\Messages\VoiceMessage;
6use App\Notifications\VoiceChannel;
7use Illuminate\Bus\Queueable;
8use Illuminate\Contracts\Queue\ShouldQueue;
9use Illuminate\Notifications\Notification;
10 
11class InvoicePaid extends Notification
12{
13 use Queueable;
14 
15 /**
16 * Get the notification channels.
17 */
18 public function via(object $notifiable): string
19 {
20 return VoiceChannel::class;
21 }
22 
23 /**
24 * Get the voice representation of the notification.
25 */
26 public function toVoice(object $notifiable): VoiceMessage
27 {
28 // ...
29 }
30}

Laravelは最も生産的な方法です
ソフトウェアを構築、デプロイ、監視します。