Skip to content

通知

はじめに

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

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

通知の生成

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

php artisan make:notification InvoicePaid

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

通知の送信

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));

Note

覚えておいてください。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メソッドがあります。通知は、maildatabasebroadcastvonageslackチャネルで送信できます。

Note

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

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

/**
 * 通知の配信チャネルを取得します。
 *
 * @return array<int, string>
 */
public function via(object $notifiable): array
{
    return $notifiable->prefers_sms ? ['vonage'] : ['mail', 'database'];
}

通知のキューイング

Warning

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

通知の送信には時間がかかる場合があります。特に、チャネルが通知を配信するために外部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メソッドは、チャネル名と遅延値の配列を返す必要があります。

/**
 * 通知の配信遅延を決定します。
 *
 * @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;

    /**
     * 新しい通知インスタンスを作成します。
     */
    public function __construct()
    {
        $this->onConnection('redis');
    }
}

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

/**
 * 各通知チャネルに使用する接続を決定します。
 *
 * @return array<string, string>
 */
public function viaConnections(): array
{
    return [
        'mail' => 'redis',
        'database' => 'sync',
    ];
}

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

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

/**
 * 各通知チャネルに使用するキューを決定します。
 *
 * @return array<string, string>
 */
public function viaQueues(): array
{
    return [
        'mail' => 'mail-queue',
        'slack' => 'slack-queue',
    ];
}

キュー通知のミドルウェア

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

use Illuminate\Queue\Middleware\RateLimited;

/**
 * 通知ジョブが通過する必要があるミドルウェアを取得します。
 *
 * @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;

    /**
     * 新しい通知インスタンスを作成します。
     */
    public function __construct()
    {
        $this->afterCommit();
    }
}

Note

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

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

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

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

/**
 * 通知を送信する必要があるかどうかを判断します。
 */
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', 'taylor@example.com')
            ->route('vonage', '5555555555')
            ->route('slack', '#slack-channel')
            ->route('broadcast', [new Channel('channel-name')])
            ->notify(new InvoicePaid($invoice));

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

Notification::route('mail', [
    'barrett@example.com' => 'Barrett Blair',
])->notify(new InvoicePaid($invoice));

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

Notification::routes([
    'mail' => ['barrett@example.com' => 'Barrett Blair'],
    'vonage' => '5555555555',
])->notify(new InvoicePaid($invoice));

メール通知

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

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

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

/**
 * 通知のメール表現を取得します。
 */
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!');
}

Note

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

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

Note

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

エラーメッセージ

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

/**
 * 通知のメール表現を取得します。
 */
public function toMail(object $notifiable): MailMessage
{
    return (new MailMessage)
                ->error()
                ->subject('Invoice Payment Failed')
                ->line('...');
}

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

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

/**
 * 通知のメール表現を取得します。
 */
public function toMail(object $notifiable): MailMessage
{
    return (new MailMessage)->view(
        'mail.invoice.paid', ['invoice' => $this->invoice]
    );
}

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

/**
 * 通知のメール表現を取得する
 */
public function toMail(object $notifiable): MailMessage
{
    return (new MailMessage)->view(
        ['mail.invoice.paid', 'mail.invoice.paid-text'],
        ['invoice' => $this->invoice]
    );
}

また、メッセージがプレーンテキストビューのみを持つ場合は、textメソッドを使用できます。

/**
 * 通知のメール表現を取得する
 */
public function toMail(object $notifiable): MailMessage
{
    return (new MailMessage)->text(
        'mail.invoice.paid-text', ['invoice' => $this->invoice]
    );
}

送信者のカスタマイズ

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

/**
 * 通知のメール表現を取得する
 */
public function toMail(object $notifiable): MailMessage
{
    return (new MailMessage)
                ->from('barrett@example.com', '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;

    /**
     * メールチャネルの通知ルート
     *
     * @return  array<string, string>|string
     */
    public function routeNotificationForMail(Notification $notification): array|string
    {
        // メールアドレスのみを返す...
        return $this->email_address;

        // メールアドレスと名前を返す...
        return [$this->email_address => $this->name];
    }
}

件名のカスタマイズ

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

/**
 * 通知のメール表現を取得する
 */
public function toMail(object $notifiable): MailMessage
{
    return (new MailMessage)
                ->subject('Notification Subject')
                ->line('...');
}

メーラーのカスタマイズ

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

/**
 * 通知のメール表現を取得する
 */
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メソッドは、ファイルへの絶対パスを最初の引数として受け取ります。

/**
 * 通知のメール表現を取得する
 */
public function toMail(object $notifiable): MailMessage
{
    return (new MailMessage)
                ->greeting('Hello!')
                ->attach('/path/to/file');
}

Note

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

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

/**
 * 通知のメール表現を取得する
 */
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;

/**
 * 通知のメール表現を取得する
 */
public function toMail(object $notifiable): Mailable
{
    return (new InvoicePaidMailable($this->invoice))
                ->to($notifiable->email)
                ->attachFromStorage('/path/to/file');
}

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

/**
 * 通知のメール表現を取得する
 */
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メソッドを呼び出す際に、添付ファイルに割り当てるファイル名を指定する必要があります。

/**
 * 通知のメール表現を取得する
 */
public function toMail(object $notifiable): MailMessage
{
    return (new MailMessage)
                ->greeting('Hello!')
                ->attachData($this->pdf, 'name.pdf', [
                    'mime' => 'application/pdf',
                ]);
}

タグとメタデータの追加

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

/**
 * 通知のメール表現を取得する
 */
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メッセージインスタンスで呼び出されるクロージャを登録できます。これにより、メッセージが配信される前にメッセージを深くカスタマイズする機会が得られます。

use Symfony\Component\Mime\Email;

/**
 * 通知のメール表現を取得する
 */
public function toMail(object $notifiable): MailMessage
{
    return (new MailMessage)
                ->withSymfonyMessage(function (Email $message) {
                    $message->getHeaders()->addTextHeader(
                        'Custom-Header', 'Header Value'
                    );
                });
}

メール可能オブジェクトの使用

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

use App\Mail\InvoicePaid as InvoicePaidMailable;
use Illuminate\Mail\Mailable;

/**
 * 通知のメール表現を取得する
 */
public function toMail(object $notifiable): Mailable
{
    return (new InvoicePaidMailable($this->invoice))
                ->to($notifiable->email);
}
/**
 * Get the mail representation of the notification.
 */
public function toMail(object $notifiable): Mailable
{
    return (new InvoicePaidMailable($this->invoice))
                ->to($notifiable->email);
}

Mailablesとオンデマンド通知

オンデマンド通知を送信する場合、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>

ボタンコンポーネント

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

<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ディレクトリには、htmltextディレクトリが含まれ、それぞれに利用可能なすべてのコンポーネントの表現が含まれます。これらのコンポーネントは自由にカスタマイズできます。

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

Note

通知可能なモデルが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 vs. toArray

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

通知へのアクセス

通知がデータベースに保存された後、通知可能なエンティティからそれらにアクセスするための便利な方法が必要です。LaravelのデフォルトのApp\Models\Userモデルには、Illuminate\Notifications\Notifiableトレイトが含まれており、notifications Eloquentリレーションを返すnotificationsメソッドが含まれています。このメソッドを使用して通知にアクセスするには、他の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;
}

Note

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

通知がデータベースに保存されたら、通知可能なエンティティからそれらにアクセスする便利な方法が必要です。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;
}

Note

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;

/**
 * 通知のブロードキャスト可能な表現を取得します。
 */
public function toBroadcast(object $notifiable): BroadcastMessage
{
    return new BroadcastMessage([
        'invoice_id' => $this->invoice->id,
        'amount' => $this->invoice->amount,
    ]);
}

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

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

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

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

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

/**
 * ブロードキャストされる通知のタイプを取得します。
 */
public function broadcastType(): string
{
    return 'broadcast.message';
}

通知のリスニング

通知は、{notifiable}.{id}という規則を使用してフォーマットされたプライベートチャンネルでブロードキャストされます。したがって、IDが1App\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;

    /**
     * ユーザーが通知ブロードキャストを受信するチャンネル。
     */
    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の公開鍵と秘密鍵を定義できます。

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

VONAGE_SMS_FROM=15556666666

SMS通知のフォーマット

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

use Illuminate\Notifications\Messages\VonageMessage;

/**
 * 通知のVonage / SMS表現を取得します。
 */
public function toVonage(object $notifiable): VonageMessage
{
    return (new VonageMessage)
                ->content('Your SMS message content');
}

Unicodeコンテンツ

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

use Illuminate\Notifications\Messages\VonageMessage;

/**
 * 通知のVonage / SMS表現を取得します。
 */
public function toVonage(object $notifiable): VonageMessage
{
    return (new VonageMessage)
                ->content('Your unicode message')
                ->unicode();
}

"From"番号のカスタマイズ

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

use Illuminate\Notifications\Messages\VonageMessage;

/**
 * 通知のVonage / SMS表現を取得します。
 */
public function toVonage(object $notifiable): VonageMessage
{
    return (new VonageMessage)
                ->content('Your SMS message content')
                ->from('15554443333');
}

クライアント参照の追加

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

use Illuminate\Notifications\Messages\VonageMessage;

/**
 * 通知のVonage / SMS表現を取得します。
 */
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;

    /**
     * Vonageチャンネルの通知をルーティングする。
     */
    public function routeNotificationForVonage(Notification $notification): string
    {
        return $this->phone_number;
    }
}

Slack通知

前提条件

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

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」タブで見つけることができます。

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

アプリの配布

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

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;

/**
 * 通知のSlack表現を取得する。
 */
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:*\ntaylor@laravel.com")->markdown();
            })
            ->dividerBlock()
            ->sectionBlock(function (SectionBlock $block) {
                $block->text('Congratulations!');
            });
}

Slackのインタラクティブ機能

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

以下の例では、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;

/**
 * 通知のSlack表現を取得する。
 */
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はデフォルトで "button_acknowledge_invoice" になります...
                $block->button('Acknowledge Invoice')->primary();

                // 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;

/**
 * 通知のSlack表現を取得する。
 */
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メソッドは、ペイロードと通知のプレビューをブラウザで表示するBlock KitビルダーへのURLを生成してダンプします。ddメソッドにtrueを渡すと、生のペイロードをダンプします。

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

Slack通知のルーティング

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

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

例えば、routeNotificationForSlackメソッドから#support-channelを返すと、アプリケーションのservices.php設定ファイルにあるBot User 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;

    /**
     * Slackチャンネルへの通知ルート
     */
    public function routeNotificationForSlack(Notification $notification): mixed
    {
        return '#support-channel';
    }
}

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

Note

外部の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;

    /**
     * Slackチャンネルへの通知ルート
     */
    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
{
    /**
     * ユーザーの優先ロケールを取得
     */
    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();

    // 注文の発送を実行...

    // 通知が送信されなかったことをアサート...
    Notification::assertNothingSent();

    // 指定されたユーザーに通知が送信されたことをアサート...
    Notification::assertSentTo(
        [$user], OrderShipped::class
    );

    // 通知が送信されなかったことをアサート...
    Notification::assertNotSentTo(
        [$user], AnotherNotification::class
    );

    // 指定された数の通知が送信されたことをアサート...
    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();

        // 注文の発送を実行...

        // 通知が送信されなかったことをアサート...
        Notification::assertNothingSent();

        // 指定されたユーザーに通知が送信されたことをアサート...
        Notification::assertSentTo(
            [$user], OrderShipped::class
        );

        // 通知が送信されなかったことをアサート...
        Notification::assertNotSentTo(
            [$user], AnotherNotification::class
        );

        // 指定された数の通知が送信されたことをアサート...
        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);

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

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
{
    /**
     * 指定されたイベントを処理
     */
    public function handle(NotificationSending $event): void
    {
        // ...
    }
}

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

/**
 * 指定されたイベントを処理
 */
public function handle(NotificationSending $event): bool
{
    return false;
}

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

/**
 * 指定されたイベントを処理
 */
public function handle(NotificationSending $event): void
{
    // $event->channel
    // $event->notifiable
    // $event->notification
}

通知送信済みイベント

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

use Illuminate\Notifications\Events\NotificationSent;

class LogNotification
{
    /**
     * 指定されたイベントを処理
     */
    public function handle(NotificationSent $event): void
    {
        // ...
    }
}

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

/**
 * 指定されたイベントを処理
 */
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
{
    /**
     * 指定された通知を送信する。
     */
    public function send(object $notifiable, Notification $notification): void
    {
        $message = $notification->toVoice($notifiable);

        // $notifiableインスタンスに通知を送信...
    }
}

通知チャンネルクラスを定義したら、任意の通知の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;

    /**
     * 通知チャンネルを取得する。
     */
    public function via(object $notifiable): string
    {
        return VoiceChannel::class;
    }

    /**
     * 通知の音声表現を取得する。
     */
    public function toVoice(object $notifiable): VoiceMessage
    {
        // ...
    }
}

ユーザーノート