非IT企業に勤める中年サラリーマンのIT日記

非IT企業でしかもITとは全く関係ない部署にいる中年エンジニア。唯一の趣味がプログラミングという”自称”プログラマー。

【システム仕様書】GASでカレンダー同期・進捗管理システム

   

飲食チェーン店向けのスケジュール管理システムの案件がネット上で目に留まったので、ちょっとトライしようと思い、まずは勝手ながら仕様書を作成してみました。GAS(Google Apps Script)を使い、エリアマネージャーの予定を店長のGoogleカレンダーへ自動同期、スマホ1タップで完了報告できる仕組みです。Google無償版のみで完結する構成で、1週間納品を想定した設計にまとめてみました。

システム概要

システムの目的

飲食チェーン店のエリアマネージャーが作成したタスクを、店長の個人Googleカレンダーへ自動同期し、スマートフォンから1タップで完了報告できる仕組みを提供します。

主要機能

  1. カレンダー自動同期: スプレッドシートに入力した予定を各店長のGoogleカレンダーへ自動反映
  2. 完了報告機能: 店長がスマホから専用URLをタップして完了報告
  3. 進捗ダッシュボード: エリアマネージャーが担当店舗の進捗を一目で確認

技術構成

  • 基盤: Google Apps Script(GAS)
  • データ管理: Google Sheets
  • カレンダー連携: Google Calendar API
  • UI: HTML/CSS/JavaScript(モバイル最適化)
  • 認証: トークンベース認証

システムの特徴

  • 外部ツール不要(Google Workspace無償版で動作)
  • 1週間で構築可能な軽量設計
  • リアルタイム同期対応(編集時トリガー)
  • モバイルファースト設計

必要なスプレッドシートファイル数

結論: 1ファイルのみ

すべてのデータを1つのスプレッドシートファイル内の複数シートで管理します。


スプレッドシートファイル構成

ファイル名候補

  • タスク管理マスター_カレンダー同期システム
  • 店舗タスク管理_進捗ダッシュボード
  • カレンダー同期_予定管理マスター

内包するシート(タブ)

このファイル内に4つのシートを作成:

No シート名 役割
1 予定マスタ タスクの登録・管理(メインデータ)
2 店舗マスタ 店舗情報・店長メールアドレス一覧
3 進捗ダッシュボード 集計結果の可視化
4 エラーログ システムエラーの記録

GASファイル構成

このスプレッドシートに紐づくGASプロジェクト内に、以下のファイルを作成します。

GASファイル一覧(6ファイル)

No ファイル名 ファイル形式 説明
1 Code.gs Google Apps Script メイン処理・エントリーポイント
2 Calendar.gs Google Apps Script カレンダー操作専用
3 WebApp.gs Google Apps Script 完了報告Web API
4 Utils.gs Google Apps Script 共通ユーティリティ関数
5 Config.gs Google Apps Script 設定値・定数定義
6 ReportPage.html HTML 完了報告画面のUI

各ファイルの関数一覧と役割

1. Code.gs(メイン処理)

関数名 役割・機能
syncCalendars() 【コア機能】カレンダー同期のメイン処理
・予定マスタから未同期行を抽出
・各店長のカレンダーにイベント登録/更新
・エラーハンドリング
・処理結果の返却
※1時間ごとのトリガーで自動実行
syncSingleRow(sheet, row) 単一行の即時同期
・指定された行のみをカレンダー同期
・編集時トリガーで使用
・リアルタイム反映用
onEdit(e) 編集時トリガーのハンドラー
・スプレッドシート編集を検知
・予定マスタシートの編集のみ反応
・編集された行をsyncSingleRow()に渡す
setupTriggers() トリガー初期設定
・既存トリガーの削除
・1時間ごとの定期実行トリガー作成
・編集時トリガー作成
※初回セットアップ時に1回だけ手動実行
setupProperties() Script Properties初期設定
・SECRET_KEY(セキュリティ用)の登録
・ADMIN_EMAIL(通知先)の登録
※初回セットアップ時に1回だけ手動実行

2. Calendar.gs(カレンダー操作)

関数名 役割・機能
createCalendarEvent(calendar, taskData) カレンダーイベント新規作成
・タスクデータからイベント情報を構築
・開始/終了時刻の設定
・完了報告URLを説明欄に埋め込み
・タイトルに未着手表示を付加
・作成したイベントIDを返却
updateCalendarEvent(calendar, eventId, taskData) 既存イベントの更新
・イベントIDから対象イベントを取得
・タイトル・日時・説明の更新
・ステータスに応じた表示変更(未着手/完了)
deleteCalendarEvent(calendar, eventId) イベント削除
・指定されたイベントIDのイベントを削除
・予定マスタから行削除時に使用
※拡張機能(オプション)
getCalendarByEmail(email) メールアドレスからカレンダー取得
・CalendarApp.getCalendarById()のラッパー
・エラーハンドリング付き
・取得失敗時はnullを返却

3. WebApp.gs(Web API)

関数名 役割・機能
doGet(e) GET リクエストハンドラー(完了報告画面表示)
・URLパラメータからタスクID/トークン取得
・トークン検証
・タスク情報の取得
・HTMLテンプレートにデータ埋め込み
・完了報告画面を返却
doPost(e) POST リクエストハンドラー(完了報告受付)
・タスクIDとトークンを検証
completeTask()を呼び出し
・JSON形式で処理結果を返却
completeTask(taskId) タスク完了処理の実行
・予定マスタからタスクIDを検索
・ステータスを「完了」に更新
・完了日時を記録
・カレンダーイベントのタイトル更新(完了表示)
・処理結果をJSON形式で返却

4. Utils.gs(ユーティリティ)

関数名 役割・機能
generateReportUrl(taskId) 完了報告URL生成
・WebアプリのURLを取得
・タスクIDとトークンをクエリパラメータに付与
・完成したURLを返却
generateToken(taskId) セキュリティトークン生成
・タスクID + SECRET_KEYをSHA-256でハッシュ化
・16文字に短縮して返却
・不正アクセス防止用
verifyToken(taskId, token) トークン検証
・受信したトークンと生成トークンを比較
・一致すればtrue、不一致ならfalse
・完了報告の正当性確認
getTaskData(taskId) タスクデータ取得
・予定マスタからタスクIDで検索
・店舗マスタと結合して店舗名取得
・タスク情報をオブジェクトで返却
・見つからない場合はnull
logError(taskId, email, errorMessage) エラーログ記録
・エラーログシートに新規行追加
・発生日時、エラー種別、詳細を記録
・トラブルシューティング用
notifyError(successCount, errorCount) エラー通知メール送信
・管理者メールアドレスに送信
・成功件数/失敗件数を通知
・エラーログ確認を促す
generateTaskId() タスクID自動生成
・フォーマット: TSK_YYYYMMDD_NNN
・日付 + 連番でユニークID作成
・予定入力時に自動付与
protectSheet() シート保護設定
・システム管理列(タスクID、イベントID等)を保護
・誤編集防止
※初回セットアップ時に1回実行
backupSpreadsheet() スプレッドシートバックアップ
・現在のファイルをコピー
・指定フォルダに日付付きで保存
※週次/月次で手動実行推奨

5. Config.gs(設定値)

定数名 役割・機能
CONFIG システム全体の設定オブジェクト
・シート名一覧(SHEET_NAMES)
・列番号定義(COLUMNS)
・バッチサイズ(BATCH_SIZE = 50)
・待機時間(SLEEP_MS = 2000)
・タイムアウト時間(TIMEOUT_MS = 330000)
START_TIME 処理開始時刻
syncCalendars()実行時に記録
・タイムアウト判定に使用

※このファイルには関数はなく、定数のみ定義


6. ReportPage.html(完了報告UI)

要素 役割・機能
HTMLテンプレート 完了報告画面のレイアウト
・タスク情報表示エリア
・完了ボタン(大きめ、タップしやすい)
・キャンセルボタン
・ローディング画面
・完了後メッセージ
CSSスタイル モバイル最適化デザイン
・レスポンシブ対応
・タップ領域60px以上
・視認性の高い配色
JavaScriptコード 完了報告送信処理
submitReport()関数
・POSTリクエスト送信
・ローディング表示制御
・完了画面への遷移

※GASのdoGet()で呼び出され、データが埋め込まれる


関数の呼び出し関係図

【定期実行(1時間ごと)】
トリガー
  └─→ syncCalendars() ─┬─→ getCalendarByEmail()
                       ├─→ createCalendarEvent()
                       │     └─→ generateReportUrl()
                       │           └─→ generateToken()
                       ├─→ updateCalendarEvent()
                       └─→ logError()
                             └─→ notifyError()

【編集時】
編集イベント
  └─→ onEdit() ───→ syncSingleRow() ─→(上記と同じ)

【完了報告】
店長がURLタップ
  └─→ doGet() ─┬─→ verifyToken()
               ├─→ getTaskData()
               └─→ ReportPage.html表示

店長が送信ボタンタップ
  └─→ doPost() ─┬─→ verifyToken()
                └─→ completeTask() ─→ updateCalendarEvent()

【初回セットアップ(手動実行)】
管理者
  ├─→ setupProperties()
  ├─→ setupTriggers()
  └─→ protectSheet()

 


まとめ

ファイル構成

  • スプレッドシート: 1ファイル(4シート構成)
  • GASファイル: 6ファイル(.gs × 5 + .html × 1)

関数総数

  • Code.gs: 5関数
  • Calendar.gs: 4関数
  • WebApp.gs: 3関数
  • Utils.gs: 9関数
  • Config.gs: 定数のみ
  • ReportPage.html: JavaScript関数1つ

合計: 22関数 + 1HTML

実行タイミング

  1. 自動実行: syncCalendars()(1時間ごと)
  2. リアルタイム: onEdit()(編集時)
  3. 外部トリガー: doGet()/doPost()(店長アクセス時)
  4. 手動実行: セットアップ系関数(初回のみ)

この構成で、1つのスプレッドシートファイルに全機能が集約され、管理が容易になります。


補足: ファイルの作成手順

スプレッドシート作成

  1. Google Driveで新規スプレッドシート作成
  2. ファイル名を変更(例: タスク管理マスター_カレンダー同期システム
  3. 4つのシートを作成・リネーム
    • 予定マスタ
    • 店舗マスタ
    • 進捗ダッシュボード
    • エラーログ

GASファイル作成

  1. スプレッドシートで「拡張機能」→「Apps Script」を開く
  2. デフォルトのCode.gsをそのまま使用
  3. 左側メニュー「+」ボタンから追加ファイルを作成
    • 「スクリプト」で.gsファイル追加(4ファイル)
    • 「HTML」でHTMLファイル追加(1ファイル)
  4. 各ファイルにコードを記述

初回セットアップ実行順序

  1. setupProperties()を実行(SECRET_KEY、ADMIN_EMAILを設定)
  2. protectSheet()を実行(シート保護)
  3. setupTriggers()を実行(トリガー登録)
  4. Webアプリをデプロイ(完了報告機能用)

 

せっかく仕様書を作ったので、コーディングまでやってみようと思います。出来たらまた紹介します。

スポンサーリンク

 - Google Apps Script, システム仕様書