Googleフォームからデータを送信してDynamoDBに登録する

もくじ

はじめに

こんにちは。あつしです。

Googleフォームで入力されたデータを、AWSのDynamoDBに登録するアプリを作ってみたいと思います。

以下のようなことをお考えの人たちに参考になれば幸いです。

  • GoogleフォームからPOSTでAWS(API Gateway)にデータをPUTする
  • API GatewayとLambdaの連携方法
  • API GatewayとLambdaにJSONを渡して単体テストする方法

この検証が終わったあと、あることに気づきました。Googleフォームの場合、API GatewayのCORSを有効にする必要がありませんでした

全体像

使用するリソース

使用するリソースは以下となります。

  • Googleフォーム
  • Google Apps Script
  • API Gateway
  • Lambda
  • DynamoDB

構成図

つながりを表して図にすると以下のようになります。

やってみる

DynamoDB

一番うしろのDynamoDBから作っていきます。

AWSコンソールにログインしてDynamoDBコンソールに移動します。「テーブル」から「テーブルの作成」をクリックします。

テーブル名は”inquiry-table”としました。パーティションキーは必須なので、文字列型で”email”としました。

他はデフォルト設定で、「テーブルの作成」をクリックしました。

Lambda

つぎはLambdaを作っていきます。API Gatewayから受け取ったデータをDynamoDBに投入する役割です。

関数名は”putDynamoFunc”としました。Python 3.9を使用することとして、一から作成しました。

コードは下記になります。event変数にAPI Gateway(Google Apps Script)から受け取ったJSONデータが入っています。これらを取り出して、DynamoDBにPUTしています。

import json
import boto3

def lambda_handler(event, context):
    
    # API Gateway(GAS)から受け取ったデータを取り出して変数に格納
    Email = event['email']
    Name = event['name']
    Gender = event['gender']
    Inquiry = event['inquiry']
    
    # DynamoDBに投入するためのアイテムをセット。JSONを作成して変数に格納
    DynamoItems = {
        'email': Email,
        'name': Name,
        'gender': Gender,
        'inquiry': Inquiry
    }
    
    # DynamoDBにデータを投入
    table = boto3.resource('dynamodb').Table('inquiry-table')
    response = table.put_item(
        Item = DynamoItems
    )
    
    return {
        'statusCode': 200,
        'body': json.dumps(response)
    }

LambdaがDynamoDBにデータを投入することができるように、権限を加える必要があります。Lambdaに付与されているロールを編集するので、「設定」→「アクセス権限」→「実行ロール」欄にあるロール名をクリックします。

IAMコンソールに飛ぶので、アタッチされているポリシーをクリックします。

「ポリシーの編集」をクリックします。

JSON形式で編集しました。今回はすべてのDynamoDBリソースへすべてのアクションを許可しました。追加した箇所は赤枠で囲っています。

追加したJSONコードだけ抜粋したのが下記です。

{
    "Effect": "Allow",
    "Action": "dynamodb:*",
    "Resource": "*"
}

確認画面が出ます。DynamoDBへのフルアクセスがついていますね。「変更の保存」をクリックします。

Lambdaを単体でテストしてみます。後述しますが、API Gateway(Google Apps Script)から以下のようなJSON形式のデータがLambdaに渡されます。

エラーが出ないことを確認します。

DynamoDBのテーブルを見てみます。レコードが入っています。

API Gateway

Googleフォームに入力されたデータを受け取る役割です。また、受け取ったデータをLambdaに渡します

REST APIで構築します。

名前は”api-GAStoLambda”としました。

リソースの作成を行います。アクセスするURLの一部となるところです。

リソース名は”test”としました。最終的にアクセスするURLの末尾が「…/test」となります。

メソッドの作成をしていきます。

今回はGoogleフォームからPOSTでで受け取るのでPOSTメソッドを作成します。

統合タイプには「Lambda関数」を選び、先ほど作ったLambda関数の名前(ここでは”putDynamoFunc”)を入力し、「保存」ボタンをクリックします。

API GatewayにLambda関数を呼び出す権限を付与する、というメッセージが表示されるので、「OK」をクリックします。

API Gatewayの単体テストをしてみます。「テスト」をクリックします。(下図参照)

リクエスト本文に先ほどと同じようなJSONを記入して(今回は変数の先頭に”API”をつけました) 、「テスト」をクリックします。

ログでエラーが発生していないことを確認します。

DynamoDBを見てみると、新しいレコードが追加されています。

デプロイしないと外部からアクセスできないので、デプロイします。

新しいステージである”v1″を作って、そこにデプロイしました。

デプロイするとAPI Gatewayの呼び出しURLが表示されます。これは後述するGoogle Apps Scriptに埋め込むものなので、メモしておきます。

Googleフォーム

Googleフォームを作ります。

ご存知と思いますが、Googleドライブの「新規」ボタンから、「Googleフォーム」をクリックしてGoogleフォームを作成できます。

完成図は以下のようになります。

それぞれ見ていこうと思います。

メールアドレス

Googleフォーム編集画面の「設定」から、「メールアドレスを収集する」にチェックを入れると、メールアドレスを入力する箇所を作れます。

名前

名前は「記述式」となります。

性別

性別は「ラジオボタン」の選択式です。

質問を入力してください

こちらは「段落」となります。

Google Apps Script

GoogleフォームからGoogle Apps Scriptを作成していきます。

Googleフォームの作成画面右上の「…」から、「スクリプトエディタ」をクリックします。

先にコードを記載します。コードの中の変数(api_endpoint)に先ほど確認した、API Gatewayの呼び出しURLを記載します。

function myFunction(event) {
  // Emailを変数に格納
  var resEmail = event.response.getRespondentEmail();

  // フォームに入力されたデータのかたまり(名前、性別、質問)を変数に格納
  var resItems = event.response.getItemResponses();
  
  // かたまりからそれぞれの値(名前、性別、質問)を取得して変数に格納
  var resName = resItems[0].getResponse();
  var resGender = resItems[1].getResponse();
  var resInquiry = resItems[2].getResponse();

  // JSONオブジェクトを用意する。この中でフォームから受け取ったデータ(Email、名前、性別、質問)をセットする
  var jsonObj = {
    "email": resEmail,
    "name": resName,
    "gender": resGender,
    "inquiry": resInquiry
    }
  
  // 
  var api_parameters = {
    'method': 'post',
    'contentType': 'application/json',
    'payload': JSON.stringify(jsonObj)
  };
  
  // JSON.stringifyでJSON形式の文字列に変換する
  //var json = JSON.stringify(obj)
  //console.log(json)
  
  var api_endpoint = 'https://mag7j9olvf.execute-api.ap-northeast-1.amazonaws.com/v1/test';
  var response = UrlFetchApp.fetch(api_endpoint, api_parameters);

  console.log(response);
  
}

スクリプトエディタの「実行」ボタンを押すと、初回だけ「承認が必要です」というダイアログボックスが表示されます。「権限を承認」をクリックします。

承認するアカウントの選択画面が出るので、クリックします。

「詳細」ボタンをクリックして、「<プロジェクト名>(安全ではないページ)に移動」をクリックします。

スクリプトエディタのプロジェクト(ここでは”フォームプロジェクト”とした)がGoogleアカウントへのアクセスを求めます。「許可」をクリックします。外部サービスとはAPI Gateway(AWS)のことです。

Google Apps Scriptが実行されますが、この段階ではエラーになります。エラーの内容は、「responseが定義されていない」というもの。スクリプトを単体で動かしているため、eventには何も入っていません。そのため、「responseが定義されていない」となっています。

Googleフォームから入力が行わると、Google Apps Scriptが実行されるようにトリガーを設定します。スクリプトエディタの左のトリガーボタンから、「トリガーを作成」ボタンをクリックし、下記のように設定します。

  • 実行する関数を選択:Google Apps Scriptの関数名を入力
  • 実行するデプロイを選択:Head
  • イベントのソースを選択:フォームから
  • イベントの種類を選択:フォーム送信時

今度はGoogleフォームがアカウントへアクセスする許可を求められます。初回だけです。

先ほどと同じように「<プロジェクト名>(安全ではないページ)に移動」をクリックします。

Googleフォームからデータを送信してみます。

Google Apps Scriptのログを確認します。エラーは出ずにステータスが「完了」となっていることを確認します。種類はGoogleフォームからトリガーされたので、「トリガー」となっています。

DynamoDBを見てみます。先ほどGoogleフォームから送ったデータが登録されています。

最後に

最後までお読みいただきありがとうございました。

今回の検証をやってみて、いろいろなことが勉強になりました。

  • GoogleフォームからGoogle Apps Scriptへ値が渡されて、どのようにGoogle Apps Scriptから取り出すのか。
  • Google Apps ScriptからどのようにAPI Gatewayを呼び出すのか。
  • API Gatewayでの単体テストの方法
  • API GatewayからどのようにLambdaを呼び出すのか。
  • JSONデータを受け取ってLambda上での扱い方
  • Lamdbaの単体テストの方法
  • LambdaからDynamoDBへのPUT方法(これは以外にも簡単だった)

少しでも参考になれば幸いです。

参考にさせていただいたサイトを下記に示します。大変助かりました。ありがとうございました。

参考サイト

ゼロから作りながら覚えるAPI Gateway環境構築

【GAS GoogleAppsScript | 基礎コード】JSONデータを扱うためのJSONオブジェクト

【コピペでOK!】GASでGoogleフォーム回答者のメールアドレスを取得する方法

GoogleForm,GASからAPI Gateway, Lambdaで入力情報をDynamoDBに格納する

AWS LambdaへのJSON入力はごっつええかんじ

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!

コメント

コメントする

コメントは日本語で入力してください。(スパム対策)

CAPTCHA

もくじ
閉じる