SES でバウンス・苦情率を改善するためのサプレッションリストを試してみる

# はじめに

一般的にメールサーバーを運用するのは大変です。出来るだけバウンス率(Bounce Rate)や苦情率(Complaint Rate)を下げて、自分たちが送付するメールが世の中に迷惑をかけていないことを守っていく必要があります。Amazon SES (Simple Email Service) をはじめとした、メールを送るときに、一般的に気を付けるべきポイントです。

Amazon SES には、その運用負担を軽減するサプレッションリスト機能が有り、以前に送ったメールがバウンスや苦情になってしまった場合、そのメールアドレス宛への送信を自動的に抑止が出来ます。

また、サプレッションリストと並行して、バウンスと苦情をそもそも発生させないように、メールの宛先や内容を健全に保つように日々アップデートすることも非常に重要です。

今回の記事では、サプレッションリストの紹介と動作を確認してみます。



# サプレッションリストとは

以前に送ったメールがバウンスや苦情になってしまった場合、そのメールアドレス宛への送信を自動的に抑止が出来ます。
SES には 「グローバルサプレッションリスト」と「アカウントレベルサプレッションリスト」の2種類があります。



- グローバルサプレッションリスト (global suppression list)
  - **SES の利用者全体に適用**される。無効にすることはできない。
  - 利用者が SES を使って送信したメールがハードバウンスを起こした場合、SES は自動的にそのメールアドレスをグローバルサプレッションリストに**一時的に追加**する。
  - グローバルサプレッションリストに既に登録されているメールアドレス宛にメールを送信しても、SES はメッセージを受け付けるが送信しない。SES 利用者全体で共有されるので、他のアカウントの影響を受ける。
  - 一定時間経過後、SES はグローバルサプレッションリストからメールアドレスを削除する。ハードバウンスするたびに一時的に登録される期間が長くなる。最長14日間残る。
  - グローバルサプレッションリストに登録されているメールアドレスを手動で削除できる
  - グローバルサプレッションリストに登録されているアドレス宛に送付した場合、**AWS アカウントのバウンスレートにカウントされる。**
  - **グローバルサプレッションリストはバウンスレートの改善に利用できない。**
  - https://docs.aws.amazon.com/ja_jp/ses/latest/dg/sending-email-global-suppression-list.html



- アカウントレベルサプレッションリスト (account-level suppression list)
  - **AWS アカウント単体**に適用される
  - 利用者が SES を使って送信したメールがハードバウンスを起こした場合、SES は自動的にそのメールアドレスをアカウントレベルサプレッションリストに追加する
  - 明示的に削除しない限り、アカウントレベルサプレッションリストに存在し続ける
  - アカウントレベルサプレッションリストに登録されているアドレス宛に送付した場合、**AWS アカウントのバウンスレートにカウントされない。**
  - **アカウントレベルサプレッションリストはバウンスレートの改善に利用可能。**
  - https://docs.aws.amazon.com/ja_jp/ses/latest/dg/sending-email-suppression-list.html



# アカウントレベルサプレッションリストを確認

マネージメントコンソールから、Suppression list を選択することで、アカウントレベルサプレッションリストが有効か確認できます。2019 年 11 月 25 日以降に作成された AWS アカウントは、デフォルトで有効になっており、SES を使って送付したメールが、バウンス or 苦情となった場合に、自動的にアカウントレベルサプレッションリストに登録されます。

![image-20211225194640130.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/e22f8e59-922a-50bc-3649-b1f2ad4e86a5.png)



自動的にアカウントレベルサプレッションリストに登録する挙動を確認するため、AWS CLI でメールを送ってみます。
(意図的にバウンスメールを送っているので、SES さんごめんなさい・・・。)

```
aws sesv2 send-email \
--from-email-address from@sugiaws.tokyo \
--destination ToAddresses=notfound@sugiaws.tokyo \
--content '
{
  "Simple": {
    "Subject": {
      "Data": "MySubject",
      "Charset": "UTF-8"
    },
    "Body": {
      "Text": {
        "Data": "MyBody",
        "Charset": "UTF-8"
      }
    }
  }
}'
```



このメールを送った後、すぐに自動登録されています。サプレッションの理由も書かれています。

![image-20211225195146472.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/ac69278e-7a30-4495-2dbd-5164f9bc2eef.png)



この時の SES のログを確認します。

- eventType : Bounce
- bounceType : Permanent
- bounceSubType : General : メールの宛先プロバイダーが、ハードバウンスとして処理した
- bouncedRecipients : 宛先メールアドレスやバウンスになった理由が含まれている

```
{
	"eventType": "Bounce",
	"bounce": {
		"feedbackId": "0106017df13b877a-4a2aa79e-aebd-40f2-bc01-48c54331dde1-000000",
		"bounceType": "Permanent",
		"bounceSubType": "General",
		"bouncedRecipients": [
			{
				"emailAddress": "notfound@sugiaws.tokyo",
				"action": "failed",
				"status": "5.1.2",
				"diagnosticCode": "smtp; 553 5.1.2 Unknown mail server. Could not find a mail server for sugiaws.tokyo"
			}
		],
		"timestamp": "2021-12-25T10:55:50.302Z",
		"reportingMTA": "dns; e234-3.smtp-out.ap-northeast-1.amazonses.com"
	},
	"mail": {
		"timestamp": "2021-12-25T10:55:48.472Z",
		"source": "from@sugiaws.tokyo",
		"sourceArn": "arn:aws:ses:ap-northeast-1:xxxxxxxxxxxx:identity/sugiaws.tokyo",
		"sendingAccountId": "xxxxxxxxxxxx",
		"messageId": "0106017df13b80f8-e9fcb4f6-3e84-4ace-9612-721857a7b60f-000000",
		"destination": [
			"notfound@sugiaws.tokyo"
		],
		"headersTruncated": false,
		"headers": [
			{
				"name": "From",
				"value": "from@sugiaws.tokyo"
			},
			{
				"name": "To",
				"value": "notfound@sugiaws.tokyo"
			},
			{
				"name": "Subject",
				"value": "MySubject"
			},
			{
				"name": "MIME-Version",
				"value": "1.0"
			},
			{
				"name": "Content-Type",
				"value": "text/plain; charset=UTF-8"
			},
			{
				"name": "Content-Transfer-Encoding",
				"value": "7bit"
			}
		],
		"commonHeaders": {
			"from": [
				"from@sugiaws.tokyo"
			],
			"to": [
				"notfound@sugiaws.tokyo"
			],
			"messageId": "0106017df13b80f8-e9fcb4f6-3e84-4ace-9612-721857a7b60f-000000",
			"subject": "MySubject"
		},
		"tags": {
			"ses:operation": [
				"SendEmail"
			],
			"ses:configuration-set": [
				"ses-bounce-log"
			],
			"ses:source-ip": [
				"xxxxxxxxxxxx"
			],
			"ses:from-domain": [
				"sugiaws.tokyo"
			],
			"ses:caller-identity": [
				"xxxxxxxxxxxx"
			]
		}
	}
}
```



アカウントレベルサプレッションリストに登録されている状態で、もう一回送ってみます。

```
aws sesv2 send-email \
--from-email-address from@sugiaws.tokyo \
--destination ToAddresses=notfound@sugiaws.tokyo \
--content '
{
  "Simple": {
    "Subject": {
      "Data": "MySubject",
      "Charset": "UTF-8"
    },
    "Body": {
      "Text": {
        "Data": "MyBody",
        "Charset": "UTF-8"
      }
    }
  }
}'
```



このときのログを確認します。

- eventType : Bounce
- bounceType : Permanent
- bounceSubType : **OnAccountSuppressionList** : アカウントレベルサプレッションリストに登録されているため、SES がメールを送るのをやめた
- bouncedRecipients : 宛先メールアドレスやバウンスになった理由が含まれている

```
{
	"eventType": "Bounce",
	"bounce": {
		"feedbackId": "0106017df13bb5cc-e237d059-cf73-4fb6-ad40-6ed401cfde4c-000000",
		"bounceType": "Permanent",
		"bounceSubType": "OnAccountSuppressionList",
		"bouncedRecipients": [
			{
				"emailAddress": "notfound@sugiaws.tokyo",
				"action": "failed",
				"status": "5.1.1",
				"diagnosticCode": "Amazon SES did not send the message to this address because it is on the suppression list for your account. For more information about removing addresses from the suppression list, see the Amazon SES Developer Guide at https://docs.aws.amazon.com/ses/latest/DeveloperGuide/sending-email-suppression-list.html"
			}
		],
		"timestamp": "2021-12-25T10:56:02.119Z",
		"reportingMTA": "dns; amazonses.com"
	},
	"mail": {
		"timestamp": "2021-12-25T10:56:01.717Z",
		"source": "from@sugiaws.tokyo",
		"sourceArn": "arn:aws:ses:ap-northeast-1:xxxxxxxxxxxx:identity/sugiaws.tokyo",
		"sendingAccountId": "xxxxxxxxxxxx",
		"messageId": "0106017df13bb4b5-14786514-21ee-40c6-9deb-19d28f301401-000000",
		"destination": [
			"notfound@sugiaws.tokyo"
		],
		"headersTruncated": false,
		"headers": [
			{
				"name": "From",
				"value": "from@sugiaws.tokyo"
			},
			{
				"name": "To",
				"value": "notfound@sugiaws.tokyo"
			},
			{
				"name": "Subject",
				"value": "MySubject"
			},
			{
				"name": "MIME-Version",
				"value": "1.0"
			},
			{
				"name": "Content-Type",
				"value": "text/plain; charset=UTF-8"
			},
			{
				"name": "Content-Transfer-Encoding",
				"value": "7bit"
			}
		],
		"commonHeaders": {
			"from": [
				"from@sugiaws.tokyo"
			],
			"to": [
				"notfound@sugiaws.tokyo"
			],
			"messageId": "0106017df13bb4b5-14786514-21ee-40c6-9deb-19d28f301401-000000",
			"subject": "MySubject"
		},
		"tags": {
			"ses:operation": [
				"SendEmail"
			],
			"ses:configuration-set": [
				"ses-bounce-log"
			],
			"ses:source-ip": [
				"xxxxxxxxxxxx"
			],
			"ses:from-domain": [
				"sugiaws.tokyo"
			],
			"ses:caller-identity": [
				"xxxxxxxxxxxx"
			]
		}
	}
}
```







# 付録 : グローバルサプレッションリストからアドレスを削除

グローバルサプレッションリストから手動で削除する画面を確認してみます。一部のリージョンの Old Console でのみ操作可能です。

- 米国東部 (バージニア北部)
- 米国西部 (オレゴン)
- ヨーロッパ (アイルランド)



メールアドレスを入力して、画像に表示されている文字列をいれて Submit を押すと、グローバルサプレッションリストから削除できそうです。

![image-20211225182651412.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/f12d0b61-c1fd-2b5c-fafa-e58fcb4fc205.png)



# まとめ

Amazon SES には、一般的なメールの運用で重労働となる苦情率・バウンス率を下げるサプレッションリストという機能があると紹介しました。特に、アカウントレベルサプレッションリストは、メール送信を抑止するとバウンスとしてカウントされないため、改善に便利に利用できます。また、サプレッションリストと並行して、そもそも送るべきメール宛先と内容は合わせて改善をしてくのが良いです。更に健全に運用が出来るとおもいます。



# 参考URL

Amazon SES グローバルサプレッションリストの使用
https://docs.aws.amazon.com/ja_jp/ses/latest/dg/sending-email-global-suppression-list.html

アカウントレベルのサプレッションリストの使用
https://docs.aws.amazon.com/ja_jp/ses/latest/dg/sending-email-suppression-list.html