Introduction

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

Configuration

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

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

Driver / Transport Prerequisites

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

Mailgun Driver

Mailgunドライバーを使用するには、Composerを介してSymfonyのMailgun Mailerトランスポートをインストールします:

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

次に、アプリケーションの config/mail.php 設定ファイル内で default オプションを 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 Driver

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

  1. composer 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 Driver

Resend ドライバーを使用するには、Composerを介してResendのPHP SDKをインストールします:

  1. composer require resend/resend-php

次に、アプリケーションの config/mail.php 設定ファイル内で default オプションを resend に設定します。アプリケーションのデフォルトのメール送信者を構成した後、config/services.php 設定ファイルに次のオプションが含まれていることを確認します:

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

SES Driver

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

  1. composer 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. */
  4. public 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 Driver

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

  1. composer require mailersend/laravel-driver

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

  1. MAIL_MAILER=mailersend
  2. MAIL_FROM_ADDRESS=
  3. MAIL_FROM_NAME="App Name"
  4. MAILERSEND_API_KEY=your-api-key

最後に、アプリケーションの config/mail.php 設定ファイルの mailers 配列にMailerSendを追加します:

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

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

Failover Configuration

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

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

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

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

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

Round Robin Configuration

roundrobin トランスポートを使用すると、複数のメール送信者にメールの作業負荷を分散できます。始めるには、アプリケーションの mail 設定ファイル内で roundrobin トランスポートを使用するメール送信者を定義します。アプリケーションの roundrobin メール送信者の設定配列には、配信に使用される構成されたメール送信者を参照する mailers の配列が含まれている必要があります:

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

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

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

ラウンドロビントランスポートは、構成されたメール送信者のリストからランダムなメール送信者を選択し、次のメールごとに次の利用可能なメール送信者に切り替えます。 高可用性 を達成するのに役立つ failover トランスポートとは対照的に、roundrobin トランスポートは 負荷分散 を提供します。

Generating Mailables

Laravelアプリケーションを構築する際、アプリケーションによって送信される各タイプのメールは「マイベール」クラスとして表されます。これらのクラスは app/Mail ディレクトリに保存されます。このディレクトリがアプリケーションに表示されない場合でも心配しないでください。最初のマイベールクラスを make:mail Artisanコマンドを使用して作成すると、自動的に生成されます:

  1. php artisan make:mail OrderShipped

Writing Mailables

マイベールクラスを生成したら、それを開いて内容を探求しましょう。マイベールクラスの設定は、envelopecontent、および attachments メソッドを含むいくつかのメソッドで行われます。

envelope メソッドは、メッセージの件名と、場合によっては受信者を定義する Illuminate\Mail\Mailables\Envelope オブジェクトを返します。content メソッドは、メッセージ内容を生成するために使用される Illuminate\Mail\Mailables\Content オブジェクトを返します。

Configuring the Sender

Using the Envelope

まず、メールの送信者を構成する方法を探求しましょう。つまり、メールが「送信元」として誰になるかです。送信者を構成する方法は2つあります。まず、メッセージの封筒で「送信元」アドレスを指定できます:

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

必要に応じて、replyTo アドレスを指定することもできます:

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

Using a Global from Address

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

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

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

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

Configuring the View

マイベールクラスの content メソッド内で、メールの内容をレンダリングする際に使用する view を定義できます。各メールは通常、内容をレンダリングするために Bladeテンプレート を使用するため、メールのHTMLを構築する際にBladeテンプレートエンジンの完全な力と便利さを利用できます:

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

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

Plain Text Emails

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

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

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

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

View Data

Via Public Properties

通常、メールのHTMLをレンダリングする際に利用できるデータをビューに渡したいと思います。ビューにデータを利用可能にする方法は2つあります。まず、マイベールクラスで定義された任意のパブリックプロパティは、自動的にビューに利用可能になります。たとえば、マイベールクラスのコンストラクタにデータを渡し、そのデータをクラスで定義されたパブリックプロパティに設定できます:

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

データがパブリックプロパティに設定されると、それは自動的にビューで利用可能になり、Bladeテンプレート内の他のデータにアクセスするのと同様にアクセスできます:

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

Via the with Parameter:

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

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

データが with メソッドに渡されると、それは自動的にビューで利用可能になり、Bladeテンプレート内の他のデータにアクセスするのと同様にアクセスできます:

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

Attachments

メールに添付ファイルを追加するには、メッセージの attachments メソッドによって返される配列に添付ファイルを追加します。まず、fromPath メソッドを使用してファイルパスを提供することで添付ファイルを追加できます:

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

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

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

Attaching Files From Disk

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

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

Raw Data Attachments

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

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

Inline Attachments

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

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

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

Embedding Raw Data Attachments

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

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

Attachable Objects

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

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

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

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

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

もちろん、添付データはAmazon S3などのリモートファイルストレージサービスに保存される場合があります。したがって、Laravelは、アプリケーションの ファイルシステムディスク の1つに保存されているデータから添付インスタンスを生成することも許可します:

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

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

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

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

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

Headers

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

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

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

Tags and Metadata

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

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

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

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

Customizing the Symfony Message

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

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

Markdown Mailables

Markdownマイベールメッセージを使用すると、マイベール内の メール通知 の事前構築されたテンプレートとコンポーネントを活用できます。メッセージはMarkdownで書かれているため、Laravelはメッセージの美しいレスポンシブHTMLテンプレートをレンダリングでき、プレーンテキストの対応物も自動的に生成されます。

Generating Markdown Mailables

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

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

次に、マイベール Content 定義を content メソッド内で構成する際に、markdown パラメータを view パラメータの代わりに使用します:

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

Writing Markdown Messages

Markdownマイベールは、BladeコンポーネントとMarkdown構文の組み合わせを使用して、メールメッセージを簡単に構築し、Laravelの事前構築されたメールUIコンポーネントを活用できます:

  1. x-mail::message
  2. # Order Shipped
  3. ご注文が発送されました!
  4. x-mail::button :url="$url"
  5. 注文を表示
  6. ⟨/x-mail::button
  7. ありがとうございます、⟨br
  8. {{ config('app.name') }}
  9. ⟨/x-mail::message

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

Button Component

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

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

Panel Component

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

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

Table Component

テーブルコンポーネントを使用すると、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>

Customizing the Components

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

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

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

Customizing the CSS

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

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

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

Sending Mail

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

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

メッセージを送信する際に「宛先」受信者を指定するだけではありません。「宛先」、「CC」、および「BCC」受信者をそれぞれのメソッドを連鎖させて設定することができます:

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

Looping Over Recipients

時には、受信者の配列/メールアドレスのリストに対してマイベールを送信する必要がある場合があります。ただし、to メソッドは、メール送信者の受信者リストにメールアドレスを追加するため、ループを通じて各反復で以前の受信者全員に別のメールが送信されます。したがって、各受信者のためにマイベールインスタンスを再作成する必要があります:

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

Sending Mail via a Specific Mailer

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

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

Queueing Mail

Queueing a Mail Message

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

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

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

Delayed Message Queueing

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

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

Pushing to Specific Queues

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

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

Queueing by Default

常にキューに入れたいマイベールクラスがある場合は、そのクラスに ShouldQueue コントラクトを実装できます。これにより、メール送信時に send メソッドを呼び出しても、マイベールは依然としてキューに入れられます。

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

Queued Mailables and Database Transactions

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

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

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

または、マイベールのコンストラクタから afterCommit メソッドを呼び出すこともできます:

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

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

メールのレンダリング

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

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

ブラウザでのメールのプレビュー

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

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

メールのローカライズ

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

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

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

ユーザーの好みのロケール

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

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

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

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

テスト

メールのコンテンツのテスト

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

予想通り、”HTML”アサーションは、メールのHTMLバージョンが指定された文字列を含んでいることを確認し、”text”アサーションは、メールのプレーンテキストバージョンが指定された文字列を含んでいることを確認します:

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

メールの送信のテスト

メールのコンテンツを、特定のユーザーに”送信された”ということを主張するテストとは別にテストすることをお勧めします。通常、メールのコンテンツはテストしているコードに関連しないため、Laravelに特定のメールを送信するよう指示されたことを主張するだけで十分です。

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

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

  1. Mail::assertQueued(OrderShipped::class);
  2. Mail::assertNotQueued(OrderShipped::class);
  3. Mail::assertNothingQueued();
  4. Mail::assertQueuedCount(3);
  1. ``````php
  2. Mail::assertSent(function (OrderShipped $mail) use ($order) {
  3. return $mail->order->id === $order->id;
  4. });
  5. `
  1. ``````php
  2. Mail::assertSent(OrderShipped::class, function (OrderShipped $mail) use ($user) {
  3. return $mail->hasTo($user->email) &&
  4. $mail->hasCc('...') &&
  5. $mail->hasBcc('...') &&
  6. $mail->hasReplyTo('...') &&
  7. $mail->hasFrom('...') &&
  8. $mail->hasSubject('...');
  9. });
  10. `

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

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

メールが送信されなかったことを主張するための2つのメソッド、assertNotSentassertNotQueuedがあることに気付いたかもしれません。時には、送信されなかったまたはキューに入れられなかったことを主張したい場合があります。これを実現するために、assertNothingOutgoingassertNotOutgoingメソッドを使用できます:

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

メールとローカル開発

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

ログドライバー

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

HELO / Mailtrap / Mailpit

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

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

グローバル宛先の使用

最後に、alwaysToメソッドを呼び出すことで、グローバル”to”アドレスを指定できます。このメソッドは、アプリケーションのサービスプロバイダーのbootメソッドから呼び出すべきです:

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

イベント

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

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

カスタムトランスポート

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

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

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

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

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

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

追加のSymfonyトランスポート

Laravelは、MailgunやPostmarkなどの既存のSymfonyメンテナンスメールトランスポートをサポートしています。ただし、追加のSymfonyメンテナンストランスポートをサポートするためにLaravelを拡張したい場合があります。その場合、Composerを介して必要なSymfonyメール送信者を要求し、Laravelにトランスポートを登録できます。たとえば、”Brevo”(以前の”Sendinblue”)Symfonyメール送信者をインストールして登録できます:

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

Brevoメール送信者パッケージがインストールされたら、アプリケーションのservices構成ファイルにBrevo API資格情報のエントリを追加できます:

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

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

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

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

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