「問い合わせメールが埋もれて、対応が遅れてしまった…」
「誰がどのお問い合わせに対応済みか、すぐに分からない…」
「CRMツールを導入したいけど、月額費用が高すぎる…」
コンタクトフォーム7(Contact Form 7、以下CF7)を使っていると、こういう悩みって意外とあるんですよね。SalesforceやHubSpotのようなCRMツールで解決できるのは分かっていても、月額費用を考えると「うちの規模ではまだ早いかな」となりがちです。
今回は、CF7のお問い合わせデータをGoogle Apps Script(GAS)経由でGoogleスプレッドシートに自動保存する方法を紹介します。プラグインもCRMの月額費用もいらないので、0円でお問い合わせの一元管理を始められます。
目次
- なぜコンタクトフォームのスプレッドシート連携が必要なのか
- メール通知だけでは問い合わせの保存に限界がある
- スプレッドシートで管理するメリット
- これはCRM(顧客管理)の第一歩
- CF7×GAS連携の全体のしくみ
- 手順1:Googleスプレッドシートを準備する
- 手順2:Google Apps Script(GAS)でWebhookを作成する
- GASエディタを開く
- スクリプトを作成する
- シークレットキーを生成する
- GASをWebアプリとしてデプロイする
- 手順3:WordPress側でWebhook送信コードを追加する
- functions.phpにコードを追加
- コードの解説
- 手順4:動作確認とテスト
- テスト手順
- curlでGASの動作だけ先にテストする
- うまくいかないときのチェックポイント
- セキュリティ対策のポイント
- シークレットキー認証
- reCAPTCHAによるスパム対策
- HTTPS通信
- 個人情報の取り扱いに関する注意
- ここからお手製CRMに育てる
- まとめ
なぜコンタクトフォームのスプレッドシート連携が必要なのか
メール通知だけでは問い合わせの保存に限界がある
CF7は送信時にメール通知が届く仕組みですが、問い合わせが増えてくると、メールだけでの管理はだんだんキツくなってきます。
- 📩 メールの見落とし — 他のメールに埋もれて対応漏れが発生
- 👥 チームでの共有が困難 — 誰が対応中か、完了したかが分かりにくい
- 📊 データの集計・分析ができない — 問い合わせの傾向を把握しづらい
スプレッドシートで管理するメリット
そこでスプレッドシートに自動で溜まる仕組みを作ると、この辺りの悩みがだいぶ楽になります。
- ✅ 一覧で管理 — 全ての問い合わせがスプレッドシート上に時系列で並ぶ
- ✅ チームで共有 — 複数人がリアルタイムで確認・ステータス更新可能
- ✅ 集計・フィルタ — 期間別やサービス別の問い合わせ傾向を簡単に把握
- ✅ プラグイン不要 — 追加プラグインなしで実装可能なため、セキュリティリスクを最小化
これはCRM(顧客管理)の第一歩
こういう「問い合わせを溜めて管理する仕組み」、ビジネスではCRM(Customer Relationship Management:顧客関係管理) と呼ばれています。代表的なツールはこんな感じです。
| ツール | 特徴 | おすすめの規模 |
|---|---|---|
| Salesforce | CRMの最大手。高機能だがコストも高い | 中〜大企業 |
| HubSpot | 無料プランあり。マーケティング連携が強い | 小〜中規模 |
| Zoho CRM | コスパに優れ、無料〜安価で機能が豊富 | 小〜中規模 |
| kintone | サイボウズ製。日本企業に人気が高い | 小〜中規模 |
| Googleスプレッドシート | 無料。カスタマイズ自由で導入の敷居が低い | スタートアップ・小規模 |
ただ、いきなりこれらを導入するのはハードルが高いかなと思います。まずはスプレッドシートで「問い合わせを一箇所にまとめる」ところから始めるのが現実的です。
対応ステータスの列を足せば進捗管理もできますし、フィルタで傾向を見ることもできます。小さなCRMとしては十分です。問い合わせが増えてきたら、そのときに本格的なツールへ移行すればOKです。
CF7×GAS連携の全体のしくみ
まず全体像を掴んでおきましょう。処理の流れはこうなっています。
sequenceDiagram
participant User as ユーザー(ブラウザ)
participant WP as WordPress(CF7)
participant GAS as Google Apps Script
participant Sheet as Googleスプレッドシート
User->>WP: フォーム送信
WP->>WP: メール送信処理
WP-)GAS: Webhook POST(JSON)※非同期
WP-->>User: 送信完了メッセージ表示
GAS->>GAS: シークレットキー検証
GAS->>Sheet: 行を追加
ポイントは3つです。
| # | 処理 | 説明 |
|---|---|---|
| 1 | フォーム送信 → メール送信 | CF7の標準機能でメール通知は従来通り動作 |
| 2 | メール送信成功 → Webhook送信 | メール送信が成功した場合のみ、GASへJSONデータをPOST |
| 3 | GAS → スプレッドシート記録 | データを検証し、スプレッドシートに1行追加 |
手順1:Googleスプレッドシートを準備する
まずはお問い合わせデータを保存する受け皿のスプレッドシートを作ります。
- Google スプレッドシートを開き、新しいスプレッドシートを作成
- シート名は任意でOKです(例:「お問い合わせ管理」)
- 1行目にヘッダーを設定します
| A列 | B列 | C列 | D列 | E列 | F列 |
|---|---|---|---|---|---|
| 問い合わせ日時 | 氏名 | メールアドレス | 電話番号 | 対象サービス | 問い合わせ内容 |
手順2:Google Apps Script(GAS)でWebhookを作成する
次に、WordPressからのデータを受け取るエンドポイント(Webhook)をGASで作成します。
GASエディタを開く
- 先ほど作成したスプレッドシートを開く
- メニュー 「拡張機能」→「Apps Script」 をクリック
- GASエディタが開きます
スクリプトを作成する
デフォルトの `myFunction` を削除し、以下のコードに置き換えます。
function doPost(e) {
var data = JSON.parse(e.postData.contents);
// シークレットキー検証
var SECRET = 'ここにシークレットキーを設定';
if (!data.secret || data.secret !== SECRET) {
return ContentService.createTextOutput('Unauthorized');
}
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
// ヘッダ行がなければ自動作成
if (sheet.getLastRow() === 0) {
sheet.appendRow([
'問い合わせ日時', '氏名', 'メールアドレス',
'電話番号', '対象サービス', '問い合わせ内容'
]);
}
sheet.appendRow([
data.timestamp,
data.name,
data.email,
data.tel,
data.target_service,
data.message
]);
return ContentService.createTextOutput('OK');
}
シークレットキーを生成する
不正なリクエストを防ぐため、WordPress側とGAS側で共有するシークレットキーを設定します。
ターミナルで以下のコマンドを実行して、ランダムな文字列を生成しましょう。
openssl rand -hex 32
生成された64文字の文字列を、スクリプト内の ‘ここにシークレットキーを設定’ の部分に貼り付けます。このキーは次の手順でWordPress側にも設定するので、必ずメモしておいてください。
GASをWebアプリとしてデプロイする
- 1.GASエディタ右上の 「デプロイ」→「新しいデプロイ」 をクリック
- 2.種類の選択で 「ウェブアプリ」 を選択
- 3.以下の設定にします
| 設定項目 | 値 |
|---|---|
| 説明 | CF7問い合わせ連携(任意) |
| 次のユーザーとして実行 | 自分 |
| アクセスできるユーザー | 全員 |
- 4.「デプロイ」 をクリック
- 5.表示されるウェブアプリのURLをコピーします(次の手順で使用)
手順3:WordPress側でWebhook送信コードを追加する
WordPress側では、CF7のメール送信完了時にGASへデータをPOSTする処理を追加します。
functions.phpにコードを追加
テーマの functions.php に以下のコードを追加します。
[text* your-name] → $data['your-name']
[email* your-email] → $data['your-email']
[tel your-tel] → $data['your-tel']
[checkbox target-service] → $data['target-service']
[textarea your-message] → $data['your-message']
フィールド名が違うとデータが取れずに空欄になるので、ここは丁寧に確認してください。
/**
* CF7メール送信成功時にGASスプレッドシートへデータを送信
*/
add_action('wpcf7_mail_sent', 'send_cf7_to_spreadsheet');
function send_cf7_to_spreadsheet($contact_form) {
// GAS WebアプリのURL
$gas_url = 'https://script.google.com/macros/s/ここにデプロイURLを設定/exec';
// シークレットキー(GAS側と同じ値)
$secret = 'ここにシークレットキーを設定';
// フォームの送信データを取得
$submission = WPCF7_Submission::get_instance();
if (!$submission) {
return;
}
$data = $submission->get_posted_data();
// ペイロードを構築
$payload = array(
'secret' => $secret,
'timestamp' => current_time('Y-m-d H:i:s'),
'name' => isset($data['your-name']) ? $data['your-name'] : '',
'email' => isset($data['your-email']) ? $data['your-email'] : '',
'tel' => isset($data['your-tel']) ? $data['your-tel'] : '',
'target_service' => isset($data['target-service'])
? (is_array($data['target-service'])
? implode(', ', $data['target-service'])
: $data['target-service'])
: '',
'message' => isset($data['your-message']) ? $data['your-message'] : '',
);
// GASへJSON POST(非同期)
wp_remote_post($gas_url, array(
'body' => wp_json_encode($payload),
'headers' => array('Content-Type' => 'application/json'),
'timeout' => 10,
'blocking' => false,
));
}
コードの解説
いくつかハマりやすいポイントがあるので補足しておきます。
wpcf7_mail_sent フック
CF7にはいくつかフックがありますが、ここでは wpcf7_mail_sent を使います。
| フック名 | 発火タイミング | 採用判断 |
|---|---|---|
| wpcf7_mail_sent | メール送信成功後 | ✅ 採用 |
| wpcf7_before_send_mail | メール送信前 | ❌ 不採用 |
wpcf7_before_send_mail を使うと、メール送信に失敗した問い合わせもスプレッドシートに記録されてしまいます。「メール送信が成功した = 正常な問い合わせ」という前提で、wpcf7_mail_sent を選択しています。
wp_remote_post の blocking => false
'blocking' => false,
blocking を false にすると、GASのレスポンスを待たずに次の処理に進みます。つまりWebhookのPOSTだけ投げて、ユーザーにはすぐ送信完了メッセージが返ります。GAS側の処理が遅くてもユーザーの待ち時間に影響しません。
ただし、GAS側でエラーが起きてもPHP側では検知できないので、書き込みが失敗していないかはGASの実行ログで確認してください。
フィールド名のカスタマイズ
上記コードの $data[‘your-name’] や $data[‘your-email’] は、CF7のフォーム設定で定義したフィールド名です。ご自身のフォームのフィールド名に合わせて変更してください。
手順4:動作確認とテスト
設定が完了したら、実際にテスト送信して動作を確認しましょう。
テスト手順
- WordPressサイトのお問い合わせページを開く
- テストデータを入力してフォームを送信
- メール通知が届くことを確認
- Googleスプレッドシートにデータが追加されていることを確認
curlでGASの動作だけ先にテストする
WordPress側の実装をする前に、GAS単体で動くか確認しておくと安心です。ターミナルから以下のコマンドを叩いてみてください。
curl -L -X POST \
'https://script.google.com/macros/s/ここにデプロイURL/exec' \
-H 'Content-Type: application/json' \
-d '{
"secret": "ここにシークレットキー",
"timestamp": "2026-02-18 12:00:00",
"name": "テスト太郎",
"email": "[email protected]",
"tel": "03-0000-0000",
"target_service": "テスト",
"message": "curlからのテスト送信です"
}'
OK と返ってきて、スプレッドシートに行が追加されれば成功です。Unauthorized が返ってきたらシークレットキーが一致していません。
curl -L --post302 -X POST \
'https://script.google.com/macros/s/ここにデプロイURL/exec' \
-H 'Content-Type: application/json' \
-d '{"secret":"キー","timestamp":"2026-02-18 12:00:00","name":"テスト","email":"[email protected]","tel":"","target_service":"テスト","message":"テスト"}'
なおGASの doPost はリダイレクト前に実行されるため、405が返ってきてもスプレッドシートへの書き込みは成功していることがあります。レスポンスよりもスプレッドシートを確認してみてください。
うまくいかないときのチェックポイント
| 症状 | 確認すること |
|---|---|
| スプレッドシートにデータが追加されない | GASのデプロイURLが正しいか確認。URLの末尾が /exec になっているか |
| GASで「Unauthorized」が返る | WordPress側とGAS側のシークレットキーが完全に一致しているか |
| curlで403やアクセス拒否が返る | GASのデプロイ設定で「アクセスできるユーザー」が「全員」になっているか。「自分のみ」だと外部からアクセスできません |
| メールは届くがスプレッドシートに反映されない | GASの「実行数」(エディタの左メニュー)でエラーログを確認 |
| GASの実行ログにエラーがない | wp_remote_post のレスポンスを確認。サーバー側のファイアウォール設定を確認 |
セキュリティ対策のポイント
Webhookを使ったデータ連携では、セキュリティ面も重要です。当社でもWordPressの保守・セキュリティ対策を数多く支援してきた経験から、今回の実装で考慮すべきポイントをまとめます。
シークレットキー認証
GASのWebアプリURLは「アクセスできるユーザー:全員」で公開されていますが、シークレットキーを知らないリクエストはすべて拒否する仕組みを入れています。
// GAS側での検証
if (!data.secret || data.secret !== SECRET) {
return ContentService.createTextOutput('Unauthorized');
}
万が一URLが漏れても、キーを知らなければデータは書き込めません。
reCAPTCHAによるスパム対策
CF7側でreCAPTCHA v3を導入しておくと、ボットによるスパム送信を防止できます。reCAPTCHAは「Contact Form 7」の「インテグレーション」設定から簡単に有効化できます。
HTTPS通信
WordPress側からGASへの通信は https:// なので、TLS(SSL)で暗号化されています。通信の盗聴を気にする必要はありません。
個人情報の取り扱いに関する注意
お問い合わせフォームのデータには個人情報が含まれるので、スプレッドシートで管理する場合は以下も意識しておきたいところです。
- 🔒 スプレッドシートの共有設定 — 「リンクを知っている全員」ではなく、必要な担当者のみに閲覧権限を付与する
- 📝 プライバシーポリシーへの記載 — 「取得した個人情報はGoogleのサービスを利用して管理します」といった旨をプライバシーポリシーに明記する
- 🗓️ データの保持期間 — 対応完了後のデータをいつまで保持するかルールを決め、不要になったデータは定期的に削除する
- 🏢 Google Workspaceの利用推奨 — ビジネス用途では、個人向けGoogleアカウントではなくGoogle Workspaceの利用が望ましい。Workspaceにはデータ処理契約(DPA)が含まれており、企業の個人情報保護方針に沿った運用がしやすくなる
ここからお手製CRMに育てる
ここまでのスプレッドシート連携で、コンタクトフォームからの問い合わせは自動で保存されるようになりました。ここからちょっと列を足すだけで、お手製のCRMっぽく使えるようになります。
たとえばこんな列を追加してみてください。
| G列 | H列 | I列 | J列 |
|---|---|---|---|
| 対応者 | ステータス | 対応日 | メモ |
ステータスはプルダウン(データの入力規則)で「未対応 / 対応中 / 完了」などを選べるようにしておくと便利です。さらに条件付き書式で「未対応 = 赤」「完了 = 緑」のように色分けすれば、対応漏れもひと目で分かります。
やっていることはシンプルですが、「誰が・いつ・どの問い合わせに対応したか」が一覧で見えるだけで、チームの動きはかなり変わります。
まとめ
やることをおさらいしておきます。
- Googleスプレッドシートを作って、ヘッダーを設定
- GASスクリプトを書いて、Webhookとしてデプロイ
- functions.phpに wpcf7_mail_sent フックでWebhook送信コードを追加
- テスト送信して動作確認
プラグインを入れずに済むので、サイトが重くなったりセキュリティリスクが増えたりする心配もありません。
一度仕組みを作ってしまえば、あとはスプレッドシート上で「対応済み」列を追加したり、条件付き書式で色分けしたりと、自分たちのやり方に合わせて育てていけます。
「自分でやるのは難しそう」「もう少し凝った連携を組みたい」という方は、お気軽にご相談ください。当社ではWordPressのカスタマイズから業務フローの自動化まで、エンジニア目線でお手伝いしています。
DX・AI支援サービスのご案内