コンテンツにスキップするには Enter キーを押してください

AWS S3とSESで「メーラーを用いた会員登録」を実装する

こんにちは、Fusic2年目の吉野です。

Webサービスでたまに見る「空メールを送信して、会員登録をする」機能を案件で作る必要がありました。
  

  

今回はそれをAWSを用いて実装したものを紹介します。

構成は以下のような形です。

また、今回はメールの送信者に対して、会員登録用のリンクを送るのみで、実際の会員登録のロジックやリンクの生成については触れません。

  

SESの設定をする

AWSマネジメントコンソールのSESのEmail Receivingの設定をします。

まずはRule setの新規作成で、受け取り用のメールアドレスを追加します。

  

ドメインをVerifyしていない場合は、SESのIdentity Managementの設定から、Domainを選択して、認証を完了する必要があります。

設定の際に発行される、MXレコードをDNSに追加することで、認証が可能です。
(※この際、「Use Route53」を押すと、Route53のMXレコードが自動で上書きされるため、注意してください。)

  

次にActionを設定します。

今回はS3にメールの内容を保存するため、S3を選択します。

S3bucketは既存のものを選択、もしくは新規作成をします。
既存のものを選択した場合は、権限に注意してください。

また、prefixは任意に設定。
SNS topicもここで新規作成が可能です。

最後にRule nameを入力して、SESの設定は完了です。

  
    
  

メールがS3に保存されるか確認する

設定したメールアドレスにメールを送ると、S3にメールの内容が保存されるか確認します。

以下のようにS3にファイルが保存されていることがわかります。

ファイルをダウンロードして、中身を確認すると、メールのヘッダーと共に、メールの内容が表示されます。

  

S3からメールアドレスを取得して、会員登録メールを送る

次にメールを送信したユーザーのアドレスに対して、会員登録用のリンクを送付します。

今回はアプリケーション側はCakePHP3を用いているため、CakePHP3のShellの機能を利用します。

class MailRegisterShell extends AppShell
{
    private $s3Region = '';
    private $s3Key = '';
    private $s3Secret = '';
    private $s3Bucket = '';
      
    public function startup()
    {
        parent::startup();
                // S3の読み取り権限のみを付与した、AWSのIAMの情報を入力します。
        $this->s3Region = Configure::read('MailRegister_Aws_Settings.Region');
        $this->s3Key = Configure::read('MailRegister_Aws_Settings.Key');
        $this->s3Secret = Configure::read('MailRegister_Aws_Settings.Secret');
        $this->s3Bucket = Configure::read('MailRegister_Aws_Settings.Bucket');
    }
          
    public function main()
    {
        $this->getFromS3();
    }
          
    public function getFromS3()
    {
        $s3 = Aws\S3\S3Client::factory([
            'region' => $this->s3Region,
            'key' => $this->s3Key,
            'secret' => $this->s3Secret,
        ]);
        try {
                        // Bucketからオブジェクト一覧を取得
            $list = $s3->ListObjects(['Bucket' => $this->s3Bucket]);
                          
                        // オブジェクトからメールアドレスを取得
            $emails = $this->getEmail($s3, $list['Contents']);
            foreach ($emails as $email) {
                try {
                    // ここにメールを送るメソッドを記述
                } catch (Exception $e) {
                    echo $e->getMessage();
                }
            }
                        // オブジェクトを削除
            $this->deleteObject($s3, $list['Contents']);
        } catch (S3Exception $e) {
            echo $e->getMessage();
        }
    }
          
    // S3オブジェクトからメールアドレスのみをとってくる
    private function getEmail($client, $objects)
    {
        $emails = [];
        foreach ($objects as $object) {
            $result = $client->getObject([
                'Bucket' => $this->s3Bucket,
                'Key' => $object['Key'],
            ]);
                        // <>で囲まれた部分をとってくる
            $start = mb_strpos($result['Body'], '<') + 1;
            $end = mb_strpos($result['Body'], '>');
            array_push($emails, mb_substr($result['Body'], $start, $end - $start));
        }
        // 重複を削除
        $emails = array_unique($emails);
        return $emails;
    }
          
        // S3オブジェクトを削除する
    public function deleteObject($client, $objects)
    {
        foreach ($objects as $object) {
            $result = $client->deleteObject([
                'Bucket' => $this->s3Bucket,
                'Key' => $object['Key'],
            ]);
        }
    }
}

  

このShellをcronで定期的に実行することによって、メールを送信したユーザーに対して、会員登録のメールが届きます。

  

以上、AWS S3とSESで「メーラーを用いた会員登録」を実装してみました。

SESの設定、非常に手軽にできますので、是非やってみてください。

ありがとうございました。

Fusicエンジニア。Webアプリケーションやブロックチェーンプログラミングをしています。PHP, Vue.js, Solidity etc..

コメントする

コメントを残す

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