SESでバウンス率が高くなってAWSから警告が来たので対応した話

こんにちは。medibaでAWSを利用してサービスを運営しているエンジニアの小川です。
この記事は[mediba Adventカレンダー](https://qiita.com/advent-calendar/2020/mediba)の22日目という事で、ちょうど最近SESのバウンス率で四苦八苦したので、記録として残したいと思います。

# はじめに
### AWSのSESはバウンス率10%で送信停止される

サービス内でメール送信を行っているサービスも多いと思います。
medibaで運用しているサービスでもメール送信を行っているサービスがあるのですが、
実は、SESはサービスの運用中にバウンス率が10%を超えるとAWSからメールの送信機能を停止する旨が規約に記載されています。

```
アカウントのバウンス率が 10% を超えた場合、当社はお客様のアカウントによる E メール送信機能を一時的に停止することがあります。
```

( [バウンス率について](https://docs.aws.amazon.com/ja_jp/pinpoint/latest/userguide/channels-email-deliverability-dashboard-bounce-complaint.html#channels-email-deliverability-dashboard-bounce-complaint-overview-bouncerate))

メールはサイト内の認証フローや問い合わせなどに使用していることが多いかと思いますが、
メール送信を止められるとサービスが成り立たなくなるサイトも多いはずです。
しかし、AWSはこちらの事情は関係なく機能を停止し、改善が図られるまではメール送信機能を凍結します。


今回は事前の警告として、バウンス率5%を超えた際AWSが警告をくれたので、その際の対応内容を残します。

# 知っておいた方がいい事
- 警告は突然来る
    - 当然ですが、警告はある日突然来ます。事例によっては警告なしで突然凍結になるという話もありますので、SESを使用した機能をリリースする前に、「凍結された際にどういう対応をするか」は検討しておいた方が良いです。
- 警告は英語メールで来る
    - AWS supportからのメール本文は英語で来ます。返信も英語で行う必要があります。
通常時ならともかく、障害に近い状況で英語対応をするのは、英語力に自信がないと少し焦ります。


# 効果がないこと
### AWSに凍結を待ってもらうように事情を説明をする
バウンス率は一定期間のエラー率を集計しているため、タイミングによってはエラー率が上がることはあります。(訴求施策を行った直後など)
  「直近でこれこれこういう施策を行ったのだが、数日待てば落ち着くから待ってくれ」と言いたい気持ちになるのですが、AWS support 側は利用の経緯などは気にしておらず数値のみを見ています。
そのため、数値が落ち着く算段がつくのであれば、「調査し対応します」とだけ返信し、数日待つ形でも問題ないです。
実際にバウンス率が下がってくれば、AWS support側で判断して進捗ありと認識してくれます。

逆にバウンス率が下がらなければ、サービスの事情は加味されないので、説明の英文を作る労力は止めにして、数値を下げる具体的な施策を考えた方が前向きだと思います。

# 効果があること
バウンス率を下げるために直接的に効果がある方法を考えましょう。
今回は以下の入会フローを持ったサイトを例に話します。

![ノーマル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/872445/3ffabba2-89fb-f78f-3df3-4597684202e0.png)

### ①ユーザの入力間違いを考慮しサプレッションリストを使用する
サービスの入会登録などの場合、サイト内からユーザにEmailアドレスを入力してもらい
そのEmailアドレスに対して登録URLを送るフローが多いかと思います。

その際に、最初にユーザが入力するEmailアドレスが正しく受信できるEmailアドレスかどうかは、担保できません。
極端に言うと

```
① ユーザが誤ったEmailアドレスを入力
↓
② システムから「登録用メール」をユーザに送信するが、送信失敗
↓
①' ユーザが再度誤ったEmailアドレスを入力
↓
②'. システムから「登録用メール」をユーザに送信するが、送信失敗
↓
①''. ユーザが再度誤ったEmailアドレスを入力
↓
②''. システムから「登録用メール」をユーザに送信するが、送信失敗
↓
~~
```

といった形でユーザが間違ったEmailアドレスを入力し続けると、バウンスメールが発生し続けます。
(ユーザは自分の入力誤りに気づくのは難しいので、何度も同じ誤りをする可能性があります)

ですので、一度バウンスメールが発生したら同じEmailアドレスは一定期間アカウントサプレッションリストに登録し、バウンスメールにならないようにしましょう。
([アカウントサプレッションリストについて](https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/sending-email-suppression-list.html))


### ②迷惑フィルターを考慮する
- 日本国内のキャリアが保有するメール
    - au (ezweb.ne.jp、au.com)
    - Softbank (softbank.ne.jp、i.softbank.jp)
    - docomo (docomo.ne.jp)

には迷惑メールフィルターという機能が各社それぞれであり、`ケータイ/PHSのみ許可` `URLつきリンク拒否`など各種のフィルタリング機能を保有しています。

各社それぞれで設定できる内容は異なりますが、迷惑フィルターでバウンスが発生する可能性としては
「サービスから送信したメールがユーザ個別の迷惑フィルターに引っかかり、受信できなかった」
という状況が想定されます。

その際に考慮すべきなのは[SMTPのレスポンスコード](https://tools.ietf.org/html/rfc5321#section-4.2.3)です。
キャリア及び各キャリアのフィルター設定によって、以下の２パターンのレスポンスコードになる可能性があります。

- 250：SMTPとしては正常に送信完了
   - キャリア側にてエンドユーザに配信をしないようにしている
- 550：SMTPとしては送信失敗

SES側は250が返ってくれば送信成功とみなしますが、550の場合はバウンスとして扱う模様です。
そのため、利用ユーザが多いキャリアとそのキャリアのフィルター設定を確認し、550として扱うフィルターがあれば、それを解除する設定をユーザへ説明し促す記載をサイトに追記するのが無難です。

ちなみに、auの[URLリンク規制](https://www.au.com/support/service/mobile/trouble/mail/email/filter/detail/antiurl/) は `550` がレスポンスコードとして返却されるフィルタリングになっていました。(2020年11月時点)

### ③送信成功メールを増やす
上記２件とは異なるアプローチですが、バウンス率を下げるために成功メール数を増やすというアプローチも一定の効果があります。

![追加パターン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/872445/573f13da-0f7e-9397-fa86-6d867537d72f.png)

もともと
　①入会登録ページURL(トークン付き)をメール送信
のみがサイト→ユーザへメール送信するタイミングですが、ここに
　②登録完了メールを送信
　③登録完了ユーザへおすすめコンテンツを告知するメール送信
などを追加します。


登録完了しているユーザはすなわち①のメールが受信出来ているユーザなので、②③は送信失敗する可能性はかなり低くトータルとしてバウンス率を下げる事ができます。

(メルマガの配信などはOpt-Inにてユーザの承諾が必要になりますので、自サイトで取得した許諾に適した内容にて送信するようにしましょう)

# おわりに
AWSのSESは、費用も安価で設定もシンプル、且つ暗号化やDKIM設定も対応しているので、手軽に利用できるSMTP機能です。
しかし、その分AWS側からの制約には適切に対応する必要があります。

利用するに当たっては、最悪メールが凍結された際にはどういうフローの運用にするか、まで検討しておくと急な警告が来た際にも慌てずにいられると思います。