DirectMailの送信結果を判定する

Posted on 2020/08/24

ToC

バウンスメール

Direct Mailの利用方法は、色々とAPIを触りながら理解が深まってきました。
今回は、実際のアプリケーションでの利用を想定したユースケースを考えてみます。

一般的にメールの送信を行う際には、メールの不達(バウンス)を出さないことが望ましいとされています。 メールが不達となるパターンとして、ソフトバウンスハードバウンスの2つがあります。

  • ソフトバウンス
    受信サーバーのメールボックスが一杯であったり、メッセージサイズが大きすぎるので 受信を拒否された等の一時的に宛先の受信サーバーの都合で受信ができない場合に発生するバウンスです。
  • ハードバウンス
    宛先のメールボックスがない、宛先のメールアドレスが不正など宛先の受信サーバーの状態によらない 致命的なエラーの場合に発生するバウンスです。(特定の送信元からのメールの受信拒否機能を持つ受信サーバーでは、 受信拒否の場合にハードバウンスとして、エラーを返す機能を持っていることもあります。)

ハードバウンスをたくさん送信すると、メールサーバーの相対的な信頼度(レピュテーション)が低下し 送信するメールがスパムメールと判定されるなど、アプリケーションとしては望ましくない状況となるため これを未然に食い止めることが必要になります。

Direct MailのプロダクトルールにもCredit gradesというものが定義されていて、 バウンス率が上がると1日あたりに送信可能なメール上限数が引き下げられるなどの規定があります。

バウンスメールを送信しないために

そのため、アプリケーションとしては、Direct Mailを利用しながらできるだけメールの不達(バウンス)を 発生させない施策を考える必要があります。

一般的な方法としては、一度ハードバウンスとして判定されたメールアドレスをプレッションリスト(Deny List) として一定期間保持することが考えられます。そして、メールを送信する前にサプレッションリストで宛先のアドレスを チェックして、リストに宛先が存在する場合にはメール送信を実行しないような施策が取られることがあります。 Direct Mail自体には、サプレッションリストの機能がないため、こうした機能をアプリケーション側で 検討して構築する必要があります。

Direct MailのSingleSendMail APIはAPI実行した際のレスポンスでは宛先のアドレスのメールボックスにメールが正常に到達したのか、不達(バウンス)となったかの 送信結果はわかりません。
そのため、アプリケーションは非同期処理にて、Direct Mailからメールの送信結果を取得して サプレッションリストを構成する必要があります。その方法として、Direct Mailの機能を利用すると 下記の2種類が考えられます。

  1. SenderStatisticsDetailを利用する
  2. Asynchronous notificationsを利用する

Sender Statistics Detailによる実装アイデア

Sender Statistics Detailは、メール送信の記事でも触れたレポーティングの機能を利用する方法です。 API(SenderStatisticsDetailByParam)にて、送信結果のログを参照できるためStatusMessageを 利用して、ハードバウンスを抽出し、対象となったToAddressをサプレッションリストに登録することが できそうです。

{
  "RequestId": "12345678-ABCD-EFGH-IJKL-123456789012",
  "data": {
    "mailDetail": [
      {
        "Status": 4,
        "UtcLastUpdateTime": 1597194016,
        "Message": "550  relaying denied by recipient not exist of check_mx_available plugin",
        "LastUpdateTime": "2020-08-12T09:00Z",
        "ToAddress": "error@example.net",
        "AccountName": "sendonly@m.example.tokyo"
      }
    ]
  },
  "NextStart": ""
}

この方法のメリットは、送信処理結果がDirect Mailの機能で一覧化されている点です。メール送信結果の発生時刻もあるので、定期的にバックグラウンドでバッチ処理を実行することでサプレッションリストを構成できます。

デメリットとしては、スケーリングが難しいという点があります。大量のメール送信を行うアプリケーションの場合には、1回でバックグラウンドで処理するデータ量が増えて処理時間が増大したり、これを解決するためにバッチの実行間隔が短くなったりするなど日和見対応に陥る可能性をはらんでいます。

そのほかにも、アプリケーションから送信したメールと送信結果が付き合わせることができないという機能的な課題もあります。現状のSender Statistics Detailでは、メールを一意に特定するEnvIdの属性が提供されないため、具体的にアプリケーションが送信したどのメールが原因でサプレッションリストに登録されたかという詳細までは追うことができません。Alibaba Cloudの機能アップに期待したいですね。

Asynchronous notificationsによるのサプレッションリストの実装アイデア

もう一つの方法として、Asynchronous notificationsの機能を利用する方法です。こちらは、送信処理結果をMessage Queue Service (MNS)のイベントとして受け取ってサプレッションリストを構築する方法です。 こちらの機能は、杭州リージョンでのみ機能提供されているため利用リージョンに制約がありますが、1つの送信結果ごとにイベント通知されるためイベントドリブンな処理が実現できます。

メリットは、先ほどの逆になりますが、イベントごとに処理が実行されるのでFunctionsなどのサーバレスコンピュートを使ったスケールアウトのデザインが可能です。そして、アプリケーションから送信したメールと送信結果が付き合わせも可能です。

デメリットは、強いて言えば、Direct Mailが一覧化、集計してくれる訳ではないのでStoreまでの処理の自前構築が必要なことです。

SenderStatisticsDetailを利用してとりあえずサービス適用して、問題が顕在化しそうになってきたら、Asynchronous notificationsの方式に切り替えても良いのかもしれませんね。

参照