CLIからAmazon SESでメールを一斉送信する必要があり、そのための手順とメールテンプレートを作成するスクリプトを作りました。

CLIからSESでメールを送信する状況はあまりないとは思いますが、参考になれば嬉しいです。

設定手順

メールテンプレートの準備

TerraformのSESのmodule配下にHTML版のメールとText版のメールのファイルをそれぞれ作成します。

  • HTML版のメールを作る際には以下に注意してください。
    日本語が含まれる場合は、変換したものを貼り付けること。参考:変換サイト
  • HTMLでは通常の改行が反映されないため、改行はbrタグに変換してください。
  • 変数に改行が含まれている場合は、HTMLメールとtextメールで別々の変数を用意し、変数名の末尾に_htmlを付けて区別します。

TerraformでSESのテンプレートを作成します。

resource "aws_ses_template" "ses_template" {
  name = "ses_template_name"

  subject = "メールタイトル"
  html = file("${path.module}/template/html-mail.html")
  text = file("${path.module}/template/text-mail.txt")
}

terraform applyで反映させます。

terraform apply

メールテンプレートが作成されたことを確認します。

aws ses list-templates

メールテンプレートの詳細を確認します。

aws ses get-template --template-name template_name

テンプレート名はマネジメントコンソールからも確認することができますが、コンソールからではテンプレートの内容の確認や使用はできません。

メールの送信先の準備

SESでは、メールの送信先を次のようなJSON形式で指定します。

[
    {
        "Destination": {
            "ToAddresses": [
                "recipient1@example.com"
            ]
        },
        "ReplacementTemplateData": "{}"
    },
    {
        "Destination": {
            "ToAddresses": [
                "recipient2@example.com"
            ]
        },
        "ReplacementTemplateData": "{}"
    }
]

件数が多いと手動で対応するのはしんどいため、CSVファイルをインプットに上記Jsonに変換するPythonスクリプトを作成しました。

Pythonスクリプトの使い方

ses_csv2json.py

import csv
import json
import sys

def convert_csv_to_json(csv_file_path, json_file_path):
    results = []
    add_html_version = False

    # CSVファイルをスキャンして改行コードが含まれているかをチェック
    with open(csv_file_path, newline='', encoding='utf-8') as csvfile:
        reader = csv.reader(csvfile)
        for row in reader:
            if any('\n' in field for field in row):
                add_html_version = True
                break

    with open(csv_file_path, newline='', encoding='utf-8') as csvfile:
        reader = csv.DictReader(csvfile)
        for row in reader:
            replacement_template_data = {}

            to_addresses = row['ToAddresses'].strip()

            for key, value in row.items():
                if key != 'ToAddresses':  # ToAddressesは別途処理
                    # JSONに変換するために改行コードをエスケープ
                    escaped_value = value.replace('\n', '\\n')
                    replacement_template_data[key] = escaped_value

                    # _htmlバージョンを追加
                    if add_html_version:
                        html_key = f"{key}_html"
                        html_value = value.replace('\n', '<br>')
                        replacement_template_data[html_key] = html_value

            data = {
                "Destination": {
                    "ToAddresses": [to_addresses]
                },
                "ReplacementTemplateData": json.dumps(replacement_template_data)
            }

            results.append(data)

    with open(json_file_path, 'w', encoding='utf-8') as jsonfile:
        json.dump(results, jsonfile, indent=4, ensure_ascii=False)

if __name__ == '__main__':
    if len(sys.argv) != 3:
        print("Usage: python ses_csv2json.py <input_csv_file> <output_json_file>")
        sys.exit(1)

    csv_path = sys.argv[1]
    json_path = sys.argv[2]
    convert_csv_to_json(csv_path, json_path)

スプレッドシートなどを使用してCSVファイルを作成し、必要なカラム(ToAddressesは必須、他はテンプレートの変数に合わせる)を設定します。

末尾が_htmlの変数はスクリプトの処理で自動で作成されるためカラムの作成は不要です。

コマンドラインから以下の形式で実行してCSVファイルからJSONファイルを作成します。

python ses_csv2json.py input.csv output.json

メール一斉送信

AWS CloudShellやローカルからCLIコマンドで実行してメールを送信します。

aws ses send-bulk-templated-email \
    --source "from@example.com" \
    --template "your_template_name" \
    --default-template-data "{}" \    
    --destinations file://path_to_your_json_file.json
  • source:送信者のメールアドレス(SESで検証済みである必要があります)
  • template:使用するメールテンプレートの名前で
  • destinations:上記で準備したJSONファイルへのパス
    (Windowsの場合でもディレクトリは/で区切る)
  • default-template-data:メール内の変数のデフォルト値