person t-kobayashi

LaravelでVerifyEmailとResetPasswordの通知メールをカスタマイズする方法

calendar_today 2021年05月14日 update 2021年05月27日
Facebook Twitter LINE はてなブックマーク Pocket

Laravelにはメールアドレス認証とパスワードリセットの際に送信されるメールのテンプレートがありますが、その内容をカスタマイズする方法をまとめます。

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

まず、メールの内容のテンプレートをパブリッシュします。以下のコマンドを実行するとパブリッシュ可能なProviderとTagの一覧が表示されます。

php artisan vendor:publish

結果

 Which provider or tag's files would you like to publish?:
  [0 ] Publish files from all providers and tags listed below
  [1 ] Provider: Facade\Ignition\IgnitionServiceProvider
  [2 ] Provider: Fideloper\Proxy\TrustedProxyServiceProvider
  [3 ] Provider: Fruitcake\Cors\CorsServiceProvider
  [4 ] Provider: Illuminate\Foundation\Providers\FoundationServiceProvider
  [5 ] Provider: Illuminate\Mail\MailServiceProvider
  [6 ] Provider: Illuminate\Notifications\NotificationServiceProvider
  [7 ] Provider: Illuminate\Pagination\PaginationServiceProvider
  [8 ] Provider: Intervention\Image\ImageServiceProviderLaravelRecent
  [9 ] Provider: Laravel\Fortify\FortifyServiceProvider
  [10] Provider: Laravel\Sail\SailServiceProvider
  [11] Provider: Laravel\Sanctum\SanctumServiceProvider
  [12] Provider: Laravel\Tinker\TinkerServiceProvider
  [13] Tag: cors
  [14] Tag: flare-config
  [15] Tag: fortify-config
  [16] Tag: fortify-migrations
  [17] Tag: fortify-support
  [18] Tag: ignition-config
  [19] Tag: laravel-errors
  [20] Tag: laravel-mail
  [21] Tag: laravel-notifications
  [22] Tag: laravel-pagination
  [23] Tag: sail
  [24] Tag: sanctum-config
  [25] Tag: sanctum-migrations

パブリッシュする必要がるのは、laravel-mailとlaravel-notificationsの2つなので、プロンプトに2021をそれぞれ入力します。

パブリッシュが成功すると/resources/views/vendor/mail//resources/views/vendor/notifications/というフォルダが作成され、その中にテンプレートファイルやスタイルファイルが作成されます。これらをカスタマイズすることで、通知メールのデザイン等をカスタマイズできます。

コンテンツのカスタマイズ

AuthServiceProviderのbootメソッドにtoMailUsingメソッドを追記することで、送信される通知の内容を指定できます。

メールアドレス認証の通知メールのカスタマイズ

AuthServiceProviderのbootメソッドに以下のようなコードを追加します。

use Illuminate\Auth\Notifications\VerifyEmail;
use Illuminate\Notifications\Messages\MailMessage;
//-------
public function boot()
{
    VerifyEmail::toMailUsing(function ($notifiable, $url) {
        return (new MailMessage)
            ->subject('件名')
            ->line('本文')
            ->action('メールアドレス認証', $url);
    });
}

toMailUsingに渡すコールバック関数の$notifiableは通知を受け取るモデルのインスタンスで、$urlはメール認証用のリンクになっています。MailMessageに渡す情報を、必要に応じてカスタマイズします。

パスワードリセットの通知メールのカスタマイズ

AuthServiceProviderのbootメソッドに以下のようなコードを追加します。

use Illuminate\Auth\Notifications\ResetPassword;
use Illuminate\Notifications\Messages\MailMessage;
//-------
public function boot()
{
    ResetPassword::toMailUsing(function ($notifiable, $token) {
        $url = url(config('app.url') . route('password.reset', [
            'token' => $token,
            'email' => $notifiable->getEmailForPasswordReset(),
        ], false));
        return (new MailMessage)
            ->subject('件名')
            ->line('本文')
            ->action('パスワードリセット', $url);
    });
}

ResetPassword::toMailUsingに渡すコールバック関数の2つ目のパラメータは$urlではなく、$tokenになっていることに注意してください。ここでは、MailMessageに渡す直前に$urlを生成しています。

その他のカスタマイズ方法

上記はlaravel-mailとlaravel-notificationsをパブリッシュして、その内容をカスタマイズするというアプローチですが、一からテンプレートを作成するということもできます。例として、パスワードリセットの通知をカスタマイズする方法を紹介します。

まず、メールのテンプレートを作成します。/resources/views/emails/reset_password.blade.phpを作成します。中身は必要に応じてカスタマイズしてください。

...

<p>{{ $body }}</p>

<a href="{{ $url }}">パスワードリセット</a>

...

次に、Notificationを作成します。

php artisan make:notification ResetPasswordNotification

上記のコマンドを実行すると、/app/Notifications/フォルダにResetPasswordNotification.phpというファイルが作成されます。内容は以下のようなものになります。

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

class ResetPasswordNotification extends Notification
{
    use Queueable;

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['mail'];
    }

    /**
     * Get the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        return (new MailMessage)
                    ->line('The introduction to the notification.')
                    ->action('Notification Action', url('/'))
                    ->line('Thank you for using our application!');
    }

    /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            //
        ];
    }
}

このファイルを以下のように編集します。

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Auth\Notifications\ResetPassword; // 追加

class ResetPasswordNotification extends ResetPassword
{
    use Queueable;

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public $token; // トークンを保持するために追加

    public function __construct($token) // トークンを受け取る
    {
        $this->token = $token; // トークンを保存
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['mail'];
    }

    /**
     * Get the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        // パスワードリセット用のリンクを生成する
        $url = url(config('app.url') . route('password.reset', [
            'token' => $this->token,
            'email' => $notifiable->getEmailForPasswordReset(),
        ], false));

     // ブレードテンプレートにデータを渡す
        return (new MailMessage)
            ->view(
                'emails.reset_password', ['body' => '本文', 'url' => $url]
            )
            ->subject('件名');
    }

    /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            //
        ];
    }
}

最後に、app/Models/User.phpに以下のメソッドを追加します。

public function sendPasswordResetNotification($token)
{
    $this->notify(new ResetPasswordNotification($token));
}

以上です。

参考サイト

https://stackoverflow.com/questions/66162320/fortify-how-to-customise-verification-password-reset-emails

https://laravel.com/docs/8.x/verification#customization

https://laravel.com/docs/8.x/passwords#reset-email-customization

関連記事

Laravelの記事一覧を見る

Laravelの質問

dosanko が3年前に投稿

質問日時 2021年05月26日

search