はじめに
AWSでSESを使用していると、バウンス対応などが必要になります。
SESのバウンスをSNSで通知させる
AWSのドキュメント
にあるとおり、
SESのNotificationsにSNSのTopicのARNをアタッチします。
arn:aws:sns:us-east-1:123456789012:ses-bounces-topic
といった感じになります。
バウンスメールを取得、保存
SNSのSubscribeで、Lambdaを実行し処理するケースが多いと想定しています。
Lambdaのコードは、AWS Serverless Application Repository に
- ses-notification-python
- ses-notification-nodejs
- ses-notification-to-s3
色々とあるので各々カスタマイズし
S3に保存やDynamoDBに保存などしていくのがいいでしょう。
Lambdaを作った後
Lambdaを作った後は、テストで実行する流れになります。
テスト実行するには、テストイベントを用意する必要があります。
Lambdaでは、テストイベントでSNSのイベントのサンプルはありますが
SNSのメッセージにSESを含んだものはありません。
を見て作るのですが
SNSのMessageに
SESの通知内容を文字列でエスケープしたり、用意するのに手間がかかります。
毎度忘れるので、忘備録として今回書き起こしました。
SNS通知にSESの内容を含むテストイベント
Bounce, Complaint, Deliveryも適当に入れてます。
このJSONをコピペして、必要に応じ削って使用する想定です。
{
"Records": [
{
"EventSource": "aws:sns",
"EventVersion": "1.0",
"EventSubscriptionArn": "arn:aws:sns:us-east-1:{{{accountId}}}:ExampleTopic",
"Sns": {
"Type": "Notification",
"MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e",
"TopicArn": "arn:aws:sns:us-east-1:123456789012:ExampleTopic",
"Subject": "example subject",
"Message": "{ \"notificationType\": \"Bounce\", \"mail\": { \"timestamp\": \"2018-10-08T14:05:45 +0000\", \"messageId\": \"000001378603177f-7a5433e7-8edb-42ae-af10-f0181f34d6ee-000000\", \"source\": \"sender@example.com\", \"sourceArn\": \"arn:aws:ses:us-west-2:888888888888:identity/example.com\", \"sourceIp\": \"127.0.3.0\", \"sendingAccountId\": \"123456789012\", \"destination\": [ \"recipient@example.com\" ], \"headersTruncated\": false, \"headers\": [ { \"name\": \"From\", \"value\": \"\\\"Sender Name\\\" \" }, { \"name\": \"To\", \"value\": \"\\\"Recipient Name\\\" \" }, { \"name\": \"Message-ID\", \"value\": \"custom-message-ID\" }, { \"name\": \"Subject\", \"value\": \"Hello\" }, { \"name\": \"Content-Type\", \"value\": \"text/plain; charset=\\\"UTF-8\\\"\" }, { \"name\": \"Content-Transfer-Encoding\", \"value\": \"base64\" }, { \"name\": \"Date\", \"value\": \"Mon, 08 Oct 2018 14:05:45 +0000\" } ], \"commonHeaders\": { \"from\": [ \"Sender Name \" ], \"date\": \"Mon, 08 Oct 2018 14:05:45 +0000\", \"to\": [ \"Recipient Name \" ], \"messageId\": \" custom-message-ID\", \"subject\": \"Message sent using Amazon SES\" }}, \"bounce\": { \"bounceType\": \"Permanent\", \"bounceSubType\": \"General\", \"bouncedRecipients\": [ { \"status\": \"5.0.0\", \"action\": \"failed\", \"diagnosticCode\": \"smtp; 550 user unknown\", \"emailAddress\": \"recipient1@example.com\" }, { \"status\": \"4.0.0\", \"action\": \"delayed\", \"emailAddress\": \"recipient2@example.com\" } ], \"reportingMTA\": \"example.com\", \"timestamp\": \"2012-05-25T14:59:38.605Z\", \"feedbackId\": \"000001378603176d-5a4b5ad9-6f30-4198-a8c3-b1eb0c270a1d-000000\", \"remoteMtaIp\": \"127.0.2.0\"}, \"complaint\": { \"userAgent\": \"AnyCompany Feedback Loop (V0.01)\", \"complainedRecipients\": [ { \"emailAddress\": \"recipient1@example.com\" } ], \"complaintFeedbackType\": \"abuse\", \"arrivalDate\": \"2009-12-03T04:24:21.000-05:00\", \"timestamp\": \"2012-05-25T14:59:38.623Z\", \"feedbackId\": \"000001378603177f-18c07c78-fa81-4a58-9dd1-fedc3cb8f49a-000000\"}, \"delivery\": { \"timestamp\": \"2014-05-28T22:41:01.184Z\", \"processingTimeMillis\": 546, \"recipients\": [ \"success@simulator.amazonses.com\" ], \"smtpResponse\": \"250 ok: Message 64111812 accepted\", \"reportingMTA\": \"a8-70.smtp-out.amazonses.com\", \"remoteMtaIp\": \"127.0.2.0\"} }",
"Timestamp": "1970-01-01T00:00:00.000Z",
"SignatureVersion": "1",
"Signature": "EXAMPLE",
"SigningCertUrl": "EXAMPLE",
"UnsubscribeUrl": "EXAMPLE",
"MessageAttributes": {
"Test": {
"Type": "String",
"Value": "TestString"
},
"TestBinary": {
"Type": "Binary",
"Value": "TestBinary"
}
}
}
}
]
}