イントロダクション
メールの送信は複雑である必要はありません。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
メソッドで行われることに注意してください。このメソッド内でfrom
、subject
、view
、attach
などのさまざまなメソッドを呼び出して、電子メールの表示と配信を設定できます。
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');
}
メッセージにファイルを添付する場合、array
をattach
メソッドの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つの引数を取ります。サポートしている色は、primary
、success
、error
です。メッセージには、必要なだけのボタンコンポーネントを追加できます。
@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ファイルがブラウザでプレビューされたときにレンダリングされません。これらのメーラブルをプレビューするには、MailHogやHELOなどのメールテストアプリケーションに送信する必要があります。
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に期待するコンテンツが含まれていることをテストするための便利な方法をいくつか提供しています。これらのメソッドは、assertSeeInHtml
、assertDontSeeInHtml
、assertSeeInText
、assertDontSeeInText
です。
ご想像のとおり、"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
もしくは、HELOやMailtrapなどのサービスと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',
],
];