サイトアイコン Mailtrap

【徹底解説】Laravelのメール送信:SMTP & API 完全ガイド 

Sending emails in laravel

この記事ではMailtrapを使ってLaravelでメールを送信する手順を、配信到達性に重点を置きながら解説していきます。

Laravel開発者の皆さんは、Laravel公式ドキュメントで主にメールテストのためのソリューションとしてMailtrapが言及されているのをご覧になったかもしれません。でも実はMailtrapプラットフォームは、メール配信API/SMTP機能も備えております。

この記事でご紹介する手順とコードスニペットは、Laravel 9.xおよびそれ以降のバージョンと互換性があります。

メール送信前のLaravelメールサービス設定

Laravelにはローカルやクラウドベースのサービスを通じてメールを送信できる独自のメールサービスがあります。

例えばLaravelとSymfony Mailerの組み合わせを使うと、SMTPやサードパーティ、Sendmail MTA経由でメールを送信するための多数のドライバーを選択できます。

なおsendmailを使ってお使いのWebアプリケーションからメールを送信することも技術的には可能ですが、その場合、メールは迷惑メールとして判定されてしまう可能性が高くなります。

またlog driverを使って外部のSMTPやAPIサービスなしでLaravelからのメール送信も可能ですが、実際にはメールは送信されず、お使いのアプリケーションのファイルにすべてのメールのメッセージが書き込まれるだけです。

Laravelのメールサービスには、以下の機能も備わっています。

Mailable(メイラブル)の生成と書き方

Laravelでメールサービスを設定する際に使う主なツールはconfig.mail.phpファイルです。このファイルにはmailersセクションがあり、そこにはLaravelがサポートする各主要メールドライバー/トランスポートのサンプル設定エントリがあります。

デフォルトでは、当該ファイルの設定方法に基づいて使うサービスが選択されます。つまりこの設定を調整することで、異なるメールの種類に対して異なるメールサービスを選択できます。

さらにLaravelでは、異なるメールの種類を表すための「mailable(メイラブル)」クラスというものがあります。これらはapp/Mailディレクトリに保存されますが、プロジェクト内にすぐには表示されず、最初のmailableクラスを作成すると生成されます。

mailableクラスを作成するためには、下記のArtisanコマンドを使います。(このコマンドはLaravelに含まれています。)

php artisan make:mail MailableName

するとmailableクラスの作成後に、クラスの内容を確認して設定できます。メソッドは次の表の通りです。

メソッド説明
Envelope件名と受信者を定義するIlluminate\Mail\Mailables\Envelopeオブジェクトを返します。
Contentメッセージコンテンツを生成するために使用されるBladeテンプレートを定義するIlluminate\Mail\Mailables\Contentオブジェクトを返します。
Attachments添付ファイルの配列を返します。

送信者の設定

次に、送信者(from メールアドレスと名前)を指定する必要があります。これには以下の方法があります。

use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Envelope;
 
/**
* メッセージのEnvelopeを取得
*
* @return \Illuminate\Mail\Mailables\Envelope
*/
public function envelope()
{
   return new Envelope(
       from: new Address('サンプル@サンプル.com', 'テスト送信者'),
       subject: 'テストメール',
   );
}
'from' => ['address' => 'サンプル@サンプル.com', 'name' => 'アプリ名']

プロからのヒント: グローバルな from アドレスは、すべてのメールで使う場合に便利です。というのも、各mailableクラスで from メソッドを呼び出す手間を省けるからです。さらに、特に他の送信者アドレスを指定しない場合はデフォルトの from アドレスとして機能してくれます。

SMTPを使ってLaravelでメールを送信する

これでLaravelのメールサービスを設定できたので、これからMailtrap メール配信API/SMTPをSMTPサービスプロバイダーとして設定し、mailableクラスを作成してテストを実行する方法をご紹介していきます。

ステップ1. Mailtrap SMTPの認証情報を使ってアプリに統合する

最初に、Mailtrap メール配信API/SMTP が提供するSMTPサーバーの認証情報を自分のウェブアプリケーションの .env に挿入します。

認証情報は、Mailtrapアカウントを作成してログインし、[Sending Domains]セクションに移動してドメインを追加して認証するだけで取得できます。

なお視覚学習者様向けに、簡単な解説動画をご用意しました。

ドメイン認証が済むと、お使いのプロジェクトやアプリ、メール配信サービスにSMTP認証情報を簡単にコピペできるページにMailtrap上で移動できます。

: この章ではTransactional Streamを使っていますが、後でBulk Streamの使用方法も説明いたします。

LaravelコードにSMTP認証情報を統合すると、以下のようになります。

// .env file

MAIL_MAILER=smtp
MAIL_HOST=live.smtp.mailtrap.io
MAIL_PORT=587
MAIL_USERNAME=//ユーザー名
MAIL_PASSWORD=// パスワード
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=送信元アドレス@サンプル.com
MAIL_FROM_NAME=// アプリ名

ステップ2. SMTP設定を確認する

認証情報を挿入し、Laravelプロジェクトからテストメールを送信すると、MailtrapがSMTP設定を確認してくれます。

なおテストメールが正常に送信された場合の応答は以下のようになります。

次に「Verify Setup」をクリックして、確認プロセスを開始します。

ステップ3. Mailtrapのトラッキング設定を有効にする(オプション)

このステップはオプションですが、これを実行するとメールのパフォーマンスをモニタリングできるようになるので、強くお勧めします。

Mailtrapは開封数、クリック数、バウンス数などを追跡できる詳細な分析を提供しており、メールのパフォーマンスをしっかりと監視するのに便利です。

統計を開くと、例えばこのような表示になります。

こちらは統計の概要です。

ステップ4. mailableクラスを作成する

先ほど紹介したmailableクラスについて覚えているでしょうか?これを以下のコマンドで作成します。

php artisan make:mail MyTestEmail

このコマンドを実行すると、「app/mailMyTestEmail.php」にMyTestEmail クラスが表示されます。

クラスのコードは以下の通りです。

<?php

namespace App\Mail;

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

class MyTestEmail extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * メッセージインスタンスの作成
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * メッセージのEnvelopeを取得
     *
     * @return \Illuminate\Mail\Mailables\Envelope
     */

    public function envelope()
    {
        return new Envelope(
            subject: 'テストメール',
        );
    }
 /**
     * メッセージコンテンツの定義を取得
     *
     * @return \Illuminate\Mail\Mailables\Content
     */

    public function content()
    {
        return new Content(
            view: 'view.name',
        );
    }

    /**
     * メッセージの添付ファイルを取得
     *
     * @return array
     */
    public function attachments()
    {
        return [];
    }
}

何か気になる点がありますか?そうです、content() メソッドはビューを返してくれるのです。それではresources/views に移動して、新しいフォルダと blade.php ファイルを作成しましょう。

テキストを入力する準備はできていますか?blade.php ファイル内で以下の通り入力します。

次にcontent() メソッドに戻り、返されたビューの名前を新しく作成したビューの名前に置き換えます。

もしくはwith 属性を使って名前を渡すと、メール template/blade.php ファイルに受信者の名前が含まれるので、少し動的になります。

以下をご確認ください。

<?php

namespace App\Mail;

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

class MyTestEmail extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * メッセージインスタンスの作成
     *
     * @return void
     */
    public function __construct(private $name)
    {
        //
    }

    /**
     * メッセージのEnvelopeを取得
     *
     * @return \Illuminate\Mail\Mailables\Envelope
     */
    public function envelope()
    {
        return new Envelope(
            subject: 'テストメール',
        );
    }

    /**
     * メッセージコンテンツの定義を取得
     *
     * @return \Illuminate\Mail\Mailables\Content
     */
    public function content()
    {
        return new Content(
            view: 'mail.test-email',
            with: ['name' => $this->name],
        );
    }
}

これを機能させるために、test-email.blade.php ビューファイルにも微細な変更を加えました。これにより$name 変数を受け入れるようになります。

// resources/views/mail/test-email.blade.php

こんにちは、{{ $name }}さん, 
Laravelアプリで、すでにメールを送信できますか? 😉 
Mailtrap

最後に、以下のコードを使ってroutes/web.php ファイルにルートを作成しましょう。

<?php

use Illuminate\Support\Facades\Route;
use App\Mail\MyTestEmail;
use Illuminate\Support\Facades\Mail;

Route::get('/testroute', function() {
    $name = "愉快なコーダー";

    // メール送信はMailファサードのtoメソッドを使用して行います
    Mail::to('テスト受信者@gmail.com'')->send(new MyTestEmail($name));
});

ファイルは次のようになります。

いよいよ重要な瞬間です。php artisan serve コマンドを実行してブラウザに移動し、作成したルートを貼り付けてテストします。私が使ったのは localhost:8000/testroute です。

すべてが正しく動作すれば、指定した「to」アドレスの受信箱にメールが届くはずです。

HTMLメールの送信

Laravelの高度なHTMLメールのカスタマイズ設定については、こちらの記事をご覧ください

Laravelで視覚的に魅力的なメールを送信するには、BladeビューにHTMLコードを追加するだけです。記憶にあるかもしれませんが、本記事では test-email.blade.php を使いました。

以下は基本的なHTMLメッセージを送信するためのコードスニペットです。

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <style>
        p {
            font-size: 12px;
        }

        .signature {
            font-style: italic;
        }
    </style>
</head>
<body>
<div>
    <p>こんにちは、{{ $name }}さん,</p>
    <p>お使いのLaravelアプリで、すでにメールを送信できますか? 😉 </p>
    <p class="signature">Mailtrap</p>
</div>
</body>
</html>

複数の受信者にメールを送信する

Laravelで複数の受信者にメールを送信するには、次のコードを使います。

foreach (['First Coder' => '最初の受信者@gmail.com', 'Second Coder' => '二番目の受信者@gmail.com'] as $name => $recipient) {
    Mail::to($recipient)->send(new MyTestEmail($name));
}

このコードは受信者の配列をループして、毎回mailableインスタンスを再生成してくれます。これにより、ループの各繰り返しで前の受信者にもメールが送られてしまう問題を防げます。 🤕

「特定の受信者にのみメールを送信し、他の人をCCやBCCにしたい場合はどうすれば良いのか?」と、読者の皆さんはお思いかもしれません。その場合は次の例を参考に、MyTestEmailクラスで以下のコードをお使いください。

return new Envelope(
    subject: 'テストメール',
    cc: ['テスト受信者-cc@gmail.com'],
    bcc: ['テスト受信者-bcc@gmail.com']
);

添付ファイル付きメールの送信

Laravelでメールに添付ファイルを追加するには、前に示したメール送信用のサンプルコード内の attachments メソッドを修正します。

まず、MyTestEmailクラス内で次のように設定します。

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Queue\SerializesModels;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Mail\Mailables\Attachment;
use Illuminate\Contracts\Queue\ShouldQueue;

class MyTestEmail extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * メッセージインスタンスの作成
     *
     * @return void
     */
    public function __construct(private $name, public $attachedFile){ }

    /**
     * メッセージのEnvelopeを取得
     *
     * @return \Illuminate\Mail\Mailables\Envelope
     */
    public function envelope()
    {
        return new Envelope(
            subject: 'テストメール',
        );
    }

    /**
     * メッセージコンテンツの定義を取得
     *
     * @return \Illuminate\Mail\Mailables\Content
     */
    public function content()
    {
        return new Content(
            view: 'mail.test-email',
            with: ['name' => $this->name],
        );
    }

    /**
     * メッセージの添付ファイルを取得
     *
     * @return array
     */
    public function attachments()
    {
        return [
            Attachment::fromPath($this->attachedFile),
        ];

    }
}

次に、routes/web.php 内の testroute コードで変更を加えます。

<?php

use Illuminate\Support\Facades\Route;
use App\Mail\MyTestEmail;

Route::get('/testroute', function () {

    $filePath = public_path('favicon.ico');

    $name = "愉快なコーダー";

    Mail::to('テスト受信者@gmail.com'')->send(new MyTestEmail($name, $filePath));
});

作業は以上です。このコードを使うと、上記のスニペットにあるようにfavicon.ico というICOファイルが添付されたメールが送信されます。

埋め込み画像付きのメールを送信する

Laravelで埋め込み画像を含むメールを送信するには、Bladeテンプレート内で embed メソッド を使います。embedメソッドを使うと画像をメールコンテンツ内に直接添付できるので、インラインで表示されます。

まず、mailableクラス(この例では MyTestEmail)がビューに必要なデータを渡すことを確認します。画像のためにクラス内で特別な変更を加える必要はありません。

次に、メールのBladeテンプレート内で embedメソッドを使って画像を埋め込みます。例えば、public/images/logo.png に画像があるとします。

// resources/views/mail/test-email.blade.php

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>
    <div>
        <p>こんにちは、{{$name}}さん,</p>
        <p>お使いのLaravelアプリですでにメールを送信できますか? 😉</p>
        <img src="{{ $message->embed(public_path('images/logo.png')) }}" alt="ロゴ">
    </div>
</body>
</html>

このコードのポイントは、以下の行です。

<img src="{{ $message->embed(public_path('images/logo.png')) }}" alt="ロゴ">

これにより、public/images/logo.png にある画像がメールに埋め込まれ、embed メソッドが画像のURLを返します。返された画像は \ タグの src 属性に設定され、メール内でインライン表示されます。

非同期送信のためのメールのキュー処理

非同期でメールを送信するには、Laravelのキューシステム ShouldQueue を使います。

まず mailableクラスが ShouldQueue インターフェースを実装し、Queueable トレイトを使っていることを確認します。

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

class MyTestEmail extends Mailable implements ShouldQueue
{
    use Queueable, SerializesModels;
    // クラスの残りの部分...
}

次にQUEUE_CONNECTION をデータベースやRedis、SQSなどのキュードライバに設定して、.env ファイルでキュードライバを設定します。

最後に、以下のコマンドでメールを送信すると、mailableクラスが ShouldQueue を実装している場合、自動的にキューに追加されます。

Mail::to('テスト受信者@サンプル.com')->send(new MyTestEmail($name));

: キューに入ったジョブを処理するには、ターミナルで php artisan queue:work コマンドを実行してキューワーカーを起動します。

Laravelでの一括(バルク)メール送信

前述のMailtrapのBulk Stream SMTP認証情報について覚えているでしょうか?今回はその認証情報を使って一括メールを送信します。

まずMailtrapアカウントにログインし、「SMTP/API Settings」タブに移動します。画面右側にBulk Streamの認証情報が表示されます。

次に.env ファイルを開いて、これらの認証情報を挿入します。設定ファイルは以下のようになります。

MAIL_MAILER=smtp
MAIL_HOST=bulk.smtp.mailtrap.io
MAIL_PORT=587
MAIL_USERNAME=あなたの_mailtrap_bulk_ユーザーネーム
MAIL_PASSWORD=あなたの_mailtrap_bulk_パスワード
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=送信元@サンプル.com
MAIL_FROM_NAME="アプリケーション名"
あなたの_mailtrap_bulk_ユーザーネームとあなたの_mailtrap_bulk_パスワードを、バルクストリーム用の実際のMailtrap SMTP認証情報に置き換えてください。

もしまだの場合、送信メール用のmailableクラスを生成する必要があります。一括送信する予定のメール用に適宜カスタマイズするのですが、下記をご参照ください。

php artisan make:mail BulkEmail

BulkEmailのmailableクラスを生成したら、メールコンテンツを設定するためのプロパティやメソッドを定義します。なおmailableクラスのコンストラクタでデータを渡し、そのデータをメールビュー内で使うことが可能です。

最後に、受信者をループして、バルク用のSMTP接続を使って個別にメールを送信します。以下の例をご覧ください。

use App\Mail\BulkEmail;
use Illuminate\Support\Facades\Mail;

$users = User::all(); // 例:メールを送りたい全ユーザーを取得

foreach ($users as $user) {
    Mail::to($user->email)->send(new BulkEmail($data));
}

ここでスケーラビリティとパフォーマンスを向上させるために、いくつか考慮すべき点があります。

User::chunk(200, function ($users) use ($data) {
    foreach ($users as $user) {
        Mail::to($user->email)->queue(new BulkEmail($data));
    }
});
class SendBulkEmailJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $user;
    protected $data;

    public function __construct($user, $data)
    {
        $this->user = $user;
        $this->data = $data;
    }

    public function handle()
    {
        Mail::to($this->user->email)->send(new BulkEmail($this->data));
    }
}

// 各ユーザーに対してジョブをディスパッチ
foreach ($users as $user) {
    SendBulkEmailJob::dispatch($user, $data)->onQueue('emails');
}

最後にアプリケーションのログやMailtrapのダッシュボードを確認し、メールが期待通りに処理・送信されていることを確かめましょう。

APIを使ってLaravelでメールを送信する

メール送信プロセスを自動化したい場合、Mailtrap メール配信API/SMTP APIが理想的なソリューションです。

MailtrapのメールAPIをLaravelアプリに統合するのは非常に簡単で、公式PHP SDKLaravelフレームワークブリッジのドキュメントを活用できます。手動で統合コードを書く必要がなくなるので、効率的に統合できます。なおMailtrapライブラリはLaravel 9.x以降に完全に対応しています。

作業を開始するには、以下の手順に従ってください。

composer require railsware/mailtrap-php symfony/http-client nyholm/psr7
<?php

return [
    /*
    |--------------------------------------------------------------------------
    | メーラー設定
    |--------------------------------------------------------------------------
    */
    'mailers' => [
    
            // mailtrapトランスポートの開始
            'mailtrap' => [
                'transport' => 'mailtrap'
            ],
            // mailtrapトランスポートの終了
    
    ]
];
MAIL_MAILER="mailtrap"
MAILTRAP_HOST="send.api.mailtrap.io"
MAILTRAP_API_KEY="ここに_API_KEY_を入力"
MAIL_FROM_ADDRESS=”名前@登録済みの_ドメイン.com”
php artisan make:mail WelcomeMail
<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Attachment;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Mail\Mailables\Headers;
use Illuminate\Queue\SerializesModels;
use Mailtrap\EmailHeader\CategoryHeader;
use Mailtrap\EmailHeader\CustomVariableHeader;
use Symfony\Component\Mime\Email;
use Symfony\Component\Mime\Header\UnstructuredHeader;

class WelcomeMail extends Mailable
{
    use Queueable, SerializesModels;

    private string $name;

    /**
     * メッセージインスタンスの作成
     */
    public function __construct(string $name)
    {
        $this->name = $name;
    }

    /**
     * メッセージのEnvelopeを取得
     */
    public function envelope(): Envelope
    {
        return new Envelope(
            from: new Address('ジェフリー@サンプル.com', 'ジェフリー・ウェイ'),
            replyTo: [
                      new Address('テイラー@サンプル.com', 'テイラー・オットウェル'),
                  ],
            subject: 'ウェルカムメール',
            using: [
                      function (Email $email) {
                          // ヘッダー
                          $email->getHeaders()
                              ->addTextHeader('X-Message-Source', 'サンプル.com')
                              ->add(new UnstructuredHeader('X-Mailer', 'Mailtrap PHP Client'))
                          ;

                          // カスタム変数
                          $email->getHeaders()
                              ->add(new CustomVariableHeader('user_id', '45982'))
                              ->add(new CustomVariableHeader('batch_id', 'PSJ-12'))
                          ;

                          // カテゴリ(1つのみ)
                          $email->getHeaders()
                              ->add(new CategoryHeader('統合テスト'))
                          ;
                      },
                  ]
        );
    }

    /**
     * メッセージコンテンツの定義を取得
     */
    public function content(): Content
    {
        return new Content(
            view: 'mail.welcome-email',
            with: ['name' => $this->name],
        );
    }

    /**
     * メッセージの添付ファイルを取得
     *
     * @return array<int, \Illuminate\Mail\Mailables\Attachment>
     */
    public function attachments(): array
    {
        return [
           Attachment::fromPath('https://mailtrap.io/wp-content/uploads/2021/04/mailtrap-new-logo.svg')
                ->as('logo.svg')
                ->withMime('image/svg+xml'),
        ];
    }

    /**
     * メッセージヘッダーを取得
     */
    public function headers(): Headers
    {
        return new Headers(
            'カスタム-メッセージ-id@サンプル.com',
            ['前の-メッセージ@サンプル.com'],
            [
                'X-Custom-Header' => 'カスタム値',
            ],
        );
    }
}
こんにちは、{{$name}}さん。ようこそ 😉

<br>
愉快なコーダー
<?php

use App\Mail\WelcomeMail;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Mail;

/*
|--------------------------------------------------------------------------
| コンソールルート
|--------------------------------------------------------------------------
|
*/

Artisan::command('send-welcome-mail', function () {
    Mail::to('テスト受信者@gmail.com')->send(new WelcomeMail("ジョン"));
    // デフォルトのメーラーが"mailtrap"でない場合、特定のメーラーを使っ送信できますが、ウェルカムメールではMailtrapの利用をお勧めします
    // Mail::mailer('mailtrap')->to('テスト受信者@gmail.com')->send(new WelcomeMail("ジョン"));
})->purpose('ウェルカムメールを送信');
php artisan send-welcome-mail

これで、エラーなしでMailtrapのメールAPIを使ってトランザクションメールを送信できるはずです。

前述のトラッキング設定について覚えていますか?メール配信APIを利用する場合、トラッキング設定を有効にできます。

HTMLメールの送信

LaravelでHTMLメールを送信するには、BladeビューのファイルにHTMLコードを追加するだけです。なお、このチュートリアルでは test-email.blade.php ファイルを使っています。

以下は、プレーンテキストメールをHTML形式にしたコード例です。

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <style>
        p {
            font-size: 12px;
        }

        .signature {
            font-style: italic;
        }
    </style>
</head>
<body>
<div>
    <p>こんにちは、{{ $name }}さん,</p>
    <p>お使いのLaravelアプリで、すでにメールを送信できますか? 😉 </p>
    <p class="signature">Mailtrap</p>
</div>
</body>
</html>

複数の受信者にメールを送信する

Laravelでは、以下のコードを使うと複数の受信者にメールを送信できます。

foreach (['First Coder' => '最初の-受信@gmail.com', 'Second Coder' => '二番目の-受信者@gmail.com'] as $name => $recipient) {
    Mail::to($recipient)->send(new MyTestEmail($name));
}

一人の受信者宛にメールを宛てて、他の受信者は「cc」や「bcc」で追加したい場合は、MyTestEmail クラス内で以下のコードを使います。

return new Envelope(
    subject: 'テストメール',
    cc: ['テスト受信者-cc@gmail.com'],
    bcc: ['テスト受信者-bcc@gmail.com']
);

添付ファイル付きのメールを送信する

SMTPと同様に、attachments メソッドを修正してメールに添付ファイルを追加します。

まず、MyTestEmail クラスで次のように設定します。

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Queue\SerializesModels;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Mail\Mailables\Attachment;
use Illuminate\Contracts\Queue\ShouldQueue;

class MyTestEmail extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * メッセージインスタンスの作成
     *
     * @return void
     */
    public function __construct(private $name, public $attachedFile){ }

    /**
     * メッセージのEnvelopeを取得
     *
     * @return \Illuminate\Mail\Mailables\Envelope
     */
    public function envelope()
    {
        return new Envelope(
            subject: 'テストメール',
        );
    }

    /**
     * メッセージコンテンツの定義を取得
     *
     * @return \Illuminate\Mail\Mailables\Content
     */
    public function content()
    {
        return new Content(
            view: 'mail.test-email',
            with: ['name' => $this->name],
        );
    }

    /**
     * メッセージの添付ファイルを取得
     *
     * @return array
     */
    public function attachments()
    {
        return [
            Attachment::fromPath($this->attachedFile),
        ];

    }
}

次に、routes/web.php 内の testroute コードに変更を加えます。

<?php

use Illuminate\Support\Facades\Route;
use App\Mail\MyTestEmail;

Route::get('/testroute', function () {

    $filePath = public_path('favicon.ico');

    $name = "愉快なコーダー";

    Mail::to(''テスト受信者@gmail.com'')->send(new MyTestEmail($name, $filePath));
});

SMTPと同様に、上記のコードを使うと、favicon.ico というICOファイルが添付されたメールが送信されます。

埋め込み画像付きのメールを送信する

Laravelで埋め込み画像を含むメールを送信するには、Bladeテンプレート内で embed メソッド を使います。例えば、画像が public/images/logo.png に保存されているとします。

その場合、以下のコードをご参照ください。

// resources/views/mail/test-email.blade.php

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>
    <div>
        <p>こんにちは、{{$name}}さん,</p>
        <p>お使いのLaravelアプリで、すでにメールを送信できますか? 😉</p>
        <img src="{{ $message->embed(public_path('images/logo.png')) }}" alt="ロゴ">
    </div>
</body>
</html>

非同期送信のためのメールのキュー処理

SMTP と同様に、非同期でメールを送信するには Laravel のキューシステム ShouldQueue を使います。

まず mailableクラスが ShouldQueue インターフェースを実装し、Queueable トレイトを使っていることを確認します。

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

class MyTestEmail extends Mailable implements ShouldQueue
{
    use Queueable, SerializesModels;
    // クラスの残りの部分...
}

次にQUEUE_CONNECTION をデータベース、Redis、SQSなどのキュードライバに設定して、.env ファイルのキュードライバを設定します。

最後に、次のコマンドでメールを送信します。

Mail::to('テスト受信者@サンプル.com')->send(new MyTestEmail($name));

: キューに入ったジョブを処理するには、ターミナルで php artisan queue:work コマンドを実行してキューワーカーを起動します。

一括メール送信

一括メールを送信するには、まずMailtrapアカウントにログインし、「SMTP/API Settings」タブに移動して、Bulk Streamの認証情報を確認します。

次に.env ファイルに、これらの認証情報を挿入します。この際、必ずBulk Streamを選択してください。

以下のように.env ファイルにBulk Stream認証情報を入力します。

MAIL_MAILER="mailtrap"
MAILTRAP_HOST="bulk.smtp.mailtrap.io"
MAILTRAP_API_KEY="ここに_BULK_STREAM_API_KEY_を入力"

認証情報を入力したら、送信メール用のmailableクラスを生成します。

php artisan make:mail BulkEmail

次の作業は、3つのやり方があります。

比較的少数の一括メールを送信する場合は次のように受信者をループして、個別にメールを送信します。

use App\Mail\BulkEmail;
use Illuminate\Support\Facades\Mail;

$users = User::all(); // 例:メールを送りたい全ユーザーを取得

foreach ($users as $user) {
    Mail::to($user->email)->send(new BulkEmail($data));
}

非常に大規模なバルク送信をする場合はチャンクメソッドを使い、ユーザーを小さなバッチに分割します。

下記をご参照ください。

User::chunk(200, function ($users) use ($data) {
    foreach ($users as $user) {
        Mail::to($user->email)->queue(new BulkEmail($data));
    }
});

大規模なバルクメール送信の際にアプリケーションが他のリクエストも処理できるようにするには、メールごとにジョブをディスパッチします。

class SendBulkEmailJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $user;
    protected $data;

    public function __construct($user, $data)
    {
        $this->user = $user;
        $this->data = $data;
    }

    public function handle()
    {
        Mail::to($this->user->email)->send(new BulkEmail($this->data));
    }
}

// 各ユーザーに対してジョブをディスパッチ
foreach ($users as $user) {
    SendBulkEmailJob::dispatch($user, $data)->onQueue('emails');
}

どの一括送信方法を選ぶにしても、アプリケーションのログとMailtrapのダッシュボードを監視して、メールが処理・送信されていることを必ず確認しましょう。

さらに多くの受信者にメールを送信する場合は、送信速度を制限したり、メール間に遅延を設けたりすることをご検討ください。

テストメールとメール送信:メールテストをすべき理由とやり方の解説

せっかくこれらのコードを書いたので、ブロックリストに載ったドメインからメールが送信されてしまう、迷惑メールとして判定される、あるいはHTMLテンプレートが特定のブラウザで正しく表示されないという状況は避けたいものです。そのため、実際にメールを送信する前にLarevelでメールをテストすることをオススメします。

ご自身の受信箱やログドライバを使ってのテストも技術的には可能です。でもドメインの評価が損なわれたり、受信箱が不要なメールで溢れてしまったりすることを避けるためにも、Mailtrapのメール送信テストを活用すると便利です。

なおMailtrapは、Laravelの公式ドキュメントでもサポートされています。

Mailtrapのメール送信テストプラットフォームには安全にメールテストを実施するための多くの機能が備わっており、テストに関する多数の問題を解決できます。

サンドボックスのセキュアな環境でテストメールをキャッチし、プレビューできるだけでなく、送信前のメールのスパムスコア確認や、HTML/CSSの分析なども行えます。

つまりMailtrapのメール送信テストを使うと、メールがスパムフォルダに入ってしまうのを防げて、適切な場所とタイミングで確実にメールを届けられます。

またテストプロセスをチームメンバーと簡単に共有でき、新しいプロジェクトを作成して複数のオブジェクトを追加できるというのも、Mailtrapのメール送信テストの利点です。

満足のいく結果が得られた後で、メールを手動または自動で実際のアドレスに転送することも可能です。

つまりここでのポイントは、Mailtrapのメールテストは非常に簡単にできるということです。

SMTP

Mailtrapでメールをテストするには、無料のMailtrapアカウントを作成するだけで、MailtrapのEmail Delivery Platform全体を利用できるようになります。つまりメール送信テストとメール配信API/SMTPの両方が利用可能になります。

アカウントを作成してログインしたら、以下の手順に従ってください。

MAIL_MAILER=smtp
MAIL_HOST=sandbox.smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=07f4dbf61b8122
MAIL_PASSWORD=d7fc5d57bc6eac
MAIL_ENCRYPTION=tls

これで準備完了です。以下のコードで最初のテストメールを送信できます。

<?php
use App\Mail\JustTesting;
use Illuminate\Support\Facades\Mail;
Route::get('/send-mail', function () {
    Mail::to('新規ユーザー@サンプル.com')->send(new JustTesting());
    return 'Mailtrapにメールが送信されました!';
});

プロからのヒント: 必ずLaravel 5.8またはそれ以降のバージョンをお使いになり、routes/web.php ファイルにルートが指定されていることをご確認ください。

テストメールを送信するには、アプリケーションを起動してブラウザで /send-mail パスにアクセスします。すると、 Email TestingInboxes でメールが確認できるはずです。

API

お使いのアプリにメール送信テストを統合し、Testing APIを使ってテスト、自動化、自動シーケンスのテストを行うこともできます。

その場合は、お使いのHTTPクライアントに応じて、次のコマンドのいずれかを実行してください。

# symfony httpクライアントの場合(推奨)
composer require railsware/mailtrap-php symfony/http-client nyholm/psr7

# guzzle httpクライアントの場合
composer require railsware/mailtrap-php guzzlehttp/guzzle php-http/guzzle7-adapter

次に、 config.mail.php ファイルにMailtrapトランスポートを追加します。

<?php

return [
    /*
    |--------------------------------------------------------------------------
    | メーラー設定
    |--------------------------------------------------------------------------
    */
    'mailers' => [
    
            // mailtrapトランスポートの開始
            'mailtrap' => [
                'transport' => 'mailtrap'
            ],
            // mailtrapトランスポートの終了
    
    ]
]

その後、APIキーを MAILTRAP_API_KEY 変数に設定し、受信箱IDを MAILTRAP_INBOX_ID に設定します。

MAIL_MAILER="mailtrap"

MAILTRAP_HOST="sandbox.api.mailtrap.io"
MAILTRAP_API_KEY="ここに_API_KEY_を入力"
MAILTRAP_INBOX_ID=1000001

:

php artisan config:clear

最初のテストメールを送信するには、メール送信の場合と同様にmailableクラスを生成します。

php artisan make:mail WelcomeMail

mailableクラスを作成したら、メールを設定できます。以下の例をご参照ください。

# app/Mail/WelcomeMail.php
<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Attachment;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Mail\Mailables\Headers;
use Illuminate\Queue\SerializesModels;
use Mailtrap\EmailHeader\CategoryHeader;
use Mailtrap\EmailHeader\CustomVariableHeader;
use Symfony\Component\Mime\Email;
use Symfony\Component\Mime\Header\UnstructuredHeader;

class WelcomeMail extends Mailable
{
    use Queueable, SerializesModels;

    private string $name;

    /**
     * メッセージインスタンスの作成
     */
    public function __construct(string $name)
    {
        $this->name = $name;
    }

    /**
     * メッセージのEnvelopeを取得
     */
    public function envelope(): Envelope
    {
        return new Envelope(
            from: new Address('ジェフリー@サンプル.com', 'ジェフリー・ウェイ'),
            replyTo: [
                      new Address('テイラー@サンプル.com', 'テイラー・オットウェル'),
                  ],
            subject: 'ウェルカムメール',
            using: [
                      function (Email $email) {
                          // ヘッダー
                          $email->getHeaders()
                              ->addTextHeader('X-Message-Source', 'サンプル.com')
                              ->add(new UnstructuredHeader('X-Mailer', 'Mailtrap PHP Client'))
                          ;

                          // カスタム変数
                          $email->getHeaders()
                              ->add(new CustomVariableHeader('user_id', '45982'))
                              ->add(new CustomVariableHeader('batch_id', 'PSJ-12'))
                          ;

                          // カテゴリ(1つのみ)
                          $email->getHeaders()
                              ->add(new CategoryHeader('統合テスト'))
                          ;
                      },
                  ]
        );
    }

    /**
     * メッセージコンテンツの定義を取得
     */
    public function content(): Content
    {
        return new Content(
            view: 'mail.welcome-email',
            with: ['name' => $this->name],
        );
    }

    /**
     * メッセージの添付ファイルを取得
     *
     * @return array<int, \Illuminate\Mail\Mailables\Attachment>
     */
    public function attachments(): array
    {
        return [
            Attachment::fromPath('https://mailtrap.io/wp-content/uploads/2021/04/mailtrap-new-logo.svg')
                ->as('logo.svg')
                ->withMime('image/svg+xml'),
        ];
    }

    /**
     * メッセージヘッダーを取得
     */
    public function headers(): Headers
    {
        return new Headers(
            'カスタム-メッセージ-id@サンプル.com',
            ['前の-メッセージ@サンプル.com'],
            [
                'X-Custom-Header' => 'カスタム値',
            ],
        );
    }
}

さらに、メールテンプレートの利用も可能です。

# resources/views/mail/welcome-email.blade.php

こんにちは、{{$name}}さん、ようこそこちらへ 😉

<br>
愉快なコーダー

次にCLIルーターを追加します。

# app/routes/console.php
<?php

use App\Mail\WelcomeMail;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Mail;

/*
|--------------------------------------------------------------------------
| コンソールルート
|--------------------------------------------------------------------------
|
*/

Artisan::command('send-welcome-mail', function () {
    Mail::to('テスト受信者@gmail.com')->send(new WelcomeMail("ジョン"));
    // デフォルトのメーラーが"mailtrap"でない場合、特定のメーラーを使っ送信できますが、ウェルカムメールではMailtrapの利用をお勧めします
    // Mail::mailer('mailtrap')->to('テスト受信者@gmail.com')->send(new WelcomeMail("ジョン"));
})->purpose('ウェルカムメールを送信');

この後、次のCLIコマンドでメールを送信します。

php artisan send-welcome-mail

Mailtrap APIに関する追加情報については、公式ドキュメントをご覧ください。

まとめ

以上で、Laravelのメール送信のやり方の解説は終了です。

本記事ではLaravelの設定からSMTP経由やAPI経由のメール送信まで、幅広く説明いたしました。どのオプションを選ぶ場合でも、このガイドで手順を確認いただけます。

Laravelについてもっとお知りになりたい方は、公式ドキュメントをぜびご覧ください。Laravelのメール送信についての役立つコンテンツは、Mailtrapブログでもお読みいただけます。ちなみに以下のような記事をご用意しております。

またMailtrapのYouTubeチャンネルでも、Laravelに関連する動画をご覧いただけます。

モバイルバージョンを終了