2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SESでメール一括送信時に考慮すべきことなどについて ~AWS100本ノック~ 18/100

Last updated at Posted at 2024-12-13

はじめに

image.png

AWS SESを利用してメールの大量送信を行う場合、メールテンプレートと呼ばれる件名と本文を定義したテンプレートファイルを作成し、SendBulkEmailというAPIで一括送信することになります。
※1件ずつ送ることも出来ますが、処理効率的にメールテンプレートを使うのが良いと思います。

以下は、テンプレート作成のAWS CLIコマンドのサンプルです。
{{xxx}}形式になっている部分は、変数になります。
名前などのユーザ毎に変わる値を変数にして、メール一括送信時に置換することでメール件名と本文の一部を変更することが出来ます。

test-template.json
{
    "Template": {
        "TemplateName": "test-template",
        "SubjectPart": "こんにちは {{name}}さん",
        "TextPart": "こんにちは {{name}}さん\r\nこれはテストメールです。"
    }
}

以下はメール一括送信のAWS CLIコマンドのサンプルです。
test@example.comからメールをBulkEmailEntriesに指定した件数分(今回は2件)送っています。

aws ses create-template \
  --cli-input-json file://test-template.json
test-template-data.json
{
  "FromEmailAddress": "test@example.com",
  "DefaultContent": {
    "Template": {
      "TemplateName": "test-template-only-text"
    }
  },
  "BulkEmailEntries":[
    {
      "Destination":{
        "ToAddresses":[
          "success@simulator.amazonses.com"
        ]
      },
      "ReplacementEmailContent": {
        "ReplacementTemplate": {
          "ReplacementTemplateData":"{ \"name\":\"user1\" }"
        }
      }
    },
    {
      "Destination":{
        "ToAddresses":[
          "bounce@simulator.amazonses.com"
        ]
      },
      "ReplacementEmailContent": {
        "ReplacementTemplate": {
          "ReplacementTemplateData":"{ \"name\":\"user2\" }"
        }
      }
    }
  ]
}
aws sesv2 send-bulk-email \
  --cli-input-json file://test-template-data.json

と、簡単に実行方法について紹介しましたが、実際にアプリケーションで利用するとなった場合、色々考慮する必要が出てきます!

なので今回は以下の3つの視点で、説明していきます。

  • SESで考慮したほうが良いこと
  • 呼び出し元で考慮したほうが良いこと
  • それ以外で考慮したほうが良いこと

ざっくり、全体をまとめた図が以下になります。

メール送信-SESまとめ.drawio.png

SESで考慮したほうが良いこと

まず、SESで考慮したほうが良いこと・やるべきことについて紹介します。

送信元の検証

当たり前ではありますがメールを送信する際には、送信元を指定する必要があります。
しかし、どんな送信元でも指定するということではありません。

送信元には、以下のどちらかを指定できます。

  • 検証されたドメインのメールアドレス ※Route53へのレコード追加が必要
    • 例えば、ドメインがhoge-example.comであれば、sender@hoge-example.comreply@hoge-example.comから送れます
  • 検証されたメールアドレス
    • 承認メールが飛ぶので、24時間以内に承認してもらうことが必要

サンドボックスの解除

SESはデフォルトだと、サンドボックスと呼ばれる制限がかかった状態になっています。
サンドボックスだと、

  • 不特定多数に送れない(検証済みのメールアドレスにしか送れない)
  • 1秒あたり1件までしかメールを送れない
  • 1日当たり200件までしかメールを送れない

といった制限があります。
なので、本番環境のアプリケーションを構築するAWSアカウントでは必ず解除する必要があります。

1.png

開発環境など不特定多数に送れてしまうとリスク(開発者が誤って利用できるメールアドレスを登録してしまってメールが飛んでしまう、など)があります。
なので、開発環境ではサンドボックスのまま運用して、必要なら解除するのが良いと思います。

制限の緩和

サンドボックスを解除すると、サンドボックスの制限が以下のように緩和されます。

  • 不特定多数に送れない(検証済みのメールアドレスにしか送れない)👉不特定多数に送れる(検証する必要がない)
  • 1秒あたり1件までしかメールを送れない👉1秒あたり14件送れる
  • 1日当たり200件までしかメールを送れない👉1日当たり50,000件送れる

サンドボックスを解除しても、送信元に関しては、検証済みのドメイン or メールアドレスである必要があります。

メール一括送信では、SendBulkEmailというAPIを利用することになるのですが、一括送信では一度に50送信先まで送れます。
なので、1秒あたり14件だと足りないかもしれません。
そういった場合は、Service Quotasで上限緩和の申請を行いましょう。
※無料のベーシックプランでも、1日前後で対応してくれると思います。

2.png

3.png

緩和申請を行うと自動的にサンドボックスが解除されてしまいました...:cry:
上限緩和は行いたいが、不特定多数には送れないようにしたい場合はサンドボックスを維持する必要があるので、そういった場合は上限緩和申請後に追加でその旨をメッセージで伝えると対応してくれるはずです。

※以下の画像は、自動的にサンドボックスが解除されたので、上限緩和はしつつ、サンドボックスに戻してもらった時のメッセージです

4.png

ログの収集

メール一括送信を実行したら、ちゃんと送れたか知りたくなりますよね?:smile:
実際にメールは色々な理由で、届かなかったり遅延したりすることがあります。

  • メールアドレスが間違っていた
  • 受信者のメールボックスがいっぱいだった
  • 送信先のメールサーバの何かしらの問題で遅延した
  • SESがメールにウイルスが含まれていると判断し、配信しなかった

SendBulkEmailのリクエストが成功したら、ユーザに必ずメールが届いたと思ってしまう人もいるのですが、実は違います。
あくまで、SendBulkEmailの成功はSESが一括送信リクエストを受け付けただけ、であり実際に配信が成功したかはわかりません。
また存在しないメールアドレスの場合、SendBulkEmail実行がエラーになると思う人が多いのですが、実際はリクエストが成功します ※SESからの配信時にバウンスします

じゃあ、どうすれば配信が成功・失敗したかわかるかというと、送信イベントを収集し、CloudWatchにログを出力するなどして、判断する必要があります。

ログの収拾については、あの人へSESで送ったメールってどうなったんだろう?どうやれば確認出来るのか ~AWS100本ノック~ 10/100という記事で紹介しています。

▼送信イベント

大分類 イベントタイプ 概要
送信と配信 Send 送信 呼び出しが成功し、Amazon SES は受信者のメールサーバーにメッセージを配信しようとしています。
RenderingFailure レンダリングの失敗 テンプレートのレンダリングの問題により、メッセージは送信されませんでした。
Reject 拒否 Amazon SES はメッセージを受け入れましたが、ウイルスが含まれていると判断し、受信者のメールサーバーに配信しようとしませんでした。
Delivery 配信 Amazon SES は、受信者のメールサーバーにメッセージを正常に配信しました。
Bounce ハードバウンス 受取人のメールサーバーが E メールを完全に拒否しました (Amazon SES が複数回試行してもメールを配信できない場合、ソフトバウンスが含まれます)。
Complaint 苦情数 メッセージは受信者のメールサーバーに正常に配信されましたが、受信者はスパムとしてマークしました。
DeliveryDelay 配信の遅延 一時的な問題が発生したため、メッセージを受信者のメールサーバーに配信できませんでした。
Subscription サブスクリプション E メールは受信者に正常に配信されました。受信者は、[リスト-サブスクリプション解除] ヘッダーをクリックするか、E メールのフッターにリンクされた [サブスクリプション解除] ウェブページを使用して、サブスクリプションの設定を更新しました。
開封とクリックの追跡 Open 開封数
Click クリック数

現在、送信イベントを収集するためのAWSサービスとしては以下が用意されています。

  • CloudWatch
  • Kinesis Data Firehose
  • Pinpoint
  • SNS
  • EventBridge

呼び出し元で考慮したほうが良いこと

呼び出し元のアプリケーションで考慮したほうが良いこと・やるべきことについて紹介します。

メールテンプレートの管理

一括送信で利用するメールテンプレートですが、以下のようにユースケースによって管理方法が変わると思っています。

  • インフラ担当者が登録/編集する、アプリケーションの管理者は閲覧・編集が出来なくていい
    👉インフラ構築で利用するCDK(CloudFormation)で管理する

  • アプリケーションの管理者は閲覧・編集をしたい
    👉アプリケーションでメールテンプレート管理をし、AWS SDKを利用してメールテンプレートを閲覧・編集する

エラー対策

次に、SendBulkEmailを実行した際のエラー対策になります。

SendBulkEmailに関しては、エラーとしては大きく以下の2パターンあります。

  • SendBulkEmailリクエスト自体が失敗する場合
  • SendBulkEmailリクエストは成功するが、あるメール送信が失敗する場合

では、それぞれについて説明します。

SendBulkEmailリクエスト自体が失敗する場合

全体が失敗するようなケースの場合は、以下のいずれかのSESの例外が投げられます。

  • TooManyRequestsException
  • LimitExceededException
  • AccountSuspendedException
  • SendingPausedException
  • MessageRejected
  • MailFromDomainNotVerifiedException
  • NotFoundException:
  • BadRequestException:

全体が失敗するようなケースっていつだろう?:thinking:って話ですが、51件メールを送信しようとした場合などがあります。
SendBulkEmailの仕様として、1リクエストで最大50の宛先をして出来る仕様(1つの送信で宛先が1つなら50件まで)があります。
なので、51件メールを送信しようとしたら全体が失敗します。

SendBulkEmailリクエストは成功するが、あるメール送信が失敗する場合

リクエストが成功した際のレスポンスとして、以下のようなBulkEmailEntries[]が返却されます。
これを見ることによって、各送信の成功・失敗がStatusから判断できます。

また、リクエストのBulkEmailEntries[]で指定した配列要素数分、BulkEmailEntryResults[]が返されます。なので、30件メールを送信すればレスポンスも30件になります。
さらに、リクエストのBulkEmailEntries[]で指定した配列と同じ順番で、BulkEmailEntryResults[]が返されます。これで、各メール送信の結果を突合できます:smile:

{
    "BulkEmailEntryResults ": [
        {
            "Status": "Success",
            "MessageId": "xxxxx-xxxxx-xxxxx-xxxxx-xxxxx-xxxxx-xxxxx"
        },
        {
            "Status": "Success",
            "MessageId": "xxxxx-xxxxx-xxxxx-xxxxx-xxxxx-xxxxx-xxxxx"
        },
        {
            "Status": "MessageRejected",
            "Error": "Email address is not verified. The following identities failed the check in region AP-NORTHEAST-1: ***@example.com"
        }
    ]
}

ここからBulkEmailEntryResultsの中身の説明になりますが、以下の3つのパラメータから構成されます。
個別の送信が失敗した場合は、BulkEmailEntryResultsのStatusがSuccess以外になります。

▼BulkEmailEntryResults

パラメータ 概要
Status 実行結果のステータス ・正常:SUCCESS
・異常:SUCCESS以外
ACCOUNT_THROTTLED
Error 詳細のエラーメッセージ ・SUCCESS:Error要素自体なし
・SUCCESS以外:エラーメッセージ
Email address is not verified. The following identities failed the check in region AP-NORTHEAST-1: ***@example.com
MessageId SESが発行した一意なUUID ・SUCCESS:UUID
・SUCCESS以外:基本的にMessageId要素自体なし
※TRANSIENT_FAILUREなどの異常系の場合に、MessageIdが発行されることがある
0106019385436fd3-8bd938e5-c5e5-4069-be33-29486930dd6b-000000

各Statusは以下のようになります。
▼Status

分類 Status 再実行で送信できる可能性があるか 概要
正常 SUCCESS - Amazon SESはメッセージを受け入れ、受信者への配信を試みます。
異常 MESSAGE_REJECTED なし メッセージがウイルスを含んでいたため、拒否されました。
異常 MAIL_FROM_DOMAIN_NOT_VERIFIED なし 送信者のメールアドレスまたはドメインが未検証です。
異常 CONFIGURATION_SET_DOES_NOT_EXIST なし 指定された設定セットが存在しません。
異常 TEMPLATE_DOES_NOT_EXIST なし 指定されたテンプレートが存在しません。
異常 ACCOUNT_SUSPENDED なし メール送信に関連する問題のため、アカウントが停止されました。
クォータ ACCOUNT_THROTTLED あり アカウントが割り当てられた送信制限を超えたため、送信可能なメール数が制限されています。
クォータ ACCOUNT_DAILY_QUOTA_EXCEEDED (日を跨がない限り)なし アカウントから送信可能な1日あたりの最大メール数に達した、または超過しました。
異常 INVALID_SENDING_POOL_NAME なし 指定された設定セットが存在しないIPプールを参照しています。
異常 ACCOUNT_SENDING_PAUSED なし UpdateAccountSendingEnabled操作を使用して、Amazon SESアカウントでのメール送信が無効化されました。
異常 CONFIGURATION_SET_SENDING_PAUSED なし UpdateConfigurationSetSendingEnabled操作を使用して、この設定セットでのメール送信が無効化されました。
異常 INVALID_PARAMETER_VALUE なし この操作の呼び出し時に指定された1つ以上のパラメータが無効です。エラーメッセージで詳細情報を確認してください。
SESの一時的な異常 TRANSIENT_FAILURE あり 一時的な問題のため、Amazon SESはリクエストを処理できませんでした。
異常 or SESの一時的な異常 FAILED あり Amazon SESはリクエストを処理できませんでした。エラーメッセージで詳細情報を確認してください。

個別の送信が失敗するようなケースっていつだろう?:thinking:って話ですが、

  • 1件のメールで宛先を51件指定した場合
  • リクエスト数が多すぎて1秒あたりの送信数上限に達してスロットリングした場合

などになります。

1秒あたりの送信上限数を超えた場合のエラーについて

おそらく、一番起こりやすいエラーは1秒あたりの送信上限数を超えた時に起きるスロットリングエラーだと思っています。
ただ、ドキュメントを見るとExceptionにTooManyRequestsException、BulkEmailEntryResultsにACCOUNT_THROTTLEDがあり、どっちになるんだろう?:thinking: って感じです...

そこでAWSサポートに問い合わせてみたところ、対象のBulkEmailEntryResultsがACCOUNT_THROTTLEDになるとのことでした。

ちなみに...最大送信レートを一時的に超えることは可能なので、例えば1秒あたり50件の制限があったとしても、一時的に50件以上送ることは可能なようです。

スロットリング予防

スロットリングした際は、上限緩和申請してリクエスト可能な数を増やすことで対応することも出来ますが、アプリケーション側でもスロットリングしないようにするスロットリングした際に再実行するような対応もしたほうが良さそうです。

スロットリングしないようにする

1.スリープ処理を入れる
1,000件のメールを50件ずつ送信する場合、すぐに次のSendBulkEmailを実行すると1秒あたりの送信上限に引っかかってスロットリングになる可能性が高くなります。
そのため、各リクエストの間にスリープ処理 ※PHPだとsleep(1)を入れるようにするのが良いと思います。

2.バッチ処理による非同期化
3.キューによる非同期化
この2つに関してはスロットリングとは関係ないのですが、大量のメール送信を同期的な処理で実行すると、長い時間同じ画面でユーザを待たせることになります。
なので、単一のメール送信ではない大量のメール送信は非同期化で行うのが良さそうです。
以下のイメージです。

学ぶべきこと-メール送信の非同期化.drawio (1).png

スロットリングした際に再実行する

なるべく、スロットリングしないように対処したいところですが、そうはいってもスロットリングは発生するかもしれません。

レスポンスのBulkEmailEntryResults[]でStatusがACCOUNT_THROTTLEDの送信に関しては、少し待って再実行すれば成功するかもしれません。
なので、必要に応じてアプリケーション側でリトライ処理を組み込みましょう。
例:「ACCOUNT_THROTTLEDが発生したメッセージは1秒スリープして再度SendBulkEmailを実行」を最大3回行う

それ以外で考慮したほうが良いこと

それ以外に考慮したほうが良いこと・やるべきことについて紹介します。

バウンス・苦情対策

バウンス・苦情が一定の割合に達するとレビュー対象になります。具体的には、

  • バウンス率が5%以上
  • 苦情率が0.1%以上

ソフトバウンスは、バウンス率には計上されません

になるとレビュー対象になり、対応が求められます。
レビュー対象中もメールは引き続き送信できますが、以下のような場合一時停止になりメール送信が出来なくなります。

  • アカウントがレビュー対象になっており、レビュー期間の終了前に問題が修正されていない
  • バウンス率が10%以上
  • 苦情率が0.5%以上
  • アカウントが同じ問題について複数回レビュー対象とされた
  • アカウントから送信されたEメールがAWSのサービス条件に違反している

バウンスには、大きく分けて以下の3種類があります。

  • Undetermined:どのバウンスか判断できない
  • Permanent:ハードバウンス
  • Transient:ソフトバウンス
bounceType bounceSubType 概要
Undetermined Undetermined 受取人の E メールプロバイダーはバウンスメッセージを送信しました。バウンスメッセージには、Amazon SES がバウンスの理由を判断できるだけの十分な情報が含まれていませんでし
Permanent General 受取人の E メールプロバイダーはハードバウンスメッセージを送信しました。このタイプのバウンス通知を受信した場合は、受取人の E メールアドレスをメーリングリストから即座に削除してください。
NoEmail バウンスメッセージから受信者のメールアドレスを取得できませんでした。
Suppressed 受信者の E メールアドレスは、最近の履歴でハードバウンスを生じているため、Amazon SES サプレッションリストに追加されています。
OnAccountSuppressionList Amazon SES は、アドレスがアカウントレベルのサプレッションリストにあるので、このアドレスへの送信を抑制しました。これは、バウンス率のメトリクスに対してはカウントされません。
Transient General 受取人の E メールプロバイダーは一般的なバウンスメッセージを送信しました。メッセージのバウンスを生じた問題が解決された場合、将来、同じ受取人にメッセージを送信できる可能性があります。
MailboxFull 受取人の E メールプロバイダーは、受取人の受信トレイが満杯であるために、バウンスメッセージを送信しました。メールボックスが満杯でなくなった場合、将来、同じ受取人に送信できる可能性があります。
MessageTooLarge 受取人の E メールプロバイダーは、受信したメッセージが大きすぎるために、バウンスメッセージを送信しました。メッセージのサイズを小さくすることで、同じ受取人にメッセージを送信できる可能性があります。
ContentRejected 受取人の E メールプロバイダーは、受信したメッセージにプロバイダーが許可しないコンテンツが含まれていたために、バウンスメッセージを送信しました。メッセージのコンテンツを変更することで、同じ受取人にメッセージを送信できる可能性があります。
AttachmentRejected 受取人の E メールプロバイダーは、メッセージ内に許容されないコンテンツが含まれていたために、バウンスメッセージを送信しました。たとえば、一部の E メールプロバイダーは特定のファイルタイプのファイルが添付されたメッセージや、非常に大きなファイルが添付されたメッセージを拒否する場合があります。添付ファイルのコンテンツを削除または変更することで、同じ受取人にメッセージを送信できる可能性があります。

ソフトバウンス=一時的なバウンスだから何も対応しなくていい、って思ってましたが存在しないドメインSESが把握していないメッセージが返却された場合などでもソフトバウンスとして判断されることがあるそうです。
よって、基本的にソフトバウンスだとしても詳細を確認して、適宜対応する必要がありそうです。

参考:
Amazon SES で存在しない宛先にメール送信した際のバウンス通知の内容を確認してみた
AWS SESでハードバウンスのようなメールがソフトバウンス扱いで届いた場合のしくみと対処について

メールが送信できないとかなり困ると思うので、対策について説明していきます。

バウンス・苦情が発生した際の通知

バウンス・苦情が発生した際に通知する手段として、以下の3つがあります。

  • Eメールのフィードバック転送
  • フィードバック通知 (SNS)
  • 設定セットのイベント送信先

細かい違いは置いといて、送られる内容の違いとしては以下のようになります。

内容 Eメールのフィードバック転送 フィードバック通知 (SNS) 設定セットのイベント送信先
From
To
件名
本文 × ×
バウンス・苦情の詳細 ×

Eメールのフィードバック転送
Fromで指定した送信元、もしくは、メール送信時に指定したフィードバック先メールアドレスへ以下のような通知を送ります。

5.png

E メールのフィードバック転送.png

フィードバック通知 (SNS)
指定したSNSトピックに通知を送ります。
SNSトピックのサブスクリプションには、EメールLambdaなどが指定できますが、Eメールを指定して通知を送ると以下のようになります。

6.png

フィードバック通知-元のヘッダーを含めない.png

※元のヘッダーを含めない、にしている場合はヘッダー要素がなくなります
{
	"notificationType": "Bounce",
	"bounce": {
		"feedbackId": "01060193bd9a2703-113732be-4432-47d3-962a-283878adce5d-000000",
		"bounceType": "Permanent",
		"bounceSubType": "General",
		"bouncedRecipients": [
			{
				"emailAddress": "bounce@simulator.amazonses.com",
				"action": "failed",
				"status": "5.1.1",
				"diagnosticCode": "smtp; 550 5.1.1 user unknown"
			}
		],
		"timestamp": "2024-12-13T01:20:16.000Z",
		"remoteMtaIp": "52.74.98.154",
		"reportingMTA": "dns; e234-7.smtp-out.ap-northeast-1.amazonses.com"
	},
	"mail": {
		"timestamp": "2024-12-13T01:20:15.988Z",
		"source": "***@example.com",
		"sourceArn": "arn:aws:ses:ap-northeast-1:***:identity/***@example.com",
		"sourceIp": "13.231.209.228",
		"callerIdentity": "AWSReservedSSO_AWSAdministratorAccess_4e81b62c3b93d452",
		"sendingAccountId": "***",
		"messageId": "01060193bd9a2474-8812a1a4-7447-480c-86f6-ad0c63bddab7-000000",
		"destination": [
			"bounce@simulator.amazonses.com"
		],
		"headersTruncated": false,
		"headers": [
			{
				"name": "Date",
				"value": "Fri, 13 Dec 2024 01:20:15 +0000"
			},
			{
				"name": "From",
				"value": "***@example.com"
			},
			{
				"name": "To",
				"value": "bounce@simulator.amazonses.com"
			},
			{
				"name": "Subject",
				"value": "こんにちは 中里さん"
			},
			{
				"name": "MIME-Version",
				"value": "1.0"
			},
			{
				"name": "Content-Type",
				"value": "text/plain; charset=UTF-8"
			},
			{
				"name": "Content-Transfer-Encoding",
				"value": "base64"
			},
			{
				"name": "X-Test-Id",
				"value": "1"
			}
		],
		"commonHeaders": {
			"from": [
				"***@example.com"
			],
			"date": "Fri, 13 Dec 2024 01:20:15 +0000",
			"to": [
				"bounce@simulator.amazonses.com"
			],
			"subject": "こんにちは 中里さん"
		}
	}
}

設定セットのイベント送信先
設定セットと呼ばれるルールのグループにイベント送信先を設定することで、通知を行うことが出来ます。
設定セットは、以下のどちらかで設定できますが、検証済みのIDに設定することが多いと思います。

  • 検証済みのID(ドメイン or メールアドレス)に設定
  • メール送信時に設定

7.png

以下のようなjsonがイベント送信先に送られます。

{
	"eventType": "Bounce",
	"bounce": {
		"feedbackId": "01060193bdbffb9f-95464acf-0ea7-49b3-b8ad-9f9f3770c97f-000000",
		"bounceType": "Permanent",
		"bounceSubType": "General",
		"bouncedRecipients": [
			{
				"emailAddress": "bounce@simulator.amazonses.com",
				"action": "failed",
				"status": "5.1.1",
				"diagnosticCode": "smtp; 550 5.1.1 user unknown"
			}
		],
		"timestamp": "2024-12-13T02:01:35.975Z",
		"remoteMtaIp": "13.213.169.222",
		"reportingMTA": "dns; e234-8.smtp-out.ap-northeast-1.amazonses.com"
	},
	"mail": {
		"timestamp": "2024-12-13T02:01:35.194Z",
		"source": "***@example.com",
		"sourceArn": "arn:aws:ses:ap-northeast-1:***:identity/***@example.com",
		"sendingAccountId": "***",
		"messageId": "01060193bdbff8da-e85c856f-738f-4755-8650-937618836252-000000",
		"destination": [
			"bounce@simulator.amazonses.com"
		],
		"headersTruncated": false,
		"headers": [
			{
				"name": "Return-Path",
				"value": "***@yahoo.co.jp"
			},
			{
				"name": "Date",
				"value": "Fri, 13 Dec 2024 02:01:35 +0000"
			},
			{
				"name": "From",
				"value": "***@example.com"
			},
			{
				"name": "To",
				"value": "bounce@simulator.amazonses.com"
			},
			{
				"name": "Subject",
				"value": "こんにちは 中里さん"
			},
			{
				"name": "MIME-Version",
				"value": "1.0"
			},
			{
				"name": "Content-Type",
				"value": "text/plain; charset=UTF-8"
			},
			{
				"name": "Content-Transfer-Encoding",
				"value": "base64"
			},
			{
				"name": "X-Test-Id",
				"value": "1"
			}
		],
		"commonHeaders": {
			"returnPath": "***@yahoo.co.jp",
			"from": [
				"***@example.com"
			],
			"date": "Fri, 13 Dec 2024 02:01:35 +0000",
			"to": [
				"bounce@simulator.amazonses.com"
			],
			"messageId": "01060193bdbff8da-e85c856f-738f-4755-8650-937618836252-000000",
			"subject": "こんにちは 中里さん"
		},
		"tags": {
			"ses:source-tls-version": [
				"TLSv1.3"
			],
			"ses:operation": [
				"SendTemplatedEmail"
			],
			"ses:configuration-set": [
				"bounce-test-set"
			],
			"ses:source-ip": [
				"13.231.209.228"
			],
			"ses:from-domain": [
				"yahoo.co.jp"
			],
			"ses:caller-identity": [
				"AWSReservedSSO_AWSAdministratorAccess_4e81b62c3b93d452"
			]
		}
	}
}

サプレッションリスト

バウンス・苦情の理由によっては、メールアドレスが正しいか確認して修正した利する必要があります。
その間は、バウンス率が上がるのを防ぐためにユーザへの送信を停止したいところですが、これを自前で構築しようとすると色々考慮が必要になりそうです...が、
AWSではサプレッションリスト(抑制リスト)という機能が提供されています:smile:

サプレッションリストには以下の2つあるのですが、以下のような挙動になります。

  • グローバルサプレッションリスト
  • アカウントレベルのサプレッションリスト

グローバルサプレッションリスト
全アカウントで共有されるリストになります。
基本的にアカウントレベルのサプレッションリストを有効化することになると思うので、あまり意識はしなくていいとは思います。

  • いずれかのAWSアカウントで発生したハードバウンスのメールアドレスが追加されます
  • このリストにあるメールアドレスへ送信を行おうとして、アカウントレベルのサプレッションリストが無効だと、SESは受け付けますがbounceSubType:Suppressedが発生します
  • このリストは閲覧・編集することが出来ません
  • 一定時間経過すると、自動的にリストから削除されます

アカウントレベルのサプレッションリスト
対象のアカウントで共有されるリストになります。
デフォルトで有効になっています。

  • 対象のAWSアカウントで発生したハードバウンスのメールアドレスが追加され、バウンス率がカウントされます
  • このリストにあるメールアドレスへ送信を行おうとすると、SESは受け付けますがbounceSubType:OnAccountSuppressionListが発生します
  • このリストにある状態で起こったバウンスは、バウンス率にカウントされません
  • 対象のメールアドレスがグローバルサプレッションリストにあったとしても、アカウントレベルのサプレッションが有効でリストになければ、メールは送信できます

テスト

SESのメール送信テスト周りについて説明します。

ローカルでのメール送信テストについて

ローカルでのテストで困るのは、メール実行環境の用意だと思います。
サポートにも問合せましたがAWS推奨の方法はないようなので、以下の3つから選択するのが良いと思います。

1. SESを模倣したスタブを自前で作成する
2. localstackなどのサードパーティーのエミュレーターサービスを利用する
3. 実際にSESにリクエストする ※その際は、サンドボックス環境で行うのが良い

AWS環境での大量送信テストについて

大量送信テストで困るのは、メールアドレスの用意だと思います。
サポートにも問合せしましたがAWS推奨の方法はないようなので、以下のどちらかを利用するのが良いと思います。

1. プラス記号を利用したメールアドレスを利用する
例:user+001@example.com, user+002@example.com

プラス記号を使ったメール送信は、ご利用のメールクライアントの送信制限に引っかかり正常に配信できない可能性があります。

2. AWSで用意されているシミュレータメールアドレスを利用する

こちらに送信したメールは実際にメールが送られるわけではないので、メールの内容確認は出来ません。
しかし、1日当たりの最大送信数のクォータの影響を受けなかったり、バウンスレートに計上されなかったりして負荷テストとしては有用です。

※バウンス時のイベント送信ログや通知などは行われます。
※1秒あたりの最大送信レートの影響は受けるので、BulkEmailEntryResultsでACCOUNT_THROTTLEDが返却されることの確認テストに利用できます

おわりに

今回はSESを利用したメール一括送信についてまとめました。
AWSでメール送信を利用する際は、必要な知識になってくると思うのでご参考になれば幸いです:bow:

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?