はじめに
掲題通り。 SendBulkEmail は Python / boto3 であれば以下のドキュメントで示す通りに利用できる。 ドキュメントを読むと、成功時にはレスポンスとして "Status": "SUCCESS"
を返すことがわかる。
今回はここで SUCCESS
を返しているにも関わらず、正常にメールが送信されない状況に遭遇した。 その調査のため、SES の検証済IDに設定可能な通知の「送信」「バウンス」「苦情」にそれぞれ通知用の SNS トピックを設定した後に同様の内容のメールを送信したが、これらの SNS に対して通知は発生しなかった。
この問題の原因と対応方法を以下に示す。
原因と対処
原因は「メール送信時に利用したテンプレートのレンダリングに失敗しているため」であった。
SendBulkEmail でメールを送信する際には SES に設定したテンプレートを利用する。 この時、例えば変数として {{NAME}}
のような変数が定義でき、かつ、これらの変数を SendBulkEmail
の呼び出し時に宛先個別に設定できるのだが、これらの変数に対して適切な値を渡していないことがある。 この場合、メール送信のデフォルトパラメータ、および、宛先個別のパラメータの中に NAME
という変数が存在していない場合にレンダリングに失敗する。
この問題を検知するには以下の手順が必要になる。
- SESの設定セット (Configuration Set) を作成する
- イベント送信先を設定し、「レンダリングの失敗」時に特定の通知先にアラートを飛ばすように設定する
- 以下のいずれかの手順で上記で作成した設定セットを利用する
- 利用する検証済 ID のデフォルト設定セットとして設定する
- SendBulkEmail の実行時に利用する設定セットを指定するようにする
今回はレンダリング失敗時に SNS を経由してサブスクリプション済のメールアドレスに通知が飛ぶようにした。 その結果、以下のような SNS 通知結果を得た。
{
"eventType":"Rendering Failure",
"mail":{"timestamp":"2023-04-05T07:44:28.098Z",
"source":"********",
"sourceArn":"arn:aws:ses:ap-northeast-1:************:identity/********",
"sendingAccountId":"************",
"messageId":"************************************************************************",
"destination":["************************************"],
"headersTruncated":false,
"tags":{"ses:operation":["SendTemplatedEmail"],
"ses:configuration-set":["template-debug"],
"ses:source-ip":["************************************"],
"ses:from-domain":["************************************"],
"ses:caller-identity":["************************************************"]}},
"failure":{
"errorMessage":"Attribute 'NAME' is not present in the rendering data.",
"templateName":"************************************************************"
}
}
この通知内の failure.errorMessage
にエラー理由が記載されている。
この場合 NAME
がレンダリング用のデータ内に存在しないため失敗した、というエラーメッセージが表示されている。
利用しない変数が誤ってテンプレート内に記載されていないかを注意しておかないと、メール送信のAPIは成功しているにも関わらず、実際のメールが送信されていないという問題が発生し得るため注意する必要がある。
参考