コンテンツにスキップ

通知

イントロダクション

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

通常、通知は、アプリケーションで発生したことをユーザーに通知する、短く情報量の多いメッセージにする必要があります。たとえば、請求アプリケーションを作成する場合、ユーザーに「請求書の支払い済み」通知をメールチャネルとSMSチャネル経由で送信できます。

通知の生成

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

php artisan make:notification InvoicePaid

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

通知の送信

Notifiableトレイトの使用

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

<?php
 
namespace App\Models;
 
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
 
class User extends Authenticatable
{
use Notifiable;
}

このトレイトによって提供される`notify`メソッドは、通知インスタンスを受け取ることを期待しています。

use App\Notifications\InvoicePaid;
 
$user->notify(new InvoicePaid($invoice));
lightbulb

`Notifiable`トレイトは、任意のモデルで使用できることに注意してください。`User`モデルにのみ含める必要はありません。

Notificationファサードの使用

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

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

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

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

配信チャネルの指定

すべての通知クラスには、通知が配信されるチャネルを決定する`via`メソッドがあります。通知は、`mail`、`database`、`broadcast`、`vonage`、および`slack`チャネルで送信できます。

lightbulb

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

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

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

通知のキューイング

exclamation

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

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

<?php
 
namespace App\Notifications;
 
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
 
class InvoicePaid extends Notification implements ShouldQueue
{
use Queueable;
 
// ...
}

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

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

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

通知の遅延

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

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

特定のチャネルの遅延量を指定するために、`delay`メソッドに配列を渡すことができます。

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

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

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

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

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

<?php
 
namespace App\Notifications;
 
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
 
class InvoicePaid extends Notification implements ShouldQueue
{
use Queueable;
 
/**
* Create a new notification instance.
*/
public function __construct()
{
$this->onConnection('redis');
}
}

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

/**
* Determine which connections should be used for each notification channel.
*
* @return array<string, string>
*/
public function viaConnections(): array
{
return [
'mail' => 'redis',
'database' => 'sync',
];
}

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

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

/**
* Determine which queues should be used for each notification channel.
*
* @return array<string, string>
*/
public function viaQueues(): array
{
return [
'mail' => 'mail-queue',
'slack' => 'slack-queue',
];
}

キューに入れられた通知のミドルウェア

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

use Illuminate\Queue\Middleware\RateLimited;
 
/**
* Get the middleware the notification job should pass through.
*
* @return array<int, object>
*/
public function middleware(object $notifiable, string $channel)
{
return match ($channel) {
'email' => [new RateLimited('postmark')],
'slack' => [new RateLimited('slack')],
default => [],
};
}

キューに入れられた通知とデータベース トランザクション

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

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

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

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

<?php
 
namespace App\Notifications;
 
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
 
class InvoicePaid extends Notification implements ShouldQueue
{
use Queueable;
 
/**
* Create a new notification instance.
*/
public function __construct()
{
$this->afterCommit();
}
}
lightbulb

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

キューに入れられた通知を送信する必要があるかどうかの判断

キューに入れられた通知がバックグラウンド処理のためにキューにディスパッチされると、通常はキュー ワーカーによって受け入れられ、目的の受信者に送信されます。

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

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

オンデマンド通知

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

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

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

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

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

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

メール通知

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

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

MailMessage クラスには、トランザクション メール メッセージの構築に役立ついくつかの簡単なメソッドが含まれています。メール メッセージには、テキスト行と「行動喚起」が含まれる場合があります。toMail メソッドの例を見てみましょう。

/**
* Get the mail representation of the notification.
*/
public function toMail(object $notifiable): MailMessage
{
$url = url('/invoice/'.$this->invoice->id);
 
return (new MailMessage)
->greeting('Hello!')
->line('One of your invoices has been paid!')
->lineIf($this->amount > 0, "Amount paid: {$this->amount}")
->action('View Invoice', $url)
->line('Thank you for using our application!');
}
lightbulb

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

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

lightbulb

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

エラーメッセージ

一部の通知は、請求書の支払いの失敗など、ユーザーにエラーを通知します。メッセージを作成するときに error メソッドを呼び出すことで、メール メッセージがエラーに関するものであることを示すことができます。メール メッセージで error メソッドを使用すると、行動喚起ボタンは黒ではなく赤になります。

/**
* Get the mail representation of the notification.
*/
public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)
->error()
->subject('Invoice Payment Failed')
->line('...');
}

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

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

/**
* Get the mail representation of the notification.
*/
public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)->view(
'mail.invoice.paid', ['invoice' => $this->invoice]
);
}

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

/**
* Get the mail representation of the notification.
*/
public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)->view(
['mail.invoice.paid', 'mail.invoice.paid-text'],
['invoice' => $this->invoice]
);
}

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

/**
* Get the mail representation of the notification.
*/
public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)->text(
'mail.invoice.paid-text', ['invoice' => $this->invoice]
);
}

送信者のカスタマイズ

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

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

受信者のカスタマイズ

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

<?php
 
namespace App\Models;
 
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Notifications\Notification;
 
class User extends Authenticatable
{
use Notifiable;
 
/**
* Route notifications for the mail channel.
*
* @return array<string, string>|string
*/
public function routeNotificationForMail(Notification $notification): array|string
{
// Return email address only...
return $this->email_address;
 
// Return email address and name...
return [$this->email_address => $this->name];
}
}

件名のカスタマイズ

デフォルトでは、メールの件名は、"タイトルケース"にフォーマットされた通知のクラス名です。そのため、通知クラスの名前が`InvoicePaid`の場合、メールの件名は`Invoice Paid`になります。メッセージに別の件名を指定する場合は、メッセージを作成するときに`subject`メソッドを呼び出すことができます。

/**
* Get the mail representation of the notification.
*/
public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)
->subject('Notification Subject')
->line('...');
}

メーラーのカスタマイズ

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

/**
* Get the mail representation of the notification.
*/
public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)
->mailer('postmark')
->line('...');
}

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

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

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

添付ファイル

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

/**
* Get the mail representation of the notification.
*/
public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)
->greeting('Hello!')
->attach('/path/to/file');
}
lightbulb

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

ファイルメッセージに添付する場合、`attach`メソッドの2番目の引数として`array`を渡すことで、表示名またはMIMEタイプ(あるいはその両方)を指定することもできます。

/**
* Get the mail representation of the notification.
*/
public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)
->greeting('Hello!')
->attach('/path/to/file', [
'as' => 'name.pdf',
'mime' => 'application/pdf',
]);
}

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

use App\Mail\InvoicePaid as InvoicePaidMailable;
 
/**
* Get the mail representation of the notification.
*/
public function toMail(object $notifiable): Mailable
{
return (new InvoicePaidMailable($this->invoice))
->to($notifiable->email)
->attachFromStorage('/path/to/file');
}

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

/**
* Get the mail representation of the notification.
*/
public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)
->greeting('Hello!')
->attachMany([
'/path/to/forge.svg',
'/path/to/vapor.svg' => [
'as' => 'Logo.svg',
'mime' => 'image/svg+xml',
],
]);
}

生のデータ添付ファイル

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

/**
* Get the mail representation of the notification.
*/
public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)
->greeting('Hello!')
->attachData($this->pdf, 'name.pdf', [
'mime' => 'application/pdf',
]);
}

タグとメタデータの追加

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

/**
* Get the mail representation of the notification.
*/
public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)
->greeting('Comment Upvoted!')
->tag('upvote')
->metadata('comment_id', $this->comment->id);
}

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

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

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

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

use Symfony\Component\Mime\Email;
 
/**
* Get the mail representation of the notification.
*/
public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)
->withSymfonyMessage(function (Email $message) {
$message->getHeaders()->addTextHeader(
'Custom-Header', 'Header Value'
);
});
}

Mailablesの使用

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

use App\Mail\InvoicePaid as InvoicePaidMailable;
use Illuminate\Mail\Mailable;
 
/**
* Get the mail representation of the notification.
*/
public function toMail(object $notifiable): Mailable
{
return (new InvoicePaidMailable($this->invoice))
->to($notifiable->email);
}

メール可能とオンデマンド通知

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

use App\Mail\InvoicePaid as InvoicePaidMailable;
use Illuminate\Notifications\AnonymousNotifiable;
use Illuminate\Mail\Mailable;
 
/**
* Get the mail representation of the notification.
*/
public function toMail(object $notifiable): Mailable
{
$address = $notifiable instanceof AnonymousNotifiable
? $notifiable->routeNotificationFor('mail')
: $notifiable->email;
 
return (new InvoicePaidMailable($this->invoice))
->to($address);
}

メール通知のプレビュー

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

use App\Models\Invoice;
use App\Notifications\InvoicePaid;
 
Route::get('/notification', function () {
$invoice = Invoice::find(1);
 
return (new InvoicePaid($invoice))
->toMail($invoice->user);
});

Markdownメール通知

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

メッセージの生成

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

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

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

/**
* Get the mail representation of the notification.
*/
public function toMail(object $notifiable): MailMessage
{
$url = url('/invoice/'.$this->invoice->id);
 
return (new MailMessage)
->subject('Invoice Paid')
->markdown('mail.invoice.paid', ['url' => $url]);
}

メッセージの作成

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

<x-mail::message>
# Invoice Paid
 
Your invoice has been paid!
 
<x-mail::button :url="$url">
View Invoice
</x-mail::button>
 
Thanks,<br>
{{ config('app.name') }}
</x-mail::message>

ボタンコンポーネント

ボタンコンポーネントは、中央揃えのボタンリンクをレンダリングします。コンポーネントは、`url`とオプションの`color`の2つの引数を受け入れます。サポートされている色は、`primary`、`green`、`red`です。通知にボタンコンポーネントをいくつでも追加できます。

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

パネルコンポーネント

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

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

テーブルコンポーネント

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

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

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

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

php 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`メソッドは、通知を送信するときに使用するテーマの名前を受け入れます。

/**
* Get the mail representation of the notification.
*/
public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)
->theme('invoice')
->subject('Invoice Paid')
->markdown('mail.invoice.paid', ['url' => $url]);
}

データベース通知

前提条件

`database`通知チャネルは、通知情報をデータベーステーブルに格納します。このテーブルには、通知の種類や通知を記述するJSONデータ構造などの情報が含まれます。

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

php artisan make:notifications-table
 
php artisan migrate
lightbulb

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

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

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

/**
* Get the array representation of the notification.
*
* @return array<string, mixed>
*/
public function toArray(object $notifiable): array
{
return [
'invoice_id' => $this->invoice->id,
'amount' => $this->invoice->amount,
];
}

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

/**
* Get the notification's database type.
*
* @return string
*/
public function databaseType(object $notifiable): string
{
return 'invoice-paid';
}

`toDatabase`と`toArray`の比較

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

通知へのアクセス

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

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

「未読」の通知のみを取得する場合は、`unreadNotifications`リレーションシップを使用できます。これらの通知も、`created_at`タイムスタンプでソートされ、最新のものから順に並びます。

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

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

通知を既読にする

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

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

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

$user->unreadNotifications->markAsRead();

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

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

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

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

ブロードキャスト通知

前提条件

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

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

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

use Illuminate\Notifications\Messages\BroadcastMessage;
 
/**
* Get the broadcastable representation of the notification.
*/
public function toBroadcast(object $notifiable): BroadcastMessage
{
return new BroadcastMessage([
'invoice_id' => $this->invoice->id,
'amount' => $this->invoice->amount,
]);
}

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

すべてのブロードキャスト通知は、ブロードキャスト用にキューに入れられます。ブロードキャスト操作のキューイングに使用するキュー接続またはキュー名を構成する場合は、`BroadcastMessage`の`onConnection`メソッドと`onQueue`メソッドを使用できます。

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

通知タイプの変更

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

/**
* Get the type of the notification being broadcast.
*/
public function broadcastType(): string
{
return 'broadcast.message';
}

通知のリッスン

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

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

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

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

<?php
 
namespace App\Models;
 
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
 
class User extends Authenticatable
{
use Notifiable;
 
/**
* The channels the user receives notification broadcasts on.
*/
public function receivesBroadcastNotificationsOn(): string
{
return 'users.'.$this->id;
}
}

SMS通知

前提条件

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

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

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

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

VONAGE_SMS_FROM=15556666666

SMS通知のフォーマット

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

use Illuminate\Notifications\Messages\VonageMessage;
 
/**
* Get the Vonage / SMS representation of the notification.
*/
public function toVonage(object $notifiable): VonageMessage
{
return (new VonageMessage)
->content('Your SMS message content');
}

Unicodeコンテンツ

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

use Illuminate\Notifications\Messages\VonageMessage;
 
/**
* Get the Vonage / SMS representation of the notification.
*/
public function toVonage(object $notifiable): VonageMessage
{
return (new VonageMessage)
->content('Your unicode message')
->unicode();
}

"送信元"番号のカスタマイズ

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

use Illuminate\Notifications\Messages\VonageMessage;
 
/**
* Get the Vonage / SMS representation of the notification.
*/
public function toVonage(object $notifiable): VonageMessage
{
return (new VonageMessage)
->content('Your SMS message content')
->from('15554443333');
}

クライアントリファレンスの追加

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

use Illuminate\Notifications\Messages\VonageMessage;
 
/**
* Get the Vonage / SMS representation of the notification.
*/
public function toVonage(object $notifiable): VonageMessage
{
return (new VonageMessage)
->clientReference((string) $notifiable->id)
->content('Your SMS message content');
}

SMS通知のルーティング

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

<?php
 
namespace App\Models;
 
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Notifications\Notification;
 
class User extends Authenticatable
{
use Notifiable;
 
/**
* Route notifications for the Vonage channel.
*/
public function routeNotificationForVonage(Notification $notification): string
{
return $this->phone_number;
}
}

Slack通知

前提条件

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

composer require laravel/slack-notification-channel

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

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

次に、アプリの「ボットユーザーOAuthトークン」をコピーして、アプリケーションの`services.php`設定ファイルの`slack`設定配列に配置します。このトークンは、Slack内の「OAuthと権限」タブにあります。

'slack' => [
'notifications' => [
'bot_user_oauth_token' => env('SLACK_BOT_USER_OAUTH_TOKEN'),
'channel' => env('SLACK_BOT_USER_DEFAULT_CHANNEL'),
],
],

アプリの配布

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

Slack通知のフォーマット

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

use Illuminate\Notifications\Slack\BlockKit\Blocks\ContextBlock;
use Illuminate\Notifications\Slack\BlockKit\Blocks\SectionBlock;
use Illuminate\Notifications\Slack\BlockKit\Composites\ConfirmObject;
use Illuminate\Notifications\Slack\SlackMessage;
 
/**
* Get the Slack representation of the notification.
*/
public function toSlack(object $notifiable): SlackMessage
{
return (new SlackMessage)
->text('One of your invoices has been paid!')
->headerBlock('Invoice Paid')
->contextBlock(function (ContextBlock $block) {
$block->text('Customer #1234');
})
->sectionBlock(function (SectionBlock $block) {
$block->text('An invoice has been paid.');
$block->field("*Invoice No:*\n1000")->markdown();
$block->field("*Invoice Recipient:*\n[email protected]")->markdown();
})
->dividerBlock()
->sectionBlock(function (SectionBlock $block) {
$block->text('Congratulations!');
});
}

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

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

use Illuminate\Notifications\Slack\SlackMessage;
use Illuminate\Support\Str;
 
/**
* Get the Slack representation of the notification.
*/
public function toSlack(object $notifiable): SlackMessage
{
$template = <<<JSON
{
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "Team Announcement"
}
},
{
"type": "section",
"text": {
"type": "plain_text",
"text": "We are hiring!"
}
}
]
}
JSON;
 
return (new SlackMessage)
->usingBlockKitTemplate($template);
}

Slackのインタラクティビティ

Slack の Block Kit 通知システムは、ユーザーインタラクションを処理するための強力な機能を提供します。これらの機能を利用するには、Slack アプリで「インタラクティビティ」が有効になっており、アプリケーションが提供する URL を指す「リクエスト URL」が設定されている必要があります。これらの設定は、Slack 内の「インタラクティビティとショートカット」アプリ管理タブから管理できます。

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

use Illuminate\Notifications\Slack\BlockKit\Blocks\ActionsBlock;
use Illuminate\Notifications\Slack\BlockKit\Blocks\ContextBlock;
use Illuminate\Notifications\Slack\BlockKit\Blocks\SectionBlock;
use Illuminate\Notifications\Slack\SlackMessage;
 
/**
* Get the Slack representation of the notification.
*/
public function toSlack(object $notifiable): SlackMessage
{
return (new SlackMessage)
->text('One of your invoices has been paid!')
->headerBlock('Invoice Paid')
->contextBlock(function (ContextBlock $block) {
$block->text('Customer #1234');
})
->sectionBlock(function (SectionBlock $block) {
$block->text('An invoice has been paid.');
})
->actionsBlock(function (ActionsBlock $block) {
// ID defaults to "button_acknowledge_invoice"...
$block->button('Acknowledge Invoice')->primary();
 
// Manually configure the ID...
$block->button('Deny')->danger()->id('deny_invoice');
});
}

確認モーダル

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

use Illuminate\Notifications\Slack\BlockKit\Blocks\ActionsBlock;
use Illuminate\Notifications\Slack\BlockKit\Blocks\ContextBlock;
use Illuminate\Notifications\Slack\BlockKit\Blocks\SectionBlock;
use Illuminate\Notifications\Slack\BlockKit\Composites\ConfirmObject;
use Illuminate\Notifications\Slack\SlackMessage;
 
/**
* Get the Slack representation of the notification.
*/
public function toSlack(object $notifiable): SlackMessage
{
return (new SlackMessage)
->text('One of your invoices has been paid!')
->headerBlock('Invoice Paid')
->contextBlock(function (ContextBlock $block) {
$block->text('Customer #1234');
})
->sectionBlock(function (SectionBlock $block) {
$block->text('An invoice has been paid.');
})
->actionsBlock(function (ActionsBlock $block) {
$block->button('Acknowledge Invoice')
->primary()
->confirm(
'Acknowledge the payment and send a thank you email?',
function (ConfirmObject $dialog) {
$dialog->confirm('Yes');
$dialog->deny('No');
}
);
});
}

Slack ブロックの検査

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

return (new SlackMessage)
->text('One of your invoices has been paid!')
->headerBlock('Invoice Paid')
->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 チャンネルに通知が送信されます。

<?php
 
namespace App\Models;
 
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Notifications\Notification;
 
class User extends Authenticatable
{
use Notifiable;
 
/**
* Route notifications for the Slack channel.
*/
public function routeNotificationForSlack(Notification $notification): mixed
{
return '#support-channel';
}
}

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

lightbulb

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

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

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

<?php
 
namespace App\Models;
 
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Slack\SlackRoute;
 
class User extends Authenticatable
{
use Notifiable;
 
/**
* Route notifications for the Slack channel.
*/
public function routeNotificationForSlack(Notification $notification): mixed
{
return SlackRoute::make($this->slack_channel, $this->slack_token);
}
}

通知のローカライズ

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

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

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

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

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

ユーザーが優先するロケール

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

use Illuminate\Contracts\Translation\HasLocalePreference;
 
class User extends Model implements HasLocalePreference
{
/**
* Get the user's preferred locale.
*/
public function preferredLocale(): string
{
return $this->locale;
}
}

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

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

テスト

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

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

<?php
 
use App\Notifications\OrderShipped;
use Illuminate\Support\Facades\Notification;
 
test('orders can be shipped', function () {
Notification::fake();
 
// Perform order shipping...
 
// Assert that no notifications were sent...
Notification::assertNothingSent();
 
// Assert a notification was sent to the given users...
Notification::assertSentTo(
[$user], OrderShipped::class
);
 
// Assert a notification was not sent...
Notification::assertNotSentTo(
[$user], AnotherNotification::class
);
 
// Assert that a given number of notifications were sent...
Notification::assertCount(3);
});
<?php
 
namespace Tests\Feature;
 
use App\Notifications\OrderShipped;
use Illuminate\Support\Facades\Notification;
use Tests\TestCase;
 
class ExampleTest extends TestCase
{
public function test_orders_can_be_shipped(): void
{
Notification::fake();
 
// Perform order shipping...
 
// Assert that no notifications were sent...
Notification::assertNothingSent();
 
// Assert a notification was sent to the given users...
Notification::assertSentTo(
[$user], OrderShipped::class
);
 
// Assert a notification was not sent...
Notification::assertNotSentTo(
[$user], AnotherNotification::class
);
 
// Assert that a given number of notifications were sent...
Notification::assertCount(3);
}
}

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

Notification::assertSentTo(
$user,
function (OrderShipped $notification, array $channels) use ($order) {
return $notification->order->id === $order->id;
}
);

オンデマンド通知

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

Notification::assertSentOnDemand(OrderShipped::class);

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

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

通知イベント

通知送信イベント

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

use Illuminate\Notifications\Events\NotificationSending;
 
class CheckNotificationStatus
{
/**
* Handle the given event.
*/
public function handle(NotificationSending $event): void
{
// ...
}
}

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

/**
* Handle the given event.
*/
public function handle(NotificationSending $event): bool
{
return false;
}

イベントリスナー内では、イベントの notifiablenotification、および channel プロパティにアクセスして、通知受信者または通知自体に関する詳細を確認できます。

/**
* Handle the given event.
*/
public function handle(NotificationSending $event): void
{
// $event->channel
// $event->notifiable
// $event->notification
}

通知送信済みイベント

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

use Illuminate\Notifications\Events\NotificationSent;
 
class LogNotification
{
/**
* Handle the given event.
*/
public function handle(NotificationSent $event): void
{
// ...
}
}

イベントリスナー内では、イベントの notifiablenotificationchannel、および response プロパティにアクセスして、通知受信者または通知自体に関する詳細を確認できます。

/**
* Handle the given event.
*/
public function handle(NotificationSent $event): void
{
// $event->channel
// $event->notifiable
// $event->notification
// $event->response
}

カスタムチャネル

Laravel には少数の通知チャネルが付属していますが、他のチャネルを介して通知を配信するために独自のドライバーを作成することもできます。Laravel はそれを簡単にします。開始するには、send メソッドを含むクラスを定義します。このメソッドは、$notifiable$notification の 2 つの引数を受け取る必要があります。

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

<?php
 
namespace App\Notifications;
 
use Illuminate\Notifications\Notification;
 
class VoiceChannel
{
/**
* Send the given notification.
*/
public function send(object $notifiable, Notification $notification): void
{
$message = $notification->toVoice($notifiable);
 
// Send notification to the $notifiable instance...
}
}

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

<?php
 
namespace App\Notifications;
 
use App\Notifications\Messages\VoiceMessage;
use App\Notifications\VoiceChannel;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
 
class InvoicePaid extends Notification
{
use Queueable;
 
/**
* Get the notification channels.
*/
public function via(object $notifiable): string
{
return VoiceChannel::class;
}
 
/**
* Get the voice representation of the notification.
*/
public function toVoice(object $notifiable): VoiceMessage
{
// ...
}
}