前編はコチラ
SESの送信設定をしよう
まずはLamdaからメールの送信を行えるように、Amazon SESで送信の準備をします。
SESは、2018/02月現在、バージニア北部、オレゴン、アイルランドの3つのリージョンでしか提供されていないため、3つのうちいずれかを選択します。
どこを選択しても構わないのですが、今回は**「米国東部(バージニア北部)」**を選択して手順を進めます。
次にSESのHome画面から、右側メニューにある**「Sending Statistics」**を選択します。
SESはデフォルトではSandbox状態となっており、事前に認証したメールアドレス、ドメインに対してしかメールを送信出来ないようになっています。
また、送信制限も掛かっており200通/24Hかつ、1通/秒までしか送信することが出来ません。
今回の問い合わせフォームという用途では特定のメールアドレスにしか送信しませんし、前提として月間500通程度ですので、このまま運用しても問題は出ないとは思います。
(宛先のメールアドレスを事前に認証しておけば)
ですが、念のため送信制限の解除を申請しておきましょう。
「Sending Statistics」を選択して表示された画面の中央あたりにある**「Request a Sending Limit Increase」**という青いボタンを押下してください。
下図のページで、何に使うのか、どこのWebサイトで使うのか、申請理由は?といったことを入力するフォームがありますので、記入して**「送信」**ボタンを押しましょう。
大体ですが、遅くとも翌営業日には申請は承認されます。
申請する制限緩和「希望する一日あたりの送信クォータ」で良いと思います。
新しい制限値はとりあえず500くらいを指定しておきましょう。
これで送信先(To)に関しては制限なく使用出来るようになるのですが、送信元(From)に設定するメールアドレスは、そのメールアドレスの持ち主であることを証明する必要があります。
右側のメニューの**「Email Addresses」を選択して、「Verify a New Email Address」**ボタンを押してください。
Eメールアドレスの入力欄がポップアップで表示されますので、SESから送信するメールの送信元(From)に設定するメールアドレスを入力して**「Verify This Email Address」**を押すと、入力したメールアドレス宛てに認証メールが送信されますので、その中にある検証用のURLをクリックすればOKです。
入力したメールアドレスのStatusが「verified」になっていることを確認しましょう。
$$\style{align: center; font-size:1.2em; font-weight:bold;}{\text{↓}}$$
LambdaのFunctionを作ろう
次にメール送信を行うためのLambda Functionを作成します。
Lambdaのホーム画面を表示したら、**「関数の作成」**ボタンを押してください。
Lambda Function の名前や実行時のIAMRoleを指定します。
今回作成するFunctionはSESの送信権限を付与する必要がありますので、「ロール」の欄は**「カスタムロールの作成」**を選択してください。
名前は任意で構いません。ランタイムも自分の好きな言語で構いませんが、今回は「Node.js 6.10」を選択して手順を進めます。
「カスタムロールの作成」を選択すると、IAM Manegiment Consoleが表示され、Lambda FunctionにアタッチするRoleの作成画面に遷移します。
デフォルトでLambdaの実行に必要なログ出力用のポリシードキュメントが表示されていますので、任意のロール名を入力し**「編集」**リンクをクリックしてポリシードキュメントの編集を行います。
下記のSESからの送信を許可するステートメントを追加します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
}
,{
"Effect": "Allow",
"Action": ["ses:Send*"],
"Resource":"*"
}
]
}
**「許可」**ボタンを押すと、IAM Manegiment Console が終了し、Lambda Functionの作成画面に戻ります。
**「既存のロール」**という欄が増えているはずですので、作成したSES送信用のRoleを選択して「関数の作成」ボタンを押しましょう。
関数コードを編集し、API Gatewayから受け取った内容をSESからメール送信するコードを記述して**「保存」**ボタンを押します。
このLambda Functionは、API Gatewayから下記のようなJSONを受け取ることを前提としてコードを記述します。
{
"form": {
"name": "名前",
"email": "Eメールアドレス",
"body": "問い合わせ本文"
}
}
Lambda Functionの中身は下記のようにしています。
'use strict'
const SDK = require('aws-sdk');
exports.handler = (event, context, callback) => {
const ses = new SDK.SES({ region: 'us-east-1' });
const email = {
// From
Source: "fromAdress@example.com",
// To
Destination: { ToAddresses: ["toAdress@example.com"] },
Message: {
// 件名
Subject: { Data: "Webからのお問い合わせ" },
// 本文
Body: {
Text: { Data: [
'[名前] : ' + event.form.name,
'[メールアドレス] : ' + event.form.email,
'[お問い合わせ] : ' + "\n" + event.form.body,
].join("\n")}
},
},
};
ses.sendEmail(email, callback);
};
コード内の fromAdress@example.com の箇所は、SESで認証済みの送信元となるメールアドレスを記述してください。toAdress@example.com の箇所は、送信先となる問い合わせフォームからのお問い合わせを受け取る担当者さんのメールアドレスを記述します。(SESがSandboxの状態であれば、こちらのアドレスもSES認証済みである必要があります)
この際、特に問題が無いのであれば基本設定やネットワークの欄はデフォルトのままで構いません。
また、Designer欄の**「トリガーの追加」**はAPI Gatewayを作成すると自動で追加されますので、この段階では特に何も指定する必要はありません。
API GatewayをDeployしよう
最後にLamda Functionを実行するためのHTTPリクエストのエンドポイントとなるAPI Gatewayを作成します。
API Gatewayのホーム画面を表示したら、**「今すぐ始める」**ボタンを押してください。
任意のAPI名を入力して、**「APIの作成」**ボタンを押します。
次にリソースの作成を行います。**「アクション」からプルダウンを表示し、「リソースの作成」**を選択します。
ここでは「send」というリソースを作成し、CORSを有効にしています。
次に、作成したリソースに対してPOSTメソッドを追加します。
sendリソースを選択した状態で**「アクション」からプルダウンを表示し、「メソッドの作成」**を選択し、POSTを追加します。
追加したPOSTメソッドのセットアップでは、統合タイプには「Lambda関数」を指定し、作成したLambda FunctionのリージョンとFunction名を入力して、**「保存」**ボタンを押してください。
POSTメソッドをセットアップしたら、メソッドの実行画面から**「統合リクエスト」**を選択します。
統合リクエストの編集画面を開いたら、**「本文マッピングテンプレート」**の追加を行います。この本文マッピングテンプレートにより、HTMLからPOSTされたJSONをLambda Functionに受け渡すJSONに変換します。
手順は**「マッピングテンプレートの追加」から、application/json を追加してテンプレート内容を記述して「保存」**ボタンを押します。
テンプレート本文は下記のように記述しています。
{
"form": {
"name": "$util.escapeJavaScript($input.path('$.name'))",
"email": "$util.escapeJavaScript($input.path('$.email'))",
"body": "$util.escapeJavaScript($input.path('$.body'))"
}
}
これはHTMLから下記のようなJSONがリクエストBODYでPOSTされることを想定しています。
{
"name": "問い合わせ太郎",
"email": "hogehoge@example.com",
"body": "問い合わせ内容の本文"
}
POSTメソッドの統合リクエストの編集が完了したらAPIをデプロイします。
**「ステージ名」**は、任意の名称で構いませんが、ここでは「v1」と入力して手順を進めます。
デプロイが無事完了すると、APIのURLが払い出されます。
ここに表示されているURLに向けて、下記のようなJSONをPOSTするとLambda Functionが実行され、SESからメールが送信されます。
{
"name": "問い合わせ太郎",
"email": "hogehoge@example.com",
"body": "問い合わせ内容の本文"
}
これをS3にホスティングしたHTMLからJavaScriptで実行すると、問い合わせフォームの出来上がりですね。
最後に
いかがでしょうか?
前後編にわたり説明はかなり長かったと思いますが、手順的には簡単に問い合わせフォームを構築することが出来たのではないかと思います。
少なくとも私にはレンタルサーバー借りて、PHPで構築するよりはずっと簡単でした。(単にPHPが苦手なだけですが)
前編でお伝えした通り、これはどのサイトにも適用可能なものではありません。
それこそ月間数十万PV行くようなサイトや画像が盛りだくさんのサイトであればデータ転送料で数千~数万円というケースもあります。
もちろんレンタルサーバーの方が安く済むケースもありますので、「皆レンタルサーバー辞めて、AWSでサーバーレスしようぜ」という話ではないのですが、「小規模な静的サイトにちょろっとサーバースクリプトが欲しい」というケースでは、こういう方法もあるというのを知って頂ければ幸いです。
おつかれさまでした。