Laravel 8.x メール

イントロダクション

メールの送信は複雑である必要はありません。Laravelは、人気のあるSwiftMailerライブラリを利用したクリーンでシンプルなメールAPIを提供します。LaravelとSwiftMailerは、SMTP、Mailgun、Postmark、AmazonSES、およびsendmailを介して電子メールを送信するためのドライバーを提供し、選択したローカルまたはクラウドベースのサービスを介してメールの送信をすばやく開始できるようにします。

設定

Laravelのメールサービスは、アプリケーションのconfig/mail.php設定ファイルを介して設定できます。このファイル内で設定された各メーラーには、独自の設定と独自の「トランスポート」があり、アプリケーションがさまざまな電子メールサービスを使用して特定の電子メールメッセージを送信できるようにします。たとえば、アプリケーションでPostmarkを使用してトランザクションメールを送信し、AmazonSESを使用して一括メールを送信するなどです。

mail設定ファイル内に、mailers設定配列があります。この配列には、Laravelがサポートしている主要なメールドライバ/トランスポートごとのサンプル設定エントリが含まれています。その中でdefault設定値は、アプリケーションが電子メールメッセージを送信する必要があるときにデフォルトで使用するメーラーを決定します。

ドライバ/トランスポートの前提条件

MailgunやPostmarkなどのAPIベースのドライバは、多くの場合、SMTPサーバを介してメールを送信するよりも簡単で高速です。可能な限り、これらのドライバのいずれかを使用することを推奨します。すべてのAPIベースのドライバには、Composerパッケージマネージャーを介してインストールできるGuzzle HTTPライブラリが必要です。

composer require guzzlehttp/guzzle

Mailgunドライバ

Mailgunドライバを使用するには、最初にGuzzle HTTPライブラリをインストールします。次に、config/mail.php設定ファイルのdefaultオプションをmailgunに設定します。次に、config/services.php設定ファイルに次のオプションを確実に含めてください。

'mailgun' => [
    'domain' => env('MAILGUN_DOMAIN'),
    'secret' => env('MAILGUN_SECRET'),
],

米国のMailgunリージョンを使用していない場合は、services設定ファイルでリージョンのエンドポイントを定義できます。

'mailgun' => [
    'domain' => env('MAILGUN_DOMAIN'),
    'secret' => env('MAILGUN_SECRET'),
    'endpoint' => env('MAILGUN_ENDPOINT', 'api.eu.mailgun.net'),
],

Postmarkドライバ

Postmarkドライバを使用するには、Composerを介してPostmarkのSwiftMailerトランスポートをインストールします。

composer require wildbit/swiftmailer-postmark

次に、Guzzle HTTPライブラリをインストールし、config/mail.php設定ファイルのdefaultオプションをpostmarkに設定します。最後に、config/services.php設定ファイルに以下のオプションを確実に含めてください。

'postmark' => [
    'token' => env('POSTMARK_TOKEN'),
],

特定のメーラで使用する必要があるPostmarkメッセージストリームを指定したい場合は、message_stream_id設定オプションをメーラの設定配列に追加してください。この設定配列は、アプリケーションのconfig/mail.php設定ファイルにあります。

'postmark' => [
    'transport' => 'postmark',
    'message_stream_id' => env('POSTMARK_MESSAGE_STREAM_ID'),
],

この方法で、メッセージストリームが異なる複数のPostmarkメーラを設定することもできます。

SESドライバ

Amazon SESドライバを使用するには、最初にAmazon AWS SDK for PHPをインストールする必要があります。このライブラリは、Composerパッケージマネージャーを介してインストールできます。

composer require aws/aws-sdk-php

次に、config/mail.php設定ファイルのdefaultオプションをsesに設定し、config/services.php設定ファイルに以下のオプションを確実に含めてください。

'ses' => [
    'key' => env('AWS_ACCESS_KEY_ID'),
    'secret' => env('AWS_SECRET_ACCESS_KEY'),
    'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
],

AWSの一時的な認証情報をセッショントークン経由で利用するには、アプリケーションのSES設定へtokenキーを追加します。

'ses' => [
    'key' => env('AWS_ACCESS_KEY_ID'),
    'secret' => env('AWS_SECRET_ACCESS_KEY'),
    'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
    'token' => env('AWS_SESSION_TOKEN'),
],

メール送信時にAWS SDKのSendRawEmailメソッドへLaravelが渡すべき追加オプションを定義したい場合、ses設定内でoptions配列を定義してください。

'ses' => [
    'key' => env('AWS_ACCESS_KEY_ID'),
    'secret' => env('AWS_SECRET_ACCESS_KEY'),
    'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
    'options' => [
        'ConfigurationSetName' => 'MyConfigurationSet',
        'Tags' => [
            ['Name' => 'foo', 'Value' => 'bar'],
        ],
    ],
],

フェイルオーバー設定

アプリケーションのメールを送信するように設定した外部サービスがダウンすることがあります。このような場合には、プライマリ配信ドライバがダウンした場合に使用する、1つ以上のバックアップメール配信設定を定義できると便利です。

これを実現するには、アプリケーションのmail設定ファイルで、failoverトランスポートを使用するメーラーを定義する必要があります。アプリケーションのfailoverメーラー設定配列に、配送に使うメールドライバを選択する順序を規定するmailersの配列を含める必要があります。

'mailers' => [
    'failover' => [
        'transport' => 'failover',
        'mailers' => [
            'postmark',
            'mailgun',
            'sendmail',
        ],
    ],

    // ...
],

フェイルオーバーメーラーを定義したら、アプリケーションのmail設定ファイル内のdefault設定キーの値に、その名前を指定して、このメーラーをアプリケーションが使用するデフォルトメーラーとして設定する必要があります。

'default' => env('MAIL_MAILER', 'failover'),

Mailableの生成

Laravelアプリケーションを構築する場合、アプリケーションが送信する各タイプの電子メールは"Mailable"クラスとして表します。これらのクラスはapp/Mailディレクトリに保存されます。アプリケーションにこのディレクトリが存在しなくても心配ありません。make:mail Artisanコマンドを使用して最初のメール可能なクラスを作成するときに、生成されます。

php artisan make:mail OrderShipped

Mailableの記述

Mailableクラスを生成したら、それを開いて、その内容を調べてください。まず、メール可能なクラスの設定はすべてbuildメソッドで行われることに注意してください。このメソッド内でfromsubjectviewattachなどのさまざまなメソッドを呼び出して、電子メールの表示と配信を設定できます。

Tip!! Mailableのbuildメソッドではタイプヒントで依存を指定できます。Laravelのサービスコンテナは、これらの依存を自動的に注入します。

Senderの設定

fromメソッドの使用

まず、メールの送信者の設定について見ていきましょう。言い換えると、電子メールを送信したのは誰かです。送信者を設定するには2つの方法があります。まず、Mailableクラスのbuildメソッド内でfromメソッドを使用する方法です。

/**
 * メッセージの作成
 *
 * @return $this
 */
public function build()
{
    return $this->from('example@example.com', 'Example')
                ->view('emails.orders.shipped');
}

グローバルfromアドレスの使用

ただし、アプリケーションがすべての電子メールに同じ「送信者」アドレスを使用している場合、生成する各メール可能クラスでfromメソッドを呼び出すのは面倒です。代わりに、config/mail.php設定ファイルでグローバルな「送信者」アドレスを指定できます。このアドレスは、Mailableクラス内で「送信者」アドレスを指定しない場合に使用します。

'from' => ['address' => 'example@example.com', 'name' => 'App Name'],

また、config/mail.php設定ファイル内でグローバルな"reply_to"アドレスも定義できます。

'reply_to' => ['address' => 'example@example.com', 'name' => 'App Name'],

ビューの設定

Mailableクラスのbuildメソッド内で、viewメソッドを使用して、電子メールのコンテンツをレンダーするときに使用するテンプレートを指定できます。通常、各メールはBladeテンプレートを使用してコンテンツをレンダーするため、メールのHTMLを作成するときにBladeテンプレートエンジンの能力と利便性を最大限に活用できます。

/**
 * メッセージの作成
 *
 * @return $this
 */
public function build()
{
    return $this->view('emails.orders.shipped');
}

Tip!! すべてのメールテンプレートを格納するためにresources/views/emailsディレクトリを作成することを推奨します。ただし、resources/viewsディレクトリ内ならば好きな場所へ自由に配置できます。

平文テキストの電子メール

電子メールの平文テキストバージョンを定義する場合は、textメソッドを使用します。viewメソッドと同様に、textメソッドは電子メールの内容をレンダーするために使用するテンプレート名を引数に取ります。メッセージのHTMLバージョンと平文テキストバージョンの両方を自由に定義できます。

/**
 * メッセージの作成
 *
 * @return $this
 */
public function build()
{
    return $this->view('emails.orders.shipped')
                ->text('emails.orders.shipped_plain');
}

ビューデータ

Publicなプロパティ経由

通常、電子メールのHTMLをレンダーするときに使用するデータをビューへ渡す必要があります。ビューでデータを利用できるようにする方法は2つあります。まず、Mailableクラスで定義したパブリックプロパティは、自動的にビューで使用できるようになります。したがって、たとえばMailableクラスのコンストラクタにデータを渡し、そのデータをクラスで定義したパブリックプロパティに設定できます。

<?php

namespace App\Mail;

use App\Models\Order;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class OrderShipped extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * 注文インスタンス
     *
     * @var \App\Models\Order
     */
    public $order;

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

    /**
     * メッセージを作成
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.orders.shipped');
    }
}

データをパブリックプロパティへ設定すると、ビューで自動的に利用できるようになるため、Bladeテンプレートの他のデータにアクセスするのと同じようにアクセスできます。

<div>
    Price: {{ $order->price }}
</div>

withメソッド経由

テンプレートへ送信する前にメールのデータの形式をカスタマイズしたい場合は、withメソッドを使用して手動でデータをビューへ渡せます。通常、Mailableクラスのコンストラクターを介してデータを渡します。ただし、このデータをprotectedまたはprivateプロパティに設定して、データがテンプレートで自動的に使用可能にならないようにする必要があります。次に、withメソッドを呼び出すときに、テンプレートで使用できるようにするデータの配列を渡します。

<?php

namespace App\Mail;

use App\Models\Order;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class OrderShipped extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * 注文インスタンス
     *
     * @var \App\Models\Order
     */
    protected $order;

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

    /**
     * メッセージを作成
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.orders.shipped')
                    ->with([
                        'orderName' => $this->order->name,
                        'orderPrice' => $this->order->price,
                    ]);
    }
}

データがwithメソッドに渡されると、ビューで自動的に利用できるようになるため、Bladeテンプレートの他のデータにアクセスするのと同じようにアクセスできます。

<div>
    Price: {{ $orderPrice }}
</div>

添付

電子メールに添付ファイルを追加するには、Mailableクラスのbuildメソッド内でattachメソッドを使用します。attachメソッドは、ファイルへのフルパスを最初の引数に受けます。

/**
 * メッセージを作成
 *
 * @return $this
 */
public function build()
{
    return $this->view('emails.orders.shipped')
                ->attach('/path/to/file');
}

メッセージにファイルを添付する場合、arrayattachメソッドの2番目の引数に渡すことにより、表示名やMIMEタイプを指定することもできます。

/**
 * メッセージを作成
 *
 * @return $this
 */
public function build()
{
    return $this->view('emails.orders.shipped')
                ->attach('/path/to/file', [
                    'as' => 'name.pdf',
                    'mime' => 'application/pdf',
                ]);
}

ディスクからファイルを添付

ファイルシステムディスクのいずれかにファイルを保存している場合は、attachFromStorageメソッドを使用してファイルを電子メールに添付できます。

/**
 * メッセージを作成
 *
 * @return $this
 */
public function build()
{
   return $this->view('emails.orders.shipped')
               ->attachFromStorage('/path/to/file');
}

必要に応じて、attachFromStorageメソッドの2番目と3番目の引数を使用して、ファイルの添付ファイル名と追加オプションを指定できます。

/**
 * メッセージを作成
 *
 * @return $this
 */
public function build()
{
   return $this->view('emails.orders.shipped')
               ->attachFromStorage('/path/to/file', 'name.pdf', [
                   'mime' => 'application/pdf'
               ]);
}

デフォルトのディスク以外のストレージディスクを指定する必要がある場合は、attachFromStorageDiskメソッドを使用します。

/**
 * メッセージを作成
 *
 * @return $this
 */
public function build()
{
   return $this->view('emails.orders.shipped')
               ->attachFromStorageDisk('s3', '/path/to/file');
}

素のデータの添付ファイル

attachDataメソッドを使用して、素のバイト文字列を添付ファイルとして添付できます。たとえば、メモリ内にPDFを生成し、ディスクに書き込まずに電子メールに添付する場合は、この方法を使用できます。attachDataメソッドは、最初の引数に素のデータバイトを取り、2番目の引数にファイルの名前、3番目の引数にオプションの配列を取ります。

/**
 * メッセージを作成
 *
 * @return $this
 */
public function build()
{
    return $this->view('emails.orders.shipped')
                ->attachData($this->pdf, 'name.pdf', [
                    'mime' => 'application/pdf',
                ]);
}

インライン添付

インライン画像をメールに埋め込むのは、通常面倒です。ただし、Laravelはメールに画像を添付する便利な方法を提供しています。インライン画像を埋め込むには、メールテンプレート内の$message変数でembedメソッドを使用します。Laravelは自動的に$message変数をすべてのメールテンプレートで利用できるようにするので、手動で渡すことを心配する必要はありません。

<body>
    Here is an image:

    <img src="{{ $message->embed($pathToImage) }}">
</body>

Note: 平文ンテキストメッセージはインライン添付ファイルを利用しないため、$message変数は平文テキストメッセージテンプレートでは使用できません。

素のデータの添付ファイルへの埋め込み

電子メールテンプレートに埋め込みたい素の画像データ文字列がすでにある場合は、$message変数でembedDataメソッドを呼び出すことができます。embedDataメソッドを呼び出すときは、埋め込み画像に割り当てる必要のあるファイル名を指定する必要があります。

<body>
    Here is an image from raw data:

    <img src="{{ $message->embedData($data, 'example-image.jpg') }}">
</body>

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

Mailable基本クラスのwithSwiftMessageメソッドを使用すると、メッセージを送信する前にSwiftMailerメッセージインスタンスで呼び出されるクロージャを登録できます。これにより、メッセージが配信される前に、メッセージを大幅にカスタマイズする機会が得られます。

/**
 * メッセージを作成
 *
 * @return $this
 */
public function build()
{
    $this->view('emails.orders.shipped');

    $this->withSwiftMessage(function ($message) {
        $message->getHeaders()->addTextHeader(
            'Custom-Header', 'Header Value'
        );
    });

    return $this;
}

Markdown Mailable

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

Markdown Mailableの生成

対応するMarkdownテンプレートを使用してMailableファイルを生成するには、make:mail Artisanコマンドの--markdownオプションを使用します。

php artisan make:mail OrderShipped --markdown=emails.orders.shipped

次に、Mailableオブジェクトをそのbuildメソッド内で設定するときに、viewメソッドの代わりにmarkdownメソッドを呼び出します。markdownメソッドは、Markdownテンプレートの名前と、テンプレートで使用するデータ配列をオプションとして引数に取ります。

/**
 * メッセージを作成
 *
 * @return $this
 */
public function build()
{
    return $this->from('example@example.com')
                ->markdown('emails.orders.shipped', [
                    'url' => $this->orderUrl,
                ]);
}

Markdownメッセージの記述

Markdown Mailableは、BladeコンポーネントとMarkdown構文の組み合わせを使用して、Laravelに組み込まれた電子メールUIコンポーネントを活用しながら、メールメッセージを簡単に作成できるようにします。

@component('mail::message')
# Order Shipped

Your order has been shipped!

@component('mail::button', ['url' => $url])
View Order
@endcomponent

Thanks,<br>
{{ config('app.name') }}
@endcomponent

Tip!! Markdownメールを書くときに余分なインデントを使用しないでください。Markdown標準に従って、Markdownパーサーはインデントされたコンテンツをコードブロックとしてレンダリングします。

ボタンコンポーネント

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

@component('mail::button', ['url' => $url, 'color' => 'success'])
View Order
@endcomponent

パネルコンポーネント

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

@component('mail::panel')
This is the panel content.
@endcomponent

テーブルコンポーネント

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

@component('mail::table')
| Laravel       | Table         | Example  |
| ------------- |:-------------:| --------:|
| Col 2 is      | Centered      | $10      |
| Col 3 is      | Right-Aligned | $20      |
@endcomponent

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

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

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

このコマンドは、Markdownメールコンポーネントをresources/views/vendor/mailディレクトリへリソース公開します。mailディレクトリにはhtmlディレクトリとtextディレクトリが含まれ、それぞれに利用可能なすべてのコンポーネントのそれぞれの表現が含まれます。これらのコンポーネントは自由にカスタマイズできます。

CSSのカスタマイズ

コンポーネントをエクスポートした後、resources/views/vendor/mail/html/themesディレクトリにはdefault.cssファイルが含まれます。このファイルのCSSをカスタマイズすると、MarkdownメールメッセージのHTML表現内でスタイルが自動的にインラインCSSスタイルに変換されます。

LaravelのMarkdownコンポーネント用にまったく新しいテーマを作成したい場合は、CSSファイルをhtml/themesディレクトリに配置できます。CSSファイルに名前を付けて保存した後、アプリケーションのconfig/mail.php設定ファイルのthemeオプションを更新して、新しいテーマの名前と一致させます。

個々のMailableのテーマをカスタマイズするには、Mailableクラスの$themeプロパティを、そのMailableを送信するときに使用するテーマの名前に設定します。

メール送信

メッセージを送信するには、Mailファサードtoメソッドを使用します。toメソッドは、電子メールアドレス、ユーザーインスタンス、またはユーザーのコレクションを受け入れます。オブジェクトまたはオブジェクトのコレクションを渡すと、メーラーは電子メールの受信者を決定するときに自動的にemailおよびnameプロパティを使用するため、これらの属性がオブジェクトで使用可能であることを確認してください。受信者を指定したら、Mailableクラスのインスタンスをsendメソッドに渡すことができます。

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Mail\OrderShipped;
use App\Models\Order;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;

class OrderShipmentController extends Controller
{
    /**
     * 指定注文を発送
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $order = Order::findOrFail($request->order_id);

        // 注文を発送…

        Mail::to($request->user())->send(new OrderShipped($order));
    }
}

メッセージを送信するときに「宛先」の受信者を指定するだけに限定されません。それぞれのメソッドをチェーン化することで、「to」、「cc」、「bcc」の受信者を自由に設定できます。

Mail::to($request->user())
    ->cc($moreUsers)
    ->bcc($evenMoreUsers)
    ->send(new OrderShipped($order));

受信者をループする

場合によっては、受信者/電子メールアドレスの配列を反復処理して、受信者のリストにMailableファイルを送信する必要が起きるでしょう。しかし、toメソッドはメールアドレスをMailable受信者のリストに追加するため、ループを繰り返すたびに、以前のすべての受信者に別のメールが送信されます。したがって、受信者ごとにMailableインスタンスを常に再作成する必要があります。

foreach (['taylor@example.com', 'dries@example.com'] as $recipient) {
    Mail::to($recipient)->send(new OrderShipped($order));
}

特定のメーラーを介してメールを送信

デフォルトでは、Laravelはアプリケーションのmail設定ファイルでdefaultメーラーとして設定されたメーラーを使用してメールを送信します。しかし、mailerメソッドを使用して、特定のメーラー設定を使用してメッセージを送信することができます。

Mail::mailer('postmark')
        ->to($request->user())
        ->send(new OrderShipped($order));

メールのキュー投入

メールメッセージのキュー投入

電子メールメッセージの送信はアプリケーションのレスポンス時間に悪影響を与える可能性があるため、多くの開発者はバックグラウンド送信のために電子メールメッセージをキューに投入することを選択します。Laravelは組み込みの統一キューAPIを使用してこれを簡単にしています。メールメッセージをキューに投入するには、メッセージの受信者を指定した後、Mailファサードでqueueメソッドを使用します。

Mail::to($request->user())
    ->cc($moreUsers)
    ->bcc($evenMoreUsers)
    ->queue(new OrderShipped($order));

このメソッドは、メッセージがバックグラウンドで送信されるように、ジョブをキューへ自動的に投入処理します。この機能を使用する前に、キューを設定しておく必要があります。

遅延メッセージキュー

キューに投入した電子メールメッセージの配信を遅らせたい場合は、laterメソッドを使用します。laterメソッドは最初の引数にメッセージの送信時期を示すDateTimeインスタンスを取ります。。

Mail::to($request->user())
    ->cc($moreUsers)
    ->bcc($evenMoreUsers)
    ->later(now()->addMinutes(10), new OrderShipped($order));

特定のキューへの投入

make:mailコマンドを使用して生成したすべてのMailableクラスはIlluminate\Bus\Queueableトレイトを利用するため、任意のMailableクラスインスタンスでonQueueメソッドとonConnectionメソッドを呼び出して、メッセージに使う接続とキュー名を指定できます。

$message = (new OrderShipped($order))
                ->onConnection('sqs')
                ->onQueue('emails');

Mail::to($request->user())
    ->cc($moreUsers)
    ->bcc($evenMoreUsers)
    ->queue($message);

デフォルトでのキュー投入

常にキューに入れたいMailableクラスがある場合は、クラスにShouldQueue契約を実装できます。これで、メール送信時にsendメソッドを呼び出しても、この契約を実装しているため、Mailableはキューへ投入されます。

use Illuminate\Contracts\Queue\ShouldQueue;

class OrderShipped extends Mailable implements ShouldQueue
{
    //
}

Mailableのキュー投入とデータベーストランザクション

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

キュー接続のafter_commit設定オプションがfalseに設定されている場合でも、メールメッセージ送信時にafterCommitメソッドを呼び出せば、キュー投入する特定のMailableが、オープンしているすべてのデータベーストランザクションのコミット後に、ディスパッチすると示せます。

Mail::to($request->user())->send(
    (new OrderShipped($order))->afterCommit()
);

あるいは、Mailableのコンストラクタで、afterCommitメソッドを呼び出すこともできます。

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class OrderShipped extends Mailable implements ShouldQueue
{
    use Queueable, SerializesModels;

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

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

Mailableのレンダー

MailableのHTMLコンテンツを送信せずにキャプチャしたい場合があります。これを行うには、Mailableのrenderメソッドを呼び出してください。このメソッドは、Mailableファイルの評価済みHTMLコンテンツを文字列として返します。

use App\Mail\InvoicePaid;
use App\Models\Invoice;

$invoice = Invoice::find(1);

return (new InvoicePaid($invoice))->render();

ブラウザによるMailableのプレビュー

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

Route::get('/mailable', function () {
    $invoice = App\Models\Invoice::find(1);

    return new App\Mail\InvoicePaid($invoice);
});

Note: インライン添付ファイルは、Mailableファイルがブラウザでプレビューされたときにレンダリングされません。これらのメーラブルをプレビューするには、MailHogHELOなどのメールテストアプリケーションに送信する必要があります。

Mailableの多言語化

Laravelを使用すると、リクエストの現在のロケール以外のロケールでMailableファイルを送信でき、メールがキュー投入される場合でもこのロケールを記憶しています。

これを実現するために、Mailファサードは目的の言語を設定するためのlocaleメソッドを提供します。Mailableのテンプレートが評価されると、アプリケーションはこのロケールに変更され、評価が完了すると前のロケールに戻ります。

Mail::to($request->user())->locale('es')->send(
    new OrderShipped($order)
);

ユーザー優先ロケール

場合によっては、アプリケーションは各ユーザーの優先ロケールを保存しています。1つ以上のモデルにHasLocalePreferenceコントラクトを実装することで、メールを送信するときにこの保存されたロケールを使用するようにLaravelに指示できます。

use Illuminate\Contracts\Translation\HasLocalePreference;

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

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

Mail::to($request->user())->send(new OrderShipped($order));

Mailableのテスト

Laravelは、Mailableに期待するコンテンツが含まれていることをテストするための便利な方法をいくつか提供しています。これらのメソッドは、assertSeeInHtmlassertDontSeeInHtmlassertSeeInTextassertDontSeeInTextです。

ご想像のとおり、"HTML"アサートは、メーラブルのHTMLバージョンに特定の文字列が含まれていることを宣言し、"text"アサートは、Mailableの平文テキストバージョンに特定の文字列が含まれていることを宣言します。

use App\Mail\InvoicePaid;
use App\Models\User;

public function test_mailable_content()
{
    $user = User::factory()->create();

    $mailable = new InvoicePaid($user);

    $mailable->assertSeeInHtml($user->email);
    $mailable->assertSeeInHtml('Invoice Paid');

    $mailable->assertSeeInText($user->email);
    $mailable->assertSeeInText('Invoice Paid');
}

Mailableの送信テスト

指定のMailableが特定のユーザーへ「送信」されたことをアサートするテストとは別に、Mailableのコンテンツをテストするのを推奨します。メールが送信されたことをテストする方法については、Mail fakeのドキュメントをご覧ください。

メールとローカル開発

電子メールを送信するアプリケーションを開発する場合、実際の電子メールアドレスに電子メールを送信したくない場合があります。Laravelは、ローカル開発中に実際の電子メールの送信を「無効にする」ためのいくつかの方法を提供します。

Logドライバ

メールを送信する代わりに、logメールドライバは検査のためにすべてのメールメッセージをログファイルに書き込みます。通常、このドライバはローカル開発中にのみ使用されます。環境ごとのアプリケーションの設定の詳細については、設定ドキュメントを確認してください。

HELO/Mailtrap/MailHog

もしくは、HELOMailtrapなどのサービスとsmtpドライバを使用して、メールメッセージを「ダミー」メールボックスに送信可能です。本当の電子メールクライアントでそれらを表示できます。このアプローチには、Mailtrapのメッセージビューアで最終的な電子メールを実際に調べられるという利点があります。

Laravel Sailを使用している場合は、MailHogを使用してメッセージをプレビューできます。Sailの実行中は、http://localhost:8025でMailHogインターフェイスにアクセスできます。

グローバルなtoアドレスの使用

最後に、Mailファサードが提供するalwaysToメソッドを呼び出し、グローバルな「宛先」アドレスを指定する方法です。通常、このメソッドは、アプリケーションのサービスプロバイダのbootメソッドから呼び出すべきでしょう。

use Illuminate\Support\Facades\Mail;

/**
 * アプリケーションの全サービスの初期起動処理
 *
 * @return void
 */
public function boot()
{
    if ($this->app->environment('local')) {
        Mail::alwaysTo('taylor@example.com');
    }
}

イベント

Laravelは、メールメッセージの送信プロセス中に2つのイベントを発行します。MessageSendingイベントはメッセージが送信される前に発生し、MessageSentイベントはメッセージが送信された後に発生します。これらのイベントは、メールをキューへ投入したときではなく、メールが送信されているときに発生することを忘れないでください。このイベントのイベントリスナは、App\Providers\EventServiceProviderサービスプロバイダで登録できます。

/**
 * アプリケーションのイベントリスナマッピング
 *
 * @var array
 */
protected $listen = [
    'Illuminate\Mail\Events\MessageSending' => [
        'App\Listeners\LogSendingMessage',
    ],
    'Illuminate\Mail\Events\MessageSent' => [
        'App\Listeners\LogSentMessage',
    ],
];

ドキュメント章別ページ

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュを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)へ移動

その他

?

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