こんにちは、AWSのlambdaを使いこなしたいと思っている中村です。
今回はバウンスメール対策について実装パターン悩んだ話しを紹介します。
まずバウンスメールとは何かについて。
■バウンスメールとは
バウンスメール (bounce message) とは、電子メールの仕組みにおいて、送信したメールメッセージが何等かの理由で目的の送信先に正常に配信されなかった場合に、メールサーバからその旨を送信元に通知されるメールメッセージのこと。エラーメールやリターンメールとも称される。(wiki参考)
不正なメールアドレスだと、配信エラーになります。
その時に送信元に通知されるエラーのメールのことになります。
メールサーバーを構築する際には必須の対応です。
■AWSのSESとは
AWSにはメール配信サービスとしてSES(Simple Email Service)というサービスがあります。
これは簡易にメール送信サーバーを構築できるというサービスです。
・SESとは
https://aws.amazon.com/jp/ses/
手順さえ覚えればインフラの知識がなくても、コンソール上でのボタン操作だけで設定できます。
とっても便利!
AWSでメールサーバー構築する際は絶対使った方がいいサービスです。
※実サービスで使う場合は送信制限解除が必須です!
・送信制限解除
https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/request-production-access.html
■SESにおけるバウンスメール対策
SESは設定が簡単ですが、バウンスメール対策は少しややこしいです。
まず、バウンスメールが多くあるとメールサーバーが不正なサーバーとして扱われ、最悪設定していたメールサーバーが廃止されます。(巷では、SESはバウンスメール対策に対して厳しいと言われています)
参考)
http://temporal.hatenablog.com/entry/2013/01/20/174500
場合により、SESを利用する権利を一時停止されてしまうことがある
権利を一時停止されてしまった(もしくは警告を受けた)際には、その原因を自分で調査して、AWSに原因と対策を英文で報告する必要がある
しかし、バウンスメール対策に対しては簡単な対処法が用意されておらず、個別で設定や実装が必要なのが現状です。
そのため、今回はこれまでの経験を元に3つの方法を紹介します。
■基本的な設定
まずどの方法でも共通する基本的な設定です。
・SES上でバウンスメールにSNSを設定する。
SESにはbouncemailを受け取ったら、特定のアクションを設定することが可能です。
設定箇所:SES>Domains>Notifications>Edit Configuration
この画面でSNSのトピックを設定可能です。
・SNSとは
https://aws.amazon.com/jp/sns/
※SNSのトピックス作成方法は割愛
この設定をすることで、バウンスメール発生時、SNSのトピックスへ通知を送ります。
基本的にはこの設定をしておけば、バウンスメール発生時、自由な設定可能です。
SNSのサブスクリプション設定画面)

今回は、このSNSトピックスをどのようなに設定し、バウンスメール対策をするかで悩みました。
自分なりに調べて考えた3つのパターンとメリット・デメリットを紹介します。
■パターン1:サブスクリプションにhttpsプロトコルを設定する方法
実際によく使っている方法です。
構成:SES+SNS+独自のhttpsプログラム
【各種設定】
・SNSの設定
プロトコル:https
エンドポイント:独自URL(https://example.com/bauncemail)
・独自のhttpsプログラム
実装:php上でバウンスデータのメールアドレス登録する処理を実装します。
登録されたメールアドレスをプログラム上から対象外の処理とする。
※注意点:SESからのみ処理できるようにする必要がある。
【メリット・デメリット】
・メリット
-AWSの設定は最小限に済むので、AWSの経験がなくても設定ができます。
・デメリット
-毎回実行されます。余計な負荷がある。
■パターン2:トピックスにSQSを設定し、独自のバッチプログラムでSQSから情報を取得
構成:SES+SNS+SQS+独自のバッチプログラム
SQSを使い、バウンス情報を保持させます。
SQSに対して、独自プログラムでキュー処理をし、ポーリング設定をします。
【各種設定】
・SNS
プロトコル:SQS
エンドポイント:SQSのエンドポイント
・SQS
SNSと連携できるキューを作成
参考)
https://dev.classmethod.jp/cloud/aws/cross-account-sns-sqs-integration/
独自のバッチプログラム)
実装:SQSへデータを取得し、データをパース。更新が必要な場合のみシステムにデータを登録させます
https://qiita.com/iron-breaker/items/0b2f8c20e7527b5aa552
【メリット・デメリット】
・メリット
-キュートしてSQSにデータを切り離して貯められるため、本サーバーへの更新が最低限で済む
・デメリット
-SQSの知識が必要になります。また、バッチでSQSへ接続してパースしたりなど、実装範囲が増える
■パターン3:LambdaとdynamoDBで完全サーバーレス
構成:SES+SNS+SQS+Lambda+dynamoDB
LambdaとdynamoDBでパターン2で実装していたバッチプログラムをAWSのコンソール上で処理します。
【各種設定】
・SNSとSQS
パターン2と同様
・Lambda
SQSへデータを取得する処理、dynamoDBへデータを登録する処理を実装
参考)
https://dev.classmethod.jp/cloud/aws/lambda-sqs-asynchronous-distributed-processing/
・dynamoDB
キー情報と、メールアドレスを登録できるデータを用意
参考)
https://qiita.com/kojiro_ueda/items/303f2466e11b55e5ec21
【メリット・デメリット】
・メリット
-サーバーレスでバウンス対策ができます。AWS環境を使う場合は、どのプロジェクトでも同じ実装が可能です。
・デメリット
-LambdaやdynamoDBなどの知識が必要になります。
以上です。
まとめ
個人的にはパターン3がベストプラクティスな気がしていますが、少し手間なので、基本的にはパターン1か2でいいかなと思います。
あと、バウンスのテストをする時には、
テスト用のメールアドレスを利用するようにしてください。
https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/mailbox-simulator.html
以上です!