• #gogcli
  • #Google Chat
  • #Google Sheets
  • #Google Calendar
  • #自動化
  • #Google Meet
開発personalメモ

gogcliでGoogle Chat・Sheets・Calendarを操作:面談自動化フローまで一気に構築

この記事の位置づけ

gogcli(Google Workspace CLIツール)でChat・Sheets・Calendarの3つのAPIを一気に触り、最終的に「freebusy確認 → Meet付き予定作成 → Chat通知」の面談自動化フローまで組み上げた。1日でやった内容が多いので、個別の詳細記事と合わせて読んでほしい。

個別記事:

この記事では全体の流れを時系列で追い、各APIの連携ポイントを整理する。


1. Google Chat API設定:Cloud Consoleの「構成」が盲点

やったこと

Chat APIを有効化済みなのに Google Chat app not found エラーが出た。原因は Chat appの「構成」タブを保存していなかったこと。

設定手順の要点

Google Cloud Console → Chat API → 構成タブを開き、以下を埋めて保存する。

フィールド設定値
アプリ名gogcli(任意の名前)
アバターのURL任意のHTTPS PNG画像URL
説明CLI tool など

インタラクティブ機能をオンにすると、メッセージ送信や受信が可能になる。CLIからの利用なら、HTTPエンドポイントURLは https://example.com で埋めればよい。

メッセージ送信テスト

gog chat messages send spaces/XXXXXXXX --text "テスト送信です"

フラグは --body ではなく --text。送信者はユーザー名ではなくChat app名(この場合「gogcli」)で表示される。つまりCLIから送ったメッセージは「ボットが投稿した」扱いになる。

詳細: gogcliでGoogle Chatのメッセージを送受信する設定手順


2. Google Sheets操作:作成から数式読み取りまで

スプレッドシートの新規作成

gog sheets create "gogcli テスト" --sheets "データ,サマリー"

タイトルとシート名を指定するだけ。--json をつけるとスプレッドシートIDやURLがJSON形式で返ってくる。

データ書き込み

gog sheets update "<spreadsheetId>" "データ!A1:D5" \
  --values-json '[["月","売上","経費","利益"],["1月","1000000","600000","400000"],["2月","1200000","650000","550000"],["3月","1100000","620000","480000"],["4月","1300000","700000","600000"]]'

値の渡し方は3種類ある。

方式用途
--values-json2次元JSON配列確実。プログラムから使うならこれ
パイプ区切り月|売上|経費セル区切り
カンマ区切り月,売上,経費行区切り(appendの場合)

パイプ区切りとカンマ区切りは動作がコマンドによって異なるので、--values-json が間違いにくい。

数式の書き込みと読み取り

数式を書き込むには --input USER_ENTERED を指定する。

gog sheets update "<spreadsheetId>" "データ!E1:E5" \
  --values-json '[["合計"],["=B2+C2"],["=B3+C3"],["=B4+C4"],["=B5+C5"]]' \
  --input USER_ENTERED

読み取りには3つのレンダリングモードがある。

# 表示値(デフォルト)-- セルに表示されている値
gog sheets get "<spreadsheetId>" "データ!A1:E5"

# 数式として取得 -- セルの数式そのもの
gog sheets get "<spreadsheetId>" "データ!A1:E5" --render FORMULA

# 書式なしの生データ -- 数値の場合は書式を除去した値
gog sheets get "<spreadsheetId>" "データ!A1:E5" --render UNFORMATTED_VALUE
モード--renderE2セルの出力例使いどころ
表示値FORMATTED_VALUE1,600,000人間が読む用
数式FORMULA=B2+C2数式の構造を把握したいとき
生データUNFORMATTED_VALUE1600000プログラムで計算に使うとき

--render FORMULA は、既存スプレッドシートの数式構造をCLIから確認できるので、スプレッドシートからWebアプリへの移行作業で使える。

詳細: gogcliでGoogle Sheetsを操作する


3. Google Calendar操作:予定作成とMeet自動生成

予定の作成

gog calendar create primary \
  --summary "gogcliテスト予定" \
  --from "2026-01-30T10:30:00+09:00" \
  --to "2026-01-30T11:00:00+09:00" \
  --description "gogcliからのテスト登録"

日時はRFC3339形式で指定する。primary はデフォルトカレンダー。

Google Meet付き予定

gog calendar create primary \
  --summary "オンライン打ち合わせ" \
  --from "2026-01-30T10:30:00+09:00" \
  --to "2026-01-30T11:00:00+09:00" \
  --with-meet

--with-meet を付けるだけでMeetリンクが自動生成される。出力にMeet URLと電話参加番号が含まれる。

meet    https://meet.google.com/xxx-xxxx-xxx

注意: --with-meetcreate のみ対応。update では使えない。既存の予定にMeetを後から追加するなら、削除してMeet付きで再作成する。

税務カレンダー自動生成のアイデア

税理士事務所では顧問先ごとに決算月が異なるため、申告期限の管理が手間になる。gogcliなら以下の流れで自動化できる。

1. Sheetsから顧問先リスト(社名・決算月)を取得
   gog sheets get "<spreadsheetId>" "顧問先!A2:C50"

2. 決算月から各申告期限を計算
   - 法人税: 決算日の2ヶ月後
   - 消費税: 決算日の2ヶ月後
   - 源泉所得税: 毎月10日(納期の特例なら7月・1月)

3. 全顧問先分のカレンダー予定を一括登録
4. 間違えたらバッチ指定で一括削除

ここで重要になるのが --private-prop による識別子の仕組み。


4. private-propによる識別子付与と一括管理

識別子の付け方

--private-prop でカレンダーUIには表示されないメタデータを付与できる。

gog calendar create primary \
  --summary "○○社 法人税申告期限" \
  --from "2026-05-31T00:00:00+09:00" \
  --to "2026-05-31T23:59:00+09:00" \
  --all-day \
  --reminder "popup:7d" --reminder "email:3d" \
  --private-prop "source=gogcli" \
  --private-prop "batch=tax-deadline-2026"
プロパティ用途
source=gogcligogcliで作った予定であることを識別
batch=tax-deadline-2026どのバッチで作ったかを識別

フィルタリングと一括削除

# このバッチで作った予定だけ取得
gog --json calendar events primary \
  --private-prop-filter "batch=tax-deadline-2026"

手動で作った予定には batch プロパティがないので、フィルタに引っかからない。間違えたバッチだけを安全に一括削除できる。

ポイント内容
private-propカレンダーUI上には表示されない裏のメタデータ
private-prop-filterそのメタデータで予定をフィルタリングできる
手動予定との分離プロパティがない予定はフィルタに引っかからない
バッチ単位の管理batch=xxx の値を変えれば世代管理もできる
誤削除の防止手動で作った予定は巻き込まれない

この仕組みがあるから、CLIで大量の予定を登録しても安心して運用できる。

詳細: gogcliでGoogle Calendar操作


5. 面談スケジュール自動化フロー

今日のハイライト。Chat・Calendar・Meetを連携して、面談スケジューリングを自動化するフローを実際にテストした。

全体の流れ

freebusy(空き確認)
  ↓
Meet付き予定作成(参加者招待)
  ↓
ChatスペースにMeet URL投稿

Claude Codeに「来週Aさんと面談入れて」と言うだけで、この3ステップが自動で走る。

Step 1: freebusyで空き時間を確認

gog --json calendar freebusy \
  "[email protected],[email protected]" \
  --from "2026-01-30T11:00:00+09:00" \
  --to "2026-01-30T18:00:00+09:00"

複数のカレンダーIDをカンマ区切りで渡すと、各メンバーのbusy時間帯がJSON形式で返ってくる。busyでない時間帯が空き時間。

Step 2: Meet付き予定を作成(参加者招待あり)

gog --json calendar create primary \
  --summary "面談:小松啓 × number55(テスト)" \
  --from "2026-01-30T13:00:00+09:00" \
  --to "2026-01-30T13:30:00+09:00" \
  --description "gogcliによる自動スケジュール登録テスト。freebusyで空き確認済み。" \
  --attendees "[email protected]" \
  --with-meet \
  --private-prop "source=gogcli" \
  --private-prop "batch=meeting-test-001"
  • --attendees で参加者を指定すると招待メールが送られる
  • --with-meet でMeet URLが自動生成される
  • --private-prop で後からバッチ管理できるようにしておく
  • JSON出力からMeetリンクを取得して次のステップに渡す

Step 3: ChatスペースにMeet URLを投稿

gog chat messages send spaces/AAAA9qhlGLw \
  --text "【面談スケジュール自動登録】

日時: 2026年1月30日(金)13:00〜13:30
件名: 面談:小松啓 × number55(テスト)
Google Meet: https://meet.google.com/xxx-xxxx-xxx
電話参加: +81 3-XXXX-XXXX(PIN: XXXXXXXXXXXXX)

※ gogcli + Claude Code による自動登録テストです。"

MeetのURLを含むメッセージを投稿すると、Google Chatが自動でビデオ会議のプレビューカードを生成してくれる。参加者はURLクリックですぐ会議に入れる。

フローの各ステップまとめ

ステップコマンド何をしているか
空き確認freebusy複数メンバーのbusy/freeを取得
予定作成create --with-meet --attendeesMeet生成 + 参加者招待を1コマンドで
Chat通知messages sendMeetリンクをChatスペースに投稿
識別子--private-prop後からバッチ単位で管理・削除可能

発展形

このフローをスクリプト化すれば、以下も可能になる。

  1. 日次スケジュール通知: 朝一で今日の予定を取得 → Chatに投稿
  2. 顧問先との定期面談: Sheetsの顧問先リストからバッチで面談予定を一括登録
  3. 繁忙期の集中時間確保: 確定申告期に focus-time で作業ブロックを自動設定
  4. 月次タスクの繰り返し登録: --rrule "RRULE:FREQ=MONTHLY;BYMONTHDAY=10" で毎月の源泉所得税納付日を登録

6. Chat APIのdelete: 本家未実装だったので自分で書いた

テスト中に大量のメッセージが溜まったので削除したかったが、gogcli v0.9.0には chat messages delete コマンドがなかった。Google Chat APIにはdeleteメソッドが存在するので、Goで実装した。

type ChatMessagesDeleteCmd struct {
    Name    string `arg:"" help:"Message resource name (spaces/*/messages/*)"`
    Force   bool   `help:"Skip confirmation" default:"false"`
    Account string `help:"Google account to use"`
}

func (cmd *ChatMessagesDeleteCmd) Run(ctx *context.Context) error {
    name := normalizeMessage(cmd.Name)
    if !cmd.Force {
        fmt.Printf("Delete message %s? [y/N] ", name)
        var answer string
        fmt.Scanln(&answer)
        if answer != "y" && answer != "Y" {
            fmt.Println("Cancelled.")
            return nil
        }
    }
    srv, err := ctx.ChatService(cmd.Account)
    if err != nil {
        return err
    }
    err = srv.Spaces.Messages.Delete(name).Do()
    if err != nil {
        return fmt.Errorf("delete message: %w", err)
    }
    fmt.Printf("Deleted: %s\n", name)
    return nil
}

既存のListやSendコマンドと同じパターンで書けるので、実装自体は30分程度で終わった。

# メッセージ一覧を取得して
gog chat messages list spaces/AAAA9qhlGLw --max 10 --order "createTime desc"

# 削除する
gog chat messages delete spaces/AAAA9qhlGLw/messages/<messageId> --force

Google Chat上では「メッセージは投稿者によって削除されました(アプリ経由)」と表示される。

詳細: gogcli Chat Delete機能の実装


今日やったことの全体像

領域作業内容使ったコマンド
Chat設定Cloud ConsoleでChat appの構成を保存--
Chat送信テストメッセージ送信、送信者がapp名になる仕様を確認chat messages send --text
Sheets作成新規スプレッドシート作成、テストデータ入力sheets create, sheets update
Sheets読み取り3つのレンダリングモードで値・数式・生データを取得sheets get --render
Calendar作成予定作成、Meet自動生成calendar create --with-meet
Calendar管理private-propで識別子付与、フィルタリング、一括削除--private-prop, --private-prop-filter
面談自動化freebusy → Meet付き予定 → Chat通知のフロー構築freebusy, create, messages send
Chat Delete本家未実装のdeleteコマンドをGoで実装chat messages delete --force

gogcliの3つのAPI(Chat・Sheets・Calendar)をCLIから操作できるようになったことで、Claude Codeとの連携で「自然言語で指示 → Google Workspaceが動く」というワークフローが現実的になった。特に面談自動化フローは、税理士事務所の日常業務で使える手応えがある。