予約管理をGoogleカレンダーで自動化する方法
GAS×フォーム実践ガイド
予約の電話対応、手帳やExcelでの管理、ダブルブッキングの不安…。予約管理は最もコスパよく自動化できる業務の一つです。
この記事では、Googleフォーム+GAS+Googleカレンダーだけで 予約管理を完全自動化する方法を、コード付きで解説します。追加費用ゼロ。
⏱ 読了時間:約12分 | 実装時間:約1時間 | 前提:Googleアカウント(無料でOK)
📖 目次
1. 予約管理の課題と自動化のメリット
❌ 手動管理の問題
- 電話対応に1件5〜10分かかる
- ダブルブッキングのリスク
- 営業時間外は予約受付できない
- 予約台帳の記入ミス
- リマインダーの送り忘れ
✅ 自動化のメリット
- 24時間予約受付
- ダブルブッキングゼロ
- カレンダーに自動登録
- 確認メール自動送信
- 前日リマインダー自動送信
📊 予約自動化の効果
2. 仕組みの全体像
┌──────────┐ 送信 ┌──────────┐ GAS ┌──────────┐
│ Google │ ────> │ スプレッド │ ────> │ Google │
│ フォーム │ │ シート │ │カレンダー │
└──────────┘ └──────────┘ └──────────┘
お客様が入力 予約データ蓄積 自動で予定登録
│
┌────┴────┐
│ GAS │
│ スクリプト │
└────┬────┘
│
┌─────────┼─────────┐
▼ ▼ ▼
確認メール リマインダー ダブルブッキング
自動送信 前日通知 チェック使うツールはGoogleだけ。Googleフォーム、スプレッドシート、カレンダー、GAS(Google Apps Script)。 すべて無料で、追加のサービスへの登録は不要です。
3. Step 1: 予約フォームを作る
Googleフォームで予約フォームを作り、スプレッドシートに回答を記録します。
Googleフォームを作成
forms.google.com → 「空白のフォーム」
必要なフィールドを追加
以下を推奨:
推奨フィールド
| 項目 | フォームの種類 | 備考 |
|---|---|---|
| お名前 | 記述式(短文) | 必須 |
| メールアドレス | 記述式(短文) | 必須・確認メール送信先 |
| 電話番号 | 記述式(短文) | 任意 |
| 希望日 | 日付 | 必須 |
| 希望時間帯 | プルダウン | 10:00, 11:00... 等 |
| メニュー/内容 | ラジオボタン | 業種に合わせて |
| 備考 | 段落(長文) | 任意 |
スプレッドシートにリンク
フォーム「回答」タブ → スプレッドシートアイコン → 「新しいスプレッドシートを作成」
4. Step 2: GASで予約をカレンダーに自動登録
フォームが送信されたら、GASが自動でGoogleカレンダーに予定を作成します。
// GASスクリプト — カレンダー自動登録
// カレンダーIDを設定(自分のカレンダーまたは予約用カレンダー)
const CALENDAR_ID = 'primary'; // または 'xxx@group.calendar.google.com'
const SLOT_DURATION_MIN = 60; // 1枠の所要時間(分)
/**
* フォーム送信時に自動実行されるトリガー関数
*/
function onFormSubmit(e) {
const response = e.namedValues;
const name = response['お名前'][0];
const email = response['メールアドレス'][0];
const phone = response['電話番号'] ? response['電話番号'][0] : '';
const date = response['希望日'][0];
const time = response['希望時間帯'][0];
const menu = response['メニュー'][0];
const note = response['備考'] ? response['備考'][0] : '';
// 日時をパース
const startTime = parseDateTime(date, time);
const endTime = new Date(
startTime.getTime() + SLOT_DURATION_MIN * 60 * 1000
);
// ダブルブッキングチェック
if (isSlotTaken(startTime, endTime)) {
// 空いていない場合 → お断りメール
sendDeclineEmail(email, name, date, time);
markAsDeclined(e.range.getRow());
return;
}
// Googleカレンダーに予定を作成
const calendar = CalendarApp.getCalendarById(CALENDAR_ID);
const event = calendar.createEvent(
'【予約】' + name + '様 - ' + menu,
startTime,
endTime,
{
description: [
'お名前: ' + name,
'メール: ' + email,
'電話: ' + phone,
'メニュー: ' + menu,
'備考: ' + note,
].join('\n'),
location: '', // 必要なら住所を設定
}
);
// 確認メールを送信
sendConfirmationEmail(email, name, date, time, menu);
// スプレッドシートにステータスを記録
markAsConfirmed(e.range.getRow(), event.getId());
}
/**
* 日付と時間の文字列をDateオブジェクトに変換
*/
function parseDateTime(dateStr, timeStr) {
// "2026/02/20" + "14:00" → Date
const parts = dateStr.split('/');
const timeParts = timeStr.split(':');
return new Date(
parseInt(parts[0]),
parseInt(parts[1]) - 1,
parseInt(parts[2]),
parseInt(timeParts[0]),
parseInt(timeParts[1]) || 0
);
}✅ GASの設定手順:
- スプレッドシートを開く → 「拡張機能」→「Apps Script」
- 上のコードを貼り付け
- 「トリガー」→「トリガーを追加」→ 関数: onFormSubmit / イベント: フォーム送信時
- 初回実行時にGoogleカレンダーへのアクセス許可を求められるので「許可」
5. Step 3: ダブルブッキング防止
予約を登録する前に、同じ時間帯に既存の予定がないかをチェックします。
// ダブルブッキングチェック関数
/**
* 指定時間帯にすでに予定があるかチェック
*/
function isSlotTaken(startTime, endTime) {
const calendar = CalendarApp.getCalendarById(CALENDAR_ID);
const events = calendar.getEvents(startTime, endTime);
// 「予約」を含むイベントがあればダブルブッキング
return events.some(
event => event.getTitle().includes('【予約】')
);
}
/**
* 予約不可メールを送信
*/
function sendDeclineEmail(email, name, date, time) {
const subject = '【ご予約について】' + date + ' ' + time;
const body = name + '様\n\n'
+ 'ご予約のお申し込みありがとうございます。\n'
+ '大変申し訳ございませんが、ご希望の日時は\n'
+ '既にご予約が入っております。\n\n'
+ '別の日時でのご予約を検討いただけますと幸いです。\n'
+ 'ご不明な点はお気軽にお問い合わせください。\n\n'
+ '-----\n'
+ 'ご予約フォーム: [フォームURLをここに]';
MailApp.sendEmail(email, subject, body);
}
/**
* スプレッドシートにステータスを記録
*/
function markAsConfirmed(row, eventId) {
const sheet = SpreadsheetApp.getActiveSheet();
// ステータス列(例: H列)に「確定」と記録
sheet.getRange(row, 8).setValue('確定');
sheet.getRange(row, 9).setValue(eventId);
}
function markAsDeclined(row) {
const sheet = SpreadsheetApp.getActiveSheet();
sheet.getRange(row, 8).setValue('不可(時間重複)');
}⚠️ 注意: カレンダーの予定タイトルに「【予約】」を含むものだけをチェックしています。 プライベートの予定とは区別されるので、同じカレンダーで個人の予定も管理できます。
6. Step 4: 確認メールの自動送信
予約が確定したら、お客様に確認メールを自動送信します。
// 確認メール送信関数
function sendConfirmationEmail(email, name, date, time, menu) {
const subject = '【予約確定】' + date + ' ' + time + ' のご予約';
const body = name + '様\n\n'
+ 'ご予約ありがとうございます!\n'
+ '以下の内容で予約を確定いたしました。\n\n'
+ '━━━━━━━━━━━━━━━━━━━━\n'
+ '📅 日時: ' + date + ' ' + time + '\n'
+ '📋 内容: ' + menu + '\n'
+ '━━━━━━━━━━━━━━━━━━━━\n\n'
+ '■ キャンセルについて\n'
+ '前日の18:00までにご連絡ください。\n'
+ '当日キャンセルはキャンセル料が\n'
+ '発生する場合があります。\n\n'
+ '■ アクセス\n'
+ '東京都○○区○○ 1-2-3\n'
+ '○○駅 徒歩5分\n\n'
+ 'ご不明な点はお気軽にご連絡ください。\n'
+ 'お会いできることを楽しみにしております!\n\n'
+ '-----\n'
+ '○○(店舗名)\n'
+ 'TEL: 03-XXXX-XXXX';
MailApp.sendEmail(email, subject, body);
}📌 GASのMailApp: Googleアカウントのメールアドレスから直接送信されます。 1日100通まで(Google Workspace の場合は1,500通)送信可能。 予約管理には十分な量です。
7. Step 5: リマインダーの自動送信
予約の前日にリマインダーメールを自動送信。無断キャンセルを最大30%削減できます。
// リマインダー送信(毎日18時に実行)
/**
* 翌日の予約にリマインダーを送信
* トリガー: 時間ベース → 毎日18時
*/
function sendReminders() {
const sheet = SpreadsheetApp.getActiveSheet();
const data = sheet.getDataRange().getValues();
const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
const tomorrowStr = Utilities.formatDate(
tomorrow, 'Asia/Tokyo', 'yyyy/MM/dd'
);
// ヘッダー行をスキップ(i=1から)
for (let i = 1; i < data.length; i++) {
const row = data[i];
const date = row[3]; // 希望日(D列)
const status = row[7]; // ステータス(H列)
if (status !== '確定') continue;
// 日付を比較
const dateStr = Utilities.formatDate(
new Date(date), 'Asia/Tokyo', 'yyyy/MM/dd'
);
if (dateStr !== tomorrowStr) continue;
const name = row[0]; // お名前
const email = row[1]; // メール
const time = row[4]; // 時間
const menu = row[5]; // メニュー
const subject = '【明日のご予約リマインダー】'
+ tomorrowStr + ' ' + time;
const body = name + '様\n\n'
+ '明日のご予約のリマインダーです。\n\n'
+ '📅 日時: ' + tomorrowStr + ' ' + time + '\n'
+ '📋 内容: ' + menu + '\n\n'
+ 'お会いできることを楽しみにしております!\n\n'
+ '※ キャンセルの場合は本日18:00まで'
+ 'にご連絡ください。';
MailApp.sendEmail(email, subject, body);
// リマインダー送信済みフラグ
sheet.getRange(i + 1, 10).setValue('リマインダー送信済み');
}
}✅ トリガー設定: GASの「トリガー」→「トリガーを追加」→ 関数: sendReminders / 時間ベース / 毎日 / 午後6時〜7時。 これで毎日自動実行されます。
8. 業種別カスタマイズ
💇 美容室・ネイルサロン
- メニュー: カット / カラー / パーマ / ネイル等を選択式に
- 所要時間: メニューごとに異なる(カット60分、カラー120分等)
- 担当者指名: スタッフ名を選択肢に追加、カレンダーを分ける
- LINE連携: 確認・リマインダーをLINEで送信(開封率UP)
🏥 クリニック・歯科
- 診療科目: 内科 / 皮膚科 / 歯科検診等を選択式に
- 初診/再診: 初診は問診票フォームへの誘導を追加
- 保険証: 確認メールに「保険証をお持ちください」を記載
- 枠制限: 1時間あたりの予約上限を設定(医師の対応可能数)
🍽️ 飲食店・レストラン
- 人数: 1名〜の選択肢。大人数はお電話でと案内
- コース: ランチ / ディナー / コース料理の選択
- アレルギー: 備考欄でアレルギー情報を事前収集
- 席種: カウンター / テーブル / 個室の希望
🏋️ ジム・スタジオ・教室
- レッスン: ヨガ / ピラティス / パーソナルトレーニング等
- 定員管理: 1枠あたりの定員をチェック(グループレッスン向け)
- 回数券: 残り回数をスプレッドシートで管理
- インストラクター: 担当者別のカレンダーで管理
9. 運用コスト
月間100件の予約を処理した場合:
💡 比較: 予約管理SaaS vs 自作
予約SaaS
(STORES予約等)
¥8,000〜/月
月額固定費
電話受付
(パートスタッフ)
¥60,000/月
時給1,200円×2.5h×20日
Google
自動化(本記事)
¥0/月
24時間自動受付
10. さらなる発展
🤖 AI応答との組み合わせ
LINE AI自動応答と組み合わせれば、 LINEで「予約したい」と言われたらAIがヒアリング → Googleカレンダーに自動登録まで完全自動化。
📱 Webサイトへの埋め込み
Googleフォームをiframeでサイトに埋め込み。もしくはNext.jsで独自フォームを作り、 GAS Web Appに送信する方法も。
📊 予約分析ダッシュボード
スプレッドシートに蓄積されたデータから、曜日別・時間帯別の予約傾向を分析。 Googleデータポータルで可視化すれば、空き枠の最適化に活用できます。
🔄 キャンセル待ち機能
満枠の時間帯にキャンセル待ちリストを作成。キャンセルが出たら 自動でキャンセル待ちの方にメール通知。機会損失を最小限に。
まとめ
- ✅Googleフォーム+GAS+カレンダーで予約管理を完全自動化
- ✅ダブルブッキング自動チェックで安心
- ✅確認メール+前日リマインダーを自動送信
- ✅美容室・クリニック・飲食店・教室などあらゆる業種に対応
- ✅運用コストは完全無料
「予約管理の自動化を導入したい」
フォーム設計から、LINE連携、AI応答の追加まで、 あなたのビジネスに最適な予約システムをご提案します。
無料で相談する →