🐕

Amazon SESでAWS SDK for PHPを使ってEメール送信してみた

2023/01/21に公開

はじめに

今回はAmazonSESサービスを使用して、Eメール配信システムを構築しました。
AmazonSESを使用するメリットは
・迅速にサービスを立ち上げられる
・メールのトラッキングができる(到達率、開封率、クリック数、バウンス数など)
・大量メール配信可能
・スケールアップが容易
・セキュアな環境
・コストが低い
・DKIMの導入で、なりすましメールだと判断されにくい
などです。
メール配信システムを構築する際の手助けになれば幸いです。

構築環境

サーバ:Amazon Lightsail
OS:Ubuntu 20.04.5
DNS:お名前.com
メールシステム:Amazon SES
言語:php7.4.3
パッケージ管理システム:Composer 2.2.5

前提条件

Amazon Lightsailでインスタンスを用意(OSはUbuntsを使用)
ドメインの登録とDNSの設定(今回はお名前.comを使用)

構築手順

1.SESの作成

※今回はサンドボックス環境で行います。サンドボックス外へ移動する場合はこちら

①左メニューより「検証済みID」を選択し、「IDの作成」をクリック

②IDの作成

IDタイプ:ドメイン
ドメイン:お名前.comで登録したドメインを記載
デフォルト設定セットの割当:チェックなし
カスタムMAILFROMドメインの使用:チェックなし

※送信者側のメールアドレスのドメインになります。受信側は⑥~で設定

③ドメインの検証

IDタイプ:Easy DKIM
DKIM署名キーの長さ:RSA_2048_BIT
DNSレコードのRoute53への発行:チェックはずす
※今回は「お名前.com」を使用するため
DKIMの署名:チェックいれる

④CNAMEレコードを設定

先程作成したIDを選択し、認証タブからDNSレコードの発行詳細でCNAMEレコードをお名前.comのDNS設定レコードから設定

・Amazon SNS

・お名前.com

⑤検証済みかどうか確認する

IDステータス:検証済み
DKIMの設定:成功
になっていれば、完了

*送信テストをする際に受信するメールアドレスIDの検証が必要となります。検証をしないとサンドボックス環境ではメールを受け取ることができません。

⑥左メニューより「検証済みID」を選択し、IDの作成

⑦EメールアドレスIDの作成

IDタイプ:Eメールアドレス
Eメールアドレス:テストの際に受信できるメールアドレスを入力
※Eメールアドレスは、アクセスでき、メールを受信できるアドレスでなければなりません。
デフォルト設定セットの割り当て:チェックなし

⑧IDの作成に使用したEメールアドレスの受信トレイを確認し、no-reply-aws@amazon.comからのEメールを探す

⑨Eメールを開き、Eメールのリンクをクリックして、Eメールアドレスの検証プロセスを完了する

完了したら、IDの状態が検証済みに更新される

2.Amazon SESにSMTP認証情報を作成する

①左メニューより「SMTP設定」を選択し、「SMTP認証情報の作成」をクリックする

IAM User Nameに表示されている名前をデフォルトのまま、作成ボタンをクリック

②ユーザーのSMTPセキュリティ認証情報をメモしておく

3.SESポリシーのアタッチ

①検索バーよりIAMを検索し、ポリシーを選択

②「ポリシーを作成」をクリック

③ポリシーエディタ「JSON」を選択し、以下JSONをコピペする

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ses:SendEmail",
                "ses:SendRawEmail"
            ],
            "Resource": [
                "arn:aws:ses:ap-northeast-1:{AWSアカウントID}:identity/{SES検証済みID}",
            ]
        }
    ]
}

※なるべく、「AmazonSESFullAccess」は使用しない

④ポリシー名を入力して、ポリシーを作成する

⑤左メニューよりユーザーを選択

⑥許可ポリシーから「許可を追加」をクリック

⑦許可を追加

許可のオプション:ポリシーを直接アタッチする
許可ポリシーの検索バーで「④で作成したポリシー」を検索し、選択する

ポリシーを許可する

4.IAMより 「アクセスキー」と「シークレットキー」を作成する

①左メニューより「ユーザー」を選択し、2.①で作成したユーザーをクリック

②タブから「セキュリティ認証情報」を選択し、アクセスキーの「アクセスキーを作成」をクリック

③アクセスキーを作成

主要なベストプラクティスと代替案にアクセスする:コマンドラインインターフェイス(CLI)を選択
上記のレコメンデーションを理解し、アクセスキーを作成します:チェックいれる
説明タグ値:任意
「アクセスキーを作成」をクリック

④作成された「アクセスキー」と「シークレットキー」をメモ or CSVダウンロードしておく

5.サーバに設定する

①サーバにSSHログイン

②aws-cliをインストール

プロジェクトのルートディレクトリに移動

apt  install awscli

※インストールされたらバージョンが表示される

aws --version

③環境変数をセットする

$aws configure
AWS Access Key ID [None]: xxxxxxxxxx ←4で作成したアクセスキー
AWS Secret Access Key [None]: xxxxxxxxxx ←4で作成したシークレットキー
Default region name [None]: ap-northeast-1
Default output format [None]: json

④確認

$ll ~/.aws
total 16
drwxr-xr-x 2 root root 4096 Jan 20 06:37 ./
drwx------ 7 root root 4096 Jan 20 06:37 ../
-rw------- 1 root root   48 Jan 20 06:37 config
-rw------- 1 root root  116 Jan 20 06:37 credentials
$ cat ~/.aws/config
[default]
output = json
region = us-west-2
$ cat ~/.aws/credentials 
[default]
aws_access_key_id = xxxxxxxxxx
aws_secret_access_key = xxxxxxxxxx

6.AWS SDK for PHPをインストールする

①アップデート可能なパッケージを更新

sudo apt update -y

②依存関係のインストール

$ sudo apt install curl php-cli php-mbstring git unzip

<説明>

  • curl:php-cliをインストールするのに必要
  • php-cli:Composerのインストールと実行に必要
  • php-mbstring:使用するライブラリに機能を提供
  • git:Composerの依存関係をダウンロードするのに必要
  • unzip:圧縮されたパッケージの解凍に必要

③Composerのインストール

公式のコマンドからインストール

php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === '55ce33d7678c5a611085589f1f3ddf8b3c52d662cd01d4ba75c0ee0459970c2200a51f492d557530c71c15d8dba01eae') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"

※インストールされたらバージョンが表示される

composer --version

④プロジェクトのベースディレクトリに移動して、AWS SDK for PHPをインストールする

composer require aws/aws-sdk-php

vendor,composer.json,composer.lockが入ってるか確認
ちなみに 「aws-sdk-php」は下記に格納されている
/vendor/aws/aws-sdk-php

7.AWS SDKを使用して Amazon SESからEメールを送信する

①テキストエディタで amazon-ses-sample.php という名前のファイルを作成し、次のコードを貼り付けてファイルを保存

<?php
require 'vendor/autoload.php';

use Aws\Ses\SesClient;
use Aws\Exception\AwsException;

$SesClient = new SesClient([
    'profile' => 'default',
    'version' => '2010-12-01',
    'region'  => 'ap-northeast-1'
]);

$sender_email = 'send-test@example.com';
$recipient_emails = ['recipient-test@gmail.com','recipient-test2@gmail.com'];

$subject = 'AmazonSES testメール';
$plaintext_body = 'このメールはAmazonSESのtestメールになります。' ;
$html_body =  '<h1>AWS Amazon Simple Email Service Test Email</h1>'.
              '<p>This email was sent with <a href="https://aws.amazon.com/ses/">'.
              'Amazon SES</a> using the <a href="https://aws.amazon.com/sdk-for-php/">'.
              'AWS SDK for PHP</a>.</p>';
$char_set = 'UTF-8';

try {
    $result = $SesClient->sendEmail([
        'Destination' => [
            'ToAddresses' => $recipient_emails,
        ],
        'ReplyToAddresses' => [$sender_email],
        'Source' => $sender_email,
        'Message' => [
          'Body' => [
              'Html' => [
                  'Charset' => $char_set,
                  'Data' => $html_body,
              ],
              'Text' => [
                  'Charset' => $char_set,
                  'Data' => $plaintext_body,
              ],
          ],
          'Subject' => [
              'Charset' => $char_set,
              'Data' => $subject,
          ],
        ],
    ]);
    $messageId = $result['MessageId'];
    echo("Email sent! Message ID: $messageId"."\n");
} catch (AwsException $e) {
    // output error message if fails
    echo $e->getMessage();
    echo("The email was not sent. Error message: ".$e->getAwsErrorMessage()."\n");
    echo "\n";
}

<説明>
$sender_email:送信元メールアドレス(1.①~⑤で検証したドメインを使用したメールアドレス)
例)
ドメイン「example.com」で検証した場合、test@example.com
$recipient_emails:受信元メールアドレス(2.⑥~⑨で検証したメールアドレス))
$subject:件名
$plaintext_body:プレビューテキスト
$html_body:本文
$char_set:文字コード

②amazon-ses-sample.php と同じディレクトリでコマンドプロンプトを開き、次のコマンドを入力

$ php amazon-ses-sample.php

⑤Eメールが正常に送信されると、コンソールに "Email sent!" が表示

Email sent! Message ID: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

~終了~

~補足~
コマンドプロンプトではなく、ファイルで実行する場合

amazon-ses-sample.phpの下記部分を変更

$credentials = [
    'key'    => '4で作成したアクセスキー',
    'secret' => '4で作成したシークレットキー',
];
$SesClient = new SesClient([
    'credentials' => $credentials,
    'version' => '2010-12-01',
    'region'  => 'ap-northeast-1'
]);

メールで必要な他設定

DMARCの設定
https://docs.aws.amazon.com/ja_jp/ses/latest/dg/send-email-authentication-dmarc.html

バウンスメールの受け取り設定
https://dev.classmethod.jp/articles/ses-bounce-check/

SPFの設定
https://docs.aws.amazon.com/ja_jp/ses/latest/dg/mail-from.html

上記が網羅された記事
https://dev.classmethod.jp/articles/another-registrar-ses-email-authentication/

参考にした記事

https://docs.aws.amazon.com/ja_jp/ses/latest/dg/Welcome.html

https://docs.aws.amazon.com/ja_jp/sdk-for-php/v3/developer-guide/welcome.html

https://qiita.com/ichishun87/items/8d2adfa4c3e5a0eec2a6

https://qiita.com/y-okuhira/items/e0a393dc3b6cec653c76#5ec2ロールにsesポリシーをアタッチ

Discussion