コンテンツへスキップ

メール

イントロダクション

メール送信は、複雑である必要はありません。Laravelは、人気のあるSymfony Mailerコンポーネントを搭載した、クリーンでシンプルなメールAPIを提供します。LaravelとSymfony Mailerは、SMTP、Mailgun、Postmark、Resend、Amazon SES、およびsendmailを介してメールを送信するためのドライバを提供しており、選択したローカルまたはクラウドベースのサービスを介して、すぐにメール送信を開始できます。

設定

Laravelのメールサービスは、アプリケーションのconfig/mail.php設定ファイルで設定します。このファイル内で設定された各メーラーは、独自の構成と、独自の「トランスポート」を持つことさえ可能です。これにより、アプリケーションは特定のメールメッセージを送信するために、異なるメールサービスを使用できます。たとえば、アプリケーションでトランザクションメールを送信するためにPostmarkを使用し、一括メールを送信するためにAmazon SESを使用する、といったことが可能です。

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

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

Mailgun、Postmark、Resend、MailerSendなどのAPIベースのドライバは、SMTPサーバを介してメールを送信するよりもシンプルで高速な場合が多いです。可能な限り、これらのドライバのいずれかを使用することをお勧めします。

Mailgunドライバ

Mailgunドライバを使用するには、ComposerでSymfonyのMailgun Mailerトランスポートをインストールしてください。

1composer require symfony/mailgun-mailer symfony/http-client

次に、アプリケーションのconfig/mail.php設定ファイルで2つの変更を行う必要があります。まず、デフォルトのメーラーをmailgunに設定してください。

1'default' => env('MAIL_MAILER', 'mailgun'),

次に、以下の設定配列をmailersの配列に追加してください。

1'mailgun' => [
2 'transport' => 'mailgun',
3 // 'client' => [
4 // 'timeout' => 5,
5 // ],
6],

アプリケーションのデフォルトメーラーを設定した後、config/services.php設定ファイルに以下のオプションを追加してください。

1'mailgun' => [
2 'domain' => env('MAILGUN_DOMAIN'),
3 'secret' => env('MAILGUN_SECRET'),
4 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'),
5 'scheme' => 'https',
6],

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

1'mailgun' => [
2 'domain' => env('MAILGUN_DOMAIN'),
3 'secret' => env('MAILGUN_SECRET'),
4 'endpoint' => env('MAILGUN_ENDPOINT', 'api.eu.mailgun.net'),
5 'scheme' => 'https',
6],

Postmarkドライバ

Postmarkドライバを使用するには、ComposerでSymfonyのPostmark Mailerトランスポートをインストールしてください。

1composer require symfony/postmark-mailer symfony/http-client

次に、アプリケーションのconfig/mail.php設定ファイルでdefaultオプションをpostmarkに設定してください。アプリケーションのデフォルトメーラーを設定したら、config/services.php設定ファイルに以下のオプションが含まれていることを確認してください。

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

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

1'postmark' => [
2 'transport' => 'postmark',
3 'message_stream_id' => env('POSTMARK_MESSAGE_STREAM_ID'),
4 // 'client' => [
5 // 'timeout' => 5,
6 // ],
7],

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

Resendドライバ

Resendドライバを使用するには、ComposerでResendのPHP SDKをインストールしてください。

1composer require resend/resend-php

次に、アプリケーションのconfig/mail.php設定ファイルでdefaultオプションをresendに設定してください。アプリケーションのデフォルトメーラーを設定したら、config/services.php設定ファイルに以下のオプションが含まれていることを確認してください。

1'resend' => [
2 'key' => env('RESEND_KEY'),
3],

SESドライバ

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

1composer require aws/aws-sdk-php

次に、config/mail.php設定ファイルでdefaultオプションをsesに設定し、config/services.php設定ファイルに以下のオプションが含まれていることを確認してください。

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

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

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

SESの購読管理機能と連携するには、メールメッセージのheadersメソッドから返される配列にX-Ses-List-Management-Optionsヘッダを返すことができます。

1/**
2 * Get the message headers.
3 */
4public function headers(): Headers
5{
6 return new Headers(
7 text: [
8 'X-Ses-List-Management-Options' => 'contactListName=MyContactList;topicName=MyTopic',
9 ],
10 );
11}

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

1'ses' => [
2 'key' => env('AWS_ACCESS_KEY_ID'),
3 'secret' => env('AWS_SECRET_ACCESS_KEY'),
4 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
5 'options' => [
6 'ConfigurationSetName' => 'MyConfigurationSet',
7 'EmailTags' => [
8 ['Name' => 'foo', 'Value' => 'bar'],
9 ],
10 ],
11],

MailerSendドライバ

トランザクションメールとSMSサービスであるMailerSendは、Laravel用の独自のAPIベースのメールドライバを保守しています。このドライバを含むパッケージは、Composerパッケージマネージャを介してインストールできます。

1composer require mailersend/laravel-driver

パッケージをインストールしたら、アプリケーションの.envファイルにMAILERSEND_API_KEY環境変数を追加します。さらに、MAIL_MAILER環境変数をmailersendとして定義する必要があります。

1MAIL_MAILER=mailersend
2MAIL_FROM_ADDRESS[email protected]
3MAIL_FROM_NAME="App Name"
4 
5MAILERSEND_API_KEY=your-api-key

最後に、アプリケーションのconfig/mail.php設定ファイルのmailers配列にMailerSendを追加してください。

1'mailersend' => [
2 'transport' => 'mailersend',
3],

ホストされたテンプレートの使用方法など、MailerSendの詳細については、MailerSendドライバのドキュメントを参照してください。

フェイルオーバー設定

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

これを実現するには、アプリケーションのmail設定ファイル内でfailoverトランスポートを使用するメーラーを定義する必要があります。アプリケーションのfailoverメーラーの設定配列には、配信のために選択されるべき設定済みメーラーの順序を参照するmailersの配列を含める必要があります。

1'mailers' => [
2 'failover' => [
3 'transport' => 'failover',
4 'mailers' => [
5 'postmark',
6 'mailgun',
7 'sendmail',
8 ],
9 ],
10 
11 // ...
12],

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

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

ラウンドロビン設定

roundrobinトランスポートを使用すると、メール送信のワークロードを複数のメーラーに分散させることができます。まず、アプリケーションのmail設定ファイル内でroundrobinトランスポートを使用するメーラーを定義します。アプリケーションのroundrobinメーラーの設定配列には、配信に使用する設定済みメーラーを参照するmailersの配列を含める必要があります。

1'mailers' => [
2 'roundrobin' => [
3 'transport' => 'roundrobin',
4 'mailers' => [
5 'ses',
6 'postmark',
7 ],
8 ],
9 
10 // ...
11],

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

1'default' => env('MAIL_MAILER', 'roundrobin'),

ラウンドロビントランスポートは、設定されたメーラーのリストからランダムにメーラーを選択し、その後、後続の各メールで次に利用可能なメーラーに切り替えます。高可用性の実現を助けるfailoverトランスポートとは対照的に、roundrobinトランスポートは負荷分散を提供します。

Mailableの生成

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

1php artisan make:mail OrderShipped

Mailableの記述

Mailableクラスを生成したら、それを開いて内容を確認しましょう。Mailableクラスの設定は、envelopecontentattachmentsメソッドなど、いくつかのメソッドで行います。

envelopeメソッドは、メッセージの件名、そして時には受信者を定義するIlluminate\Mail\Mailables\Envelopeオブジェクトを返します。contentメソッドは、メッセージコンテンツの生成に使用するBladeテンプレートを定義するIlluminate\Mail\Mailables\Contentオブジェクトを返します。

送信者の設定

エンベロープの使用

まず、メールの送信者の設定について見ていきましょう。言い換えれば、メールが誰「から」送信されるかです。送信者を設定する方法は2つあります。1つ目は、メッセージのエンベロープで「from」アドレスを指定する方法です。

1use Illuminate\Mail\Mailables\Address;
2use Illuminate\Mail\Mailables\Envelope;
3 
4/**
5 * Get the message envelope.
6 */
7public function envelope(): Envelope
8{
9 return new Envelope(
10 from: new Address('[email protected]', 'Jeffrey Way'),
11 subject: 'Order Shipped',
12 );
13}

必要であれば、replyToアドレスを指定することもできます。

1return new Envelope(
2 from: new Address('[email protected]', 'Jeffrey Way'),
3 replyTo: [
4 new Address('[email protected]', 'Taylor Otwell'),
5 ],
6 subject: 'Order Shipped',
7);

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

しかし、アプリケーションがすべてのメールで同じ「from」アドレスを使用する場合、生成するすべてのMailableクラスにそれを追加するのは面倒になります。代わりに、config/mail.php設定ファイルでグローバルな「from」アドレスを指定できます。このアドレスは、Mailableクラス内で他の「from」アドレスが指定されていない場合に使用されます。

1'from' => [
2 'address' => env('MAIL_FROM_ADDRESS', '[email protected]'),
3 'name' => env('MAIL_FROM_NAME', 'Example'),
4],

さらに、config/mail.php設定ファイル内でグローバルな「reply_to」アドレスを定義することもできます。

1'reply_to' => ['address' => '[email protected]', 'name' => 'App Name'],

ビューの設定

Mailableクラスのcontentメソッド内で、view、つまりメールのコンテンツをレンダリングする際に使用するテンプレートを定義できます。各メールは通常、そのコンテンツをレンダリングするためにBladeテンプレートを使用するため、メールのHTMLを構築する際には、Bladeテンプレートエンジンのすべてのパワーと利便性を活用できます。

1/**
2 * Get the message content definition.
3 */
4public function content(): Content
5{
6 return new Content(
7 view: 'mail.orders.shipped',
8 );
9}

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

プレーンテキストメール

メールのプレーンテキスト版を定義したい場合は、メッセージのContent定義を作成する際にプレーンテキストテンプレートを指定できます。viewパラメータと同様に、textパラメータはメールのコンテンツをレンダリングするために使用されるテンプレート名である必要があります。メッセージのHTML版とプレーンテキスト版の両方を自由に定義できます。

1/**
2 * Get the message content definition.
3 */
4public function content(): Content
5{
6 return new Content(
7 view: 'mail.orders.shipped',
8 text: 'mail.orders.shipped-text'
9 );
10}

明確にするために、htmlパラメータはviewパラメータのエイリアスとして使用できます。

1return new Content(
2 html: 'mail.orders.shipped',
3 text: 'mail.orders.shipped-text'
4);

ビューデータ

publicプロパティ経由

通常、メールのHTMLをレンダリングする際に利用できるデータをビューに渡したくなるでしょう。ビューでデータを利用できるようにするには2つの方法があります。1つ目は、Mailableクラスで定義されたpublicプロパティは、すべて自動的にビューで利用可能になります。したがって、たとえば、Mailableクラスのコンストラクタにデータを渡し、そのデータをクラスで定義されたpublicプロパティに設定できます。

1<?php
2 
3namespace App\Mail;
4 
5use App\Models\Order;
6use Illuminate\Bus\Queueable;
7use Illuminate\Mail\Mailable;
8use Illuminate\Mail\Mailables\Content;
9use Illuminate\Queue\SerializesModels;
10 
11class OrderShipped extends Mailable
12{
13 use Queueable, SerializesModels;
14 
15 /**
16 * Create a new message instance.
17 */
18 public function __construct(
19 public Order $order,
20 ) {}
21 
22 /**
23 * Get the message content definition.
24 */
25 public function content(): Content
26 {
27 return new Content(
28 view: 'mail.orders.shipped',
29 );
30 }
31}

データがpublicプロパティに設定されると、ビューで自動的に利用可能になるため、Bladeテンプレートで他のデータにアクセスするのと同じようにアクセスできます。

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

withパラメータ経由

メールのデータをテンプレートに送信する前にフォーマットをカスタマイズしたい場合は、Content定義のwithパラメータを介して手動でデータをビューに渡すことができます。通常、データはMailableクラスのコンストラクタを介して渡しますが、データが自動的にテンプレートで利用可能にならないように、このデータをprotectedまたはprivateプロパティに設定する必要があります。

1<?php
2 
3namespace App\Mail;
4 
5use App\Models\Order;
6use Illuminate\Bus\Queueable;
7use Illuminate\Mail\Mailable;
8use Illuminate\Mail\Mailables\Content;
9use Illuminate\Queue\SerializesModels;
10 
11class OrderShipped extends Mailable
12{
13 use Queueable, SerializesModels;
14 
15 /**
16 * Create a new message instance.
17 */
18 public function __construct(
19 protected Order $order,
20 ) {}
21 
22 /**
23 * Get the message content definition.
24 */
25 public function content(): Content
26 {
27 return new Content(
28 view: 'mail.orders.shipped',
29 with: [
30 'orderName' => $this->order->name,
31 'orderPrice' => $this->order->price,
32 ],
33 );
34 }
35}

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

1<div>
2 Price: {{ $orderPrice }}
3</div>

添付ファイル

メールに添付ファイルを追加するには、メッセージのattachmentsメソッドから返される配列に添付ファイルを追加します。まず、Attachmentクラスが提供するfromPathメソッドにファイルパスを指定することで、添付ファイルを追加できます。

1use Illuminate\Mail\Mailables\Attachment;
2 
3/**
4 * Get the attachments for the message.
5 *
6 * @return array<int, \Illuminate\Mail\Mailables\Attachment>
7 */
8public function attachments(): array
9{
10 return [
11 Attachment::fromPath('/path/to/file'),
12 ];
13}

メッセージにファイルを添付する際、asメソッドとwithMimeメソッドを使用して、添付ファイルの表示名やMIMEタイプを指定することもできます。

1/**
2 * Get the attachments for the message.
3 *
4 * @return array<int, \Illuminate\Mail\Mailables\Attachment>
5 */
6public function attachments(): array
7{
8 return [
9 Attachment::fromPath('/path/to/file')
10 ->as('name.pdf')
11 ->withMime('application/pdf'),
12 ];
13}

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

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

1/**
2 * Get the attachments for the message.
3 *
4 * @return array<int, \Illuminate\Mail\Mailables\Attachment>
5 */
6public function attachments(): array
7{
8 return [
9 Attachment::fromStorage('/path/to/file'),
10 ];
11}

もちろん、添付ファイルの名前とMIMEタイプも指定できます。

1/**
2 * Get the attachments for the message.
3 *
4 * @return array<int, \Illuminate\Mail\Mailables\Attachment>
5 */
6public function attachments(): array
7{
8 return [
9 Attachment::fromStorage('/path/to/file')
10 ->as('name.pdf')
11 ->withMime('application/pdf'),
12 ];
13}

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

1/**
2 * Get the attachments for the message.
3 *
4 * @return array<int, \Illuminate\Mail\Mailables\Attachment>
5 */
6public function attachments(): array
7{
8 return [
9 Attachment::fromStorageDisk('s3', '/path/to/file')
10 ->as('name.pdf')
11 ->withMime('application/pdf'),
12 ];
13}

生データ添付

fromData添付メソッドは、生のバイト文字列を添付ファイルとして添付するために使用できます。たとえば、メモリ内でPDFを生成し、ディスクに書き込まずにメールに添付したい場合などにこのメソッドを使用します。fromDataメソッドは、生のデータバイトと添付ファイルに割り当てるべき名前を解決するクロージャを受け入れます。

1/**
2 * Get the attachments for the message.
3 *
4 * @return array<int, \Illuminate\Mail\Mailables\Attachment>
5 */
6public function attachments(): array
7{
8 return [
9 Attachment::fromData(fn () => $this->pdf, 'Report.pdf')
10 ->withMime('application/pdf'),
11 ];
12}

インライン添付

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

1<body>
2 Here is an image:
3 
4 <img src="{{ $message->embed($pathToImage) }}">
5</body>

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

生データ添付の埋め込み

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

1<body>
2 Here is an image from raw data:
3 
4 <img src="{{ $message->embedData($data, 'example-image.jpg') }}">
5</body>

添付可能オブジェクト

メッセージへのファイルの添付は、単純な文字列パスで十分なことが多いですが、多くの場合、アプリケーション内の添付可能なエンティティはクラスによって表現されます。たとえば、アプリケーションがメッセージに写真を添付する場合、その写真を表すPhotoモデルも存在するかもしれません。そのような場合、単にPhotoモデルをattachメソッドに渡せると便利ではないでしょうか?添付可能オブジェクトは、まさにそれを可能にします。

まず、メッセージに添付可能となるオブジェクトにIlluminate\Contracts\Mail\Attachableインターフェイスを実装します。このインターフェイスは、クラスがIlluminate\Mail\Attachmentインスタンスを返すtoMailAttachmentメソッドを定義することを規定しています。

1<?php
2 
3namespace App\Models;
4 
5use Illuminate\Contracts\Mail\Attachable;
6use Illuminate\Database\Eloquent\Model;
7use Illuminate\Mail\Attachment;
8 
9class Photo extends Model implements Attachable
10{
11 /**
12 * Get the attachable representation of the model.
13 */
14 public function toMailAttachment(): Attachment
15 {
16 return Attachment::fromPath('/path/to/file');
17 }
18}

添付可能オブジェクトを定義したら、メールメッセージを構築する際に、そのオブジェクトのインスタンスをattachmentsメソッドから返すことができます。

1/**
2 * Get the attachments for the message.
3 *
4 * @return array<int, \Illuminate\Mail\Mailables\Attachment>
5 */
6public function attachments(): array
7{
8 return [$this->photo];
9}

もちろん、添付データはAmazon S3などのリモートファイルストレージサービスに保存することもできます。そのため、Laravelでは、アプリケーションのファイルシステムディスクのいずれかに保存されているデータから添付インスタンスを生成することもできます。

1// Create an attachment from a file on your default disk...
2return Attachment::fromStorage($this->path);
3 
4// Create an attachment from a file on a specific disk...
5return Attachment::fromStorageDisk('backblaze', $this->path);

さらに、メモリ内にあるデータから添付インスタンスを作成することもできます。これを実現するには、fromDataメソッドにクロージャを提供します。クロージャは、添付ファイルを表す生データを返す必要があります。

1return Attachment::fromData(fn () => $this->content, 'Photo Name');

Laravelは、添付ファイルをカスタマイズするために使用できる追加のメソッドも提供しています。たとえば、asメソッドとwithMimeメソッドを使用して、ファイルの名前とMIMEタイプをカスタマイズできます。

1return Attachment::fromPath('/path/to/file')
2 ->as('Photo Name')
3 ->withMime('image/jpeg');

ヘッダ

送信メッセージに追加のヘッダを添付する必要がある場合があります。たとえば、カスタムのMessage-Idやその他の任意のテキストヘッダを設定する必要があるかもしれません。

これを実現するには、Mailableにheadersメソッドを定義します。headersメソッドはIlluminate\Mail\Mailables\Headersインスタンスを返す必要があります。このクラスはmessageIdreferencestextパラメータを受け入れます。もちろん、特定のメッセージに必要なパラメータのみを提供することができます。

1use Illuminate\Mail\Mailables\Headers;
2 
3/**
4 * Get the message headers.
5 */
6public function headers(): Headers
7{
8 return new Headers(
9 messageId: '[email protected]',
10 references: ['[email protected]'],
11 text: [
12 'X-Custom-Header' => 'Custom Value',
13 ],
14 );
15}

タグとメタデータ

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

1use Illuminate\Mail\Mailables\Envelope;
2 
3/**
4 * Get the message envelope.
5 *
6 * @return \Illuminate\Mail\Mailables\Envelope
7 */
8public function envelope(): Envelope
9{
10 return new Envelope(
11 subject: 'Order Shipped',
12 tags: ['shipment'],
13 metadata: [
14 'order_id' => $this->order->id,
15 ],
16 );
17}

アプリケーションがMailgunドライバを使用している場合、タグメタデータの詳細についてはMailgunのドキュメントを参照してください。同様に、Postmarkのドキュメントも、タグメタデータのサポートに関する詳細について参照できます。

アプリケーションがメール送信にAmazon SESを使用している場合は、metadataメソッドを使用してメッセージにSES「タグ」を添付する必要があります。

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

Laravelのメール機能はSymfony Mailerによって実現されています。Laravelでは、メッセージを送信する前にSymfony Messageインスタンスとともに呼び出されるカスタムコールバックを登録できます。これにより、送信前にメッセージを詳細にカスタマイズする機会が得られます。これを実現するには、Envelope定義にusingパラメータを定義します。

1use Illuminate\Mail\Mailables\Envelope;
2use Symfony\Component\Mime\Email;
3 
4/**
5 * Get the message envelope.
6 */
7public function envelope(): Envelope
8{
9 return new Envelope(
10 subject: 'Order Shipped',
11 using: [
12 function (Email $message) {
13 // ...
14 },
15 ]
16 );
17}

Markdown Mailable

Markdown Mailableメッセージを使用すると、Mailableでメール通知の構築済みテンプレートとコンポーネントを活用できます。メッセージはMarkdownで記述されるため、Laravelはメッセージのために美しくレスポンシブなHTMLテンプレートをレンダリングできると同時に、プレーンテキストの対応物も自動的に生成します。

Markdown Mailableの生成

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

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

次に、Mailableのcontentメソッド内でContent定義を設定する際に、viewパラメータの代わりにmarkdownパラメータを使用します。

1use Illuminate\Mail\Mailables\Content;
2 
3/**
4 * Get the message content definition.
5 */
6public function content(): Content
7{
8 return new Content(
9 markdown: 'mail.orders.shipped',
10 with: [
11 'url' => $this->orderUrl,
12 ],
13 );
14}

Markdownメッセージの記述

Markdown Mailableは、BladeコンポーネントとMarkdown構文の組み合わせを使用しており、Laravelの構築済みメールUIコンポーネントを活用しながら、簡単にメールメッセージを構築できます。

1<x-mail::message>
2# Order Shipped
3 
4Your order has been shipped!
5 
6<x-mail::button :url="$url">
7View Order
8</x-mail::button>
9 
10Thanks,<br>
11{{ config('app.name') }}
12</x-mail::message>

Markdownメールを記述する際には、過度なインデントを使用しないでください。Markdownの標準に従い、Markdownパーサはインデントされたコンテンツをコードブロックとしてレンダリングします。

ボタンコンポーネント

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

1<x-mail::button :url="$url" color="success">
2View Order
3</x-mail::button>

パネルコンポーネント

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

1<x-mail::panel>
2This is the panel content.
3</x-mail::panel>

テーブルコンポーネント

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

1<x-mail::table>
2| Laravel | Table | Example |
3| ------------- | :-----------: | ------------: |
4| Col 2 is | Centered | $10 |
5| Col 3 is | Right-Aligned | $20 |
6</x-mail::table>

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

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

1php 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表現内でインラインCSSスタイルに変換されます。

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

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

メールの送信

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

1<?php
2 
3namespace App\Http\Controllers;
4 
5use App\Http\Controllers\Controller;
6use App\Mail\OrderShipped;
7use App\Models\Order;
8use Illuminate\Http\RedirectResponse;
9use Illuminate\Http\Request;
10use Illuminate\Support\Facades\Mail;
11 
12class OrderShipmentController extends Controller
13{
14 /**
15 * Ship the given order.
16 */
17 public function store(Request $request): RedirectResponse
18 {
19 $order = Order::findOrFail($request->order_id);
20 
21 // Ship the order...
22 
23 Mail::to($request->user())->send(new OrderShipped($order));
24 
25 return redirect('/orders');
26 }
27}

メッセージを送信する際に、「to」受信者を指定するだけに限定されません。「to」、「cc」、「bcc」受信者を、それぞれのメソッドを連結して自由に設定できます。

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

受信者のループ処理

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

1foreach (['[email protected]', '[email protected]'] as $recipient) {
2 Mail::to($recipient)->send(new OrderShipped($order));
3}

特定のメーラー経由でのメール送信

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

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

メールのキュー投入

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

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

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

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

遅延メッセージキューイング

キューに入れられたメールメッセージの配信を遅延させたい場合は、laterメソッドを使用できます。laterメソッドは、最初の引数として、メッセージを送信する日時を示すDateTimeインスタンスを受け入れます。

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

特定のキューへのプッシュ

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

1$message = (new OrderShipped($order))
2 ->onConnection('sqs')
3 ->onQueue('emails');
4 
5Mail::to($request->user())
6 ->cc($moreUsers)
7 ->bcc($evenMoreUsers)
8 ->queue($message);

デフォルトでのキューイング

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

1use Illuminate\Contracts\Queue\ShouldQueue;
2 
3class OrderShipped extends Mailable implements ShouldQueue
4{
5 // ...
6}

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

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

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

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

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

1<?php
2 
3namespace App\Mail;
4 
5use Illuminate\Bus\Queueable;
6use Illuminate\Contracts\Queue\ShouldQueue;
7use Illuminate\Mail\Mailable;
8use Illuminate\Queue\SerializesModels;
9 
10class OrderShipped extends Mailable implements ShouldQueue
11{
12 use Queueable, SerializesModels;
13 
14 /**
15 * Create a new message instance.
16 */
17 public function __construct()
18 {
19 $this->afterCommit();
20 }
21}

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

Mailableのレンダリング

MailableのHTMLコンテンツを送信せずにキャプチャしたい場合があります。これを実現するには、Mailableのrenderメソッドを呼び出します。このメソッドは、Mailableの評価されたHTMLコンテンツを文字列として返します。

1use App\Mail\InvoicePaid;
2use App\Models\Invoice;
3 
4$invoice = Invoice::find(1);
5 
6return (new InvoicePaid($invoice))->render();

ブラウザでのMailableプレビュー

Mailableのテンプレートをデザインする際、一般的なBladeテンプレートのように、レンダリングされたMailableをブラウザですばやくプレビューできると便利です。このため、Laravelでは、ルートクロージャやコントローラから直接任意のMailableを返すことができます。Mailableが返されると、レンダリングされてブラウザに表示され、実際のメールアドレスに送信することなく、そのデザインをすばやくプレビューできます。

1Route::get('/mailable', function () {
2 $invoice = App\Models\Invoice::find(1);
3 
4 return new App\Mail\InvoicePaid($invoice);
5});

Mailableのローカライズ

Laravelでは、リクエストの現在のロケールとは異なるロケールでMailableを送信でき、メールがキューに入れられた場合でもそのロケールを記憶します。

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

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

ユーザーの優先ロケール

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

1use Illuminate\Contracts\Translation\HasLocalePreference;
2 
3class User extends Model implements HasLocalePreference
4{
5 /**
6 * Get the user's preferred locale.
7 */
8 public function preferredLocale(): string
9 {
10 return $this->locale;
11 }
12}

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

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

テスト

Mailableコンテンツのテスト

Laravelは、Mailableの構造を検査するためのさまざまなメソッドを提供しています。さらに、Laravelは、Mailableが期待するコンテンツを含んでいることをテストするための便利なメソッドをいくつか提供しています。これらのメソッドは、assertSeeInHtmlassertDontSeeInHtmlassertSeeInOrderInHtmlassertSeeInTextassertDontSeeInTextassertSeeInOrderInTextassertHasAttachmentassertHasAttachedDataassertHasAttachmentFromStorage、およびassertHasAttachmentFromStorageDiskです。

ご想像のとおり、「HTML」アサーションはMailableのHTML版に特定の文字列が含まれていることを表明し、「text」アサーションはMailableのプレーンテキスト版に特定の文字列が含まれていることを表明します。

1use App\Mail\InvoicePaid;
2use App\Models\User;
3 
4test('mailable content', function () {
5 $user = User::factory()->create();
6 
7 $mailable = new InvoicePaid($user);
8 
9 $mailable->assertFrom('[email protected]');
10 $mailable->assertTo('[email protected]');
11 $mailable->assertHasCc('[email protected]');
12 $mailable->assertHasBcc('[email protected]');
13 $mailable->assertHasReplyTo('[email protected]');
14 $mailable->assertHasSubject('Invoice Paid');
15 $mailable->assertHasTag('example-tag');
16 $mailable->assertHasMetadata('key', 'value');
17 
18 $mailable->assertSeeInHtml($user->email);
19 $mailable->assertSeeInHtml('Invoice Paid');
20 $mailable->assertSeeInOrderInHtml(['Invoice Paid', 'Thanks']);
21 
22 $mailable->assertSeeInText($user->email);
23 $mailable->assertSeeInOrderInText(['Invoice Paid', 'Thanks']);
24 
25 $mailable->assertHasAttachment('/path/to/file');
26 $mailable->assertHasAttachment(Attachment::fromPath('/path/to/file'));
27 $mailable->assertHasAttachedData($pdfData, 'name.pdf', ['mime' => 'application/pdf']);
28 $mailable->assertHasAttachmentFromStorage('/path/to/file', 'name.pdf', ['mime' => 'application/pdf']);
29 $mailable->assertHasAttachmentFromStorageDisk('s3', '/path/to/file', 'name.pdf', ['mime' => 'application/pdf']);
30});
1use App\Mail\InvoicePaid;
2use App\Models\User;
3 
4public function test_mailable_content(): void
5{
6 $user = User::factory()->create();
7 
8 $mailable = new InvoicePaid($user);
9 
10 $mailable->assertFrom('[email protected]');
11 $mailable->assertTo('[email protected]');
12 $mailable->assertHasCc('[email protected]');
13 $mailable->assertHasBcc('[email protected]');
14 $mailable->assertHasReplyTo('[email protected]');
15 $mailable->assertHasSubject('Invoice Paid');
16 $mailable->assertHasTag('example-tag');
17 $mailable->assertHasMetadata('key', 'value');
18 
19 $mailable->assertSeeInHtml($user->email);
20 $mailable->assertSeeInHtml('Invoice Paid');
21 $mailable->assertSeeInOrderInHtml(['Invoice Paid', 'Thanks']);
22 
23 $mailable->assertSeeInText($user->email);
24 $mailable->assertSeeInOrderInText(['Invoice Paid', 'Thanks']);
25 
26 $mailable->assertHasAttachment('/path/to/file');
27 $mailable->assertHasAttachment(Attachment::fromPath('/path/to/file'));
28 $mailable->assertHasAttachedData($pdfData, 'name.pdf', ['mime' => 'application/pdf']);
29 $mailable->assertHasAttachmentFromStorage('/path/to/file', 'name.pdf', ['mime' => 'application/pdf']);
30 $mailable->assertHasAttachmentFromStorageDisk('s3', '/path/to/file', 'name.pdf', ['mime' => 'application/pdf']);
31}

Mailable送信のテスト

特定のMailableが特定のユーザーに「送信された」ことを表明するテストとは別に、Mailableのコンテンツをテストすることをお勧めします。通常、Mailableのコンテンツはテストしているコードとは関係なく、Laravelが特定のMailableを送信するように指示されたことを表明するだけで十分です。

Mailファサードのfakeメソッドを使用すると、メールの送信を防ぐことができます。Mailファサードのfakeメソッドを呼び出した後、Mailableがユーザーに送信するように指示されたことを表明したり、Mailableが受け取ったデータを検査したりすることもできます。

1<?php
2 
3use App\Mail\OrderShipped;
4use Illuminate\Support\Facades\Mail;
5 
6test('orders can be shipped', function () {
7 Mail::fake();
8 
9 // Perform order shipping...
10 
11 // Assert that no mailables were sent...
12 Mail::assertNothingSent();
13 
14 // Assert that a mailable was sent...
15 Mail::assertSent(OrderShipped::class);
16 
17 // Assert a mailable was sent twice...
18 Mail::assertSent(OrderShipped::class, 2);
19 
20 // Assert a mailable was sent to an email address...
21 Mail::assertSent(OrderShipped::class, '[email protected]');
22 
23 // Assert a mailable was sent to multiple email addresses...
24 Mail::assertSent(OrderShipped::class, ['[email protected]', '...']);
25 
26 // Assert a mailable was not sent...
27 Mail::assertNotSent(AnotherMailable::class);
28 
29 // Assert 3 total mailables were sent...
30 Mail::assertSentCount(3);
31});
1<?php
2 
3namespace Tests\Feature;
4 
5use App\Mail\OrderShipped;
6use Illuminate\Support\Facades\Mail;
7use Tests\TestCase;
8 
9class ExampleTest extends TestCase
10{
11 public function test_orders_can_be_shipped(): void
12 {
13 Mail::fake();
14 
15 // Perform order shipping...
16 
17 // Assert that no mailables were sent...
18 Mail::assertNothingSent();
19 
20 // Assert that a mailable was sent...
21 Mail::assertSent(OrderShipped::class);
22 
23 // Assert a mailable was sent twice...
24 Mail::assertSent(OrderShipped::class, 2);
25 
26 // Assert a mailable was sent to an email address...
27 Mail::assertSent(OrderShipped::class, '[email protected]');
28 
29 // Assert a mailable was sent to multiple email addresses...
30 Mail::assertSent(OrderShipped::class, ['[email protected]', '...']);
31 
32 // Assert a mailable was not sent...
33 Mail::assertNotSent(AnotherMailable::class);
34 
35 // Assert 3 total mailables were sent...
36 Mail::assertSentCount(3);
37 }
38}

バックグラウンドでMailableをキューに入れて配信している場合は、assertSentの代わりにassertQueuedメソッドを使用する必要があります。

1Mail::assertQueued(OrderShipped::class);
2Mail::assertNotQueued(OrderShipped::class);
3Mail::assertNothingQueued();
4Mail::assertQueuedCount(3);

assertSentassertNotSentassertQueued、またはassertNotQueuedメソッドにクロージャを渡すことで、特定の「真理テスト」に合格するMailableが送信されたことを表明できます。指定された真理テストに合格するMailableが少なくとも1つ送信されていれば、アサーションは成功します。

1Mail::assertSent(function (OrderShipped $mail) use ($order) {
2 return $mail->order->id === $order->id;
3});

Mailファサードのアサーションメソッドを呼び出す際、提供されたクロージャが受け取るMailableインスタンスは、Mailableを調べるための便利なメソッドを公開しています。

1Mail::assertSent(OrderShipped::class, function (OrderShipped $mail) use ($user) {
2 return $mail->hasTo($user->email) &&
3 $mail->hasCc('...') &&
4 $mail->hasBcc('...') &&
5 $mail->hasReplyTo('...') &&
6 $mail->hasFrom('...') &&
7 $mail->hasSubject('...');
8});

Mailableインスタンスには、Mailableの添付ファイルを調べるための便利なメソッドもいくつか含まれています。

1use Illuminate\Mail\Mailables\Attachment;
2 
3Mail::assertSent(OrderShipped::class, function (OrderShipped $mail) {
4 return $mail->hasAttachment(
5 Attachment::fromPath('/path/to/file')
6 ->as('name.pdf')
7 ->withMime('application/pdf')
8 );
9});
10 
11Mail::assertSent(OrderShipped::class, function (OrderShipped $mail) {
12 return $mail->hasAttachment(
13 Attachment::fromStorageDisk('s3', '/path/to/file')
14 );
15});
16 
17Mail::assertSent(OrderShipped::class, function (OrderShipped $mail) use ($pdfData) {
18 return $mail->hasAttachment(
19 Attachment::fromData(fn () => $pdfData, 'name.pdf')
20 );
21});

メールが送信されなかったことを表明するためのメソッドが2つあることにお気づきかもしれません:assertNotSentassertNotQueuedです。メールが送信もキュー投入もされなかったことを表明したい場合があるかもしれません。これを実現するには、assertNothingOutgoingメソッドとassertNotOutgoingメソッドを使用できます。

1Mail::assertNothingOutgoing();
2 
3Mail::assertNotOutgoing(function (OrderShipped $mail) use ($order) {
4 return $mail->order->id === $order->id;
5});

メールとローカル開発

メールを送信するアプリケーションを開発している際、おそらく実際のメールアドレスにメールを送信したくはないでしょう。Laravelは、ローカル開発中にメールの実際の送信を「無効にする」ためのいくつかの方法を提供しています。

Logドライバ

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

HELO / Mailtrap / Mailpit

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

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

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

最後に、Mailファサードが提供するalwaysToメソッドを呼び出すことで、グローバルな「to」アドレスを指定できます。通常、このメソッドはアプリケーションのサービスプロバイダのいずれかのbootメソッドから呼び出す必要があります。

1use Illuminate\Support\Facades\Mail;
2 
3/**
4 * Bootstrap any application services.
5 */
6public function boot(): void
7{
8 if ($this->app->environment('local')) {
9 Mail::alwaysTo('[email protected]');
10 }
11}

イベント

Laravelは、メールメッセージの送信中に2つのイベントをディスパッチします。MessageSendingイベントはメッセージが送信される前にディスパッチされ、MessageSentイベントはメッセージが送信された後にディスパッチされます。これらのイベントは、メールがキューに入れられたときではなく、*送信されている*ときにディスパッチされることを覚えておいてください。アプリケーション内でこれらのイベントに対するイベントリスナを作成できます。

1use Illuminate\Mail\Events\MessageSending;
2// use Illuminate\Mail\Events\MessageSent;
3 
4class LogMessage
5{
6 /**
7 * Handle the given event.
8 */
9 public function handle(MessageSending $event): void
10 {
11 // ...
12 }
13}

カスタムトランスポート

Laravelにはさまざまなメールトランスポートが含まれていますが、Laravelが標準でサポートしていない他のサービスを介してメールを配信するために、独自のトランスポートを作成したい場合があるかもしれません。まず、Symfony\Component\Mailer\Transport\AbstractTransportクラスを拡張するクラスを定義します。次に、トランスポートにdoSendメソッドと__toString()メソッドを実装します。

1use MailchimpTransactional\ApiClient;
2use Symfony\Component\Mailer\SentMessage;
3use Symfony\Component\Mailer\Transport\AbstractTransport;
4use Symfony\Component\Mime\Address;
5use Symfony\Component\Mime\MessageConverter;
6 
7class MailchimpTransport extends AbstractTransport
8{
9 /**
10 * Create a new Mailchimp transport instance.
11 */
12 public function __construct(
13 protected ApiClient $client,
14 ) {
15 parent::__construct();
16 }
17 
18 /**
19 * {@inheritDoc}
20 */
21 protected function doSend(SentMessage $message): void
22 {
23 $email = MessageConverter::toEmail($message->getOriginalMessage());
24 
25 $this->client->messages->send(['message' => [
26 'from_email' => $email->getFrom(),
27 'to' => collect($email->getTo())->map(function (Address $email) {
28 return ['email' => $email->getAddress(), 'type' => 'to'];
29 })->all(),
30 'subject' => $email->getSubject(),
31 'text' => $email->getTextBody(),
32 ]]);
33 }
34 
35 /**
36 * Get the string representation of the transport.
37 */
38 public function __toString(): string
39 {
40 return 'mailchimp';
41 }
42}

カスタムトランスポートを定義したら、Mailファサードが提供するextendメソッドを介して登録できます。通常、これはアプリケーションのAppServiceProviderサービスプロバイダのbootメソッド内で行う必要があります。extendメソッドに提供されるクロージャには$config引数が渡されます。この引数には、アプリケーションのconfig/mail.php設定ファイルでメーラーに定義された設定配列が含まれます。

1use App\Mail\MailchimpTransport;
2use Illuminate\Support\Facades\Mail;
3 
4/**
5 * Bootstrap any application services.
6 */
7public function boot(): void
8{
9 Mail::extend('mailchimp', function (array $config = []) {
10 return new MailchimpTransport(/* ... */);
11 });
12}

カスタムトランスポートが定義され、登録されたら、アプリケーションのconfig/mail.php設定ファイル内で新しいトランスポートを利用するメーラー定義を作成できます。

1'mailchimp' => [
2 'transport' => 'mailchimp',
3 // ...
4],

追加のSymfonyトランスポート

Laravelには、MailgunやPostmarkなど、Symfonyが保守している既存のメールトランスポートのサポートが含まれています。しかし、Symfonyが保守している追加のトランスポートのサポートでLaravelを拡張したい場合があるかもしれません。それには、Composerを介して必要なSymfonyメーラーを要求し、Laravelにトランスポートを登録することで実現できます。たとえば、「Brevo」(旧「Sendinblue」)Symfonyメーラーをインストールして登録できます。

1composer require symfony/brevo-mailer symfony/http-client

Brevoメーラーパッケージがインストールされたら、アプリケーションのservices設定ファイルにBrevo API認証情報のエントリを追加できます。

1'brevo' => [
2 'key' => 'your-api-key',
3],

次に、Mailファサードのextendメソッドを使用して、Laravelにトランスポートを登録できます。通常、これはサービスプロバイダのbootメソッド内で行う必要があります。

1use Illuminate\Support\Facades\Mail;
2use Symfony\Component\Mailer\Bridge\Brevo\Transport\BrevoTransportFactory;
3use Symfony\Component\Mailer\Transport\Dsn;
4 
5/**
6 * Bootstrap any application services.
7 */
8public function boot(): void
9{
10 Mail::extend('brevo', function () {
11 return (new BrevoTransportFactory)->create(
12 new Dsn(
13 'brevo+api',
14 'default',
15 config('services.brevo.key')
16 )
17 );
18 });
19}

トランスポートが登録されたら、アプリケーションのconfig/mail.php設定ファイル内で新しいトランスポートを利用するメーラー定義を作成できます。

1'brevo' => [
2 'transport' => 'brevo',
3 // ...
4],

Laravelは最も生産的な方法です
ソフトウェアを構築、デプロイ、監視します。