7
8

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 3 years have passed since last update.

AWS Lambda + API Gateway で作るサーバーレス問い合わせ機能

Last updated at Posted at 2020-04-24

静的ページ用の問い合わせ機能を、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の値を入手します。

スクリーンショット 2020-04-23 22.33.56.png

この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 はご自身の情報に修正してください。

index.js
'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 のマッピングテンプレートを追加します。テンプレートの記載内容は次の通りです。

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)
    }
  })
}

References

7
8
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
7
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?