• 活用ブログTOP
  • Webhook を利用してフォームの送信データを Google スプレッドシートに送る方法
hayase hayase

Webhook を利用してフォームの送信データを Google スプレッドシートに送る方法

今回はフォーム機能に新しく追加されたWebhook機能を利用して、Google スプレッドシートに送信データを直接送る方法をご紹介します。
※ Webhook 機能は MovableType.net、MovableType.net フォーム共にスタンダードプラン以上で利用できます。

Google スプレッドシート側の設定

まず、新しくスプレッドシートを作成します。

次に、拡張機能メニューのApps Scriptを選択します。

スクリプトエディタ画面が開いたら、以下のスクリプトを貼り付けます。今回のスクリプトでは、添付ファイルの項目の場合はGoogleドライブにアップロードしてURLを表示します。

// プログラムの設定 ------------------------------------------------

// ファイル項目を保存するフォルダ名
// 複数のフォームを利用する場合には、フォーム毎にフォルダ名を変更することをお勧めします。
const folderName = 'Webhook Form';

// Webhookの送信元の検証に利用する値
// Webhook設定の「secret」に入力した値を指定してください。
const secret = "secret";


// プログラムの本体 ------------------------------------------------

function doPost(e) {
  try {
    return insertEntry(e);
  } catch (error) {
    return ContentService.createTextOutput(JSON.stringify({
      httpStatusCode: 500,
      message: error.message
    }))
      .setMimeType(ContentService.MimeType.JSON);
  }
}

function insertEntry(e) {
  const sheet = SpreadsheetApp.getActive().getActiveSheet();
  const entryJson = e.parameter.entry;
  const signature = e.parameter.signature;

  // シグニチャの検証
  const byteArray = Utilities.computeHmacSha256Signature(entryJson, secret, Utilities.Charset.UTF_8);

  // シグニチャは16進数で送られてくるのでbyte arrayを16進数の値に変換する。
  const signatureVerify = Array.from(byteArray, function (byte) {
    return ('0' + (byte & 0xFF).toString(16)).slice(-2);
  }).join('');

  if (signature !== signatureVerify) {
    throw new Error(`Invalid Signature: secret=${secret}`);
  }

  const entry = JSON.parse(entryJson);

  // ヘッダーがなければヘッダーをつくる
  const a1 = sheet.getRange('A1').getValue();
  if (!a1) {
    const headers = ['受付番号', '日付'];
    for (let i = 0; i < entry.columns.length; i++) {
      headers.push(entry.columns[i].label);
    }
    sheet.appendRow(headers);
  }

  // 行を追加する
  const sequenceNumber = entry.sequence_number.toString();
  const rows = [
    sequenceNumber,
    new Date(Date.parse(entry.created_at) + 32400000) // 日本時間で表示する
  ];

  let entryFolder;
  for (let i = 0; i < entry.columns.length; i++) {
    const column = entry.columns[i];

    if (column.type === "file" && column.url) {
      entryFolder = entryFolder || createFolder(sequenceNumber);
      try {
        const response = UrlFetchApp.fetch(column.url);
        const fileBlob = response.getBlob();
        const file = entryFolder.createFile(fileBlob);
        rows.push(file.getDownloadUrl());
      } catch (error) {
        rows.push(column.url);
      }
    } else {
      rows.push(column.value);
    }
  }

  sheet.appendRow(rows);

  return HtmlService.createHtmlOutput("Entry accepted");
}

function createFolder(sequenceNumber) {
  // Google Drive のフォーム用のフォルダを取得
  let folder;

  const folderIterator = DriveApp.getFoldersByName(folderName);
  if (folderIterator.hasNext()) {
    folder = folderIterator.next();
  }

  // Google Drive にフォルダが見つからなかったらフォルダを作成
  if (!folder) {
    folder = DriveApp.createFolder(folderName);
  }

  // entry用のフォルダを作成
  let entryFolder;
  const entryFolderIterator = folder.getFoldersByName(sequenceNumber);
  if (entryFolderIterator.hasNext()) {
    entryFolder = entryFolderIterator.next();
  }

  if (!entryFolder) {
    entryFolder = folder.createFolder(sequenceNumber);
  }

  return entryFolder;
}

1点変更が必要で、シグニチャの検証のsecretの部分を後ほどMovableType.net側で設定するものと同じものにします。

スクリプトの編集が終わったらプロジェクトを保存します。

次に、「デプロイ > 新しいデプロイ」に進みます。

新しいデプロイの画面が表示されるので種類の選択からウェブアプリを選択します。

設定の内容が表示されるので、ウェブアプリ自分(自分のアカウントのメールアドレス)を選択し、アクセスできるユーザーでは全員を選択してデプロイボタンを押します。

許可を求めるウィンドウが表示されるので、アクセスを承認を選択します。

その後、自分のGoogleアカウントを選択すると、以下の画面が表示されますが詳細をクリックして進みます。

さらにフォームスクリプト(安全ではないページ)に移動をクリックします。

権限を確認する画面が表示されるので、許可ボタンを押します。

ウェブアプリとしてデプロイしたメッセージが表示されるので、「ウェブアプリ > URL」をコピーします。

MovableType.net 側のフォームの設定

MovableType.net 側のフォームの設定は、各フォームの基本設定の受付データのデータの保存Webhookに送信を選択し、先程コピーしたURLを Payload URL の欄に貼り付け、Secret 欄には先程スクリプト内で指定したものと同じものを記述します。

上記設定を行い保存すれば、Webhook連携は完了です。

後は実際にフォームのデータを送信すると

以下のようにGoogleスプレッドシートに直接データが送られます。

以上、効率的なフォームの運用にご活用ください。