この記事は、AWS LambdaとServerless #2 Advent Calendar 2019 の24日目の記事です。
Introduction
システムからのメール配信を行っている場合、BounceやComplaintとなったメールアドレスへの対処が求められます。
Amazon SES の場合、SandboxからProductionで使用する際にどのようなプロセスを実装しているかを申請する必要があります。
AWS公式では以下のような知見が紹介されています。
How do I create an AWS Lambda function to store Amazon SNS notification contents for Amazon SES to an Amazon DynamoDB database?
概要としては、以下のような処理になります。
- Eメールのバウンス、苦情、配信などを Amazon SNS で通知するよう設定
- SNSでの通知を受けて、Lambdaを実行
- Lambdaの処理でDynamoDBへ保存
今回は上の記事をSAMで実装したものを紹介します。
レポジトリ
SAM でデプロイ可能なものを上のレポジトリで公開しております。
ランタイムは、Python3.7
設定方法
1. 通知に使用するSNSを作成
$ aws sns create-topic --name ses-messages --region us-east-1
※このとき、Amazon SES と同じリージョン内でSNSを作成する必要があります。
2. SESの設定で、バウンス、苦情、配信を通知するSNSを設定
bounces, complaints, deliveries に関する通知を受け取るためのSNSとして、
1.で作成したSNSを設定します。

3. 配信結果を保存するDynamoDBを作成
DynamoDBのスキーマを定義したjsonファイルを置いております。
$ aws dynamodb create-table --cli-input-json file://dynamodb_table.json
※ 上で作成したDynamoDBのテーブルは簡易的なものです。GSIの設定、READ/WRITE Capacityの設定などは運用に合わせて必要です。
4. Lambda関数をデプロイ
環境変数
-
S3_BUCKET
SAMデプロイ用のS3バケット -
TABLE_SES_NOTIFICATIONS
3.で作成したDynamoDBのテーブル名 -
SNS_TOPIC_ARN
created sns topic
2.で作成したSNS ARN
各環境変数を設定してデプロイ完了です。
$ S3_BUCKET=sam-app-artifacts \
TABLE_SES_NOTIFICATIONS=SESNotifications \
SNS_TOPIC_ARN=arn:aws:sns:us-east-1:xxx:ses-messages \
make deploy
メール配信結果
以下のように、送信毎にDynamoDBに保存されます。

あとはこのテーブルを使って、DynamoDB Triggersや別のバッチ処理を書いてそれぞれの処理を行います。
これで Bounce, Complaint などへの対処が可能になりました。
Lambda関数での処理
特に手の凝った処理はしていません。
よくあるSNSからの通知内容をパースして保存する形です。
Bounce, Complaint といった各シナリオでテストがしたい場合は、以下のアドレスが用意されています。
これを使えばデバッグもスムーズに行なえます。
https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/mailbox-simulator.html