静的ページ用の問い合わせ機能を、AWS Lambda + API Gateway (+ Amazon SES) でサーバーレスに実装する手順を整理します。
GitHubのソースコードはこちら
手順
設計の全体像は、クライアントから API Gateway の POST メソッドを呼び出し、それをトリガーに Lambda 関数を発火させて、SES の送信用メールアドレスで管理者にメール通知をおこなう感じです。
1. Amazon SES
まずは問い合わせ内容を通知するためのメールアドレスの設定です。
メールアドレスの追加・認証
Amazon SESの管理画面で、送信用のメールアドレスを追加し、届いたメールから認証を完了させます。
ドメイン用 DKIM の設定
設定したアドレスからSESでメールを送信する時に、送信元アドレスとして xxx@xxx.com via amazon.com
のように via amazon.com
と表記されることがあります。
この via amazon.com
を消すために DKIM の設定をします。
Amazon SESの管理画面から送信用アドレスの詳細ページにいき、「DKIM」のCNAMEの値を入手します。
このCNAMEの3つをメールアドレスのドメインのDNSレコードに追加します。
2. AWS Lambda
続いて、問い合わせ通知の処理を AWS Lambda で実装します。
IAMロール
まずは IAMの管理画面で今回の Lambda に適用するロールを作成します。
ロールは以下の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":"*"
}
]
}
Lambda 関数の作成
Lambda の管理画面で新しい関数を作成します。アクセス権限には、先ほど作成したロールを割り当てます。
index.js の更新
index.js
を次のように更新します。region:
や Source
はご自身の情報に修正してください。
'use strict'
const SDK = require('aws-sdk')
exports.handler = (event, context, callback) => {
const ses = new SDK.SES({ region: 'ap-southeast-2' })
const email = {
// From
Source: "YOUR_EMAIL_ADDRESS",
// To
Destination: { ToAddresses: [event.form.to] },
Message: {
Subject: { Data: event.form.subject },
Body: {
Text: { Data: event.form.body }
},
},
};
ses.sendEmail(email, callback);
};
3. API Gateway
最後に API Gateway で、問い合わせを受け付けるエンドポイントを作ります。
API の新規作成
上で作成した Lambda 関数のページの「トリガーを追加」で API Gateway の REST API を新規作成します。
リソースの追加
作成後、同 REST API のページに自動的に移動します。
「アクション > リソースの追加」で、/send
など、任意のリソースを追加します。
POST メソッドの追加
「アクション > メソッドの追加」で、追加したリソースに POST
メソッドを追加します。
POST メソッドの設定
リクエストマッピングテンプレート
POST
メソッドの詳細ページ「統合リクエスト > マッピングテンプレート」で application/json
のマッピングテンプレートを追加します。テンプレートの記載内容は次の通りです。
{
"form": $input.json('$')
}
レスポンスヘッダー
POST
メソッドの詳細ページ「メソッドレスポンス > 200 のレスポンスヘッダー」で Access-Control-Allow-Origin
というヘッダーを追加します。
その後、「統合レスポンス > ヘッダーのマッピング」で次のように値をセットします。
レスポンスヘッダー | マッピングの値 |
---|---|
Access-Control-Allow-Origin | '*' |
上記設定がないと、僕の環境下では、クライアントから呼び出した時に
No 'Access-Control-Allow-Origin' header is present on the requested resource
のエラーが出ました。この Access-Control-Allow-Origin
の設定で解決できました。
API のデプロイ
「アクション > API のデプロイ」で、任意のステージ(v1
など)に REST API をデプロイします。
ステージの「URL の呼び出し」にエンドポイントの記載があります。
POST https://xxxxxx.execute-api.YOUR_REGION.amazonaws.com/v1/YOUR_API_NAME/send
このエンドポイントで作成した POST メソッドを呼び出せます。
4. クライアントでの呼び出し
静的ページから POST リクエストで API Gateway のエンドポイントを呼ぶことで、Lambda 関数が発火します。
jQuery で利用する場合、次のように呼び出します。
function submitContact(url, to, subject, body) {
const jsonData = JSON.stringify({
'to': to,
'subject': subject,
'body': body
})
$.ajax({
type: "POST",
url: url,
async: true,
contentType: 'application/json',
dataType: 'json',
data: jsonData,
error: function(data) {
console.log(data)
},
success: function(data) {
console.log(data)
}
})
}