[Laravel 7.x]メールの送信にAmazon SESを使う

AWS

はじめに

Amazon LinuxからAmazon Linux 2へサーバを移行したのだけれど、メールが送信されてこない。。。

普通にsendmailで送るのもよいけど、EC2を使っていると、ポート25の制限を解除を忘れてしまう…

公式によると、

SMTP、Mailgun、Postmark、Amazon SES、sendmailドライバーを提供しており…

https://readouble.com/laravel/7.x/ja/mail.html

ってことなんで、サーバはEC2だし、Amazon SESを使ってみることにする。

Laravel側の設定

SESのSTMP経由で送信するのであれば、下記の処理は不要。
まずは、composer.jsonファイルのrequireに以下を追加して、composer updateする。
まぁ、$ composer require aws/aws-sdk-phpでも良いかと。

"aws/aws-sdk-php": "~3.0"

いろいろとアップデートされるけど、まぁいいや。

AWS側の設定

Amazon SESの料金は、東京リージョンで、EC2から送信するEメールのうち最初の62,000通が無料、以降1,000通ごとに0.10USD(2020/10/23現在)。まぁ無料枠で収まりそう。

さて、AWSの設定画面…英語かーい!

Email Addressから行ってみるか。どうも存在するメールアドレスが必要らしい…存在していないからなぁ。。。

Domainsはどうだろう?まぁドメインでやってみますかね。Verify a New Domainをクリックして、

ドメイン名を入力して、DKIMをチェックONにして、進む。

そうすると、DNSの設定をいろいろやれと言ってくるので、DNSを設定する。最後のMXレコードはなしでもいいと思う。

そうすると、ペンディング状態になるので、しばらく待機。。。

そのうち確認完了となる。

ドメインを選択して、Send a Test Emailをクリック

必要事項を入力して、Send Test Emailボタンをクリックすると、エラーが出る。。。
なんでやねん!
上記でドメインで認証しているが、メールアドレスで認証して、テストメール送信すると、メールアドレス認証しているメールアドレス宛は大丈夫だが、認証していないメールアドレス宛には送信できないので、SES使用に制限があるのかと思われる…

左メニューのSending StatisticsをクリックしてみるとSandboxと…Sandbox環境で動くのね…AWS側の承認をいただかなければ!ということで、Edit your account detailsをクリックしてみる。

Enable Production AccessYesにして、その他の必要事項を記入して、Submit for reviewをクリック

レビュー待ちとなったので、AWSからの返答を待つ…(2020/10/23 13:48から待機…)

こんなメールも届く。

こんなメールが届く(2020/10/24 00:07 およそ10時間ぐらい)
1日50,000メッセージ、毎秒14メッセージの制限もあるけど、1日は50,000通も送らんからええけど、毎秒14メッセージはどうなんやろ…あり得る気もする…まぁ運用してみて考えるか。

AWSの管理コンソールで確認すると、SandboxからEnabledに変わってる!!!やった!

テストメールを送信してみよう!今回は問題なく送信された!

Laravelのメールドライバーは、API経由で送信するやりかたっぽく、IAMの設定あんましたくないなぁって思ってたんだけど、SMTP Settingってのがあるやん!Create My Credentialsをクリックする。

IAM User Name を適当に入力して、作成をクリック

日本語になるんか―い!まぁいいや。
SMTPユーザー名と、SMTPパスワードをメモっておく。

LaravelからSESのSMTP経由でメールを送信してみる

まずは.envファイルのメール部分を修正する。

MAIL_DRIVER=smtp
MAIL_HOST=email-smtp.ap-northeast-1.amazonaws.com
MAIL_PORT=465
MAIL_USERNAME=上記IAMで作成したユーザー名
MAIL_PASSWORD=上記IAMで作成したパスワード
MAIL_ENCRYPTION=true

で、tinkerつかってメールを送信してみようと思うわけですよ。
。。。エラーになるんかい!

% sudo php artisan tinker
Psy Shell v0.10.4 (PHP 7.4.11 — cli) by Justin Hileman
>>> Mail::raw('mail body', function($message) { $message->to('example@example.com')->subject('mail subject'); });
Swift_TransportException with message 'Connection could not be established with host email-smtp.ap-northeast-1.amazonaws.com :stream_socket_client(): unable to connect to 1://email-smtp.ap-northeast-1.amazonaws.com:465 (Can't assign requested address)'

ポート番号を25,587に変えても同様のエラー…

まずは、エラーを分析!

とりえあず、ココの接続をテストしてみる。と普通に送信された。。。ってことはLaravel側で問題があるってことだよなぁ。。。

めっちゃはずかしいのだけど。。。

.envは、

MAIL_ENCRYPTION=true

ではなく、

MAIL_ENCRYPTION=tls

にしたら、送信されました。trueではなく、tlsです。。。めちゃはずかしい。。。

LaravelからSESのAPI経由でメールを送信してみる

まずは、AWSのIAM設定

AWSのIAMにアクセスしてユーザーをクリック、先程SMTPユーザーを作ったユーザー名(なんかわかりにくいけど。。。)をクリック

ユーザーの情報が表示される。メールが送信されれば良いので、アクセス権は「AmazonSesSendingAccess」だけあればよい。(さっきSMTPで送信できたのだから問題ない)
認証情報のタブをクリック

スクショは、アクセスキー作成後になってしまったのだが、
アクセスキーの作成をクリックして、アクセスキーやシークレットキーをメモしておく。
SMTPユーザー追加で作成したアクセスキーでは、API経由でのメール送信は行えない。

次にLaravel側の設定

.envを修正する。上記SMTPで設定したMAILから始まる設定はコメントアウトするなり削除するなり。

MAIL_DRIVER=ses

SES_KEY=上記IAMで作成したアクセスキー
SES_SECRET=上記IAMで作成したシークレットキー
SES_REGION=ap-northeast-1

config/services.phpを修正する。なぜかリージョンが固定だった。

'ses' => [
	'key' => env('SES_KEY'),
	'secret' => env('SES_SECRET'),
	'region' => env('SES_REGION', 'us-east-1'), // 'region' => 'us-east-1',
],

はい。では、テストメール送信!

SMTPでやったようにtinkerでメールの送信をしてみる。無事にメールが送信された!!

% sudo php artisan tinker
Psy Shell v0.10.4 (PHP 7.4.11 — cli) by Justin Hileman
>>> Mail::raw('mail body', function($message) { $message->to('example@example.com')->subject('mail subject'); });
=> null

まとめ

だいぶ、長々となった。
ほとんどのサイトでAWSの制限解除せずにSandbox環境でメール送信するっていう記事がほとんど。それやらなかったら別のドメインに送信できないからメールとして意味がないんだけど。
まぁ無事にSMTP経由でもAPI経由でも送信できるようになったからまぁOKよ!

コメント

タイトルとURLをコピーしました