メール
- はじめに
- Mailableの生成
- Mailableの記述
- Markdown Mailable
- メールの送信
- Mailableのレンダリング
- Mailableのローカライズ
- テスト
- メールとローカル開発
- イベント
- カスタムトランスポート
はじめに
メールの送信は複雑である必要はありません。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トランスポートをインストールします
composer require symfony/mailgun-mailer symfony/http-client
次に、アプリケーションの`config/mail.php`設定ファイルの`default`オプションを`mailgun`に設定し、`mailers`の配列に次の設定配列を追加します
'mailgun' => [ 'transport' => 'mailgun', // 'client' => [ // 'timeout' => 5, // ],],
アプリケーションのデフォルトメーラーを設定した後、`config/services.php`設定ファイルに次のオプションを追加します
'mailgun' => [ 'domain' => env('MAILGUN_DOMAIN'), 'secret' => env('MAILGUN_SECRET'), 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'), 'scheme' => 'https',],
米国のMailgunリージョンを使用していない場合は、`services`設定ファイルでリージョンのエンドポイントを定義できます
'mailgun' => [ 'domain' => env('MAILGUN_DOMAIN'), 'secret' => env('MAILGUN_SECRET'), 'endpoint' => env('MAILGUN_ENDPOINT', 'api.eu.mailgun.net'), 'scheme' => 'https',],
Postmarkドライバ
Postmarkドライバを使用するには、Composerを介してSymfonyのPostmark Mailerトランスポートをインストールします
composer require symfony/postmark-mailer symfony/http-client
次に、アプリケーションの`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'), // 'client' => [ // 'timeout' => 5, // ],],
このようにして、異なるメッセージストリームを持つ複数のPostmarkメーラーを設定することもできます。
Resendドライバ
Resend ドライバを使用するには、Composer 経由で Resend の PHP SDK をインストールします。
composer require resend/resend-php
次に、アプリケーションの `config/mail.php` 設定ファイルの `default` オプションを `resend` に設定します。アプリケーションのデフォルトメーラーを設定した後、`config/services.php` 設定ファイルに次のオプションが含まれていることを確認します
'resend' => [ 'key' => env('RESEND_KEY'),],
SESドライバ
Amazon SESドライバを使用するには、最初にPHP用Amazon AWS SDKをインストールする必要があります。このライブラリは、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'),],
SESの suscripción 管理機能 と連携するには、メールメッセージの`headers`メソッドによって返される配列で`X-Ses-List-Management-Options`ヘッダーを返すことができます
/** * Get the message headers. */public function headers(): Headers{ return new Headers( text: [ 'X-Ses-List-Management-Options' => 'contactListName=MyContactList;topicName=MyTopic', ], );}
Laravelがメールを送信するときにAWS SDKの`SendEmail`メソッドに渡す追加オプションを定義する場合は、`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', 'EmailTags' => [ ['Name' => 'foo', 'Value' => 'bar'], ], ],],
MailerSendドライバ
MailerSendは、トランザクションメールとSMSサービスであり、Laravel用の独自のAPIベースのメールドライバを保守しています。ドライバを含むパッケージは、Composerパッケージマネージャーを介してインストールできます
composer require mailersend/laravel-driver
パッケージがインストールされたら、`MAILERSEND_API_KEY`環境変数をアプリケーションの`.env`ファイルに追加します。さらに、`MAIL_MAILER`環境変数は`mailersend`として定義する必要があります
MAIL_MAILER=mailersendMAIL_FROM_ADDRESS[email protected]MAIL_FROM_NAME="App Name" MAILERSEND_API_KEY=your-api-key
最後に、アプリケーションの`config/mail.php`設定ファイルの`mailers`配列にMailerSendを追加します
'mailersend' => [ 'transport' => 'mailersend',],
ホストされたテンプレートの使用方法など、MailerSendの詳細については、MailerSendドライバのドキュメントを参照してください。
フェイルオーバー設定
アプリケーションのメールを送信するように設定した外部サービスがダウンしている場合があります。このような場合、プライマリ配信ドライバがダウンした場合に使用される、1つ以上のバックアップメール配信設定を定義すると便利です。
これを実現するには、`failover`トランスポートを使用するメーラーをアプリケーションの`mail`設定ファイル内で定義する必要があります。アプリケーションの`failover`メーラーの設定配列には、設定されたメーラーが配信に選択される順序を参照する`mailers`の配列が含まれている必要があります
'mailers' => [ 'failover' => [ 'transport' => 'failover', 'mailers' => [ 'postmark', 'mailgun', 'sendmail', ], ], // ...],
フェイルオーバーメーラーが定義されたら、アプリケーションの`mail`設定ファイル内の`default`設定キーの値としてその名前を指定することにより、このメーラーをアプリケーションで使用されるデフォルトメーラーとして設定する必要があります
'default' => env('MAIL_MAILER', 'failover'),
ラウンドロビン設定
`roundrobin`トランスポートを使用すると、メールのワークロードを複数のメーラーに分散できます。開始するには、`roundrobin`トランスポートを使用するメーラーをアプリケーションの`mail`設定ファイル内で定義します。アプリケーションの`roundrobin`メーラーの設定配列には、配信に使用する設定済みメーラーを参照する`mailers`の配列が含まれている必要があります
'mailers' => [ 'roundrobin' => [ 'transport' => 'roundrobin', 'mailers' => [ 'ses', 'postmark', ], ], // ...],
ラウンドロビンメーラーが定義されたら、アプリケーションの`mail`設定ファイル内の`default`設定キーの値としてその名前を指定することにより、このメーラーをアプリケーションで使用されるデフォルトメーラーとして設定する必要があります
'default' => env('MAIL_MAILER', 'roundrobin'),
ラウンドロビントランスポートは、設定されたメーラーのリストからランダムにメーラーを選択し、後続の各メールで次に利用可能なメーラーに切り替えます。高可用性を実現するのに役立つfailover
トランスポートとは対照的に、roundrobin
トランスポートは負荷分散を提供します。
Mailableの生成
Laravelアプリケーションを構築する場合、アプリケーションによって送信される各タイプのメールは、「mailable」クラスとして表されます。これらのクラスは、app/Mail
ディレクトリに格納されます。アプリケーションにこのディレクトリが表示されない場合でも、make:mail
Artisanコマンドを使用して最初のmailableクラスを作成すると生成されるため、心配する必要はありません。
php artisan make:mail OrderShipped
Mailableの記述
mailableクラスを生成したら、それを開いて内容を確認します。 Mailableクラスの設定は、envelope
、content
、attachments
メソッドなど、いくつかのメソッドで行われます。
envelope
メソッドは、メッセージの件名と、場合によっては受信者を定義するIlluminate\Mail\Mailables\Envelope
オブジェクトを返します。 content
メソッドは、メッセージコンテンツの生成に使用されるBladeテンプレートを定義するIlluminate\Mail\Mailables\Content
オブジェクトを返します。
送信者の設定
エンベロープの使用
まず、メールの送信者、つまりメールの「送信元」の設定について説明します。送信者を設定するには、2つの方法があります。まず、メッセージのエンベロープに「from」アドレスを指定できます。
use Illuminate\Mail\Mailables\Address;use Illuminate\Mail\Mailables\Envelope; /** * Get the message envelope. */public function envelope(): Envelope{ return new Envelope( subject: 'Order Shipped', );}
必要に応じて、replyTo
アドレスも指定できます。
return new Envelope( replyTo: [ ], subject: 'Order Shipped',);
グローバルなfrom
アドレスの使用
ただし、アプリケーションですべてのメールに同じ「from」アドレスを使用する場合、生成するmailableクラスごとに追加するのは面倒になる可能性があります。代わりに、config/mail.php
設定ファイルでグローバルな「from」アドレスを指定できます。このアドレスは、mailableクラス内で他の「from」アドレスが指定されていない場合に使用されます。
'from' => [ 'name' => env('MAIL_FROM_NAME', 'Example'),],
さらに、config/mail.php
設定ファイル内でグローバルな「reply_to」アドレスを定義できます。
ビューの設定
mailableクラスのcontent
メソッド内で、view
、つまりメールのコンテンツをレンダリングするときに使用するテンプレートを定義できます。各メールは通常、コンテンツをレンダリングするためにBladeテンプレートを使用するため、メールのHTMLを作成する際にBladeテンプレートエンジンのすべての機能と利便性を活用できます。
/** * Get the message content definition. */public function content(): Content{ return new Content( view: 'mail.orders.shipped', );}
すべてのメールテンプレートを格納するためにresources/views/emails
ディレクトリを作成することもできますが、resources/views
ディレクトリ内のどこにでも自由に配置できます。
プレーンテキストメール
メールのプレーンテキストバージョンを定義する場合は、メッセージのContent
定義を作成するときにプレーンテキストテンプレートを指定できます。 view
パラメータと同様に、text
パラメータは、メールのコンテンツのレンダリングに使用されるテンプレート名である必要があります。メッセージのHTMLバージョンとプレーンテキストバージョンの両方を自由に定義できます。
/** * Get the message content definition. */public function content(): Content{ return new Content( view: 'mail.orders.shipped', text: 'mail.orders.shipped-text' );}
わかりやすくするために、html
パラメータをview
パラメータのエイリアスとして使用できます。
return new Content( html: 'mail.orders.shipped', text: 'mail.orders.shipped-text');
ビュ データ
パブリックプロパティ経由
通常、メールのHTMLをレンダリングするときに利用できるデータをビューに渡す必要があります。ビューでデータを利用できるようにするには、2つの方法があります。まず、mailableクラスで定義されているパブリックプロパティはすべて、自動的にビューで使用できるようになります。そのため、たとえば、データをmailableクラスのコンストラクタに渡して、そのデータをクラスで定義されたパブリックプロパティに設定できます。
<?php namespace App\Mail; use App\Models\Order;use Illuminate\Bus\Queueable;use Illuminate\Mail\Mailable;use Illuminate\Mail\Mailables\Content;use Illuminate\Queue\SerializesModels; class OrderShipped extends Mailable{ use Queueable, SerializesModels; /** * Create a new message instance. */ public function __construct( public Order $order, ) {} /** * Get the message content definition. */ public function content(): Content { return new Content( view: 'mail.orders.shipped', ); }}
データがパブリックプロパティに設定されると、ビューで自動的に使用できるようになるため、Bladeテンプレートの他のデータにアクセスするのと同じようにアクセスできます。
<div> Price: {{ $order->price }}</div>
with
パラメータ経由
テンプレートに送信される前にメールデータの形式をカスタマイズする場合は、Content
定義のwith
パラメータを使用してデータをビューに手動で渡すことができます。通常、mailableクラスのコンストラクタを介してデータを渡しますが、データがテンプレートで自動的に使用できないように、このデータをprotected
またはprivate
プロパティに設定する必要があります。
<?php namespace App\Mail; use App\Models\Order;use Illuminate\Bus\Queueable;use Illuminate\Mail\Mailable;use Illuminate\Mail\Mailables\Content;use Illuminate\Queue\SerializesModels; class OrderShipped extends Mailable{ use Queueable, SerializesModels; /** * Create a new message instance. */ public function __construct( protected Order $order, ) {} /** * Get the message content definition. */ public function content(): Content { return new Content( view: 'mail.orders.shipped', with: [ 'orderName' => $this->order->name, 'orderPrice' => $this->order->price, ], ); }}
データがwith
メソッドに渡されると、ビューで自動的に使用できるようになるため、Bladeテンプレートの他のデータにアクセスするのと同じようにアクセスできます。
<div> Price: {{ $orderPrice }}</div>
添付ファイル
メールに添付ファイルを追加するには、メッセージのattachments
メソッドによって返される配列に添付ファイルを追加します。まず、Attachment
クラスによって提供されるfromPath
メソッドにファイルパスを提供することで、添付ファイルを追加できます。
use Illuminate\Mail\Mailables\Attachment; /** * Get the attachments for the message. * * @return array<int, \Illuminate\Mail\Mailables\Attachment> */public function attachments(): array{ return [ Attachment::fromPath('/path/to/file'), ];}
メッセージにファイルを添付する場合、as
およびwithMime
メソッドを使用して、添付ファイルの表示名またはMIMEタイプ(あるいはその両方)を指定することもできます。
/** * Get the attachments for the message. * * @return array<int, \Illuminate\Mail\Mailables\Attachment> */public function attachments(): array{ return [ Attachment::fromPath('/path/to/file') ->as('name.pdf') ->withMime('application/pdf'), ];}
ディスクからファイルを添付する
ファイルシステムディスクのいずれかにファイルを保存した場合、fromStorage
添付ファイルメソッドを使用してメールに添付できます。
/** * Get the attachments for the message. * * @return array<int, \Illuminate\Mail\Mailables\Attachment> */public function attachments(): array{ return [ Attachment::fromStorage('/path/to/file'), ];}
もちろん、添付ファイルの名前とMIMEタイプも指定できます。
/** * Get the attachments for the message. * * @return array<int, \Illuminate\Mail\Mailables\Attachment> */public function attachments(): array{ return [ Attachment::fromStorage('/path/to/file') ->as('name.pdf') ->withMime('application/pdf'), ];}
デフォルトのディスク以外のストレージディスクを指定する必要がある場合は、fromStorageDisk
メソッドを使用できます。
/** * Get the attachments for the message. * * @return array<int, \Illuminate\Mail\Mailables\Attachment> */public function attachments(): array{ return [ Attachment::fromStorageDisk('s3', '/path/to/file') ->as('name.pdf') ->withMime('application/pdf'), ];}
生データの添付ファイル
fromData
添付ファイルメソッドを使用して、生のバイト文字列を添付ファイルとして添付できます。たとえば、メモリ内でPDFを生成し、ディスクに書き込まずにメールに添付する場合に、このメソッドを使用できます。 fromData
メソッドは、生のデータバイトと添付ファイルに割り当てる名前を解決するクロージャを受け入れます。
/** * Get the attachments for the message. * * @return array<int, \Illuminate\Mail\Mailables\Attachment> */public function attachments(): array{ return [ Attachment::fromData(fn () => $this->pdf, 'Report.pdf') ->withMime('application/pdf'), ];}
インライン添付ファイル
インライン画像をメールに埋め込むのは通常は面倒ですが、Laravelは画像をメールに添付する便利な方法を提供しています。インライン画像を埋め込むには、メールテンプレート内の$message
変数でembed
メソッドを使用します。 Laravelは、$message
変数をすべてのメールテンプレートで自動的に使用できるようにするため、手動で渡すことについて心配する必要はありません。
<body> Here is an image: <img src="{{ $message->embed($pathToImage) }}"></body>
プレーンテキストメッセージはインライン添付ファイルを使用しないため、$message
変数はプレーンテキストメッセージテンプレートでは使用できません。
生データ添付ファイルを埋め込む
メールテンプレートに埋め込む生の画像データ文字列が既にある場合は、$message
変数でembedData
メソッドを呼び出すことができます。 embedData
メソッドを呼び出すときは、埋め込まれた画像に割り当てるファイル名を指定する必要があります。
<body> Here is an image from raw data: <img src="{{ $message->embedData($data, 'example-image.jpg') }}"></body>
添付可能なオブジェクト
単純な文字列パスを介してメッセージにファイルを添付するだけで十分な場合もありますが、多くの場合、アプリケーション内の添付可能なエンティティはクラスによって表されます。たとえば、アプリケーションがメッセージに写真を添付している場合、アプリケーションにはその写真を表すPhoto
モデルもある場合があります。その場合、Photo
モデルをattach
メソッドに渡すだけで済むと便利ではありませんか? 添付可能なオブジェクトを使用すると、まさにそれができます。
開始するには、メッセージに添付可能なオブジェクトにIlluminate\Contracts\Mail\Attachable
インターフェースを実装します。このインターフェースは、クラスがIlluminate\Mail\Attachment
インスタンスを返すtoMailAttachment
メソッドを定義することを規定しています。
<?php namespace App\Models; use Illuminate\Contracts\Mail\Attachable;use Illuminate\Database\Eloquent\Model;use Illuminate\Mail\Attachment; class Photo extends Model implements Attachable{ /** * Get the attachable representation of the model. */ public function toMailAttachment(): Attachment { return Attachment::fromPath('/path/to/file'); }}
添付可能なオブジェクトを定義したら、メールメッセージを作成するときに、attachments
メソッドからそのオブジェクトのインスタンスを返すことができます。
/** * Get the attachments for the message. * * @return array<int, \Illuminate\Mail\Mailables\Attachment> */public function attachments(): array{ return [$this->photo];}
もちろん、添付ファイルデータは、Amazon S3などのリモートファイルストレージサービスに保存できます。そのため、Laravelでは、アプリケーションのファイルシステムディスクのいずれかに保存されているデータから添付ファイルインスタンスを生成することもできます。
// Create an attachment from a file on your default disk...return Attachment::fromStorage($this->path); // Create an attachment from a file on a specific disk...return Attachment::fromStorageDisk('backblaze', $this->path);
さらに、メモリにあるデータを介して添付ファイルインスタンスを作成できます。これを実現するには、fromData
メソッドにクロージャを提供します。クロージャは、添付ファイルを表す生のデータを返す必要があります。
return Attachment::fromData(fn () => $this->content, 'Photo Name');
Laravelは、添付ファイルをカスタマイズするために使用できる追加のメソッドも提供しています。たとえば、as
およびwithMime
メソッドを使用して、ファイルの名前とMIMEタイプをカスタマイズできます。
return Attachment::fromPath('/path/to/file') ->as('Photo Name') ->withMime('image/jpeg');
ヘッダー
送信メッセージに追加のヘッダーを添付する必要がある場合があります。たとえば、カスタムのMessage-Id
またはその他の任意のテキストヘッダーを設定する必要がある場合があります。
これを実現するには、mailableにheaders
メソッドを定義します。 headers
メソッドは、Illuminate\Mail\Mailables\Headers
インスタンスを返す必要があります。このクラスは、messageId
、references
、およびtext
パラメータを受け入れます。もちろん、特定のメッセージに必要なパラメータのみを提供できます。
use Illuminate\Mail\Mailables\Headers; /** * Get the message headers. */public function headers(): Headers{ return new Headers( text: [ 'X-Custom-Header' => 'Custom Value', ], );}
タグとメタデータ
MailgunやPostmarkなどの一部のサードパーティのメールプロバイダーは、メッセージの「タグ」と「メタデータ」をサポートしており、アプリケーションから送信されたメールをグループ化および追跡するために使用できます。 Envelope
定義を介してメールメッセージにタグとメタデータを追加できます。
use Illuminate\Mail\Mailables\Envelope; /** * Get the message envelope. * * @return \Illuminate\Mail\Mailables\Envelope */public function envelope(): Envelope{ return new Envelope( subject: 'Order Shipped', tags: ['shipment'], metadata: [ 'order_id' => $this->order->id, ], );}
アプリケーションでMailgunドライバーを使用している場合は、タグとメタデータの詳細について、Mailgunのドキュメントを参照してください。 同様に、Postmarkのドキュメントも、タグとメタデータのサポートに関する詳細情報について参照できます。
アプリケーションでAmazon SESを使用してメールを送信する場合は、metadata
メソッドを使用して、SES「タグ」をメッセージに添付する必要があります。
Symfonyメッセージのカスタマイズ
Laravelのメール機能は、Symfony Mailerによって強化されています。 Laravelでは、メッセージを送信する前にSymfony Messageインスタンスで呼び出されるカスタムコールバックを登録できます。これにより、メッセージを送信する前に詳細にカスタマイズする機会が得られます。これを実現するには、Envelope
定義でusing
パラメータを定義します。
use Illuminate\Mail\Mailables\Envelope;use Symfony\Component\Mime\Email; /** * Get the message envelope. */public function envelope(): Envelope{ return new Envelope( subject: 'Order Shipped', using: [ function (Email $message) { // ... }, ] );}
Markdown Mailable
Markdown mailableメッセージを使用すると、mailableでメール通知の事前に構築されたテンプレートとコンポーネントを活用できます。メッセージはMarkdownで記述されているため、Laravelはメッセージの美しくレスポンシブなHTMLテンプレートをレンダリングし、プレーンテキストの対応物を自動的に生成できます。
Markdown Mailableの生成
対応するMarkdownテンプレートを使用してmailableを生成するには、make:mail
Artisanコマンドの--markdown
オプションを使用できます。
php artisan make:mail OrderShipped --markdown=mail.orders.shipped
次に、content
メソッド内でmailable Content
定義を設定するときは、view
パラメータの代わりにmarkdown
パラメータを使用します。
use Illuminate\Mail\Mailables\Content; /** * Get the message content definition. */public function content(): Content{ return new Content( markdown: 'mail.orders.shipped', with: [ 'url' => $this->orderUrl, ], );}
Markdownメッセージの記述
Markdown mailableは、BladeコンポーネントとMarkdown構文を組み合わせて使用することで、Laravelの事前に構築されたメールUIコンポーネントを活用しながら、メールメッセージを簡単に作成できます。
<x-mail::message># Order Shipped Your order has been shipped! <x-mail::button :url="$url">View Order</x-mail::button> Thanks,<br>{{ config('app.name') }}</x-mail::message>
Markdownメールを作成するときは、過剰なインデントを使用しないでください。 Markdown標準に従って、Markdownパーサーはインデントされたコンテンツをコードブロックとしてレンダリングします。
ボタンコンポーネント
ボタンコンポーネントは、中央揃えのボタンリンクをレンダリングします。コンポーネントは、url
とオプションのcolor
の2つの引数を受け入れます。サポートされている色は、primary
、success
、およびerror
です。メッセージにボタンコンポーネントをいくつでも追加できます。
<x-mail::button :url="$url" color="success">View Order</x-mail::button>
パネルコンポーネント
パネルコンポーネントは、メッセージの残りの部分とはわずかに異なる背景色を持つパネルに、指定されたテキストブロックをレンダリングします。これにより、特定のテキストブロックに注意を引くことができます。
<x-mail::panel>This is the panel content.</x-mail::panel>
テーブルコンポーネント
テーブルコンポーネントを使用すると、MarkdownテーブルをHTMLテーブルに変換できます。このコンポーネントは、Markdownテーブルをコンテンツとして受け入れます。テーブルの列の配置は、デフォルトのMarkdownテーブルの配置構文を使用してサポートされています。
<x-mail::table>| Laravel | Table | Example || ------------- | :-----------: | ------------: || Col 2 is | Centered | $10 || Col 3 is | Right-Aligned | $20 |</x-mail::table>
コンポーネントのカスタマイズ
すべての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コンポーネント用にまったく新しいテーマを作成する場合は、`html/themes`ディレクトリにCSSファイルを配置できます。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\RedirectResponse;use Illuminate\Http\Request;use Illuminate\Support\Facades\Mail; class OrderShipmentController extends Controller{ /** * Ship the given order. */ public function store(Request $request): RedirectResponse { $order = Order::findOrFail($request->order_id); // Ship the order... Mail::to($request->user())->send(new OrderShipped($order)); return redirect('/orders'); }}
メッセージの送信時に「宛先」の受信者のみを指定することに限定されません。それぞれのメソッドを連結することで、「宛先」、「CC」、「BCC」の受信者を自由に設定できます。
Mail::to($request->user()) ->cc($moreUsers) ->bcc($evenMoreUsers) ->send(new OrderShipped($order));
受信者のループ処理
場合によっては、受信者/メールアドレスの配列を反復処理して、受信者のリストにMailableを送信する必要があります。ただし、`to`メソッドはメールアドレスをMailableの受信者リストに追加するため、ループを繰り返すたびに、前のすべての受信者に別のメールが送信されます。したがって、受信者ごとにMailableインスタンスを再作成する必要があります。
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; /** * Create a new message instance. */ public function __construct() { $this->afterCommit(); }}
これらの問題の回避策の詳細については、キューに入れられたジョブとデータベースのトランザクションに関するドキュメントを参照してください。
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);});
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{ /** * Get the user's preferred locale. */ public function preferredLocale(): string { return $this->locale; }}
インターフェースを実装すると、LaravelはモデルにMailableと通知を送信するときに、優先ロケールを自動的に使用します。したがって、このインターフェースを使用するときは、`locale`メソッドを呼び出す必要はありません。
Mail::to($request->user())->send(new OrderShipped($order));
テスト
Mailableコンテンツのテスト
Laravelは、Mailableの構造を検査するためのさまざまなメソッドを提供しています。さらに、Laravelは、Mailableに期待されるコンテンツが含まれていることをテストするためのいくつかの便利なメソッドを提供しています。これらのメソッドは、`assertSeeInHtml`、`assertDontSeeInHtml`、`assertSeeInOrderInHtml`、`assertSeeInText`、`assertDontSeeInText`、`assertSeeInOrderInText`、`assertHasAttachment`、`assertHasAttachedData`、`assertHasAttachmentFromStorage`、および`assertHasAttachmentFromStorageDisk`です。
ご想像のとおり、「HTML」アサーションはMailableのHTMLバージョンに特定の文字列が含まれていることをアサートし、「テキスト」アサーションはMailableのプレーンテキストバージョンに特定の文字列が含まれていることをアサートします。
use App\Mail\InvoicePaid;use App\Models\User; test('mailable content', function () { $user = User::factory()->create(); $mailable = new InvoicePaid($user); $mailable->assertHasSubject('Invoice Paid'); $mailable->assertHasTag('example-tag'); $mailable->assertHasMetadata('key', 'value'); $mailable->assertSeeInHtml($user->email); $mailable->assertSeeInHtml('Invoice Paid'); $mailable->assertSeeInOrderInHtml(['Invoice Paid', 'Thanks']); $mailable->assertSeeInText($user->email); $mailable->assertSeeInOrderInText(['Invoice Paid', 'Thanks']); $mailable->assertHasAttachment('/path/to/file'); $mailable->assertHasAttachment(Attachment::fromPath('/path/to/file')); $mailable->assertHasAttachedData($pdfData, 'name.pdf', ['mime' => 'application/pdf']); $mailable->assertHasAttachmentFromStorage('/path/to/file', 'name.pdf', ['mime' => 'application/pdf']); $mailable->assertHasAttachmentFromStorageDisk('s3', '/path/to/file', 'name.pdf', ['mime' => 'application/pdf']);});
use App\Mail\InvoicePaid;use App\Models\User; public function test_mailable_content(): void{ $user = User::factory()->create(); $mailable = new InvoicePaid($user); $mailable->assertHasSubject('Invoice Paid'); $mailable->assertHasTag('example-tag'); $mailable->assertHasMetadata('key', 'value'); $mailable->assertSeeInHtml($user->email); $mailable->assertSeeInHtml('Invoice Paid'); $mailable->assertSeeInOrderInHtml(['Invoice Paid', 'Thanks']); $mailable->assertSeeInText($user->email); $mailable->assertSeeInOrderInText(['Invoice Paid', 'Thanks']); $mailable->assertHasAttachment('/path/to/file'); $mailable->assertHasAttachment(Attachment::fromPath('/path/to/file')); $mailable->assertHasAttachedData($pdfData, 'name.pdf', ['mime' => 'application/pdf']); $mailable->assertHasAttachmentFromStorage('/path/to/file', 'name.pdf', ['mime' => 'application/pdf']); $mailable->assertHasAttachmentFromStorageDisk('s3', '/path/to/file', 'name.pdf', ['mime' => 'application/pdf']);}
Mailable送信のテスト
Mailableのコンテンツのテストは、特定のユーザーに特定のMailableが「送信」されたことをアサートするテストとは別にテストすることをお勧めします。通常、Mailableのコンテンツはテスト対象のコードとは無関係であり、Laravelが特定のMailableを送信するように指示されたことをアサートするだけで十分です。
`Mail`ファサードの`fake`メソッドを使用して、メールの送信を防ぐことができます。`Mail`ファサードの`fake`メソッドを呼び出した後、Mailableがユーザーに送信されるように指示されたことをアサートし、Mailableが受信したデータを検査することもできます。
<?php use App\Mail\OrderShipped;use Illuminate\Support\Facades\Mail; test('orders can be shipped', function () { Mail::fake(); // Perform order shipping... // Assert that no mailables were sent... Mail::assertNothingSent(); // Assert that a mailable was sent... Mail::assertSent(OrderShipped::class); // Assert a mailable was sent twice... Mail::assertSent(OrderShipped::class, 2); // Assert a mailable was sent to an email address... // Assert a mailable was sent to multiple email addresses... // Assert a mailable was not sent... Mail::assertNotSent(AnotherMailable::class); // Assert 3 total mailables were sent... Mail::assertSentCount(3);});
<?php namespace Tests\Feature; use App\Mail\OrderShipped;use Illuminate\Support\Facades\Mail;use Tests\TestCase; class ExampleTest extends TestCase{ public function test_orders_can_be_shipped(): void { Mail::fake(); // Perform order shipping... // Assert that no mailables were sent... Mail::assertNothingSent(); // Assert that a mailable was sent... Mail::assertSent(OrderShipped::class); // Assert a mailable was sent twice... Mail::assertSent(OrderShipped::class, 2); // Assert a mailable was sent to an email address... // Assert a mailable was sent to multiple email addresses... // Assert a mailable was not sent... Mail::assertNotSent(AnotherMailable::class); // Assert 3 total mailables were sent... Mail::assertSentCount(3); }}
バックグラウンドで配信するためにMailableをキューイングしている場合は、`assertSent`の代わりに`assertQueued`メソッドを使用する必要があります。
Mail::assertQueued(OrderShipped::class);Mail::assertNotQueued(OrderShipped::class);Mail::assertNothingQueued();Mail::assertQueuedCount(3);
`assertSent`、`assertNotSent`、`assertQueued`、または`assertNotQueued`メソッドにクロージャを渡して、特定の「真理テスト」に合格するMailableが送信されたことをアサートできます。指定された真理テストに合格するMailableが少なくとも1つ送信された場合、アサーションは成功します。
Mail::assertSent(function (OrderShipped $mail) use ($order) { return $mail->order->id === $order->id;});
`Mail`ファサードのアサーションメソッドを呼び出すと、提供されたクロージャによって受け入れられたMailableインスタンスは、Mailableを検査するための便利なメソッドを公開します。
Mail::assertSent(OrderShipped::class, function (OrderShipped $mail) use ($user) { return $mail->hasTo($user->email) && $mail->hasCc('...') && $mail->hasBcc('...') && $mail->hasReplyTo('...') && $mail->hasFrom('...') && $mail->hasSubject('...');});
Mailableインスタンスには、Mailableの添付ファイルを検査するための便利なメソッドもいくつか含まれています。
use Illuminate\Mail\Mailables\Attachment; Mail::assertSent(OrderShipped::class, function (OrderShipped $mail) { return $mail->hasAttachment( Attachment::fromPath('/path/to/file') ->as('name.pdf') ->withMime('application/pdf') );}); Mail::assertSent(OrderShipped::class, function (OrderShipped $mail) { return $mail->hasAttachment( Attachment::fromStorageDisk('s3', '/path/to/file') );}); Mail::assertSent(OrderShipped::class, function (OrderShipped $mail) use ($pdfData) { return $mail->hasAttachment( Attachment::fromData(fn () => $pdfData, 'name.pdf') );});
メールが送信されなかったことをアサートする2つのメソッドがあることに気付いたかもしれません。`assertNotSent`と`assertNotQueued`です。メールが送信もキューイングもされなかったことをアサートしたい場合があります。これを実現するには、`assertNothingOutgoing`および`assertNotOutgoing`メソッドを使用できます。
Mail::assertNothingOutgoing(); Mail::assertNotOutgoing(function (OrderShipped $mail) use ($order) { return $mail->order->id === $order->id;});
メールとローカル開発
メールを送信するアプリケーションを開発する場合、実際にはライブメールアドレスにメールを送信したくない場合があります。Laravelは、ローカル開発中にメールの実際の送信を「無効にする」ためのいくつかの方法を提供しています。
ログドライバー
`log`メールドライバーは、メールを送信する代わりに、すべてのメールメッセージをログファイルに書き込んで検査します。通常、このドライバーはローカル開発中にのみ使用されます。環境ごとのアプリケーションの設定の詳細については、設定ドキュメントを確認してください。
HELO / Mailtrap / Mailpit
または、HELOやMailtrapなどのサービスと`smtp`ドライバーを使用して、メールメッセージを「ダミー」メールボックスに送信し、そこで実際のメールクライアントで表示できます。このアプローチには、Mailtrapのメッセージビューアーで最終的なメールを実際に検査できるという利点があります。
Laravel Sailを使用している場合は、Mailpitを使用してメッセージをプレビューできます。Sailの実行中は、`http://localhost:8025`でMailpitインターフェースにアクセスできます。
グローバルな`to`アドレスの使用
最後に、`Mail`ファサードが提供する`alwaysTo`メソッドを呼び出すことにより、グローバルな「宛先」アドレスを指定できます。通常、このメソッドは、アプリケーションのサービスプロバイダーの1つの`boot`メソッドから呼び出す必要があります。
use Illuminate\Support\Facades\Mail; /** * Bootstrap any application services. */public function boot(): void{ if ($this->app->environment('local')) { }}
イベント
Laravelは、メールメッセージの送信中に2つのイベントをディスパッチします。`MessageSending`イベントはメッセージが送信される前にディスパッチされ、`MessageSent`イベントはメッセージが送信された後にディスパッチされます。これらのイベントは、メールがキューに入れられたときではなく、_送信_されているときにディスパッチされることに注意してください。アプリケーション内でこれらのイベントのイベントリスナーを作成できます。
use Illuminate\Mail\Events\MessageSending;// use Illuminate\Mail\Events\MessageSent; class LogMessage{ /** * Handle the given event. */ public function handle(MessageSending $event): void { // ... }}
カスタムトランスポート
Laravelにはさまざまなメールトランスポートが含まれています。ただし、Laravelが標準でサポートしていない他のサービスを介してメールを配信するために、独自のトランスポートを作成することができます。開始するには、`Symfony\Component\Mailer\Transport\AbstractTransport`クラスを拡張するクラスを定義します。次に、トランスポートに`doSend`および`__toString()`メソッドを実装します。
use MailchimpTransactional\ApiClient;use Symfony\Component\Mailer\SentMessage;use Symfony\Component\Mailer\Transport\AbstractTransport;use Symfony\Component\Mime\Address;use Symfony\Component\Mime\MessageConverter; class MailchimpTransport extends AbstractTransport{ /** * Create a new Mailchimp transport instance. */ public function __construct( protected ApiClient $client, ) { parent::__construct(); } /** * {@inheritDoc} */ protected function doSend(SentMessage $message): void { $email = MessageConverter::toEmail($message->getOriginalMessage()); $this->client->messages->send(['message' => [ 'from_email' => $email->getFrom(), 'to' => collect($email->getTo())->map(function (Address $email) { return ['email' => $email->getAddress(), 'type' => 'to']; })->all(), 'subject' => $email->getSubject(), 'text' => $email->getTextBody(), ]]); } /** * Get the string representation of the transport. */ public function __toString(): string { return 'mailchimp'; }}
カスタムトランスポートを定義したら、`Mail`ファサードによって提供される`extend`メソッドを介して登録できます。通常、これはアプリケーションの`AppServiceProvider`サービスプロバイダーの`boot`メソッド内で行う必要があります。`$config`引数が`extend`メソッドに提供されたクロージャに渡されます。この引数には、アプリケーションの`config/mail.php`設定ファイルでメーラー用に定義された設定配列が含まれます。
use App\Mail\MailchimpTransport;use Illuminate\Support\Facades\Mail; /** * Bootstrap any application services. */public function boot(): void{ Mail::extend('mailchimp', function (array $config = []) { return new MailchimpTransport(/* ... */); });}
カスタムトランスポートが定義および登録されると、アプリケーションの`config/mail.php`設定ファイル内に、新しいトランスポートを利用するメーラー定義を作成できます。
'mailchimp' => [ 'transport' => 'mailchimp', // ...],
追加のSymfonyトランスポート
Laravelは、MailgunやPostmarkなど、Symfonyがメンテナンスしている既存のメールトランスポートのサポートを含んでいます。ただし、Symfonyがメンテナンスしている追加のトランスポートのサポートをLaravelに拡張したい場合があります。必要なSymfonyメーラーをComposer経由で要求し、Laravelにトランスポートを登録することで、これを行うことができます。たとえば、「Brevo」(旧「Sendinblue」)Symfonyメーラーをインストールして登録できます。
composer require symfony/brevo-mailer symfony/http-client
Brevoメーラーパッケージがインストールされたら、アプリケーションの`services`設定ファイルにBrevo API資格情報のエントリを追加できます。
'brevo' => [ 'key' => 'your-api-key',],
次に、`Mail`ファサードの`extend`メソッドを使用して、Laravelにトランスポートを登録できます。通常、これはサービスプロバイダーの`boot`メソッド内で行う必要があります。
use Illuminate\Support\Facades\Mail;use Symfony\Component\Mailer\Bridge\Brevo\Transport\BrevoTransportFactory;use Symfony\Component\Mailer\Transport\Dsn; /** * Bootstrap any application services. */public function boot(): void{ Mail::extend('brevo', function () { return (new BrevoTransportFactory)->create( new Dsn( 'brevo+api', 'default', config('services.brevo.key') ) ); });}
トランスポートが登録されると、アプリケーションの`config/mail.php`設定ファイル内に、新しいトランスポートを利用するメーラー定義を作成できます。
'brevo' => [ 'transport' => 'brevo', // ...],