【Python】AWS SESとLambdaでメール送信システムを作ってみた!

AWS

こんにちは!らるちゃんです。
今回は、AWS SESとlambdaを用いてメールの送信システムを作ってみます。

1. はじめに

サーバーレス環境で動作するメール送信システムは、手間が少なくスケーラブルで便利です。

今回は、AWSのサーバーレスサービス「Lambda」を使って、AWS SES(Simple Email Service)を利用したメール送信システムを構築する方法を紹介します。

LambdaやSESについて詳しく知りたい方は、以下の記事を参考にして下さい!

今回作成するメール送信システムは、以下のようなシチュエーションで、応用可能です。
是非、参考にしてみて下さい。

  • 定期的なレポートや通知メールの自動送信
  • エラー発生時のアラートメール送信
  • ユーザー登録時の確認メール送信

2. 全体の構成

今回は、以下のように進めていきます。
全体像を頭に入れつつ、読み進めて下さい!

  1. AWS SESを設定してメール送信機能を有効化。
  2. Lambda関数を作成し、Pythonでメール送信ロジックを実装。
  3. AWS EventBridge(旧CloudWatch Events)でトリガーを設定して自動実行。

それでは、早速はじめていきましょう。


3. SESの設定手順

まず最初に、SESの設定から作業していきます。
SESを有効化するための手順を以下で説明します。

3-1: SESの有効化

まず、AWSマネジメントコンソールから「Simple Email Service」を検索して開きましょう。

   ①リージョンが「東京」であることを確認します。
   ②ダッシュボードから「ID」を選択し、
   ③「IDの作成」へと進みます。

「IDの作成」へ進むと、以下の画面になるので、IDタイプはEメールアドレスを選択し、今回の検証で用いる、Eメールアドレスを入力します。

(IDタイプは、今回はEメールアドレスとします。違いが気になる方は、以下のドキュメントを参考にして下さい。→https://docs.aws.amazon.com/ja_jp/ses/latest/dg/creating-identities.html)

ここまで終わると、登録したメールアドレスに確認のメールが届くので、URLをクリックし、認証を完了します。

以下の画面が表示され、検証が完了したら、OKです!


3-2: 補足

SESでは、初期状態では、サンドボックスという環境(検証目的の環境)に配置されており、不正利用防止を目的として「認証済みのメールアドレスに対してのみメール送信が可能」という制約があります。

したがって、今回は不特定多数のメールアドレスにメールを送信することはできません。
先ほど登録した登録したメールアドレスを用いて、検証を行う形となります。

本番環境で使用するには制限解除リクエストをAWSサポートに送信する必要があります。

4. Lambda関数の作成

続いて、Lambdaの設定を行います。
Lambda関数を作成し、Pythonコードをデプロイします。

AWSのコンソールから、Lambdaへと移動し、関数を作成します。
言語は、Pythonを選択します。

関数を作成したら、以下のサンプルコードをコピーして貼り付けます。

サンプルコード

以下のコードは、AWS SESを使用してメールを送信するLambda関数の例です。

import boto3
import json
import os

def lambda_handler(event, context):
    # SESクライアントの初期化
    ses_client = boto3.client('ses', region_name='ap-northeast-1')  # SESを有効化したリージョンを指定    
    # 環境変数またはイベントから設定値を取得
    sender = os.environ['SENDER_EMAIL']
    recipient = os.environ['RECIPIENT_EMAIL']
    subject = "Lambdaからのメール通知"
    body_text = "これはAWS Lambdaから送信されたメールです。"
    body_html = """
    <html>
    <body>
        <h1>Lambdaからのメール通知</h1>
        <p>これはAWS Lambdaを使って送信されたメールです。</p>
    </body>
    </html>
    """

    try:
        # SESでメールを送信
        response = ses_client.send_email(
            Source=sender,
            Destination={'ToAddresses': [recipient]},
            Message={
                'Subject': {'Data': subject},
                'Body': {
                    'Text': {'Data': body_text},
                    'Html': {'Data': body_html}
                }
            }
        )
        return {
            'statusCode': 200,
            'body': json.dumps(f"メールが送信されました: {response['MessageId']}")
        }
    except Exception as e:
        print(f"エラーが発生しました: {e}")
        return {
            'statusCode': 500,
            'body': json.dumps("メール送信に失敗しました。")
        }

環境変数設定

続いて、送信者と受信者のメールアドレスを環境変数に設定します。(同じメールアドレスです。)
設定タブへ移動し、環境変数を登録して下さい。

  • SENDER_EMAIL: 認証済みの送信者メールアドレス
  • RECIPIENT_EMAIL: 受信者メールアドレス

5. IAMロールの設定

Lambda関数がSESにアクセスするためには、適切なIAMロールを設定する必要があります。
IAMロールについては、以下の記事で解説していますので、こちらも参考にして下さい。

5-1 IAMポリシーの作成

AWSマネジメントコンソールでIAMを開き、ポリシーを作成します。

以下のJSONをポリシーエディタに貼り付けます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "ses:SendEmail",
            "Resource": "*"
        }
    ]
}

作成したポリシーにわかりやすい名前をつけて保存します(例: LambdaSESPolicy)。

5-2 Lambda関数のロールにポリシーを割り当て

Lambda関数の「設定」タブで、作成したポリシーを割り当てます。

「許可を追加」から「ポリシーのアタッチ」を選択し、先ほど作成したポリシーを追加。

6. 実行結果

ここまで終わったら、Testイベントを作成して、Lambdaで実行してみましょう。

受信者のメールアドレスには以下の内容が届きます。
迷惑メールフォルダに入っている可能性もあるので、届いてない場合はよく確認して下さい!

  • 件名: Lambdaからのメール通知
  • 本文(HTML形式): 「これはAWS Lambdaを使って送信されたメールです。」

7. 応用例

今回はここまでとします。
ここまでの内容を応用する例を以下にあげたので試してみて下さい!
(私も暇があればまた記事にします。)
AWSのEventBridge等のサービスを使って、Lambdaのトリガーを設定し自動化するのも良いですね!

  1. メールをカスタマイズ
    Lambda関数に動的なパラメータを渡して、宛先やメール内容をカスタマイズ。
    (SESのメールアドレスの認証は必要です。)
  2. 添付ファイル付きメールの送信
    SESのsend_raw_emailを使用して、添付ファイルを含むメールを送信。
  3. エラーメールの自動送信
    Lambda関数を他のAWSサービス(例: CloudWatchアラーム)と連携させ、システムエラー時にアラートメールを送信。

8. まとめ

AWS LambdaとSESを組み合わせることで、サーバーレスかつスケーラブルなメール送信システムを構築できます。今回のシンプルな構成をベースに、さらに高度な機能を追加してみてください。

AWS Lambdaの自動化機能とSESを活用して、あなたのアプリケーションや業務をさらに効率化しましょう!


コメント

タイトルとURLをコピーしました