SNSとSESのLamdaをテストするためのイベントサンプル

はじめに

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を含んだものはありません。

Amazon SES の Amazon SNS 通知の内容

を見て作るのですが
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"
          }
        }
      }
    }
  ]
}