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

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

2026.03.17

サンプルスクリプトの記述を一部変更しました。

MovableType.net および MovableType.net フォームでは、フォームの受付データを Webhook を使って他サービスへ送信することができます。
Webhook 機能は、いずれのサービスでも、スタンダードプラン以上で利用可能です。

本記事では、フォームの受付データを Google スプレッドシートへ自動で反映させる Webhook プログラムの構築手順を詳しく解説します。

目次

Google スプレッドシートからスクリプトを作成する

スプレッドシートを新規作成し、[拡張機能] > [Apps Script] からエディタを立ち上げます。そこにサンプルスクリプトを貼り付け、プロジェクト名を付けて保存します。

  1. スプレッドシートを新規作成し、[拡張機能] > [Apps Script] をクリックします。
  2. エディタ内の初期コードをすべて削除し、サンプルスクリプトを貼り付けます。
  3. [無題のプロジェクト] をクリックし、任意の名称を入力してプロジェクト名を変更します。
  4. [ドライブにプロジェクトを保存] (フロッピーディスクアイコン)をクリックして、スクリプトを保存します。

サンプルスクリプト

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

// シグネチャ検証用シークレットのキー名(スクリプト プロパティ)
const secretKey = 'SECRET';

// 添付ファイル保存先フォルダ名のキー名(スクリプト プロパティ)
const folderNameKey = 'FOLDER_NAME';

// フォルダ名のデフォルト値(スクリプト プロパティ未設定時に使用)
const defaultFolderName = 'フォーム添付ファイル';


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

const scriptProperties = PropertiesService.getScriptProperties();

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 secret = scriptProperties.getProperty(secretKey);

  if (!secret) {
    throw new Error(`Script property "${secretKey}" is not set.`);
  }

  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進数の文字列に変換
  const signatureVerify = Array.from(byteArray, function (byte) {
    return ('0' + (byte & 0xFF).toString(16)).slice(-2);
  }).join('');

  // シグネチャの検証(一致しなければエラーを出す)
  if (signature !== signatureVerify) {
    throw new Error(`Invalid Signature`);
  }

  const entry = JSON.parse(entryJson);

  // ヘッダーがなければヘッダーをつくる
  const a1 = sheet.getRange('A1').getValue();
  if (!a1) {
    const headers = ['受付番号', '日付'];
    for (let i = 0; i < entry.columns.length; i++) {
      const column = entry.columns[i];
      if (column.type !== 'note') {
        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 if (column.type !== "note") {
      rows.push(column.value);
    }
  }

  sheet.appendRow(rows);

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

function createFolder(sequenceNumber) {
  // スクリプト プロパティからフォルダ名を取得(未設定の場合はデフォルト値を使用)
  const folderName = scriptProperties.getProperty(folderNameKey) || defaultFolderName;

  // Google ドライブのフォーム用フォルダを取得
  let folder;

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

  // Google ドライブにフォルダがない場合は新規作成
  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. 左側のメニューの [プロジェクトの設定](歯車アイコン) をクリックします。
  2. [スクリプト プロパティを追加] をクリックします。
  3. [プロパティ] にキー名、[値] に値を入力します。
  4. [スクリプト プロパティを保存] をクリックします。
スクリプト プロパティの設定例

スクリプトをデプロイする

Google Workspace をご利用の場合、管理者の設定により、デプロイ時に [アクセスできるユーザー] 項目で [全員] が選択できない場合があります。この項目が制限されていると、外部サービスとの連携が正しく機能しないため、事前に組織のポリシーをご確認ください。

スクリプトをウェブアプリ」としてデプロイ(公開)します。

なお、初回デプロイ時に「Google hasn't verified this app(Google はこのアプリを検証していません)」という警告画面が表示されることがありますが、これはエラーではありません。自作のプログラムを安全に公開するための Google の標準的な確認画面ですので、手順に沿って承認フローを続行してください。

警告画面の表示例
  1. [デプロイ] > [新しいデプロイ] をクリックします。
  2. [種類の選択] の隣の [デプロイタイプを有効にする](歯車アイコン)> [ウェブアプリ] をクリックします。
  3. [次のユーザーとして実行] 項目で [自分]、[アクセスできるユーザー] 項目で [全員] を選択し、[デプロイ] をクリックします。
  4. 「Google hasn't verified this app」画面左下の [Advanced] > [Go to...(unsafe)] をクリックします。(※この画面が表示されない場合は、次のステップに進んでください)
  5. スクリプトへのアクセス権付与の同意画面で [Select all] にチェックを入れ、[Continue] をクリックします。
  6. [ウェブアプリ] のURLをクリップボードにコピーします。
新しいデプロイの設定画面

MovableType.net フォームの設定

スクリプトのデプロイが完了したら、次は MovableType.net フォーム側の設定を行います。

ここでは、先ほどスクリプト プロパティに追加したシークレットの値と、デプロイ時にコピーしたウェブアプリのURLを使用します。

  1. MovableType.net の管理画面にログインします。
  2. ダッシュボードに表示されるウェブサイトとブログ一覧から、ウェブサイト名をクリックします。
  3. 左サイドバーの [フォーム] > [一覧] をクリックします。
  4. Webhook 設定を行うフォーム名をクリックします。
  5. 「基本設定」タブの [受付データ] 項目で [Webhookに送信] を選択します。
  6. 「Webhook設定」の [Payload URL] に、ウェブアプリのURLを貼り付けます。
  7. 「Webhook設定」の [Secret] に、スクリプト プロパティの値を貼り付けます。
  8. ページ下部の [保存] をクリックして、変更内容を保存します。
Webhook設定の入力例

フォームのテスト送信をする

最後に、フォームのテスト送信をします。フォームが送信され、スクリプトが正常に実行されると、スプレッドシートに受付データが自動で反映されます。

活用と運用のポイント

複数フォームでの活用や、運用時に役立つTipsをご紹介します。

スクリプトを編集する

このスクリプトは、スプレッドシートにアタッチされた形式(コンテナバインド)で作成されているため、Google ドライブ上には独立したファイルとして表示されません。スクリプトを編集する際は、バインド先のスプレッドシートのメニューの [拡張機能] > [Apps Script] をクリックして、エディタを開いてください。

フォームごとにスプレッドシートを分ける

フォームごとにスプレッドシートを分けて管理する場合は、それぞれ別のプロジェクトとして作成・デプロイが必要です。プロジェクトの作成は、「スプレッドシートの複製」または「新規作成」の2通りの方法で行えます。スクリプトはシートに紐付いているため、複製するとプログラムもそのまま引き継がれます。フォーム項目が同じであれば、複製して使い回すのがおすすめです。

いずれの場合も、添付ファイルの保存先フォルダはフォームごとに分けておくと管理が容易になります。なお、スクリプト プロパティはプロジェクト間で共有されず、手動での再設定が必要となりますので、忘れずに行ってください。

まとめ

Webhook 機能を活用して、フォームの受付データをスプレッドシートに自動で反映することで、チームでの共有やデータ活用がしやすくなります。

より効率的なフォーム運用のための工夫として、ぜひお役立てください。