サーバレスでお問い合わせフォームを実装してみる (2)
こんにちは、システムエンジニアの今井です。
前回のブログ「サーバレスでお問い合わせフォームを実装してみる(1)」の続きです。
(導入編)「サーバーレスとは本当にサーバーがないこと?」
(1)サーバーレスでお問い合わせフォームを実装してみる(フォームとAPIの作成)
→(2)サーバーレスでお問い合わせフォームを実装してみる(フォームからAPIへ値の送信)
(3)サーバレスでお問い合わせフォームに記載された内容をDBに保存してみる1
(4)サーバレスでお問い合わせフォームに記載された内容をDBに保存してみる2
前回作成したフォームとAPIを連携させて、お問い合わせフォームとして動作させるまでを解説します。
1. API GatewayのURLをHTMLに反映(貼り付けて再アップロード)
フォームをSubmitした際にデータが送信される先に API GatewayのURLを設定します。
以前アップロードしたフォームのhtmlファイルにはURLが記載されていないため、ファイルを編集してから再アップロードします。
まずはAPI GatewayのURLを取得します。
(1)Lambda のページを開きます。
https://ap-northeast-1.console.aws.amazon.com/lambda/home
「index.html 17行目」に貼り付けます。
<!doctype html> <html lang="ja"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/> <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, width=device-width"> <title>test</title> </head> <body> <form id="contact_form"> 会社名:<input type="text" name="company" value="" required /><br/> メールアドレス:<input type="email" name="email" value="" required /><br/> <input type="button" id="send" value="送 信"/> </form> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script> var target_url = '【ここにAPI Gateway のURLを貼り付けます】'; ~~~~ 以下省略 ~~~~
次に、既にアップロードされている index.html ファイルを削除します。
(1)Amazon S3のページを開きます。
https://s3.console.aws.amazon.com/s3/
(2)「contact-example」をクリックします。
(3)index.html にチェックを入れて「削除」をクリックします。
(4)「完全に削除」と入力し、「オブジェクトの削除」をクリックします。
(※別のファイルを削除してしまわないように注意してください)
(7)編集したindex.html ファイルを範囲にドラッグアンドドロップします。
続いて、htmlファイルは非公開になっているためアクセス権限を付与します。
(12)全員(公開アクセス)の「読み込み」をチェックします。
「index.html」の差し替えが完了しました。(見た目上の変化はありません)
2. CORSの設定
API Gatewayは許可されたページ以外からのアクセスを拒否する設定になっています。(クロスオリジンアクセスポリシー)
そのため、さきほどアップロードしたフォームからのアクセスを許可する必要があります。
(1)S3のページを開きます。
https://s3.console.aws.amazon.com/s3/home
(4)オブジェクトのURLをコピーします。(例:https://【文字列】.s3-ap-northeast-1.amazonaws.com/index.html)
(5)「API Gateway」のページを開きます。
https://ap-northeast-1.console.aws.amazon.com/apigateway/main/apis
(9)「Access-Control-Allow-Origin」にさきほどコピーしたオブジェクトURLの「ドメイン部分」を貼り付けます。
(オブジェクトURL:https://【文字列】.s3-ap-northeast-1.amazonaws.com/index.html)
(ドメイン部分:https://【文字列】.s3-ap-northeast-1.amazonaws.com)
(11)「Access-Control-Allow-Methods」に「POST」を設定します。
3. Lambdaの動作確認
Lambdaのプログラムをテスト用のコードに変更して動作確認をしてみます。
(1)Lambda のページを開きます。
https://ap-northeast-1.console.aws.amazon.com/lambda/home
(3)スクロールして main.pyをダブルクリックします。
「テスト用のコード main.py」
import boto3 import json print('Loading function') def respond(err, res=None): return { 'statusCode': '400' if err else '200', 'body': err.message if err else json.dumps(res), 'headers': { 'Content-Type': 'application/json', }, } def lambda_handler(event, context): body = {'result':1} return respond(None, body)
(6)「API Gateway」のURLにアクセスしてみます。
「{“result”: 1}」というエラーではない正常なレスポンスを返すことができました。
ここまでの手順でフォームも動作するようになります。
index.htmlにアクセスしてみます。
テスト用のコードでは、問い合わせの内容を内容を確認することができないため、問い合わせフォームから入力された内容をメールで受信できるように作り変えていきます。
4. SESでメール送信(SESで送受信できるメールアドレスを追加)
メールの送信にはSESというサービスを利用します。LambdaからSESを使ってメール送信してみます。
まずはSESの設定を行います。
(1)SESのページを開きます。
https://ap-northeast-1.console.aws.amazon.com/ses/home
(3)「Verify a New Email Address」をクリックします。
(4)問い合わせを受信したいメールアドレスを入力し「Verify This Email Address」をクリックします。
(6)受信トレイを確認すると確認用のメールが届いています。確認用のURLをクリックします。
(7)SESの一覧画面に戻ると Verified(確認済み)になりました。
次にLambdaからSESにアクセスできるようにロールに権限を追加します。
(1)IAM のページを開きます。
https://console.aws.amazon.com/iam/home
(3)「contact-example-role」をクリックします。
(5)ポリシーのフィルタに「AmazonSESFullAccess」と入力して絞り込みます。
(6)チェックを入れて「ポリシーのアタッチ」をクリックします。
ロールにSESにアクセスするために必要なポリシーが追加されました。
最後にLambdaのコードを更新して、問い合わせがあった際にメールが送信されるようにします。
(1)Lambdaのページを開きます。
https://ap-northeast-1.console.aws.amazon.com/lambda/home
(3)スクロールしてエディタに「Lambdaメール送信用コード」を貼り付けます。
「Lambdaメール送信用コード」
import json import boto3 from urllib.parse import parse_qs import time import base64 MAILTO = 'xxxxxxxx@gmail.com' MAILFROM = 'xxxxxxxx@gmail.com' def respond(err, res=None): return { 'statusCode': '400' if err else '200', 'body': err.message if err else json.dumps(res), 'headers': { 'Content-Type': 'application/json', }, } def sendmail(to, subject, body): client = boto3.client('ses', region_name='ap-northeast-1') response = client.send_email( Source=MAILFROM, ReplyToAddresses=[MAILFROM], Destination= { 'ToAddresses': [ to ] }, Message={ 'Subject': { 'Data':subject, 'Charset':'UTF-8' }, 'Body':{ 'Text':{ 'Data':body, 'Charset':'UTF-8' } } } ) print('Loading function') def lambda_handler(event, context): print("Received event: " + json.dumps(event)) try: param = base64.b64decode(event['body']) param = param.decode("UTF-8") param = parse_qs(param) company = param['company'][0] email = param['email'][0] ipaddress = event['requestContext']['http']['sourceIp'] useragent = event['requestContext']['http']['userAgent'] now = time.time() mailbody = """ 送信日時 = {0} ブラウザ = {1} IPアドレス = {2} 会社名 = {3} email = {4} """.format(now, useragent, ipaddress, company, email) subject = company + '様よりお問い合わせがありました' sendmail(MAILTO, subject, mailbody) body = {'result':1} return respond(None, body) except: import traceback traceback.print_exc() body = {'result':0} return respond(None, body)
(4)「Deploy」をクリックして適用します。
フォームを開いて動作確認してみましょう。
受信トレイを確認するとお問い合わせメールが届いています。
ここまでの手順でお問い合わせの基本機能が実現できました。
次回ですが、メールの送信に失敗した場合に備えて、問い合わせ内容をデータベースに保存する処理を追加してみます。