Amazon SES と SNS を使って バウンスメールを PHPでハンドリング

システムにメール送信機能を組み込む際に気を付けなければいけないのは、バウンスメール(エラーメール)の処理。

バウンスになったメールアドレスには今後はメールを送信しない仕組みを作らないと、送信元のサーバがブラックリスト入りしてしまい、問題ないメールアドレスにもメールが届かなくなってしまいます。

特にAmazon SESはバウンスメールが多くなると利用を制限されてしまうので注意が必要です。

今回はAmazon SES と SNS を使って バウンスメールを PHPでハンドリングする処理を紹介していきます。

コーディング

まずは先にコーディングを行い、サーバーにプログラムを配置します。

サーバーでバウンスメールをAmazon SNSから取得するには、以下の2つのプログラムを組んでおく必要があります。

  • SubscribeURLに自動でアクセスする処理(受信登録の確認)
  • バウンスメール(エラーメール)を取得する処理

※コーディングはAWS側の設定が済んでからでもOKです。

SubscribeURLに自動でアクセスする処理(受信登録の確認)

Amazon SNSの設定をすると、指定のサーバ(指定のURL)へJSON形式のデータがPOSTで送られてくることになります。

Amazon SNSの設定が済んだら、まずは受信登録の確認用のデータが送信されてきます。

その際、POSTされてくるデータの中にSubscribeURLという認証用のURLが含まれているので、そのURLにアクセスして認証をさせる必要があります。

PHP上でPOSTされてきたデータを解析して、SubscribeURLに自動でアクセスして自動で認証させる処理を記述します。

受信登録の確認の詳しいデータ形式は「公式サイト」を参照してください。

// AWS SDK for PHPをインクルード
include_once 'aws/aws-autoloader.php';

use GuzzleHttp\Client;

// Amazon SNSから送信されたPOSTデータ(JSON形式)を取得し、解析。
$snsObj = json_decode(file_get_contents('php://input'));

// 認証用のデータは TypeがSubscriptionConfirmationになっている
if ($snsObj->Type == 'SubscriptionConfirmation') {
    $client = new GuzzleHttp\Client();
    // SubscribeURLにアクセスする
    $client->get($snsObj->SubscribeURL)->send();
}

バウンス(エラー)になったメールアドレスを取得する

続いて、バウンス(エラー)になったメールアドレスを取得します。

バウンスの通知の詳しいデータ形式は「公式サイト」を参照してください。


// Amazon SNSから送信されたPOSTデータ(JSON形式)を取得し、解析。
$snsObj = json_decode(file_get_contents('php://input'));

// バウンスメールの場合は、TypeがNotificacion
if ($snsObj->Type == 'Notification') {
    // バウンスメールのデータはMssageの中にjson形式で保存されているので、
  // デコードする
    $msgObj = json_decode($snsObj->Message);

    // バウンスメールの通知か確認
    if ($msgObj->notificationType == 'Bounce') {
        // バウンスになったメールアドレスを取得
        foreach ($msgObj->bounce->bouncedRecipients as $bounce) {
            // バウンスになったメールアドレス
            print $bounce->emailAddress;
        }
    }
}

最終コード

今回は上記の2つのコードを1つのphpにまとめてしまいます。

ファイル名をget.phpにして、サーバーの任意の場所に配置しましょう。

include_once 'aws/aws-autoloader.php';

use GuzzleHttp\Client;

$msg_body = '';
$msgs     = json_decode(file_get_contents('php://input'));

if ($msgs->Type == 'SubscriptionConfirmation') {
    $client = new GuzzleHttp\Client();
    // SubscribeURLにアクセスする
    $client->get($msgs->SubscribeURL)->send();
} else {
    $msgs = json_decode($str);
    if ($msgObj->notificationType == 'Bounce') {
        foreach ($msgs->bounce->bouncedRecipients as $bounce) {
            // バウンスされたメールアドレスに対する処理を記述
            print $bounce->emailAddress;
        }
    }
}

AWS側の準備

コーディングができたら、AWS側の設定を行います。

設定が必要なのはAmazon SNSとSESの2つです。

1つ注意してほしいのは、SNSとSESのリージョンを同じにする必要があるという点です。
同じリージョンじゃないとうまく動作しないようなので注意してください。

今回は米国西部(オレゴン)を選択しています。

Amazon SNSにトピックを追加

まずはAmazon SNSにトピックを追加します。

サービス一覧の「Simple Notification Service」をクリックします。

SNSのダッシュボードが表示されるので、サイドメニューの「トピック」をクリックします。

トピック画面の「トピックを作成」ボタンをクリックします。

「名前」と「表示名」を適当に設定して、トピックを作成します。
今回は「名前」と「表示名」以外は特に設定せずに保存してしまってOKです。

トピックの作成を行うと、作成されたトピックの詳細画面に自動で遷移します。
※自動で遷移されない場合は、トピック一覧から作成したトピックを選択して詳細画面を開いてください。

サブスクリプションを追加、トピックと結びつける

トピック詳細画面で、「サブスクリプションを作成」ボタンをクリックします。

「トピックARN」は自動で入力されているはずなので、特にはいじりません。

「プロトコル」はHTTPかHTTPSを利用しましょう。
通知を受け取るPHPを配置したサーバー次第なので、状況に合わせて選びましょう。

「エンドポイント」とは、通知を送るURLです。
今回は最初に作成したget.phpの配置されているURLを記述してください。

他は特にいじらずに「サブスクリプションの作成」ボタンをクリックします。

サブスクリプションを作成すると、サブスクリプションの詳細画面が表示されます。

表示されたばかりのころはステータスが「保留中の確認」になっている場合があります。

事前にプログラムを作成して配置しているなら、画面を再読み込みすれば「確認済み」に変更されているはずです。

※「確認済」にならない場合、AWSの設定後にコーディングする場合は以下の通り

「確認済」にならない場合は、エンドポイントが間違っているか、プログラムに不具合があるかのどちらかが考えられます。

指定したエンドポイントにphpを配置したら以下の操作を行ってください。

  1. トピック一覧に戻って、トピックを選択
  2. トピック詳細のサブスクリプション一覧にあるサブスクリプションを選択
  3. 「リクエストの確認」ボタンをクリックしましょう。

Amazon SESで登録したメールアドレスにトピックを設定

最後にAmazon SESに登録されているメールアドレスに、作成したトピックを結びつけます。

Amazon SESのメールアドレス一覧から適当なメールアドレスをチェックして、「View Details」をクリックします。

メールアドレスの詳細が表示されるので、Notificationsの項目を開いて、「Edit Configuration」ボタンをクリックします。

BounceとComplaintsの2つのプルダウンの内容を、作成したトピック(今回はsample_sns)に設定します。

プルダウンの設定が済んだら、「Save Config」ボタンをクリックしましょう。

これで設定は完了です。

確認方法

メールアドレス一覧からトピックを結び付けたメールアドレスを選択して「Send a Test Email」ボタンをクリックします。

Toにバウンスになるメールアドレスを設定します。
バウンスになるメールアドレスは公式サイトで紹介されているbounce@simulator.amazonses.comを使います。

あとは、subjectとbodyを適当に入力して「Send Test Email」ボタンをクリックします。

AWS側の設定とプログラムを間違えてなければ、バウンスメールの処理が行われるはずです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください