Amazon SESのバウンスレート上昇時の対策



# はじめに
Amazon SES使ってますか？
多くのユースケースとしてAmazon Cognitoからのアクティベーションコードの送信時の利用が想定されますが(実際に公式も推奨してますし。)、SESを利用時には切っても切り離せない問題として **バウンスレート** と **スパム率** があります。SESではバウンスレートとスパム率が閾値を超えるとメールの送信が **制限** ないしは **停止** する可能性があります。

今回は **Cognitoからのアクティベーションメール送信をユースケース** とし、その対応策を考えていきたいと思います。
※アクティベーションコードのメールをスパム報告するユーザーは多くないと思っているので、今回はメール送信停止の主な原因であるバウンスレートを中心に書いていきます。

各種用語については今回は説明を省きます。優しい私がここにドキュメントを貼っておくのでわからない人は読んでください。
 [Amazon SES と配信性能](https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/sending-concepts-deliverability.html)

## もくじ
- バウンスレートを抑える(アプリ側対応)
- バウンスレートを抑える(インフラ側対応)
- バウンスレートを管理する。

## バウンスレートを抑える(アプリ側対応)
基本的に実装が容易な場合が多いです。ざっくり考えてみると以下の3つが思い浮かびました。

1. メールアドレス確認用のフォームを置く
2. 再送信可能回数を絞る
3. 正確なバリデーションチェックを行う

### 1.メールアドレス確認用のフォームを置く
割とよく見るケースだと思います。下の画像のようなイメージですね。
![コメント 2020-03-07 173240.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382072/1c591c2b-66b2-4ba5-e0db-7df6a0d3d424.png)

**Pros**

- ユーザーにメールアドレスの整合性の確認を任せられる
- Javascriptでも2つのメールアドレスの整合性確認ができる
- 対策の実装が容易

**Cons**

- 大抵のユーザーはコピペで済ませる
- メールアドレスが有効かどうかの確認はできない。(バリデーションチェックでは検知できない)
    - abc@example.com...メールが受信できる存在するメールアドレス(有効)
    - abb@example.com...存在しないメールアドレス(無効)

### 2. 再送信可能回数を絞る
こちらもよく見るケースの一つだと思います。再送信を可能にすることでソフトバウンスのユーザーの復帰に繋がりますが、何度も再送信可能な状態だとメールが届かなかったユーザーがハードバウンスを理由とした際にバウンスレートの上昇にも繋がります。そこで再送信回数を1回までに絞った場合です。

**Pros**

- 再送信の機能は残しつつ、バウンスレート上昇を抑えられる
- 対策の実装が容易

**Cons**

- 再送信の口は残しているので2回までバウンスカウントされる。
- 攻撃もできなくはない

### 3. 正確なバリデーションチェックを行う
バリデーションチェックを細かく行うことで、ユーザーの誤入力によって生まれる無効なメールアドレスで登録されることからある程度守ることができる。ライブラリで導入するのが一般的ですかね。

**Pros**

- 誤入力による無効なメールアドレスの登録を防ぐ
- メールアドレスをDBで管理する際にSQLインジェクションの防止にもなる

**Cons**　

- 特になし
- 言うまでもなかった


アプリ側の対応としてはざっくりこんな感じかなと思います。実装が容易なので、バウンスレート上昇の対策としては比較的取り入れやすいものだと思います。

続いてインフラ側対応です。
インフラ側対応は特にConsが思い浮かばないので特にPros Consは書きません。

## バウンスレートを抑える(インフラ側対応)
インフラ側(AWSサービスを利用する)の対応としては以下があります。
2点ともドキュメントを引用しているので、詳しくはドキュメントを確認してください。

1. Cloudwatchによる監視
2. アカウントレベルのサプレッションリストの有効化 **(2019年11月25日以降よりデフォルトで有効設定です。)**

### 1. CloudWatchによる監視
Amazon SESのバウンスレートやスパム率も漏れなくCloudWatchによる監視が可能です。
[CloudWatch を使用して評価モニタリングアラームを作成する](https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/reputationdashboard-cloudwatch-alarm.html)

Amazon SESでは、バウンスレートは **5%** 、スパム率は **0.1%** でレビュー対象となります。個人的にはレビュー対象となる以前から対応を取り始められるように、レビュー対象の閾値よりも少し低めに設定することをおすすめします。

また、ドキュメント上ではCloudWatch AlarmからのトリガーとしてAmazon SNSを設定しメールで通知する方法を紹介していますが、SNSでLambdaをトリガーさせてやることで通知方法を自由にカスタマイズすることも可能です。
私の所属するチームではチャットツールとしてSlackを利用しているので、最終的にSlackに通知が届くようになっています。

上記の場合の構成図
![コメント 2020-03-07 202726.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382072/3d66ff8c-0794-3768-df62-31dc98af09e0.png)

アラートが鳴った際の通知(日本語の文言はAlarm設定時に設定可能)
![コメント 2020-03-07 203359.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382072/df6df120-347f-4cdf-c73a-f4d90d86106c.png)

### 2. アカウントレベルのサプレッションリストの有効化 
**(2019年11月25日以降よりAmazon SESの利用を開始した場合はデフォルトで有効設定です。)**

Amazon SESには2つのサプレッションリストが存在します。 **グローバル** と **アカウントレベル** です。詳しくはドキュメントをいただけると幸いです。
[グローバルサプレッションリスト](https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/sending-email-global-suppression-list.html)
[アカウントレベルのサプレッションリスト](https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/sending-email-suppression-list.html)

最も大きな違いとしては、以下の点です。

>Amazon SES は、アカウントレベルのサプレッションリストのアドレスに送信したメッセージを、アカウントのバウンスレートに対してカウントしません。

図も用意してみました。

![コメント 2020-03-07 205400.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382072/f480a2d0-779c-ba31-0076-eb6f1a100123.png)

Amazon SESの仕様として、アカウントレベルに追加されているメールアドレスに対してメール送信のリクエストを受け取った際、 **拒否せずメールは送信しない** ので、すでにアプリでメール再送信などの場所を用意しておいた場合でも、アプリ側に手を入れる必要はないので導入しやすいですね。
アカウントレベルのサプレッションリストでは手動でリストの登録削除なども可能なので、ドキュメントを読まれることをおすすめします。


インフラ側の対応としてはこんな感じですかね。どちらも非常に効果的な対応になるので、予め設定を有効にしておくといいでしょう。


## バウンスレートを管理する。
ここまでバウンスレートの上昇を抑える対策を上げてきましたが、正直に言うとバウンスレートは管理することができます。
[Never send to old addresses, but what if you have to?](https://aws.amazon.com/jp/blogs/messaging-and-targeting/never-send-to-old-addresses-but-what-if-you-have-to/)

記事を要約します。(記事の訳ではないので注意)

- Amazon SESから確実に届くメールアドレスに対してメールを送信する。
- バウンスレート・スパム率は総送信数の対比なので、メールの送信成功が増えればバウンスレート・スパム率は下がる。
- 各レートが上昇してきたら確実届くにメールアドレスにメールを送信することで自己的に下げることが可能になる。

穴を突いたような話ですが、AWSの公式ブログで紹介されているので全然ホワイトな方法のようですね！！
私のチームではまだこの方法をとってはいないので、その仕組を構築した際にはまた記事にしようと思います。

# 最後に
今回はAmazon SESのバウンレート対策の方法を記事にしてみました。Amazon SESは記事としてまとまっていることも少ないので、参考になればいいなと思います。
また他にもこんな方法があるよ、うちではこんなことやってるよとかも教えていただけると幸いです。