🚗

【個人開発】家族で使える車予約LINE Botを作った話

に公開

はじめに

こんにちは!今回は、家族や友人と車をシェアする際の予約管理を簡単にするLINE Botを
この待ちに待った連休で作成しました。

🚗 完成したBotはこちら:
https://line.me/R/ti/p/@159irqkm
⚠今は閉鎖しています。

作った背景

実は私の周りには、1台の車を家族でシェアしている友人が何人もいました。話を聞くと、みんな同じような悩みを抱えていたんです。

🤔 既存の方法の問題点

1.LINEグループで都度確認

  • 過去のメッセージに埋もれる
  • 「結局いつ使うんだっけ?」状態に

2.共有カレンダー

  • 家族全員が使いこなせない
  • アプリの切り替えが面倒
  • 更新を忘れがち

3.紙のカレンダー

  • 外出先から確認できない
  • 書き間違いや見間違い

💡 理想の解決策
そこで考えたのが「普段使っているLINEで全部できたら最高じゃない?」ということ。

  • アプリの追加インストール不要
  • 外出先からもサッと確認
  • 予約の重複を自動でチェック

こうして、家族みんなが使えるシンプルな車予約Botの開発がスタートしました。

完成したシステムの特徴

🎯 主な機能

  1. グループ管理機能

    • 家族や友人とグループを作成
    • 招待コードでメンバーを追加
    • グループ単位で車を管理
  2. 予約機能

    • 日時と用途を指定して予約
    • 重複チェック機能(1台しかないので重要!)
    • 予約の確認・キャンセル
  3. 今日の予約表示

    • 現在の使用状況をリアルタイム表示
    • 今日の空き時間が一目で分かる
  4. リッチメニュー対応

    • ボタンタップで簡単操作

📱 実際の画面

グループの設定は招待コード(ランダム生成)で実現しました。

技術スタック

  • LINE Messaging API: ユーザーインターフェース
  • Google Apps Script (GAS): バックエンド処理
  • Google Sheets: データベース
  • LINE Official Account Manager: リッチメニュー設定

実装のポイント

1. データ構造の設計

Google Sheetsを3つのシートで構成:

const CONFIG = {
  SHEETS: {
    RESERVATIONS: '予約データ',  // 予約情報
    GROUPS: 'グループ',          // グループ情報
    USERS: 'ユーザー'           // ユーザー情報
  }
};

2. 重複チェックの実装

車は1台しかないので、時間の重複チェックは必須でした:

function checkReservationConflict(groupId, date, startTime, endTime) {
  const existingReservations = getGroupReservations(groupId);
  const sameDateReservations = existingReservations.filter(r => r.date === date);
  
  const newStartMinutes = timeToMinutes(startTime);
  const newEndMinutes = timeToMinutes(endTime);
  
  const conflicts = [];
  
  for (const existing of sameDateReservations) {
    const existingStartMinutes = timeToMinutes(existing.startTime);
    const existingEndMinutes = timeToMinutes(existing.endTime);
    
    // 重複判定
    const isOverlapping = (newStartMinutes < existingEndMinutes) && 
                         (newEndMinutes > existingStartMinutes);
    
    if (isOverlapping) {
      conflicts.push(existing);
    }
  }
  
  return { hasConflict: conflicts.length > 0, conflicts };
}

3. パフォーマンス最適化

GASは実行時間に制限があるため、以下の工夫をしました:

キャッシュシステムの実装

// グローバルキャッシュ
let spreadsheetCache = null;
let sheetCache = {};
let userCache = {};
let groupCache = {};

function getSheet(sheetName) {
  if (!sheetCache[sheetName]) {
    sheetCache[sheetName] = getSpreadsheet().getSheetByName(sheetName);
  }
  return sheetCache[sheetName];
}

バッチ処理による高速化

// 期限切れ予約の一括更新
function cleanupExpiredReservations() {
  const rowsToUpdate = [];
  // ... 期限切れ予約を収集
  
  if (rowsToUpdate.length > 0) {
    const rangeList = sheet.getRangeList(rowsToUpdate.map(row => `J${row}`));
    rangeList.setValue('期限切れ');  // 一括更新
  }
}

4. ユーザビリティの工夫

日付の見やすい表示

function formatDateForDisplay(dateString) {
  const date = new Date(dateString);
  const today = new Date();
  const tomorrow = new Date(today);
  tomorrow.setDate(today.getDate() + 1);
  
  if (isSameDate(date, today)) {
    return `今日 ${month}/${day}(${weekday})`;
  } else if (isSameDate(date, tomorrow)) {
    return `明日 ${month}/${day}(${weekday})`;
  } else {
    return `${month}/${day}(${weekday})`;
  }
}

予約IDを隠してユーザーフレンドリーに

// 内部では予約IDで管理するが、ユーザーには番号で表示
displayReservations.forEach((reservation, index) => {
  actions.push({
    type: 'message',
    label: `${index + 1}. ${shortDate} ${reservation.startTime}`,
    text: `予約番号${index + 1}をキャンセル`
  });
});

5. セキュリティとデータ整合性

  • グループ単位での管理: 他のグループの予約は見えない
  • 本人確認: 自分の予約のみキャンセル可能
  • データ正規化: 日付と時間を統一フォーマットで保存
// 日付を必ず YYYY-MM-DD 形式に変換
function normalizeDate(dateValue) {
  // ... 変換処理
  return `${year}-${month}-${day}`;
}

// 時間を必ず HH:MM 形式に変換
function normalizeTime(timeValue) {
  // ... 変換処理
  return `${hours}:${minutes}`;
}

苦労した点と解決策

1. 日付・時間形式の不一致問題

問題: GooglesheetsとJavaScriptで日付形式が異なり、重複チェックが機能しない

解決: すべての日付・時間を正規化する関数を作成し、保存・比較時に必ず通すように

2. レスポンス速度の改善

問題: スプレッドシートへのアクセスが多いと遅い

解決:

  • メモリキャッシュの実装
  • getRangeListを使用したバッチ処理
  • 不要なAPI呼び出しの削減

3. LINE Messaging APIの制限

問題: ボタンは最大4つまで、文字数制限あり

解決:

  • 機能を絞って最重要なものだけボタン化
  • テキストコマンドも併用
  • 文字数制限を考慮した表示調整

今後の展望

  • 通知機能: 予約開始1時間前にリマインド
  • 統計機能: 月間の利用状況レポート
  • 複数車両対応: 車が増えた場合の対応
  • Google Calendar連携: カレンダーへの自動登録

まとめ

Google Apps ScriptとLINE Messaging APIを組み合わせることで、実用的な予約システムを無料で構築できました。特に:

  • LINEだけで完結: アプリのインストール不要
  • グループ機能: 家族や友人と簡単に共有
  • リアルタイム性: 今の状況がすぐ分かる

という点で、日常的に使いやすいシステムになったと思います。

ソースコード

完全なソースコードは長いので、主要な部分を抜粋して紹介しました。
もし興味がある方は、コメントいただければ詳細な実装についてもお答えします!

試してみたい方へ

🚗 LINE Bot: https://line.me/R/ti/p/@159irqkm

友だち追加後、以下の手順でお試しください:

  1. 「グループ作成」でグループを作成
  2. 「車を予約」で予約を作成
  3. 「今日の予約」で確認

ぜひ使ってみてフィードバックをいただけると嬉しいです!


参考記事

タグ

#LINE #Bot #GoogleAppsScript #個人開発 #予約システム

Discussion