LINE公式アカウントとGoogleスプレッドシートで予約管理システムを作る方法【完全ガイド】 - collect-info

LINE公式アカウントとGoogleスプレッドシートで予約管理システムを作る方法【完全ガイド】

店舗経営や訪問型サービスを提供している方の多くが抱える悩み、それは「予約管理の煩雑さ」です。電話やメッセージで受けた予約を手作業でスプレッドシートや紙の台帳に転記する作業は、時間がかかるだけでなく、入力ミスや重複予約のリスクも伴います。

そこで本記事では、多くのお客様が日常的に使用している「LINE公式アカウント」と、データ管理に優れた「Googleスプレッドシート」を連携させた自動予約管理システムの構築方法を、実際に動作するコード例とともに詳しく解説します。

このシステムで実現できること

構築完了後は、以下のような流れで予約管理が自動化されます:

  • お客様がLINEで予約ができる
  • システムが自動で日時・メニュー・連絡先を聞き出し
  • 回答内容がリアルタイムでGoogleスプレッドシートに記録
  • 店舗側はスプレッドシートを確認するだけで予約状況を把握
  • 予約確認や前日リマインドも自動送信可能

なぜLINE × Googleスプレッドシートなのか

お客様にとってのメリット

LINEは日本国内で9,500万人以上が利用する最も身近なコミュニケーションツールです。専用アプリのインストールや新規アカウント作成が不要なため、予約への心理的ハードルが大幅に下がります。また、予約内容の変更やキャンセルも気軽にメッセージで連絡できるため、お客様の利便性が向上します。

店舗側にとってのメリット

Googleスプレッドシートは多くの事業者が既に業務で使用しているため、新たな操作を覚える必要がありません。リアルタイムでの情報共有、スタッフ間でのアクセス権限管理、顧客データの分析・集計など、スプレッドシートならではの柔軟性を活かせます。さらに、初期費用・月額費用ともにほぼゼロで始められる点も大きな魅力です。

システムの仕組みと全体構成

3つの構成要素

このシステムは以下3つの要素で構成されます:

  • LINE公式アカウント: お客様とのコミュニケーション窓口
  • Google Apps Script(GAS): LINEとスプレッドシートを繋ぐ中継プログラム
  • Googleスプレッドシート: 予約データの保存・管理

データフローの詳細

お客様がLINEでメッセージを送信すると、LINE Messaging APIがそのデータをキャッチし、Webhookという仕組みを通じてGASに送信されます。GASは受け取ったメッセージを解析し、予約に必要な情報(日時・メニュー・連絡先など)を抽出してスプレッドシートの適切なセルに自動記録します。この一連の処理は数秒以内に完了するため、店舗側はリアルタイムで予約状況を把握できます。

ステップ1:Googleスプレッドシートの準備

基本シートの作成

まず、予約データを保存するスプレッドシートを作成します:

  1. Googleドライブにアクセス
  2. 「新規」→「Googleスプレッドシート」を選択
  3. シート名を「LINE予約管理」に変更

データ項目の設定

A行目に以下のヘッダーを設定します:

A列B列C列D列E列F列
受信日時LINEユーザーIDお名前希望日時メニュー連絡先

この構成により、予約に必要な基本情報を体系的に管理できます。

ステップ2:LINE公式アカウントの設定

アカウント作成

  1. 「LINE Official Account Manager」にアクセス
  2. LINEアカウントでログイン
  3. 「アカウントを作成」から新規作成
  4. 業種・業態を選択(後から変更可能)

Messaging APIの有効化

  1. LINE Developersコンソール(https://developers.line.biz/)にアクセス
  2. 「プロバイダー」を新規作成
  3. 「チャネルを作成」→「Messaging API」を選択
  4. 先ほど作成した公式アカウントと連携

重要な設定値として、以下2つをメモしておきます:

  • チャネルシークレット
  • チャネルアクセストークン(長期)

ステップ3:Google Apps Scriptの実装

GASプロジェクトの作成

  1. 作成したスプレッドシートを開く
  2. メニューから「拡張機能」→「Apps Script」を選択
  3. プロジェクト名を「LINE予約管理システム」に変更

メインプログラムの実装

以下のコードを貼り付けます:

Copy// 設定値(実際の値に置き換えてください)
const CHANNEL_ACCESS_TOKEN = 'YOUR_CHANNEL_ACCESS_TOKEN';
const SPREADSHEET_ID = 'YOUR_SPREADSHEET_ID';

/**
 * LINEからのWebhookを受信する関数
 */
function doPost(e) {
  try {
    const json = JSON.parse(e.postData.contents);
    const events = json.events;

    events.forEach(event => {
      if (event.type === 'message' && event.message.type === 'text') {
        handleMessage(event);
      }
    });

    return ContentService.createTextOutput('OK');
  } catch (error) {
    console.error('Error in doPost:', error);
    return ContentService.createTextOutput('Error');
  }
}

/**
 * メッセージ処理のメイン関数
 */
function handleMessage(event) {
  const userId = event.source.userId;
  const userMessage = event.message.text;
  const timestamp = new Date(event.timestamp);

  // 予約関連キーワードの判定
  if (userMessage.includes('予約') || userMessage.includes('予約希望')) {
    sendReservationForm(userId);
  } else if (isReservationData(userMessage)) {
    processReservation(userId, userMessage, timestamp);
  } else {
    sendGeneralResponse(userId);
  }
}

/**
 * 予約フォームの送信
 */
function sendReservationForm(userId) {
  const message = `ご予約ありがとうございます!
以下の形式でご入力ください:

【予約フォーム】
お名前:
希望日時:(例:5月20日 14:00)
メニュー:
連絡先:(電話番号またはメール)

上記の形式でメッセージをお送りください。`;

  sendLineMessage(userId, message);
}

/**
 * 予約データの判定
 */
function isReservationData(message) {
  return message.includes('お名前:') && 
         message.includes('希望日時:') && 
         message.includes('メニュー:');
}

/**
 * 予約データの処理
 */
function processReservation(userId, message, timestamp) {
  const reservationData = parseReservationData(message);
  
  if (reservationData.name && reservationData.datetime && reservationData.menu) {
    saveToSpreadsheet(userId, reservationData, timestamp);
    sendConfirmationMessage(userId, reservationData);
  } else {
    sendErrorMessage(userId);
  }
}

/**
 * 予約データの解析
 */
function parseReservationData(message) {
  const lines = message.split('\n');
  let name = '';
  let datetime = '';
  let menu = '';
  let contact = '';

  lines.forEach(line => {
    const trimmedLine = line.trim();
    if (trimmedLine.startsWith('お名前:')) {
      name = trimmedLine.replace('お名前:', '').trim();
    } else if (trimmedLine.startsWith('希望日時:')) {
      datetime = trimmedLine.replace('希望日時:', '').trim();
    } else if (trimmedLine.startsWith('メニュー:')) {
      menu = trimmedLine.replace('メニュー:', '').trim();
    } else if (trimmedLine.startsWith('連絡先:')) {
      contact = trimmedLine.replace('連絡先:', '').trim();
    }
  });

  return { name, datetime, menu, contact };
}

/**
 * スプレッドシートへの保存
 */
function saveToSpreadsheet(userId, data, timestamp) {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  sheet.appendRow([
    timestamp,
    userId,
    data.name,
    data.datetime,
    data.menu,
    data.contact
  ]);
}

/**
 * 予約確認メッセージの送信
 */
function sendConfirmationMessage(userId, data) {
  const message = `予約を承りました!

【予約内容】
お名前:${data.name}
希望日時:${data.datetime}
メニュー:${data.menu}
連絡先:${data.contact}

内容を確認して、改めてご連絡いたします。
ありがとうございました!`;

  sendLineMessage(userId, message);
}

/**
 * LINEメッセージ送信関数
 */
function sendLineMessage(userId, text) {
  const url = 'https://api.line.me/v2/bot/message/push';
  
  const payload = {
    to: userId,
    messages: [{
      type: 'text',
      text: text
    }]
  };

  const options = {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN
    },
    payload: JSON.stringify(payload)
  };

  UrlFetchApp.fetch(url, options);
}

/**
 * 一般的な応答メッセージ
 */
function sendGeneralResponse(userId) {
  const message = `いらっしゃいませ!
ご予約をご希望の場合は「予約」とメッセージをお送りください。`;
  
  sendLineMessage(userId, message);
}

/**
 * エラーメッセージの送信
 */
function sendErrorMessage(userId) {
  const message = `申し訳ございません。
正しい形式でもう一度ご入力ください。

「予約」とメッセージいただければ、
入力フォームをご案内いたします。`;
  
  sendLineMessage(userId, message);
}
Copy

設定値の更新

コード冒頭の以下2つの値を実際の値に置き換えます:

  • CHANNEL_ACCESS_TOKEN: LINE Developersで発行したトークン
  • SPREADSHEET_ID: スプレッドシートのID(URLの/d//editの間の文字列)

ステップ4:Webhookの設定

GASのデプロイ

  1. Apps Script画面で「デプロイ」→「新しいデプロイ」
  2. 種類で「ウェブアプリ」を選択
  3. 実行ユーザー:自分
  4. アクセス権限:全員(匿名ユーザーを含む)
  5. 「デプロイ」をクリック

発行されるWebアプリURLをコピーします。

LINE側のWebhook設定

  1. LINE Developersのコンソールに戻る
  2. 該当チャネルの「Messaging API設定」タブを開く
  3. Webhook URLに先ほどのGAS URLを設定
  4. 「検証」ボタンで接続確認
  5. 「Webhookの利用」をオンに変更

ステップ5:動作テストと運用開始

基本動作の確認

  1. スマートフォンで作成した公式アカウントを友だち追加
  2. 「予約」とメッセージを送信
  3. 案内に従って予約情報を入力
  4. スプレッドシートに正しく記録されることを確認

運用時の注意点

  • 定期的にスプレッドシートのデータをバックアップ
  • 予約件数が増加した場合はGASの実行時間制限に注意
  • お客様への返信は迅速に行い、信頼関係を維持

応用・カスタマイズの可能性

高度な機能追加

基本システムが動作したら、以下のような機能を段階的に追加できます:

  • カレンダー連携: Google Calendarとの同期で空き時間の自動表示
  • 重複防止機能: 同じ時間帯の予約を自動チェック
  • リマインド機能: 予約前日に自動でメッセージ送信
  • キャンセル処理: LINEからの簡単キャンセル・変更受付
  • 顧客管理: 来店履歴や売上データとの連携
  • 担当者指名機能: 担当者を指名して予約

業種別の特化機能

訪問型サービスの場合は、移動時間の計算、スタッフのスケジュール管理、サービス提供エリアの制限など、業種特有の要件に対応したカスタマイズが重要になります。

自作か外注かの判断基準

自作に向いているケース

  • 予約件数が1日10件以下の小規模運営
  • ITに慣れており、トラブル時の対応が可能
  • 時間をかけて段階的に機能追加したい
  • 初期費用を極力抑えたい

プロに依頼すべきケース

  • 予約件数が多く、システム停止が売上に直結
  • 複数スタッフ・複数店舗での運用が必要
  • 顧客管理・売上分析まで一元化したい
  • 本業に集中するため、システム構築・保守を任せたい

特に訪問美容、出張カメラマン、訪問鍼灸、出張ネイルなどの訪問型サービスでは、移動スケジュールの最適化、サービスエリア管理、顧客カルテとの連携など、複雑な業務フローに対応したシステム設計が求められます。

より実用的なシステムをお求めの方へ

本記事では基本的なLINE予約システムの構築方法をご紹介しましたが、実際の業務で使用するには、より高度で安定したシステムが必要な場合も多いでしょう。

私はシステム開発の専門家として、ココナラにて各種業務管理システムのオーダーメイド構築を承っております。これまでに美容サロン向けの複雑な予約フロー管理、訪問型サービス向けの業務ツール、会計事務所向けの進捗管理システムなど、多数の開発実績があります(プラチナ認定出品者)。

対応可能な業種・システム例:

  • 訪問美容・出張ネイル・訪問鍼灸の予約・顧客管理
  • 出張カメラマン・訪問パーソナルトレーナーのスケジュール管理
  • 店舗型サービスの予約・売上・在庫管理
  • 中小企業向けの業務自動化・データ連携

「自社の業務にぴったり合ったシステムが欲しい」「安定稼働する本格的なツールを導入したい」とお考えの方は、ぜひ一度ご相談ください。現在の課題をヒアリングさせていただき、最適なシステム構成をご提案いたします。

予約管理・顧客管理・業務管理システム作ります 困っていること疑問点などお気軽にご相談ください | ココナラ
こんなお悩みありませんか?■ 訪問予約をLINEや電話で受けているが管理が煩雑■ Excelやノートで顧客管理しているが情報が散らばる■ スタッフ間で予約状況や...

お客様の業務効率化と売上向上のお手伝いをさせていただければ幸いです。


まとめ

LINE公式アカウントとGoogleスプレッドシートを活用した予約管理システムは、初期費用を抑えながら業務効率を大幅に向上させる優れたソリューションです。基本的な仕組みから始めて、業務の成長に合わせて段階的に機能を拡張していくことで、長期的に価値のあるシステムを構築できます。

技術的な実装から業務フローの設計まで、お困りの際はお気軽にご相談ください。

コメント

タイトルとURLをコピーしました