これでLaravelメール送信が完全にわかる

これからLaravelを使用してメールを送信したいという入門者を対象にできるだけ詳細にLaravelでのメール送信設定の解説を行っています。Laravelのバージョンによりメールに関する環境変数やコントローラーの記述方法が異なる箇所があるのでその場合は都度各バージョンでの記述方法を記載していきます。メールに関するコア部分は変わっていないのでバージョンの変更による影響はほとんどありません。
本文書の内容については現行のLaravel8.xでも動作を確認しています。
シンプルな方法でのメール送信
Laravel 5.3以降に追加されたMailableクラスを使った方法しか最近のバージョンのマニュアルは記載がないので、最初はLaravel5.2のマニュアルを参考にシンプルな形でメールの送信確認を行います。

コントローラーの作成
メール送信の動作確認を行うためにweb.phpに新たにルーティング/mailを追加します 。/mailにアクセスがあった場合の処理はMailSendController.phpコントローラーに記述し、MailSendController.phpはphp artisanコマンドで作成します。
Laravel8.Xの場合
作成したMailSendController.phpに下記を記述します。メールアドレスabc987@example.comの宛先にメールタイトルがThis is a test mailのメールを送信する設定を行なっています。
Mailファサードについて
Mailファサードのsendメソッドは下記のように3つの引数を取ることができます。
- view_nameは、メールの本文の内容を記述するビューの名前です。htmlタグが使えます。
- dataはビューに渡す変数です。
- callbackはメッセージインスタンスを受け取るクロージャ(関数)です。メッセージインスタンスはto, from, cc, subjectなどのメソッドを持っています。詳しくはメッセージインスタンスのマニュアルを確認してください。
toにはメールの送信先、subjectにはメールの件名を設定しています。
resourceの下にviews/emailsディレクトリ、その下にtest.blade.phpファイルを作成してメールの本文の内容を記述します。
送信内容をログへ書き出し
メールの送信設定(サーバやメールアカウント)を行わなければいけませんが、サーバからのメール送信になると不安になる人もいると思うので、まずはLaravelのログにメール内容を表示させる設定を行います。Laravelの環境設定ファイルである.envファイルを開いてMAIL_DRIVERをデフォルトのsmtpからlogに変更してください。

設定は完了したのでphp artisan serveで開発用サーバを起動します。

サーバが起動したら、/mailにアクセスしてください。そのあと画面に何も表示されなければ/storage/logsの下にあるlaravel-日付.logファイルを開いてください。

laravel-日付.logファイルに下記のように送信されたメールの内容が表示されているか確認してください。FromのExample<hello@example.com>以外は設定した内容になっていることが確認できます。
その他に送信するメールのContent-Typeからhtmlメールであることと文字コードはutf-8であることがわかります。
実際のメールサーバを利用した送信
ログへのメール内容の書き出しが正常に行われることが確認できたので、実際にメールを送信します。送信するメールサーバ、ユーザアカウント、パスワードの情報が必要になります。メールの設定情報は各自の環境によって異なるため、会社であれば管理者に確認を行う必要があります。それらの情報を.envファイルのメール関連のパラメータを使って設定します。設定が反映されない場合は、configのキャッシュを一度削除するためphp artisan config:cacheを実行してください。
動作確認を行うサーバなどの環境がない、社内のアカウントでテストは行えないなどの制約がある場合はダミーのSMTPサーバを利用して動作確認を行うことができます。
.envファイル設定後、MailSendControllerに設定したtoのメールアドレスも実在するメールアドレスに変更を行なってください。

上記までの設定を完了させ、ブラウザから/mailにアクセスするとtoで設定したメールアドレスに向けてメールが送信されます。メールが受信できているか確認を行なってください。
メールの送信元のFromがhello@example.comになっているので、Fromを正しいメールアドレスにするためにはMailSendCotroller.phpにfromメソッドを追加する必要があります。再度メールを送信するとFromも設定値が反映されていることを確認することができます。
Fromのデフォルト値はconfig/mail.phpに記述されています。.envにMAIL_FROM_ADDRESSとMAIL_FROM_NAMEを追加し指定することでFromのメールアドレスを固定することができます。
Gmailを利用したメール送信
Gmailのsmtpを利用してLaravelからメールを送信することができます。

安全性の低いアプリのアクセス許可による送信
.envファイルをGmailのアカウント情報に変更する必要があります。MAIL_USERNAMEとMAIL_PASSWORDは各自のGmailアカウントの情報となります。
上記の設定でメールの送信を行うとエラーが発生し、Googleアカウントのメールボックスには重大なセキュリティ通知という件名で下記のようなメールが届きます。Laravel側にもエラーが発生しており、メール送信は失敗しています。
ログインのブロックつまり、smtp経由で設定した情報でログインを試みようとしていますが、ログインする前にGmailによりログインがはじかれています。

”アクティビティを確認”をクリックして、はい、心当たりがありますをクリックしておきます。Laravelで接続設定をしただけでは不審なアプリと判断され、ログインが許可されません。許可を与えるためにセキュリティの設定を変更する必要があります。

Gmailのセキュリティ設定
Gmailのアカウントの設定からセキュリティを選択し、安全性の低いアプリのアクセスの設定画面を開きます。デフォルトではオフになっているので、オンにする必要があります。アクセスを有効にする(非推奨)をクリックしてください。


ONにするとGmailに先ほどと同じように重大なセキュリティ通知メールが届きます。内容は、安全性の低いアプリのアクセスが有効になりましたという設定変更の通知です。”アクティビティを確認”して、”はい、心当たりがあります”を選択してください。
これで安全性の低いアプリのアクセスがONになったので、メールを送信することができます。
テストの動作確認で安全性の低いアプリのアクセスをONにした場合は動作確認完了後、OFFに戻してください。また次の2段階認証設定を利用する場合もこの設定は必要ないので、OFFに戻しておいてください。
2段階認証設定によるメールの送信
Gmailにログインする際の2段階認証の設定を行っていない人は下記のように2段階認証プロセスがオフになっています。

オフの場合は設定をオンにする必要があります。詳しい説明はここでは行いませんが、設定をオンにしてください。頻繁に利用しているGmailアカウントで設定をオンにしていない人はLaravelからメール送信をするしないに関わらずセキュリティのことを考えオンにしておきましょう。設定には電話番号が必要になります。
アプリパスワードの設定
設定が完了すると2段階認証プロセスがオンになり、アプリパスワードという項目が表示されます。

アプリパスワードを選択してください。

アプリの選択をメールにし、デバイスの選択に任意の名前をつけて生成ボタンをクリックすると16桁のパスワードが表示されます。使い方をしっかり読んでください。

Laravelの.envファイルを開いて、先程設定していたUSER_PASSWODの設定をこの16桁のパスワードに変更します。
設定変更後は、php artisan config:cacheを実行されば、Gmailからメールを送信することができます。

Mailableクラスを使用したメール送信
Mailableクラスの作成
Mailableクラスを利用してメールの送信を行います。Mailableクラスはphp artisan make:mailコマンドで作成します。
コマンドを実行するとMaiableファイルはapp¥Mailディレクトリの下に作成され、中身は下記の通りです。
これまでと全く同じ内容のテストメールを送るため、SendTestMail.phpのbuildメソッドを下記のように書き換えます。

MailSendController.phpでは以下のように作成したMaiableクラスを利用するために更新が必要になります。
この設定でブラウザで/mailにアクセスするとメールが送信されます。
HTMLメール or テキストメール
これまではメールを送信する時にviewメソッドでビューファイルを指定し、htmlとして送信を行っていましたがテキストメールでも送信を行うことができます。viewメソッドをtextメソッドに変更して、ビューのファイルの内容をテキスト形式に変更します。
views/emailsの下にtest_text.blade.phpファイルを作成し下記を記述します。
メールクライアントで見ると改行も行われて記述どおりの内容が送信されていることが確認できます。

ヘッダーのcontent-typeを確認するとtext/plainであることも確認できます。HTMLメールだとcontent-typeはtext/htmlになります。
textとhtmlのマルチパートでも送ることができます。
受信したメールクライアントでヘッダーのContent-Typeを確認し、multipart/alternativeになっていればhtmlとtext形式どちらでも送信されていることが確認できます。
複数人にメールを送る場合
一度に複数人の人にメールを送信する場合は下記のように配列を使用します。
メールにエイリアスをつけたい場合は次のように行うことができます。
$toにはcollectionを使用することができます。つまりusersテーブルから取得したユーザ情報をそのまま$toに渡すことができます。
usersテーブルには、ユーザの登録が必要です。ここではUser::all()を使用していますが、実際はwhere句を利用して送信するユーザを選択してください。usersテーブルのemail、nameの列が使用されます。
bccやccについては、Mailableクラスの中で設定を行いますが、設定方法はtoの場合と同じです。
ビューに変数を渡す
データベースに保存されたテーブルから取得したデータをメールの内容に渡すためには変数を利用する必要があります。
usersテーブルに登録されたユーザ情報を利用して動作確認を行います。変数は、MailableクラスのSendTestMailをインスタンス化する時に渡すことができます。
SendTestMailのbuildメソッドでwithを利用して変数を渡します。
test_text.blade.phpは{{ }}を利用して値を展開することができます。
この設定でメールを送信すると{{ }}の中に$user->nameと$user->emailの値に置き換えられて送信されます。
ローカルファイルを添付する
ローカルファイルに保存されているファイルを添付する方法を確認します。ローカルのファイルを添付するためには、事前にファイルをローカルに保存しておく必要があります。
Laravelでのファイルのアップロード方法を知りたい場合は、下記を参照してください。
アップロードしたファイルの保存先はstorage/appの下なのでその直下のpdfディレクトリに添付するファイルが保存されている状態で話を進めます。
メールにファイルを添付するためには、attachメソッドを追加します。attachメソッドに添付するファイルのパスを設定することでメールへのファイル添付を行うことができます。
SendTestMailのbuildメソッドでattachを利用してファイルを添付します。
上記ではLaravelのhelper関数のstorage_pathを利用してファイルのパスを設定しています。storage_pathの戻り値は各環境で異なりますが、storageまでのフルパスを取得することができます。pdfファイルはstorage/app/pdfの下に保存されているので、storage(‘app/pdf/test_1.pdf’)を設定しています。

メールを送信するとファイルが添付されて送られます。
.envファイルのMAIL_DRIVERをlogに設定してログを見るとPDFの場合は下記のようにファイルの内容がテキストで表示されます。ファイルの内容によってはかなりの行になります。
複数のファイルを添付する
複数のファイルをメールに添付したい場合は複数のattachをつけることで対応することができます。
さらにファイルを添付したいという場合にはattachを増やしていくのは現実的ではありません。foreachを組み合わせて添付を行います。

ここまでの内容が理解できればLaravelで構築したアプリケーションへのメール送信機能の実装は難しくはないと思います。ぜひチャレンジしてください。