34
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

API Gateway + Lambda + SES で安価な問い合わせフォームを構築しよう(後編)

Last updated at Posted at 2018-02-22

前編はコチラ

SESの送信設定をしよう

まずはLamdaからメールの送信を行えるように、Amazon SESで送信の準備をします。
SESは、2018/02月現在、バージニア北部、オレゴン、アイルランドの3つのリージョンでしか提供されていないため、3つのうちいずれかを選択します。

SES01.png

どこを選択しても構わないのですが、今回は**「米国東部(バージニア北部)」**を選択して手順を進めます。

次にSESのHome画面から、右側メニューにある**「Sending Statistics」**を選択します。

SES02.png

SESはデフォルトではSandbox状態となっており、事前に認証したメールアドレス、ドメインに対してしかメールを送信出来ないようになっています。
また、送信制限も掛かっており200通/24Hかつ、1通/秒までしか送信することが出来ません。

今回の問い合わせフォームという用途では特定のメールアドレスにしか送信しませんし、前提として月間500通程度ですので、このまま運用しても問題は出ないとは思います。
(宛先のメールアドレスを事前に認証しておけば)

ですが、念のため送信制限の解除を申請しておきましょう。

「Sending Statistics」を選択して表示された画面の中央あたりにある**「Request a Sending Limit Increase」**という青いボタンを押下してください。

SES03.png

下図のページで、何に使うのか、どこのWebサイトで使うのか、申請理由は?といったことを入力するフォームがありますので、記入して**「送信」**ボタンを押しましょう。
大体ですが、遅くとも翌営業日には申請は承認されます。
申請する制限緩和「希望する一日あたりの送信クォータ」で良いと思います。
新しい制限値はとりあえず500くらいを指定しておきましょう。

SES04.png

これで送信先(To)に関しては制限なく使用出来るようになるのですが、送信元(From)に設定するメールアドレスは、そのメールアドレスの持ち主であることを証明する必要があります。
右側のメニューの**「Email Addresses」を選択して、「Verify a New Email Address」**ボタンを押してください。

SES05.png

Eメールアドレスの入力欄がポップアップで表示されますので、SESから送信するメールの送信元(From)に設定するメールアドレスを入力して**「Verify This Email Address」**を押すと、入力したメールアドレス宛てに認証メールが送信されますので、その中にある検証用のURLをクリックすればOKです。

入力したメールアドレスのStatusが「verified」になっていることを確認しましょう。

SES06.png

$$\style{align: center; font-size:1.2em; font-weight:bold;}{\text{↓}}$$

SES07.png

LambdaのFunctionを作ろう

次にメール送信を行うためのLambda Functionを作成します。
Lambdaのホーム画面を表示したら、**「関数の作成」**ボタンを押してください。

Lambda01.png

Lambda Function の名前や実行時のIAMRoleを指定します。
今回作成するFunctionはSESの送信権限を付与する必要がありますので、「ロール」の欄は**「カスタムロールの作成」**を選択してください。
名前は任意で構いません。ランタイムも自分の好きな言語で構いませんが、今回は「Node.js 6.10」を選択して手順を進めます。

Lambda02.png

「カスタムロールの作成」を選択すると、IAM Manegiment Consoleが表示され、Lambda FunctionにアタッチするRoleの作成画面に遷移します。

デフォルトでLambdaの実行に必要なログ出力用のポリシードキュメントが表示されていますので、任意のロール名を入力し**「編集」**リンクをクリックしてポリシードキュメントの編集を行います。

IAM01.png

下記の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を選択して「関数の作成」ボタンを押しましょう。

Lambda03.png

関数コードを編集し、API Gatewayから受け取った内容をSESからメール送信するコードを記述して**「保存」**ボタンを押します。

Lambda04.png

このLambda Functionは、API Gatewayから下記のようなJSONを受け取ることを前提としてコードを記述します。

application/json
{
    "form": {
        "name":  "名前",
        "email": "Eメールアドレス",
        "body":  "問い合わせ本文"
    }
}

Lambda Functionの中身は下記のようにしています。

index.js
'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認証済みである必要があります)

この際、特に問題が無いのであれば基本設定やネットワークの欄はデフォルトのままで構いません。

Lambda05.png

また、Designer欄の**「トリガーの追加」**はAPI Gatewayを作成すると自動で追加されますので、この段階では特に何も指定する必要はありません。

API GatewayをDeployしよう

最後にLamda Functionを実行するためのHTTPリクエストのエンドポイントとなるAPI Gatewayを作成します。
API Gatewayのホーム画面を表示したら、**「今すぐ始める」**ボタンを押してください。

AG01.png

任意のAPI名を入力して、**「APIの作成」**ボタンを押します。

AG02.png

次にリソースの作成を行います。**「アクション」からプルダウンを表示し、「リソースの作成」**を選択します。

AG03.png

ここでは「send」というリソースを作成し、CORSを有効にしています。

AG05.png

次に、作成したリソースに対してPOSTメソッドを追加します。
sendリソースを選択した状態で**「アクション」からプルダウンを表示し、「メソッドの作成」**を選択し、POSTを追加します。

追加したPOSTメソッドのセットアップでは、統合タイプには「Lambda関数」を指定し、作成したLambda FunctionのリージョンとFunction名を入力して、**「保存」**ボタンを押してください。

AG06.png

POSTメソッドをセットアップしたら、メソッドの実行画面から**「統合リクエスト」**を選択します。

AG07.png

統合リクエストの編集画面を開いたら、**「本文マッピングテンプレート」**の追加を行います。この本文マッピングテンプレートにより、HTMLからPOSTされたJSONをLambda Functionに受け渡すJSONに変換します。

手順は**「マッピングテンプレートの追加」から、application/json を追加してテンプレート内容を記述して「保存」**ボタンを押します。

AG08.png

テンプレート本文は下記のように記述しています。

マッピングテンプレート
{
    "form": {
        "name":  "$util.escapeJavaScript($input.path('$.name'))",
        "email": "$util.escapeJavaScript($input.path('$.email'))",
        "body":  "$util.escapeJavaScript($input.path('$.body'))"
    }
}

これはHTMLから下記のようなJSONがリクエストBODYでPOSTされることを想定しています。

HTTPRequestBody
{
  "name": "問い合わせ太郎",
  "email": "hogehoge@example.com",
  "body": "問い合わせ内容の本文"
}

POSTメソッドの統合リクエストの編集が完了したらAPIをデプロイします。

AG10.png

**「ステージ名」**は、任意の名称で構いませんが、ここでは「v1」と入力して手順を進めます。

AG09.png

デプロイが無事完了すると、APIのURLが払い出されます。

AG11.png

ここに表示されているURLに向けて、下記のようなJSONをPOSTするとLambda Functionが実行され、SESからメールが送信されます。

HTTPRequestBody
{
  "name": "問い合わせ太郎",
  "email": "hogehoge@example.com",
  "body": "問い合わせ内容の本文"
}

これをS3にホスティングしたHTMLからJavaScriptで実行すると、問い合わせフォームの出来上がりですね。

最後に

いかがでしょうか?
前後編にわたり説明はかなり長かったと思いますが、手順的には簡単に問い合わせフォームを構築することが出来たのではないかと思います。
少なくとも私にはレンタルサーバー借りて、PHPで構築するよりはずっと簡単でした。(単にPHPが苦手なだけですが)

前編でお伝えした通り、これはどのサイトにも適用可能なものではありません。
それこそ月間数十万PV行くようなサイトや画像が盛りだくさんのサイトであればデータ転送料で数千~数万円というケースもあります。
もちろんレンタルサーバーの方が安く済むケースもありますので、「皆レンタルサーバー辞めて、AWSでサーバーレスしようぜ」という話ではないのですが、「小規模な静的サイトにちょろっとサーバースクリプトが欲しい」というケースでは、こういう方法もあるというのを知って頂ければ幸いです。

おつかれさまでした。

34
24
2

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
34
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?