はじめに

Laravelは、メール送信のサポートに加えて、メール、SMS(Vonage、以前はNexmoとして知られていた)、およびSlackを含むさまざまな配信チャネルを通じて通知を送信するサポートを提供します。さらに、数十の異なるチャネルを介して通知を送信するために作成されたさまざまなコミュニティ構築の通知チャネルもあります!通知はデータベースに保存され、ウェブインターフェースに表示されることもあります。

通常、通知はアプリケーション内で発生した何かをユーザーに通知する短い情報メッセージであるべきです。たとえば、請求アプリケーションを作成している場合、ユーザーに「請求書が支払われました」という通知をメールおよびSMSチャネルを介して送信することができます。

通知の生成

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

  1. php artisan make:notification InvoicePaid

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

通知の送信

Notifiableトレイトの使用

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

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

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

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

覚えておいてください、Notifiableトレイトはあなたのモデルのいずれかに使用できます。Userモデルにのみ含める必要はありません。

通知ファサードの使用

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

  1. use Illuminate\Support\Facades\Notification;
  2. Notification::send($users, new InvoicePaid($invoice));
  1. ``````php
  2. Notification::sendNow($developers, new DeploymentCompleted($deployment));
  3. `

配信チャネルの指定

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

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

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

通知のキューイング

通知をキューに入れる前に、キューを構成し、ワーカーを開始する必要があります。

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

  1. <?php
  2. namespace App\Notifications;
  3. use Illuminate\Bus\Queueable;
  4. use Illuminate\Contracts\Queue\ShouldQueue;
  5. use Illuminate\Notifications\Notification;
  6. class InvoicePaid extends Notification implements ShouldQueue
  7. {
  8. use Queueable;
  9. // ...
  10. }
  1. ``````php
  2. $user->notify(new InvoicePaid($invoice));
  3. `

通知をキューに入れると、各受信者とチャネルの組み合わせに対してキューされたジョブが作成されます。たとえば、通知に3人の受信者と2つのチャネルがある場合、6つのジョブがキューに送信されます。

通知の遅延

通知の配信を遅延させたい場合は、通知のインスタンス化にdelayメソッドをチェーンすることができます:

  1. $delay = now()->addMinutes(10);
  2. $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. */
  6. public function withDelay(object $notifiable): array
  7. {
  8. return [
  9. 'mail' => now()->addMinutes(5),
  10. 'sms' => now()->addMinutes(10),
  11. ];
  12. }

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

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

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

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

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

キューされた通知ミドルウェア

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

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

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

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

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

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

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

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

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

キューされた通知を送信するかどうかの判断

キューされた通知がバックグラウンド処理のためにキューに送信されると、通常はキュー作業者によって受け入れられ、意図された受信者に送信されます。

ただし、キュー作業者によって処理された後にキューされた通知を送信するかどうかの最終的な判断を行いたい場合は、通知クラスにshouldSendメソッドを定義できます。このメソッドがfalseを返す場合、通知は送信されません:

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

オンデマンド通知

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

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

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

  1. Notification::route('mail', [
  2. '' => 'Barrett Blair',
  3. ])->notify(new InvoicePaid($invoice));
  1. ``````php
  2. Notification::routes([
  3. 'mail' => ['' => 'Barrett Blair'],
  4. 'vonage' => '5555555555',
  5. ])->notify(new InvoicePaid($invoice));
  6. `

メール通知

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

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

  1. ``````php
  2. /**
  3. * Get the mail representation of the notification.
  4. */
  5. public function toMail(object $notifiable): MailMessage
  6. {
  7. $url = url('/invoice/'.$this->invoice->id);
  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. }
  15. `
  1. この例では、挨拶、テキストの行、アクションを呼びかける部分、そしてもう一つのテキストの行を登録します。`````MailMessage`````オブジェクトによって提供されるこれらのメソッドは、小さなトランザクションメールをフォーマットするのを簡単かつ迅速にします。メールチャネルは、メッセージコンポーネントを美しい、レスポンシブなHTMLメールテンプレートに変換し、プレーンテキストの対応物を自動的に生成します。`````mail`````チャネルによって生成されたメールの例は次のとおりです:
  2. ![](https://cdn.hedaai.com/projects/laravel-11-x/62e1b0e64592a6a4235fa5d924b02664.png_big1500.jpeg)
  3. メール通知を送信する際は、`````name`````構成オプションを`````config/app.php`````構成ファイルに設定してください。この値は、メール通知メッセージのヘッダーとフッターに使用されます。
  4. <a name="error-messages"></a>
  5. #### エラーメッセージ
  6. 一部の通知は、失敗した請求書の支払いなど、ユーザーにエラーを通知します。メッセージを構築する際に`````error`````メソッドを呼び出すことで、メールメッセージがエラーに関するものであることを示すことができます。メールメッセージの`````error`````メソッドを使用すると、アクションを呼びかけるボタンが黒ではなく赤になります:
  7. ``````php
  8. /**
  9. * Get the mail representation of the notification.
  10. */
  11. public function toMail(object $notifiable): MailMessage
  12. {
  13. return (new MailMessage)
  14. ->error()
  15. ->subject('Invoice Payment Failed')
  16. ->line('...');
  17. }
  18. `

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

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

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

送信者のカスタマイズ

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

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

受信者のカスタマイズ

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

件名のカスタマイズ

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

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

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

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

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

添付ファイル

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

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

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

メッセージにファイルを添付する際、表示名および/またはMIMEタイプを指定することもできます。これは、arrayattachメソッドの2番目の引数として渡すことで行います:

  1. /**
  2. * Get the mail representation of the notification.
  3. */
  4. public 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. }

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

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

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

  1. /**
  2. * Get the mail representation of the notification.
  3. */
  4. public 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. }

生データの添付

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

タグとメタデータの追加

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

  1. /**
  2. * Get the mail representation of the notification.
  3. */
  4. public 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メッセージのカスタマイズ

  1. ``````php
  2. use Symfony\Component\Mime\Email;
  3. /**
  4. * Get the mail representation of the notification.
  5. */
  6. public 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. }
  15. `

Mailablesの使用

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

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

Mailablesとオンデマンド通知

オンデマンド通知を送信している場合、$notifiableメソッドに渡されるインスタンスはtoMailのインスタンスであり、routeNotificationForメソッドを使用してオンデマンド通知を送信するメールアドレスを取得できます:

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

メール通知のプレビュー

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

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

Markdownメール通知

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

メッセージの生成

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

  1. php 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. */
  4. public function toMail(object $notifiable): MailMessage
  5. {
  6. $url = url('/invoice/'.$this->invoice->id);
  7. return (new MailMessage)
  8. ->subject('Invoice Paid')
  9. ->markdown('mail.invoice.paid', ['url' => $url]);
  10. }

メッセージの作成

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

  1. x-mail::message
  2. # 請求書が支払われました
  3. 請求書が支払われました!
  4. x-mail::button :url="$url"
  5. 請求書を表示
  6. ⟨/x-mail::button
  7. ありがとうございます、⟨br
  8. {{ config('app.name') }}
  9. ⟨/x-mail::message

ボタンコンポーネント

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

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

パネルコンポーネント

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

  1. <x-mail::panel>
  2. This 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アセットタグを公開します:

  1. 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ファイルの名前を付けて保存した後、theme構成ファイルのmailオプションを新しいテーマの名前に一致するように更新します。

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

  1. /**
  2. * Get the mail representation of the notification.
  3. */
  4. public 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. }

データベース通知

前提条件

  1. テーブルをクエリして、アプリケーションのユーザーインターフェースに通知を表示できます。しかし、その前に、通知を保持するためのデータベーステーブルを作成する必要があります。`````make:notifications-table`````コマンドを使用して、適切なテーブルスキーマを持つ[migration](/read/laravel-11-x/9d423b761ce26264.md)を生成できます:
  2. ``````shell
  3. php artisan make:notifications-table
  4. php artisan migrate
  5. `

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

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

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

  1. /**
  2. * Get the array representation of the notification.
  3. *
  4. * @return array<string, mixed>
  5. */
  6. public 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. */
  6. public function databaseType(object $notifiable): string
  7. {
  8. return 'invoice-paid';
  9. }

toDatabase vs. toArray

  1. <a name="accessing-the-notifications"></a>
  2. ### 通知へのアクセス
  3. 通知がデータベースに保存されると、通知可能なエンティティからそれらにアクセスする便利な方法が必要です。Laravelのデフォルトの`````App\Models\User`````モデルに含まれる`````Illuminate\Notifications\Notifiable`````トレイトには、エンティティの通知を返す`````notifications````` [Eloquentリレーションシップ](/read/laravel-11-x/3c1a7b9119505b21.md)が含まれています。通知を取得するには、このメソッドに他のEloquentリレーションシップと同様にアクセスできます。デフォルトでは、通知は`````created_at`````タイムスタンプでソートされ、最も最近の通知がコレクションの先頭に表示されます:
  4. ``````php
  5. $user = App\Models\User::find(1);
  6. foreach ($user->notifications as $notification) {
  7. echo $notification->type;
  8. }
  9. `

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

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

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

通知を既読としてマークする

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

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

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

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

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

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

通知をテーブルから完全に削除するためにdeleteすることができます:

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

通知のブロードキャスト

前提条件

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

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

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

ブロードキャストキューの構成

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

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

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

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

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

通知のリスニング

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

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

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

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

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

SMS通知

前提条件

LaravelでSMS通知を送信するには、Vonage(以前はNexmoとして知られていました)を使用します。Vonageを介して通知を送信する前に、laravel/vonage-notification-channel および guzzlehttp/guzzle パッケージをインストールする必要があります:

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

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

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

  1. VONAGE_SMS_FROM=15556666666

SMS通知のフォーマット

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

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

Unicodeコンテンツ

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

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

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

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

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

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

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

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

SMS通知のルーティング

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

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

Slack通知

前提条件

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

  1. composer require laravel/slack-notification-channel

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

アプリが作成された同じSlackワークスペースに通知を送信するだけの場合は、アプリが chat:writechat:write.public、および chat:write.customize スコープを持っていることを確認する必要があります。これらのスコープは、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内のアプリの「配布管理」タブから管理できます。アプリが配布されると、Socialite を使用して、アプリケーションのユーザーに代わって Slack Botトークンを取得できます。

Slack通知のフォーマット

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

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

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

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

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

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

確認モーダル

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

  1. use Illuminate\Notifications\Slack\BlockKit\Blocks\ActionsBlock;
  2. use Illuminate\Notifications\Slack\BlockKit\Blocks\ContextBlock;
  3. use Illuminate\Notifications\Slack\BlockKit\Blocks\SectionBlock;
  4. use Illuminate\Notifications\Slack\BlockKit\Composites\ConfirmObject;
  5. use Illuminate\Notifications\Slack\SlackMessage;
  6. /**
  7. * Get the Slack representation of the notification.
  8. */
  9. public 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. $block->button('Acknowledge Invoice')
  22. ->primary()
  23. ->confirm(
  24. 'Acknowledge the payment and send a thank you email?',
  25. function (ConfirmObject $dialog) {
  26. $dialog->confirm('Yes');
  27. $dialog->deny('No');
  28. }
  29. );
  30. });
  31. }

Slackブロックの検査

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

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

Slack通知のルーティング

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

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

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

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

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

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

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

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

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

通知のローカライズ

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

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

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

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

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

ユーザーの好みのロケール

アプリケーションが各ユーザーの好みのロケールを保存することがあります。通知可能なモデルに HasLocalePreference インターフェースを実装することで、Laravelにこの保存されたロケールを使用して通知を送信するよう指示できます:

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

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

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

テスト

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

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

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

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

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

オンデマンド通知

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

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

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

  1. Notification::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 イベントが通知システムによって発行されます。これには「通知可能」エンティティと通知インスタンス自体が含まれます。このイベントに対して、アプリケーション内でevent listenersを作成できます:

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

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

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

イベントリスナー内で、notifiablenotification、および channel プロパティにアクセスして、通知の受信者や通知自体についての詳細を知ることができます:

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

通知送信イベント

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

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

イベントリスナー内で、notifiablenotificationchannel、および response プロパティにアクセスして、通知の受信者や通知自体についての詳細を知ることができます:

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

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

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