HTMLフォームからデータをGoogleシートに送信する


私は、このような状況に、私はメーリングリスト、オプトインフォーム、または調査のようなもののためのウェブサイト上でユーザーデータを収集する必要がある場所をますます頻繁に実行しているが、私はデータを格納するためのマーケティングプラットフォームを持っていない.彼らはすべての異なる価格と機能を持って、私は使用する方法を把握する時間がない.私はフロントエンドからGoogleシート(列ヘッダーへのマッピングフィールド)への投稿を追加し、後でマーケティングプラットフォームについて心配したいと思いました.しかし、私はそれを行うには良いサービスを見つけることができなかった.
だから私は自分でそれを構築することを決めた.そのハード、右できませんでしたか?
どうやってやったのか

テックスタック


私が以前書いたように、私は、あなたのスタートアップのために完全な技術スタックがあなたが速く仕事をさせるために使うことができるものであると思います.私のために、それはMern StackでのバリエーションですServerless ホストフレームワークとして.
あなたが前にServerlessアプリを構築したことがない場合は、何かを始めるために探している.take a look at this boilerplate project I threw together. それはかなり基本的ですが、私は物事を始めるために多くのプロジェクトのためにそれを使用します.
プロジェクトを見たときの重要な考慮点は以下の通りでした.
  • HTTP入力を使用してフォームの入力を検証し、ユーザーの目に見えるエラーをスローする必要がありました.
  • すべてがよく見えたならば、それは我々がシートを更新することについてGoogleに話すのを始める必要があった時です.そして、これが第三者であったので、我々は責任があって相互に作用して、我々の料金を制限する必要がありました.
  • 私はもう一つの記事でこれについて書きました、しかし、Googleとのどんな相互作用も労働者機能でキューで起こる必要がありました.これはServerlessとFIFOのための最適なアプリケーションです.
    最後にスケッチした基本的なアーキテクチャは以下のようになります.

    この枠組みを適所にして、論理の各ビットの詳細を理解する必要があった.

    GoogleシートAPIの操作


    HTTPエンドポイントは次のようにポストペイロードを得ています.
    {
        "DOB": "6/20/1997"
        "Name": "Jane Doe",
        "Email": "[email protected]",
    }
    
    以下のようなシートに変換する必要がありました.

    唯一の警告は、値が正しくデータを注文する必要があるため、値はシート内の列にマッチし、シートの末尾に追加されます.かなり簡単.
    注意:これらのすべての例はGoogle Sheets API, v4.

  • https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/append
  • const { google } = require('googleapis');
    
    class ExecuteSheetUpdateCommand {
      /**
       * @param {string} spreadsheetId ID of the Google Spreadsheet.
       * @param {Object} data Object that contains the data to add to the sheet as key-value pairs.
       * @param {google.auth.OAuth2} auth An Google OAuth client with a valid access token: https://github.com/googleapis/google-api-nodejs-client.
      */
      static async exec(spreadsheetId, data, auth) {
        const sheets = google.sheets({ version: 'v4', auth });
    
        const rows = [data.Name, data.Email, data.DOB];
        // Add our new data to the bottom of the sheet.
        await sheets.spreadsheets.values.append({
          spreadsheetId,
          range: 'A1',
          valueInputOption: 'RAW',
          insertDataOption: 'INSERT_ROWS',
          resource: {
            values: [rows],
          },
        });
      }
    }
    
    ビオラ!つのシンプルな機能を使用すると、自動的にGoogleシートにフォームデータをマッピングしていた.
    今この機能は明らかではない.フォームヘッダーをシート構造に結合します.const rows = [data.Name, data.Email, data.DOB]; あなたは本当にそれをすべきではない.(例えば、スプレッドシートの列を移動した場合、この関数は古い位置にデータを挿入し続けるでしょう.しかし、フォームヘッダーをシートヘッダーに自動的にマップするのは少し複雑です.

    SQSワーカーによる残りのエンドポイントの追加


    ので、JSONオブジェクトをGoogleシートに送信できる機能を持っていますが、HTMLフォームでどうやって行うのですか?答えはhttp + sqsです.
    ノードとノードに精通している場合はExpress . (他のノードにやさしい環境で簡単に配備することができますが、ServerlessやAWSでどうするかを示します.私はaws-serverless-express パッケージは、Serverlessなラムダ関数として私の急行アプリを出荷します.と組み合わせるserverless-api-cloudfront パッケージは、それは非常にスケーラブルなAPIをスピンに簡単です.
    Googleシートへのアップデートを開始する、明示的なHTTPエンドポイントです.
    const express = require('express');
    const bodyParser = require('body-parser');
    
    // An AWS SQS client
    const sqsClient = require('./clients/SQSClient');
    
    const app = express();
    
    app.use(bodyParser.urlencoded({ extended: true }));
    
    app.post('/form/:spreadsheetId', async (req, res, next) => {
      const { spreadsheetId } = req.params; // The Google Sheet ID
      const { body } = req; // The post body
    
      /* Note: You should run your own custom validation on the 
         * form before forwarding it on. In this example we just continue.
       *
         * At a minimum, make sure you have permission to update the 
       * sheet, otherwise this will break downstream.
         */
      const passedValidation = true;
    
      if(passedValidation) {
        // Send the data to our SQS queue for further processing
        await sqsClient.createEntry.sendMessage({
          spreadsheetId,
                body,
        });
      } else {
        throw new Error('Invalid form data');
      }
    
      res.status(200).send('Submitted your form');
    });
    
    そして、ここでは、スロットされたSQS FIFOキューのデータをプルし、それをGoogleのために処理するラムダ関数です.
    const { google } = require('googleapis');
    const ExecuteSheetUpdateCommand = require('../commands/ExecuteSheetUpdateCommand');
    
    exports.handle = async (event, context, callback) => {
      const messages = event.record.body;
    
      // This little logic helps us throttle our API interactions
      messages.reduce(async (previousPromise, nextMessage) => {
        await previousPromise;
        const { spreadsheetId, body } = nextMessage;
        const accessToken = /* Load a valid access token for your Google user */;
        // Construct an oAuth client with your client information that you've securely stored in the environment
            const oAuth2Client = new google.auth.OAuth2(
          process.env.GOOGLE_CLIENT_ID, process.env.GOOGLE_CLIENT_SECRET, null,
        );
        oAuth2Client.setCredentials({
          access_token: accessToken,
        });
        await ExecuteSheetUpdateCommand.exec(spreadsheetId, body, oAuth2Client);
        return new Promise((resolve) => {
          setTimeout(resolve, 1000); // Throttle for the Google API
        });
      }, Promise.resolve());
    
      callback();
    };
    
    我々が使っている理由SQS with FIFO HTTPエンドポイントでこれを実行するだけではなく、フォームを送信しているユーザーにすぐに対応でき、APIの制限を尊重しながらすぐにシートを更新できます.
    API限界について考えないなら、フォームを提出するとすぐにユーザーがエラー画面を見せられる状況に陥ります.良い.GoogleのシートAPIは、“ユーザーごとに100秒あたり100リクエスト”の制限を持って、または1要求/秒は、我々がそれと対話することができますように高速です.
    SQS FIFO queues 我々のシート更新をユーザIDでグループ化した単一のラインに入れることを許します、そして、それから我々はそれを使用してそれらの実行を絞りますmessages.reduce 上記のスニペットは、1リクエスト/秒/ユーザの制限を超えないことを確認します.そして、我々はまた、AWSは絞りのハードワークを行うことができます追加の利点を得る.キーは、あなたがFIFO待ち行列を積んでいるとき、確かですMessageGroupId OAuth要求を行っているGoogleユーザーIDに設定されます.

    包み上げる


    これらのテクニックと関数の組み合わせを使用すると、次のようなHTMLフォームを書くことができます.
    <form action="https://<my-express-endpoint>/form/<my-sheet-id>" method="post">
    <input type="email" name="Email" placeholder="Enter your email" required />
    <input type="name" name="Name" placeholder="Enter your name" required />
    <input type="submit" value="Submit" />
    </form>
    
    そして、それが提出されるたびに、データはあなたのGoogleシートで魔法的に現れます

    シートモンキー


    を、私は思ったよりも多くの仕事だった.そういうわけで、私はこれをAに変えましたlittle indie product . あなたのHTMLフォームをGoogleシートに送信する必要がある場合は、独自のソリューションを構築する手間をかけたくない場合は、私はシートモンキーで構築したチェックアウト.