SES→SNS→Lambdaでバウンスが行われたときに、Lambdaのテストで使えるイベントJSON

## 概要

SESで送ったメールがバウンスし、SNSのトピックを通じ、サブスクしているLambdaを動かして何かしらの動作を行いたい場合にLambdaのテストのイベントJSONに記載して使う事のできるイベントJSONの内容を考えたので記載しておく。

## 内容

下記にイベントJSONの内容を記載しておく。

```json
{
  "Records": [
    {
      "EventVersion": "1.0",
      "EventSubscriptionArn": "arn:aws:sns:EXAMPLE",
      "EventSource": "aws:sns",
      "Sns": {
        "SignatureVersion": "1",
        "Timestamp": "1970-01-01T00:00:00.000Z",
        "Signature": "EXAMPLE",
        "SigningCertUrl": "EXAMPLE",
        "MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e",
        "Message": "{\"notificationType\":\"Bounce\",\"mail\":{\"timestamp\":\"2023-04-01T14:05:45 +0000\",\"messageId\":\"000001378603177f-7a5433e7-8edb-42ae-af10-f0181f34d6ee-000000\",\"source\":\"sender@example.com\",\"sourceArn\":\"arn:aws:ses:us-east-1:123456789012:identity/example.com\",\"sourceIp\":\"127.0.3.0\",\"sendingAccountId\":\"123456789012\",\"destination\":[\"recipient@example.com\"],\"headersTruncated\":false,\"headers\":[{\"name\":\"From\",\"value\":\"\\\"Sender Name\\\" <sender@example.com>\"},{\"name\":\"To\",\"value\":\"\\\"Recipient Name\\\" <recipient@example.com>\"},{\"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\":\"Sat, 01 Apr 2023 14:05:45 +0000\"}],\"commonHeaders\":{\"from\":[\"Sender Name <sender@example.com>\"],\"date\":\"Sat, 01 Apr 2023 14:05:45 +0000\",\"to\":[\"Recipient Name <recipient@example.com>\"],\"messageId\":\"custom-message-ID\",\"subject\":\"Message sent using Amazon SES\"}},\"bounce\":{\"bounceType\":\"Permanent\",\"bounceSubType\":\"General\",\"bouncedRecipients\":[{\"emailAddress\":\"recipient@example.com\",\"action\":\"failed\",\"status\":\"5.0.0\",\"diagnosticCode\":\"X-Postfix; unknown user\"}],\"timestamp\":\"2023-04-01T14:05:50 +0000\",\"feedbackId\":\"000001378603177f-7a5433e7-8edb-42ae-af10-f0181f34d6ee-000001\",\"remoteMtaIp\":\"127.0.0.1\"}}",
        "MessageAttributes": {
          "Test": {
            "Type": "String",
            "Value": "TestString"
          },
          "TestBinary": {
            "Type": "Binary",
            "Value": "TestBinary"
          }
        },
        "Type": "Notification",
        "UnsubscribeUrl": "EXAMPLE",
        "TopicArn": "arn:aws:sns:EXAMPLE",
        "Subject": "TestInvoke"
      }
    }
  ]
}
```

SESのトップレベルJSONオブジェクト部分から下の階層が文字列として扱われてしまっているのでこちらをJSON化したものを下記に記載する。

```json
{
  "notificationType": "Bounce",
  "mail": {
    "timestamp": "2023-04-01T14:05:45 +0000",
    "messageId": "000001378603177f-7a5433e7-8edb-42ae-af10-f0181f34d6ee-000000",
    "source": "sender@example.com",
    "sourceArn": "arn:aws:ses:us-east-1:123456789012:identity/example.com",
    "sourceIp": "127.0.3.0",
    "sendingAccountId": "123456789012",
    "destination": [
      "recipient@example.com"
    ],
    "headersTruncated": false,
    "headers": [
      {
        "name": "From",
        "value": "\"Sender Name\" <sender@example.com>"
      },
      {
        "name": "To",
        "value": "\"Recipient Name\" <recipient@example.com>"
      },
      {
        "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": "Sat, 01 Apr 2023 14:05:45 +0000"
      }
    ],
    "commonHeaders": {
      "from": [
        "Sender Name <sender@example.com>"
      ],
      "date": "Sat, 01 Apr 2023 14:05:45 +0000",
      "to": [
        "Recipient Name <recipient@example.com>"
      ],
      "messageId": "custom-message-ID",
      "subject": "Message sent using Amazon SES"
    }
  },
  "bounce": {
    "bounceType": "Permanent",
    "bounceSubType": "General",
    "bouncedRecipients": [
      {
        "emailAddress": "recipient@example.com",
        "action": "failed",
        "status": "5.0.0",
        "diagnosticCode": "X-Postfix; unknown user"
      }
    ],
    "timestamp": "2023-04-01T14:05:50 +0000",
    "feedbackId": "000001378603177f-7a5433e7-8edb-42ae-af10-f0181f34d6ee-000001",
    "remoteMtaIp": "127.0.0.1"
  }
}
```

なるほど、、SNSからのイベントはMessageのなかに文字列としてSESのバウンス情報が入っているのか、、だから取り出してJSONのパースしないといけないのか、、。。
しかし。。この辺のLambdaのテスト用イベントJSONってもっと簡単に用意する方法無いんだろうか。。もちろんGPTに相談したがこれを導き出すのは結構大変だった。。

## 参考文献

https://docs.aws.amazon.com/ja_jp/ses/latest/dg/notification-contents.html

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/with-sns.html

https://docs.aws.amazon.com/ja_jp/sns/latest/dg/sns-message-and-json-formats.html