0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Mailable】Laravelでメール送信する最適解【2024年夏最新版】

Posted at

前回 のメール編!
Laravelで困るのって、書類発行とメール送信だと思う。
(JobやWebSocketから目をそらして)


1. メール設定

Laravel は標準でメール送信に対応している。
まず、基本設定についてまとめる。
設定中の動作確認は「2. メールの送り方」を参照のこと。

.env 設定値

設定は config/mail.php.envMAIL_ で始まるキーで定義されている。

.env
MAIL_MAILER=log
MAIL_HOST=127.0.0.1
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"

:pushpin: MAIL_MAILER

config/mail.phpmailers で定義されているドライバ情報を記入する。

基本的には smtp で良い。
Amazon SES を使うのであれば ses
log にすると、Laravel のログに出力されるので便利。

:pushpin: MAIL_HOST MAIL_PORT MAIL_USERNAME MAIL_PASSWORD MAIL_ENCRYPTION

接続先の情報。
メール送信に使用するサーバーやサービスの情報を記載する。
sail 環境であれば、mailpit コンテナを使用する。

MAIL_ENCRYPTIONtls ssl null の値を取る。
困ったら tls で動くはず。
適切に設定しないと、エラーで弾かれることが多い。

:pushpin: MAIL_FROM_ADDRESS MAIL_FROM_NAME

送信元の情報。
基本的には送信に利用するアドレス情報を指定すればよい。
一括して support@xxx みたいなアドレスを使用したい場合、こちらに記載する。

※ドメインが異なる場合、セキュリティの都合で弾かれることが多い。
 ちゃんと存在するアドレスを指定しよう。

一般的なメールサーバーの場合

基本的には、メーラーに設定するSMTP情報を使うことで、メール送信が可能になる。
「Xserver Business」の場合、こちらに記載があった。

使用するアドレスのアカウント情報と合わせて、設定値を作成する。

.env
MAIL_MAILER=smtp
MAIL_HOST="sv***.xbiz.ne.jp"
MAIL_PORT=587
MAIL_USERNAME="xxxxxx@example.com"
MAIL_PASSWORD="xxxxxxxx"
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="xxxxxx@example.com"
MAIL_FROM_NAME="${APP_NAME}"

Gmail の場合 (アプリパスワード)

以前であれば、「一般的なメールサーバーの場合」と同様に設定できたのだが、セキュリティ強化の影響で使用できなくなるみたい...。

https://support.google.com/a/answer/14114704?hl=ja
2024 年秋:
すべての Google アカウントで、安全性の低いアプリへのアクセスが無効になります。
CalDAV、CardDAV、IMAP、SMTP、POP で従来のパスワード(基本認証)を使用できなくなります。

(アプリパスワードは例外です)

でもアプリパスワードは使えるみたい!
セキュリティ的には脆弱になるので、安全性を高めるには下の OAuth 認証方式を使おう。

https://myaccount.google.com/security

まず使いたいアカウントの管理画面にアクセスして、「セキュリティ」「二段階認証プロセス」を選択する。
※あらかじめ二段階認証を有効にする必要があります。

ページ下部の「アプリパスワード」を選択する。

任意の名称を付けると、パスワードが生成される。
二度と閲覧できないので記録しよう。

これらの値より、設定値を作成する。
SMTP情報はこちら。

.env
MAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME="xxxxxx@gmail.com"
MAIL_PASSWORD="xxxxxxxx"
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="xxxxxx@gmail.com"
MAIL_FROM_NAME="${APP_NAME}"

MAIL_PASSWORD に先ほど取得したアプリパスワードを記入する。

Gmail の場合 (OAuth)

他の人にお任せする!
この方が分かりやすいかと。

これ!っていうライブラリが無いから紹介しにくい...。

Amazon SES の場合

AWS にて SES のアカウント設定が必要。(割愛)

$ composer require aws/aws-sdk-php

設定値はこんな感じ。
MAIL 設定のほかに AWS の IAM 設定が必要になる。
意外とシンプルに扱える。

.env
AWS_ACCESS_KEY_ID="xxxxxxxx"
AWS_SECRET_ACCESS_KEY="xxxxxxxx"
AWS_DEFAULT_REGION="ap-northeast-1"

MAIL_MAILER=ses
MAIL_FROM_ADDRESS="xxxxxx@example.com"
MAIL_FROM_NAME="${APP_NAME}"

あとは他の人にお任せする!
この方が分かりやすいかと。

2. メールの送り方

一般的にSMTP送信時に行うことは何でもできる。
メールは動作確認が大事なので、送信テスト用コマンドを作っておくと良い。

シンプルにメールを送る

実はドキュメントに乗っていない方法。
というか Model と Blade を使う方法しか載ってない。
ただ送るだけの時に作るの面倒なので、こちらを用意。

use Illuminate\Console\Command;
use Illuminate\Mail\Mailables\Attachment;
use Illuminate\Mail\Message;
use Illuminate\Support\Facades\Mail;
use Symfony\Component\Mime\Address;

Mail::raw('本文です。', function (Message $message) {
    $message
        ->to([
            new Address('test@example.com', 'Lara'),
            new Address('sub@example.com', 'Vel'),
        ])
        ->subject('タイトル')
        ->attach(
            Attachment::fromStorage('red.png')
                ->as('赤い画像.png')
                ->withMime('image/png')
        );
});

生成されるメール本文はこちら。

From: Laravel <xxxxxxxx@gmail.com>
To: Lara <test@example.com>, Vel <sub@example.com>
Subject: =?utf-8?Q?=E3=82=BF=E3=82=A4=E3=83=88=E3=83=AB?=
MIME-Version: 1.0
Date: Mon, 16 Sep 2024 03:29:33 +0000
Message-ID: <dfca79409fde9d1630bd1fbe206b1925@gmail.com>
Content-Type: multipart/mixed; boundary=tOuA3Ufv

--tOuA3Ufv
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

本文です。
--tOuA3Ufv
Content-Type: image/png;
 name="=?utf-8?Q?=E8=B5=A4=E3=81=84=E7=94=BB=E5=83=8F=2Epng?="
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
 name*=utf-8''%E8%B5%A4%E3%81%84%E7%94%BB%E5%83%8F.png;
 filename*=utf-8''%E8%B5%A4%E3%81%84%E7%94%BB%E5%83%8F.png

iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsEAAA7BAbiRa+0AAAANSURBVBhXY3gro/IfAAVUAi3GPZKdAAAAAElF
TkSuQmCC
--tOuA3Ufv--

詳しい関数はソースを見たほうが早い。

:pushpin: to cc bcc

to($address, $name = null, $override = false)

宛先情報の追加。
送信先を Address で作って、配列で指定する。
複数実行した場合、過去の値はそのままに追加される。

文字列指定もできるが、挙動が若干複雑なのでこっちをおすすめ。
Address は Symfony のほうを使う。
(多分 raw の使用は考慮されてない)

※ Address の代わりに User モデルを指定することも可能!

:pushpin: from (sender)

from($address, $name = null)

サンプルでは指定していないが、送信元も指定できる。
未指定の場合は .env で指定した値が使用される。

sender() は意識する機会あるのかな?

:pushpin: subject

subject($subject)

メールのタイトル。
ちなみに本文は raw() の第一引数なので注意。

:pushpin: attachment

attach($file, array $options = [])

添付ファイル。
Attachment を使ってファイルを添付することができる。
添付元は fromStorage() fromStorageDisk() fromData() fromPath() と、必要そうなものは大体用意されている。
ちゃんと設定すれば s3 から直接添付もできるんじゃないかな。

ファイル名未指定時は、元のファイル名がそのまま使われる。
Mime未指定時は、拡張子から勝手に推測されるみたい。(未検証)

いくつか付与したい場合は、何回も呼び出そう。

また zip にしたい場合は、別途 zip ライブラリを使って先に固める必要がある。

Mailable + Blade を使ってメールを送る

メール送信用のテンプレートを作って、それを呼び出す一般的な使い方。
個人的には準備するものが多くなるので、インラインでも良くないか?と思っている。

テンプレートはコマンドで生成可能。

$ php artisan make:mail TestMail

$ php artisan make:view mail/testMailView
resources/views/mail/testMailView.blade.php
<div>
    <p>こんにちは {{ $name }} さん</p>
</div>
app/Mail/TestMail.php
<?php

namespace App\Mail;

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

class TestMail extends Mailable
{
    use Queueable, SerializesModels;

    public function __construct(protected string $name)
    {
        //
    }

    public function envelope(): Envelope
    {
        return new Envelope(
            subject: 'テストメール',
        );
    }

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

    public function attachments(): array
    {
        return [
            Attachment::fromStorage('red.png')
                ->as('赤い画像.png')
                ->withMime('image/png')
        ];
    }
}

使い方。

$res = Mail::to([
        new Address('test@example.com', 'Lara'),
        new Address('sub@example.com', 'Vel'),
    ])
    ->send(new TestMail('たなかさん'));

to などの仕様は Mail::raw() と同等。

:pushpin: envelope

宛名情報を記録する場所。
基本は subject のメール件名を記載する場所。
他にも fromtags metadata などが指定可能。

:pushpin: content

本文を記載する場所。
view モードと markdown モードに対応している。

text を指定しておくと、平文メールの際の描画を決められる。

with に配列を指定することで、bladeファイルに値を渡すことができる。
このテンプレート内部で使用する値は、コンストラクタの引数に渡しておこう。

:pushpin: attachments

添付ファイルを指定するところ。
これは先の説明と同じ。

送信履歴について

送信履歴、送信トレイに、送信メールが保管されるかはメールサーバー次第。
基本的には履歴は残らないと思った方が良い。

送信時の戻り値をDBなどに格納しておこう。
送信失敗時はちゃんと例外で処理される。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?