2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

お題は不問!Qiita Engineer Festa 2024で記事投稿!
Qiita Engineer Festa20242024年7月17日まで開催中!

S3とLambda、SESを用いてお問合せフォームを作成した話

Last updated at Posted at 2024-06-18

前回はS3とRoute 53、CloudFrontで静的なHPの作成を行いました。
今回は前回のものによくあるお問い合わせフォームを組み合わせ、お問い合わせフォームからメールが送られるようにします。
2回に分けて記事を書かせていただきます。
前回時点でS3より左側の設定までは完了している部分です。
今回はS3から右側の設定を行い、次回S3と今回の部分をつなげます。

image.png

※2024/6/25:Lambdaのコード修正しました。

Amazon Simple Email Service

SESはクラウドベースのメールサービスです。
無料枠もありますが今回はS3からのメール送信となりますので有料になります。1,000通あたり$0.10になります。

image.png

メールアドレスの登録

まずはIDを作成より、受信元となるメールアドレスの登録をします。

image.png

今回はEメールアドレスで作成します。
Eメールアドレスを選択後、アドレス入力欄に受信元のアドレスを入力してください。

image.png

登録後、確認のメールが届きます。
内容に従い、メールアドレスを有効化します。

image.png

画像のようにステータスが検証済みになっていれば完了です。

image.png

Lambda

Lambdaはイベントごとにあらかじめ登録したプログラムを実行するサービスです。

関数の作成

まずは関数の作成より関数を作成していきます。
image.png

今回は一から作成のままで進みます。

image.png

関数名の入力とランタイムの選択をします。
関数名はお好きなものを入力で問題ないです。
ランタイムはPythonを選択します。
選択後、関数の作成を押下します。

image.png

下記の画面に遷移するかと思います。
このまま、コードの登録まで行います。

image.png

続いてコードを入力します。
今回はChat GPTで作成したものを多少アレンジしています。
入力後、デプロイを押下して反映させます。
※本来、メールアドレスなどは環境変数に書くべきですが今回はテストなのでじかがきしています

※2024/06/25更新:ログ出力のために修正しています。

emailSender.py
import json
import boto3
import os

def lambda_handler(event, context):
    try:
        print(f"Event: {event}")
        try:
            form_data = event
        except json.JSONDecodeError as e:
            print(f"JSON decode error: {str(e)}")
            raise ValueError("Invalid JSON format")

        print(f"Form data: {form_data}")

        name = form_data.get('name')
        email = form_data.get('email')
        message = form_data.get('message')

        if not name or not email or not message:
            raise ValueError("Missing one or more required fields")

        ses_client = boto3.client('ses', region_name='us-east-1')

        email_address = os.environ.get('SEND_EMAIL')

        if email_address is None:
            raise ValueError("Environment variable SEND_EMAIL is missing")

        email_address = email_address.strip()

        body = f"""
        Name:           {name}
        Email Address: {email}
        Message:       {message}
        """

        response = ses_client.send_email(
            Source=email_address,
            Destination={
                'ToAddresses': [email_address]
            },
            Message={
                'Body': {
                    'Text': {
                        'Charset': 'UTF-8',
                        'Data': body
                    }
                },
                'Subject': {
                    'Charset': 'UTF-8',
                    'Data': 'Contact Form Submission'
                }
            }
        )

        print(f"SES Response: {response}")

        return {
            'statusCode': 200,
            'body': json.dumps('Email sent successfully.')
        }
    except ValueError as ve:
        print(f"Value Error: {str(ve)}")
        return {
            'statusCode': 400,
            'body': json.dumps(f'Error: {str(ve)}')
        }
    except Exception as e:
        print(f"Error: {str(e)}")
        return {
            'statusCode': 500,
            'body': json.dumps(f'An error occurred: {str(e)}')
        }

アクセス権限の設定

続いてアクセス権限の設定を行います。
設定タブよりアクセス権限を開きます。
実行ロールの下にこの関数のロールが表示されているので、このロールにメールを送信するための権限を付与していきます。
ロールを押下し、画面を遷移します。

image.png

許可ポリシーよりインラインポリーを作成を選択します。

image.png

JSON形式でポリシーを追加します。
以下のJSONを記入します。
ポリシーの中身はこの記事を参考にしています

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"logs:CreateLogGroup",
				"logs:CreateLogStream",
				"logs:PutLogEvents"
			],
			"Resource": "arn:aws:logs:*:*:*"
		},
		{
			"Effect": "Allow",
			"Action": [
				"ses:Send*"
			],
			"Resource": "*"
		}
	]
}

次へを押下し、ポリシーの作成を押下し完了です。
image.png

ここまで作成できたので一度Lamdaからメールが送信できるのか確認します。
下記のJSONをテスト用のメッセージとします。

{
  "name": "テスト",
  "email": "test@test.com",
  "message": "テストメッセージです。"
}

無事に届いていれば完了です。

API Gateway

API Gatewayの設定を行います。実際のお問い合わせフォームからのPOST内容をLambdaに渡す役割をしています。

image.png

APIの作成

今回はREST APIで作成します。

image.png

好きなAPI名を入力し新しいAPIを作成します。

image.png

続いてメソッドを作成していきます。

image.png

今回はフォームからのPOSTをLambda関数に流すので、メソッドタイプをPOST、統合タイプをLambda関数を選択します。

image.png

Lambda関数は先ほど作成した関数を選択します。

image.png

ここまで完了したので再度テストを行います。
テストのタブに移動し、リクエスト本文に先ほどと同じJSONの内容を書き込みます。
入力後、テストを押下します。
無事にメールが届いていれば完了です。

image.png

続いてCORSの有効化を行い、APIを叩ける状態にします。

image.png

POSTにチェックを入れ保存を押下します。

image.png

最後にデプロイを行います。
任意のステージ名を入力し、デプロイします。

image.png

おわり

今回はAPI Gatewayから先の設定を行いました。
実は何回か躓いきましたが何とか形になりました。
次回はJSのコードを書き、今回のものと組み合わせ、お問い合わせフォームを作成をします。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?