Laravel 8.x 通知

イントロダクション

メールの送信のサポートに加えて、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つの方法で送信できます。Notizableトレイトは、アプリケーションの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));

Tip!! どのモデルでもNotifiableトレイトを使用できることを忘れないでください。Userモデルに含めるだけに限定されません。

Notificationファサードの使用

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

use Illuminate\Support\Facades\Notification;

Notification::send($users, new InvoicePaid($invoice));

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

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

配信チャンネルの指定

通知を配信するチャンネルを指定するため、すべての通知クラスはviaメソッドを持っています。通知はmaildatabasebroadcastnexmoslackへ送れるようになっています。

Tip!! TelegramやPusherのような、他の配信チャンネルを利用したい場合は、コミュニティが管理している、Laravel Notification Channels websiteをご覧ください。

viaメソッドは、通知を送っているクラスのインスタンスである、$notifiableインスタンスを引数に受け取ります。$notifiableを使い、通知をどこに配信するチャンネルなのかを判定できます。

/**
 * 通知の配信チャンネルを取得
 *
 * @param  mixed  $notifiable
 * @return array
 */
public function via($notifiable)
{
    return $notifiable->prefers_sms ? ['nexmo'] : ['mail', 'database'];
}

通知のキューイング

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

通知の送信には時間がかかる場合があります。特に、チャンネルが通知を配信するために外部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));

通知の配信を遅らせたい場合、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),
]));

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

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

キューへ投入した通知は、アプリケーションのデフォルトのキュー接続を使用してキュー投入します。特定の通知に別の接続を使用する必要がある場合は、通知クラスに$connectionプロパティを定義します。

/**
 * 通知をキューに入れるときに使用するキュー接続名
 *
 * @var string
 */
public $connection = 'redis';

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

各通知チャンネルが使用し、その通知がサポートしている特定のキューを指定する場合、通知へviaQueuesメソッドを定義してください。このメソッドはチャンネル名/キュー名のペアの配列を返してください。

/**
 * 各通知チャンネルで使用するキューを判断。
 *
 * @return array
 */
public function viaQueues()
{
    return [
        'mail' => 'mail-queue',
        'slack' => 'slack-queue',
    ];
}

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

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

キュー接続の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;

    /**
     * 新しいメッセージインスタンスの生成
     *
     * @return void
     */
    public function __construct()
    {
        $this->afterCommit();
    }
}

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

キュー投入した通知を送信するか判定

バックグラウンド処理のため、通知をキューへディスパッチすると、通常はキューワーカがそれを受け取り、意図した受信者へ送信します。

しかし、キューワーカが処理した後に、そのキュー投入済み通知を送信すべきか最終的に判断したい場合は、通知クラスにshouldSendメソッドを定義してください。このメソッドからfalseを返す場合、通知は送信されません。

/**
 * 通知を送信する必要があるかどうか確認
 *
 * @param  mixed  $notifiable
 * @param  string  $channel
 * @return bool
 */
public function shouldSend($notifiable, $channel)
{
    return $this->invoice->isPaid();
}

オンデマンド通知

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

Notification::route('mail', 'taylor@example.com')
            ->route('nexmo', '5555555555')
            ->route('slack', 'https://hooks.slack.com/services/...')
            ->notify(new InvoicePaid($invoice));

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

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

メール通知

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

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

MailMessageクラスには、トランザクションメールメッセージの作成に役立ついくつかの簡単なメソッドが含まれています。メールメッセージには、「行動を促すフレーズ」だけでなく、テキスト行も含まれる場合があります。toMailメソッドの例を見てみましょう。

/**
 * 通知のメールプレゼンテーションを取得
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\MailMessage
 */
public function toMail($notifiable)
{
    $url = url('/invoice/'.$this->invoice->id);

    return (new MailMessage)
                ->greeting('Hello!')
                ->line('課金が支払われました。')
                ->action('インボイス確認', $url)
                ->line('私達のアプリケーションをご利用いただき、ありがとうございます。');
}

Tip!! toMailメソッドの中で、$this->invoice->idを使っていることに注意してください。通知メッセージを生成するために必要な情報は、どんなものでも通知のコンストラクタへ渡せます。

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

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

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

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

/**
 * 通知のメールプレゼンテーションを取得
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\MailMessage
 */
public function toMail($notifiable)
{
    return (new MailMessage)->view(
        'emails.name', ['invoice' => $this->invoice]
    );
}

viewメソッドに与える配列の2番目の要素としてビュー名を渡すことにより、メールメッセージの平文テキストビューを指定できます。

/**
 * 通知のメールプレゼンテーションを取得
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\MailMessage
 */
public function toMail($notifiable)
{
    return (new MailMessage)->view(
        ['emails.name.html', 'emails.name.plain'],
        ['invoice' => $this->invoice]
    );
}

エラーメッセージ

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

/**
 * 通知のメールプレゼンテーションを取得
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Message
 */
public function toMail($notifiable)
{
    return (new MailMessage)
                ->error()
                ->subject('Notification Subject')
                ->line('...');
}

送信者のカスタマイズ

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

/**
 * 通知のメールプレゼンテーションを取得
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\MailMessage
 */
public function toMail($notifiable)
{
    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;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * メールチャンネルに対する通知をルートする
     *
     * @param  \Illuminate\Notifications\Notification  $notification
     * @return array|string
     */
    public function routeNotificationForMail($notification)
    {
        // メールアドレスのみを返す場合
        return $this->email_address;

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

件名のカスタマイズ

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

/**
 * 通知のメールプレゼンテーションを取得
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\MailMessage
 */
public function toMail($notifiable)
{
    return (new MailMessage)
                ->subject('Notification Subject')
                ->line('...');
}

Mailerのカスタマイズ

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

/**
 * 通知のメールプレゼンテーションを取得
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\MailMessage
 */
public function toMail($notifiable)
{
    return (new MailMessage)
                ->mailer('postmark')
                ->line('...');
}

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

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

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

添付

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

/**
 * 通知のメール表現の取得
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\MailMessage
 */
public function toMail($notifiable)
{
    return (new MailMessage)
                ->greeting('Hello!')
                ->attach('/path/to/file');
}

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

/**
 * 通知のメール表現の取得
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\MailMessage
 */
public function toMail($notifiable)
{
    return (new MailMessage)
                ->greeting('Hello!')
                ->attach('/path/to/file', [
                    'as' => 'name.pdf',
                    'mime' => 'application/pdf',
                ]);
}

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

use App\Mail\InvoicePaid as InvoicePaidMailable;

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

素のデータの添付

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

/**
 * 通知のメール表現の取得
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\MailMessage
 */
public function toMail($notifiable)
{
    return (new MailMessage)
                ->greeting('Hello!')
                ->attachData($this->pdf, 'name.pdf', [
                    'mime' => 'application/pdf',
                ]);
}

Mailablesの使用

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

use App\Mail\InvoicePaid as InvoicePaidMailable;

/**
 * 通知のメール表現の入手
 *
 * @param  mixed  $notifiable
 * @return Mailable
 */
public function toMail($notifiable)
{
    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;

/**
 * 通知のメール表現の入手
 *
 * @param  mixed  $notifiable
 * @return Mailable
 */
public function toMail($notifiable)
{
    $address = $notifiable instanceof AnonymousNotifiable
            ? $notifiable->routeNotificationFor('mail')
            : $notifiable->email;

    return (new InvoicePaidMailable($this->invoice))
                ->to($address);
}

メール通知のプレビュー

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

use App\Invoice;
use App\Notifications\InvoicePaid;

Route::get('/notification', function () {
    $invoice = Invoice::find(1);

    return (new InvoicePaid($invoice))
                ->toMail($invoice->user);
});

Markdownメール通知

Markdownメール通知により、事前に構築したテンプレートとメール通知のコンポーネントの利点をMailable中で利用できます。メッセージをMarkdownで記述すると、Laravelは美しいレスポンシブHTMLテンプレートをレンダーすると同時に、自動的に平文テキスト版も生成します。

メッセージ生成

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

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

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

/**
 * 通知のメールプレゼンテーションを取得
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\MailMessage
 */
public function toMail($notifiable)
{
    $url = url('/invoice/'.$this->invoice->id);

    return (new MailMessage)
                ->subject('Invoice Paid')
                ->markdown('mail.invoice.paid', ['url' => $url]);
}

メッセージ記述

Markdownメール通知ではBladeコンポーネントとMarkdown記法が利用でき、メールメッセージを簡単に構築できると同時に、Laravelが用意している通知コンポーネントも活用できます。

@component('mail::message')
# 発送のお知らせ

商品が発送されました!

@component('mail::button', ['url' => $url])
注文の確認
@endcomponent

注文の確認<br>
{{ config('app.name') }} 様
@endcomponent

Buttonコンポーネント

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

@component('mail::button', ['url' => $url, 'color' => 'green'])
注文の確認
@endcomponent

Panelコンポーネント

パネルコンポーネントは、メッセージの他の部分とは少し異なった背景色のパネルの中に、指定されたテキストブロックをレンダーします。これにより、指定するテキストに注目を集められます。

@component('mail::panel')
ここはパネルの内容です。
@endcomponent

Tableコンポーネント

テーブルコンポーネントは、MarkdownテーブルをHTMLテーブルへ変換します。このコンポーネントはMarkdownテーブルを内容として受け入れます。デフォルトのMarkdownテーブルの記法を使った、文字寄せをサポートしています。

@component('mail::table')
| Laravel       | テーブル      | 例       |
| ------------- |:-------------:| --------:|
| 第2カラムは  | 中央寄せ      | $10      |
| 第3カラムは  | 右寄せ        | $20      |
@endcomponent

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

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

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

このコマンドにより、resources/views/vendor/mailディレクトリ下にMarkdownメールコンポーネントがリソース公開されます。mailディレクトリ下に、htmltextディレクトリがあります。各ディレクトリは名前が示す形式で、利用できるコンポーネントすべてのレスポンシブなプレゼンテーションを持っています。これらのコンポーネントはお好きなよう、自由にカスタマイズしてください。

CSSのカスタマイズ

コンポーネントをエクスポートすると、resources/views/vendor/mail/html/themesディレクトリに、default.cssファイルが用意されます。このファイル中のCSSをカスタマイズすれば、Markdownメール通知変換後のHTML形式の中に、インラインCSSとして自動的に取り込まれます。

LaravelのMarkdownコンポーネントの完全に新しいテーマを作成したい場合は、html/themesディレクトリの中にCSSファイルを設置してください。CSSファイルに名前をつけ保存したら、mail設定ファイルのthemeオプションを新しいテーマの名前に更新してください。

個別の通知にカスタムテーマを使いたい場合は、通知のメールメッセージを構築する時に、themeメソッドを呼び出してください。themeメソッドの引数は、その通知送信で使用するテーマの名前です。

/**
 * 通知のメールプレゼンテーションを取得
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\MailMessage
 */
public function toMail($notifiable)
{
    return (new MailMessage)
                ->theme('invoice')
                ->subject('Invoice Paid')
                ->markdown('mail.invoice.paid', ['url' => $url]);
}

データベース通知

事前要件

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

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

php artisan notifications:table

php artisan migrate

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

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

/**
 * 通知の配列プレゼンテーションの取得
 *
 * @param  mixed  $notifiable
 * @return array
 */
public function toArray($notifiable)
{
    return [
        'invoice_id' => $this->invoice->id,
        'amount' => $this->invoice->amount,
    ];
}

toDatabasetoArray

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

通知へのアクセス

通知をデータベースへ保存したら、notifiableエンティティからアクセスするための便利な方法が必要になるでしょう。LaravelのデフォルトのApp\Models\Userモデルに含まれているIlluminate\Notifications\Notificationトレイトには、エンティティのために通知を返すnotificationsEloquentリレーションが含まれています。通知を取得するため、他の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;
}

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

Readとしての通知作成

通常、ユーザーが閲覧したときに、その通知を「既読」とマークするでしょう。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メソッドを定義します。このメソッドは$notifyエンティティを受け取り、BroadcastMessageインスタンスを返す必要があります。toBroadcastメソッドが存在しない場合は、toArrayメソッドを使用してブロードキャストする必要のあるデータを収集します。返したデータはJSONへエンコードされ、JavaScriptを利用したフロントエンドにブロードキャストされます。toBroadcastメソッドの例を見てみましょう。

use Illuminate\Notifications\Messages\BroadcastMessage;

/**
 * 通知のブロードキャストプレゼンテーションの取得
 *
 * @param  mixed  $notifiable
 * @return BroadcastMessage
 */
public function toBroadcast($notifiable)
{
    return new BroadcastMessage([
        'invoice_id' => $this->invoice->id,
        'amount' => $this->invoice->amount,
    ]);
}

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

すべてのブロードキャスト通知はキューへ投入されます。ブロードキャスト操作に使用されるキューの接続や名前を設定したい場合は、BroadcastMessageonConnectiononQueueメソッドを使用してください。

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

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

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

use Illuminate\Notifications\Messages\BroadcastMessage;

/**
 * ブロードキャストする通知のタイプ
 *
 * @return string
 */
public function broadcastType()
{
    return 'broadcast.message';
}

通知のリッスン

Notifications will broadcast on a private channel formatted using a {notifiable}.{id} convention. So, if you are sending a notification to an App\Models\User instance with an ID of 1, the notification will be broadcast on the App.Models.User.1 private channel. When using Laravel Echo, you may easily listen for notifications on a channel using the notification method:

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

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

エンティティのブロードキャスト通知がブロードキャストされるチャンネルをカスタマイズする場合は、notifiableエンティティに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;

    /**
     * ユーザーがブロードキャストされる通知を受け取るチャンネル
     *
     * @return string
     */
    public function receivesBroadcastNotificationsOn()
    {
        return 'users.'.$this->id;
    }
}

SMS通知

事前要件

LaravelでのSMS通知の送信は、Vonage(旧称Nexmo)を利用しています。Vonage経由で通知を送信する前に、laravel/nexmo-notification-channelnexmo/laravelComposerパッケージをインストールする必要があります

composer require laravel/nexmo-notification-channel nexmo/laravel

nexmo/laravelパッケージは、独自の設定ファイルを持っています。しかし、この設定ファイルを独自のアプリケーションにエクスポートする必要はありません。NEXMO_KEYおよびNEXMO_SECRET環境変数を使用するだけで、Vonageの公開鍵と秘密鍵を設定できます。

次に、nexmo設定エントリをconfig/services.php設定ファイルに追加する必要があります。以下の設定例をコピーして開始できます。

'nexmo' => [
    'sms_from' => '15556666666',
],

sms_fromオプションは、SMSメッセージの送信元の電話番号です。Vonageコントロールパネルでアプリケーションの電話番号を生成する必要があります。

SMS通知のフォーマット

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

/**
 * 通知のVonage/SMS表現を取得
 *
 * @param  mixed  $notifiable
 * @return NexmoMessage
 */
public function toNexmo($notifiable)
{
    return (new NexmoMessage)
                ->content('Your SMS message content');
}

Unicodeコンテンツ

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

/**
 * 通知のVonage/SMS表現を取得
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\NexmoMessage
 */
public function toNexmo($notifiable)
{
    return (new NexmoMessage)
                ->content('Your unicode message')
                ->unicode();
}

ショートコード通知のフォーマット

Laravelは、Vonageアカウントで事前定義されたメッセージテンプレートであるショートコード通知の送信もサポートしています。ショートコードSMS通知を送信するには、通知クラスでtoShortcodeメソッドを定義する必要があります。このメソッド内から、通知のタイプ(alert2fa、またはmarketing)と、テンプレートに入力するカスタム値を指定する配列を返してください。

/**
 * 通知のVonage/Shortcode表現を取得
 *
 * @param  mixed  $notifiable
 * @return array
 */
public function toShortcode($notifiable)
{
    return [
        'type' => 'alert',
        'custom' => [
            'code' => 'ABC123',
        ],
    ];
}

Tip!! SMS通知のルート指定と同様に、通知モデルrouteNotificationForShortcodeメソッドを実装する必要があります。

発信元電話番号のカスタマイズ

config/services.phpファイルで指定している電話番号とは別の電話番号から通知を送信したい場合は、NexmoMessageインスタンスでfromメソッドを呼び出すことができます。

/**
 * 通知のVonage/SMS表現を取得します。
 *
 * @param  mixed  $notifiable
 * @return NexmoMessage
 */
public function toNexmo($notifiable)
{
    return (new NexmoMessage)
                ->content('Your SMS message content')
                ->from('15554443333');
}

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

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

/**
 * 通知のVonage/SMS形式の取得
 *
 * @param  mixed  $notifiable
 * @return NexmoMessage
 */
public function toNexmo($notifiable)
{
    return (new NexmoMessage)
                ->clientReference((string) $notifiable->id)
                ->content('Your SMS message content');
}

SMS通知のルート指定

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

<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
 * @return \Illuminate\Notifications\Message\SlackMessage

    /**
     * Nexmoチャンネルへの通知をルートする
     *
     * @param  \Illuminate\Notifications\Notification  $notification
     * @return string
     */
    public function routeNotificationForNexmo($notification)
    {
        return $this->phone_number;
    }
}

Slack通知

事前要件

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

composer require laravel/slack-notification-channel

チーム用のSlackアプリも作成する必要があります。アプリを作成したら、ワークスペースの「受信Webhook」を設定する必要があります。Slackは更にSlack通知のルーティングに使用できるWebhookのURLも提供します。

Slack通知のフォーマット

通知がSlackメッセージとしての送信をサポートする場合、通知クラスにtoSlackメソッドを定義する必要があります。このメソッドは$notifiableエンティティを受け取り、Illuminate\Notifications\Messages\SlackMessageインスタンスを返す必要があります。Slackメッセージはテキストと同時に、追加テキストのフォーマットか、フィールドの配列を「添付」として含みます。基本的なtoSlackの例を見てください。

/**
 * 通知のSlackプレゼンテーションを取得
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\SlackMessage
 */
public function toSlack($notifiable)
{
    return (new SlackMessage)
                ->content('One of your invoices has been paid!');
}

送信者と受信者のカスタマイズ

fromtoメソッドを使い、送信者と受信者のカスタマイズができます。fromメソッドはユーザー名と絵文字識別子を受け付け、toメソッドはチャンネルかユーザー名を受け取ります。

/**
 * 通知のSlackプレゼンテーションを取得
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\SlackMessage
 */
public function toSlack($notifiable)
{
    return (new SlackMessage)
                ->from('Ghost', ':ghost:')
                ->to('#bots')
                ->content('This will be sent to #bots');
}

文字の代わりに「ロゴ」からの画像を使用することもできます。

/**
 * 通知のSlackプレゼンテーションを取得
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\SlackMessage
 */
public function toSlack($notifiable)
{
    return (new SlackMessage)
                ->from('Laravel')
                ->image('https://laravel.com/img/favicon/favicon.ico')
                ->content('This will display the Laravel logo next to the message');
}

Slack添付

Slackメッセージに「添付」を追加することもできます。添付はシンプルなテキストメッセージよりも、リッチなフォーマットのオプションを提供します。以下の例では、アプリケーションで起きた例外についてのエラー通知で、例外についての詳細情報を表示するリンクを含めています。

/**
 * 通知のSlackプレゼンテーションを取得
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\SlackMessage
 */
public function toSlack($notifiable)
{
    $url = url('/exceptions/'.$this->exception->id);

    return (new SlackMessage)
                ->error()
                ->content('Whoops! Something went wrong.')
                ->attachment(function ($attachment) use ($url) {
                    $attachment->title('Exception: File Not Found', $url)
                               ->content('File [background.jpg] was not found.');
                });
}

添付ではさらに、ユーザーに対し表示すべきデータの配列を指定することもできます。簡単によめるよう指定したデータは、テーブルスタイルの形式で表示されます。

/**
 * 通知のSlackプレゼンテーションを取得
 *
 * @param  mixed  $notifiable
 * @return SlackMessage
 */
public function toSlack($notifiable)
{
    $url = url('/invoices/'.$this->invoice->id);

    return (new SlackMessage)
                ->success()
                ->content('One of your invoices has been paid!')
                ->attachment(function ($attachment) use ($url) {
                    $attachment->title('Invoice 1322', $url)
                               ->fields([
                                    'Title' => 'Server Expenses',
                                    'Amount' => '$1,234',
                                    'Via' => 'American Express',
                                    'Was Overdue' => ':-1:',
                                ]);
                });
}

Markdown添付コンテンツ

添付フィールドをMarkdownで構成している場合、markdownメソッドでSlackへ指定した添付フィールドがMarkdown形式のテキストであるため、パースしてから表示するように指示します。このメソッドが受け取る値は、pretexttextfieldsです。Slackの添付形式についての詳細は、Slack APIドキュメントをご覧ください。

/**
 * 通知のSlackプレゼンテーションを取得
 *
 * @param  mixed  $notifiable
 * @return SlackMessage
 */
public function toSlack($notifiable)
{
    $url = url('/exceptions/'.$this->exception->id);

    return (new SlackMessage)
                ->error()
                ->content('Whoops! Something went wrong.')
                ->attachment(function ($attachment) use ($url) {
                    $attachment->title('Exception: File Not Found', $url)
                               ->content('File [background.jpg] was *not found*.')
                               ->markdown(['text']);
                });
}

Slack通知のルート指定

Slack通知を適切なSlackチームとチャンネルにルーティングするには、通知エンティティでrouteNotificationForSlackメソッドを定義します。これは通知の配信先となるWebフックURLを返します。WebフックURLは、Slackチームに「IncomingWebhook」サービスを追加することで生成できます。

<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * Slackチャンネルに対する通知をルートする
     *
     * @param  \Illuminate\Notifications\Notification  $notification
     * @return string
     */
    public function routeNotificationForSlack($notification)
    {
        return 'https://hooks.slack.com/services/...';
    }
}

通知のローカライズ

Laravelを使用すると、HTTPリクエストの現在のロケール以外のロケールで通知を送信でき、通知をキュー投入する場合でもこのロケールを記憶しています。

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

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

通知可能な複数のエンティティをローカライズするのも、Notificationファサードにより可能です。

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

ユーザー希望のローケル

ユーザーの希望するローケルをアプリケーションで保存しておくことは良くあります。notifiableモデルでHasLocalePreference契約を実装すると、通知送信時にこの保存してあるローケルを使用するように、Laravelへ指示できます。

use Illuminate\Contracts\Translation\HasLocalePreference;

class User extends Model implements HasLocalePreference
{
    /**
     * ユーザーの希望するローケルの取得
     *
     * @return string
     */
    public function preferredLocale()
    {
        return $this->locale;
    }
}

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

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

通知イベント

通知送信前イベント

通知を送信するときは、通知システムが Illuminate\Notifications\Events\NotificationSendingイベントを発行します。このイベントは、"notifiable "エンティティと通知インスタンス自体を含んでいます。アプリケーションのEventServiceProviderでこのイベントのリスナを登録できます。

/**
 * アプリケーションにマップするイベントリスナの登録
 *
 * @var array
 */
protected $listen = [
    'Illuminate\Notifications\Events\NotificationSending' => [
        'App\Listeners\CheckNotificationStatus',
    ],
];

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

use Illuminate\Notifications\Events\NotificationSending;

/**
 * イベントの処理
 *
 * @param  \Illuminate\Notifications\Events\NotificationSending  $event
 * @return void
 */
public function handle(NotificationSending $event)
{
    return false;
}

イベントリスナの中では、イベントのnotifiablenotificationchannelプロパティへアクセスし、通知先や通知自体の詳細を調べられます。

/**
 * イベントの処理
 *
 * @param  \Illuminate\Notifications\Events\NotificationSending  $event
 * @return void
 */
public function handle(NotificationSending $event)
{
    // $event->channel
    // $event->notifiable
    // $event->notification
}

通知送信後イベント

通知が送信されると通知システムが、Illuminate\Notifications\Events\NotificationSentイベントを発行します。このイベントは、"notifiable"エンティティと通知インスタンス自体を含んでいます。このイベントのリスナはEventServiceProviderで登録できます。

/**
 * アプリケーションにマップされるイベントリスナ
 *
 * @var array
 */
protected $listen = [
    'Illuminate\Notifications\Events\NotificationSent' => [
        'App\Listeners\LogNotification',
    ],
];

Tip!! EventServiceProviderでリスナを登録した後に、event:generate Artisanコマンドを使うと、リスナクラスが素早く生成できます。

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

/**
 * イベントの処理
 *
 * @param  \Illuminate\Notifications\Events\NotificationSent  $event
 * @return void
 */
public function handle(NotificationSent $event)
{
    // $event->channel
    // $event->notifiable
    // $event->notification
    // $event->response
}

カスタムチャンネル

Laravelには通知チャンネルがいくつか付属していますが、他のチャンネルを介して通知を配信する独自​​のドライバを作成することもできます。Laravelではこれをシンプルに実現できます。作成開始するには、sendメソッドを含むクラスを定義します。このメソッドは、$notifying$notificationの2つの引数を受け取る必要があります。

sendメソッド内で、通知メソッドを呼び出して、チャンネルが理解できるメッセージオブジェクトを取得し、必要に応じて通知を$notizableインスタンスに送信します。

<?php

namespace App\Notifications;

use Illuminate\Notifications\Notification;

class VoiceChannel
{
    /**
     * 指定された通知の送信
     *
     * @param  mixed  $notifiable
     * @param  \Illuminate\Notifications\Notification  $notification
     * @return void
     */
    public function send($notifiable, Notification $notification)
    {
        $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;

    /**
     * 通知チャンネルの取得
     *
     * @param  mixed  $notifiable
     * @return array|string
     */
    public function via($notifiable)
    {
        return [VoiceChannel::class];
    }

    /**
     * 通知の音声プレゼンテーションを取得
     *
     * @param  mixed  $notifiable
     * @return VoiceMessage
     */
    public function toVoice($notifiable)
    {
        // ...
    }
}

ドキュメント章別ページ

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュをURLへ付加します。

移動

クリックで即時移動します。

設定

適用ボタンクリック後に、全項目まとめて適用されます。

カラーテーマ
和文指定 Pagination
和文指定 Scaffold
Largeスクリーン表示幅
インデント
本文フォント
コードフォント
フォント適用確認

フォントの指定フィールドから、フォーカスが外れると、当ブロックの内容に反映されます。EnglishのDisplayもPreviewしてください。

フォント設定時、表示に不具合が出た場合、当サイトのクッキーを削除してください。

バックスラッシュを含むインライン\Code\Blockの例です。

以下はコードブロックの例です。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザに関連する電話レコードを取得
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

設定を保存する前に、表示が乱れないか必ず確認してください。CSSによるフォントファミリー指定の知識がない場合は、フォントを変更しないほうが良いでしょう。

キーボード・ショートカット

オープン操作

PDC

ページ(章)移動の左オフキャンバスオープン

HA

ヘッダー移動モーダルオープン

MS

移動/設定の右オフキャンバスオープン

ヘッダー移動

T

最初のヘッダーへ移動

E

最後のヘッダーへ移動

NJ

次ヘッダー(H2〜H4)へ移動

BK

前ヘッダー(H2〜H4)へ移動

その他

?

このヘルプページ表示
閉じる