WordPressのお問い合わせフォームに届いた内容を、Googleスプレッドシートに1行ずつ自動で記録したい。問い合わせの件数を数えたり、対応状況を社内で共有したりするには、メールよりも表のほうが便利です。
専用のプラグインを使う方法もありますが、当社ではGoogleのスプレッドシートに付いている「Apps Script」と、WordPressの標準機能だけで記録する仕組みを作り、自社の相談フォームで動かしています。この記事では、その手順と、実際に動かしてつまずいた点を紹介します。
結論から言うと、スプレッドシート側に「受け取って1行追加する」小さなプログラム(ウェブアプリ)を置き、WordPressからは合言葉を付けて送ります。注意点は2つです。1つは、先頭が「=」の値が数式として動かないようにすること。もう1つは、Apps Scriptが返す「転送」をWordPressに自動で追わせないことです。
フォームの内容をスプレッドシートで管理したい理由
問い合わせがメールだけに届いていると、「今月何件来たか」「誰が対応中か」「返信済みか」を確かめるたびにメールを探すことになります。担当者が複数いると、同じ問い合わせに2人が返信したり、誰も返信していなかったりもします。
スプレッドシートに1行ずつ記録しておけば、並べ替えや絞り込みで件数や対応状況がすぐに分かり、社内での共有も簡単です。当社では、受付日時・会社名・お名前・メールのほか、問い合わせの種類や優先度、要約、「対応状況」と「メモ」の列を用意し、対応状況は最初「未対応」で記録されるようにしています。

スプレッドシート側の準備(Apps Script)
まずは、スプレッドシートに「データを受け取って1行追加する」プログラムを置きます。
- Googleドライブで新しいスプレッドシートを作り、1枚目のシート名を「相談台帳」にする
- メニューの「拡張機能」→「Apps Script」を開き、最初からあるコードを消して次のコードを貼り付ける(当社で使っているものから、記事用に列を減らした例です)
- 3行目の合言葉(TOKEN)を、推測されにくい長いランダムな文字列に変えて保存する
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
const SHEET_NAME = '相談台帳'; const TOKEN = 'ここを推測されにくい長い文字列に変える'; const HEADERS = ['受付日時', '会社名', 'お名前', 'メール', '内容', '対応状況', 'メモ']; function doPost(e) { let data; try { data = JSON.parse(e.postData.contents); } catch (err) { return json({ ok: false, error: 'bad_json' }); } if (!data || data.token !== TOKEN) { return json({ ok: false, error: 'forbidden' }); } const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME); if (!sheet) return json({ ok: false, error: 'no_sheet' }); if (sheet.getLastRow() === 0) { sheet.appendRow(HEADERS); sheet.setFrozenRows(1); } // 先頭が = + - @ の値は数式として解釈されないように ' を付ける const safe = (v) => { const s = v === undefined || v === null ? '' : String(v); return /^[=+\-@]/.test(s) ? "'" + s : s; }; sheet.appendRow([ data.received_at, data.company, data.name, data.email, data.message, '未対応', '' ].map(safe)); return json({ ok: true }); } function json(obj) { return ContentService.createTextOutput(JSON.stringify(obj)).setMimeType(ContentService.MimeType.JSON); } |
次に、このプログラムをインターネットから呼べるように公開します。
- 右上の「デプロイ」→「新しいデプロイ」→ 種類に「ウェブアプリ」を選ぶ
- 「次のユーザーとして実行」は「自分」、「アクセスできるユーザー」は「全員」にする
- 「デプロイ」を押し、自分のGoogleアカウントで許可する(「このアプリは確認されていません」と出たら「詳細」から進む。自分で作ったプログラムなので問題ありません)
- 表示されたウェブアプリのURL(script.google.com/macros/s/…/exec)を控える
「全員」にすると不安に感じるかもしれませんが、合言葉が一致しないデータは記録しないので、URLを知っている人でも勝手に書き込めません。実際に違う合言葉で送ると、「forbidden(拒否)」と返ってきて、行は追加されませんでした。
合言葉は「人が覚えないランダムな文字列」にする
この合言葉は、人が入力するものではなく、WordPressとApps Scriptがお互いを確かめるための鍵です。覚える必要がないので、32文字程度のランダムな英数字にしておくのが安全です。短い言葉や、会社名・日付などの推測しやすいものは避けてください。
なお、Apps Scriptのコードを書き換えて保存しただけでは、公開中のウェブアプリには反映されません。「デプロイ」→「デプロイを管理」→ 鉛筆アイコン →「バージョン:新バージョン」で更新すると、URLを変えずに反映できます。合言葉を変えたときは、この更新を忘れないようにしてください。
ここまでのまとめ
- スプレッドシートにApps Scriptで「受け取って1行追加する」ウェブアプリを置く
- URLは公開されるので、合言葉で書き込みを守る。合言葉は長いランダムな文字列にする
- 先頭が「=」などの値は、’ を付けて数式として動かないようにする
技術者向け:WordPressから送るコードと「転送」の落とし穴
WordPress側は、フォームの送信後にwp_remote_post()でウェブアプリのURLへJSONを送るだけです。ところが、最初に書いたコードでは記録に失敗しました。原因はApps Scriptの「転送」です。

Apps Scriptのウェブアプリは、データを受け取って処理したあと、結果を別のURL(script.googleusercontent.com)への302転送で返します。WordPressの送信機能に転送を自動で追わせると、転送先にもう一度POSTで送ってしまい、Googleが400エラーを返しました。転送は自動で追わず、転送先をGETで読むと、{“ok”:true}が返ってきます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<?php function my_send_to_sheet( array $row ) { if ( ! defined( 'MY_SHEET_URL' ) || ! defined( 'MY_SHEET_TOKEN' ) ) { return null; // 未設定なら何もしない } $row['token'] = MY_SHEET_TOKEN; // Apps Script は 302 で結果のURLへ転送する。自動で追わず、転送先は GET で読む $res = wp_remote_post( MY_SHEET_URL, array( 'timeout' => 20, 'redirection' => 0, 'headers' => array( 'Content-Type' => 'application/json' ), 'body' => wp_json_encode( $row, JSON_UNESCAPED_UNICODE ), ) ); if ( is_wp_error( $res ) ) { return false; } $code = (int) wp_remote_retrieve_response_code( $res ); if ( in_array( $code, array( 301, 302, 303, 307, 308 ), true ) ) { $location = (string) wp_remote_retrieve_header( $res, 'location' ); if ( '' === $location ) { return false; } $res = wp_remote_get( $location, array( 'timeout' => 20 ) ); if ( is_wp_error( $res ) ) { return false; } } $json = json_decode( (string) wp_remote_retrieve_body( $res ), true ); return is_array( $json ) && ! empty( $json['ok'] ); } |
URLと合言葉は、コードに直接書かず、wp-config.phpに定数(MY_SHEET_URL、MY_SHEET_TOKEN)として書いておきます。テーマやプラグインのファイルを人に見せたり、GitHubに置いたりしても漏れないようにするためです。この関数を、使っているフォームの「送信後」のフックから呼び出します。当社の実装は同じ処理を自作のフォームで動かしており、上のコードはそれを汎用の形に書き直したものです。
「失敗」でも行は追加されていることがある
検証で分かったもう1つの落とし穴が、WordPress側で失敗と判定された回も、スプレッドシートには行が追加されていたことです。行の追加は最初のPOSTの時点で終わっていて、失敗していたのはその後の「結果を読む」部分だったからです。
つまり、「失敗したら送り直す」処理を安易に入れると、同じ問い合わせが2行記録されることがあります。当社では送り直しはせず、失敗はログに残すだけにしています。問い合わせの本体は通知メールで必ず届いているので、記録が抜けていたら人が後から足せば済むからです。
また、4回続けて送ったテストでは、1回だけGoogle側の応答が30秒で時間切れになりました。フォームの送信直後にこの処理を直接行うと、お客様の画面がその間待たされます。WP-Cronで「裏で動かす処理」として予約し、画面は先に完了させる作りがおすすめです。この考え方は問い合わせをAIで自動整理する方法でも紹介しています。
よくある質問
Q. プラグインを使ったほうが簡単ではありませんか?
連携用のプラグインを使えば、コードを書かずに設定できるものもあります。ただ、有料だったり、外部サービスを経由したりすることもあります。今回の方法は、Googleアカウントとスプレッドシートがあれば追加の費用がかからず、どの列に何を記録するかを自由に決められるのが利点です。
Q. 個人情報をスプレッドシートに記録しても大丈夫ですか?
スプレッドシートの共有範囲を必要な人だけに絞り、プライバシーポリシーに記録先を書いておくことが大切です。当社では、問い合わせの全文や返信の下書きはメールだけに載せ、スプレッドシートには要約など管理に必要な項目だけを記録しています。
Q. 送信に失敗したら、問い合わせが消えてしまいますか?
通常の通知メールを別に送っていれば、問い合わせ自体は届いています。スプレッドシートへの記録は「管理用の控え」と考え、失敗したときは通知メールを見て手で足してください。
フォームと社内の業務をつなげたい方へ
フォームの内容をスプレッドシートに記録できると、件数の集計や対応漏れの確認、AIによる整理など、次の自動化にもつなげやすくなります。当社はWordPress専門のエンジニアとして、フォームと社内のツールをつなぐ仕組みを、「どこまで自動にして、どこで人が確認するか」から一緒に考えます。
▶ AI業務自動化・AIシステム開発の詳細を見る(相談無料)
更新履歴
- 2026年9月29日:作成(当社の相談フォームで実装し、テスト送信で確認)