🗓️ Googleカレンダーの予定をDiscordに自動通知するBotをUbuntuサーバーで構築する手順(cron運用まで完全解説)

🎯 目的

Googleカレンダーから**「今日の予定」**を取得し、
予定が1件以上ある場合にだけ Discordチャンネルへ自動通知するBotを構築します。
通知は毎朝9時に自動で実行(cron)されます。


🧩 全体の構成

/discord-bot/gcal2discord/
├── .env                    # 設定ファイル(Botトークン、カレンダーIDなど)
├── credentials.json        # Google Cloud Consoleで取得する認証情報
├── token.json              # Google認可後に自動生成されるトークン
├── gcal_to_discord.py      # メインスクリプト
├── diag_list.py            # カレンダー診断スクリプト(デバッグ用)
└── .venv/                  # Python仮想環境

🪄 手順

1. Google Cloud ConsoleでAPI設定

  1. https://console.cloud.google.com/ にアクセスし、新しいプロジェクトを作成。
  2. 「APIとサービス」→「有効なAPIとサービス」→「+ 有効にする」。
    • Google Calendar API を検索して有効化。
  3. 「認証情報」→「認証情報を作成」→「OAuthクライアントID」。
    • アプリの種類:デスクトップアプリ
    • 作成後、credentials.json をダウンロード。

2. OAuth同意画面設定

  1. 「OAuth同意画面」を開く。
  2. ユーザータイプ:外部
  3. テストユーザーに自分のGoogleアカウントを追加。 これを忘れると「このアプリは現在テスト中」エラーが出ます。

3. サーバー環境を準備

sudo mkdir -p /discord-bot/gcal2discord
sudo chown $USER:$USER /discord-bot/gcal2discord
cd /discord-bot/gcal2discord

Python仮想環境を作成

python3 -m venv .venv
. .venv/bin/activate
pip install --upgrade pip
pip install google-api-python-client google-auth google-auth-oauthlib python-dateutil pytz requests python-dotenv

4. 設定ファイルを作成

.env

nano /discord-bot/gcal2discord/.env

内容:

DISCORD_BOT_TOKEN=あなたのDiscordBotトークン
DISCORD_CHANNEL_ID=投稿先チャンネルの数値ID
GOOGLE_CALENDAR_ID='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx@group.calendar.google.com'
TIMEZONE=Asia/Tokyo
GOOGLE_CREDENTIALS_JSON=/discord-bot/gcal2discord/credentials.json
GOOGLE_TOKEN_JSON=/discord-bot/gcal2discord/token.json

GOOGLE_CALENDAR_ID は後で診断スクリプトで確認します。
# を含む場合(例:祝日カレンダー)は必ず ' ' で囲んでください。


5. メインスクリプトを配置

ファイル名:/discord-bot/gcal2discord/gcal_to_discord.py

このスクリプトが、当日の予定を取得してDiscordに送信します。
実装内容(抜粋要約):

  • GoogleカレンダーAPIで当日のイベントを取得
  • 予定が1件以上あればDiscord Bot APIで投稿
  • 予定が0件なら何もしない(正常終了)
  • タイムゾーンは .envTIMEZONE に従う
  • ログを標準出力に出すのでcronからも追える

6. ローカルで token.json を発行

GUIのブラウザが使えないサーバーでは、ローカルPCで認可を行うのが簡単です。

  1. ローカルでPython環境を作り、同じ credentials.json を置く。
  2. コマンド実行: python gcal_to_discord.py
  3. ブラウザが開くので、Googleでログイン→「許可」。
  4. token.json が生成される。
  5. それをサーバーへコピー: scp token.json user@server:/discord-bot/gcal2discord/token.json chmod 600 /discord-bot/gcal2discord/token.json

7. カレンダーIDを確認する(診断スクリプト)

ファイル:/discord-bot/gcal2discord/diag_list.py
このスクリプトを実行して、どのカレンダーを使うか確認します。

/discord-bot/gcal2discord/.venv/bin/python /discord-bot/gcal2discord/diag_list.py

出力例:

[見えるカレンダー一覧]
- summary=日本の祝日  id=ja.japanese#holiday@group.v.calendar.google.com
- summary=エコランプロジェクト  id=400802251bca...@group.calendar.google.com
- summary=アーカイブ  id=example@gmail.com  primary=True

[今日] ...
■ エコランプロジェクト (...) : 2件
   - 2025-11-04 臨時活動日
   - 2025-11-04T16:30:00+09:00 M109作業日

このとき表示された「予定があるカレンダーのid」を .envGOOGLE_CALENDAR_ID に設定してください。
(例)

GOOGLE_CALENDAR_ID='400802251bca...@group.calendar.google.com'

8. 動作確認(手動実行)

set -a && source /discord-bot/gcal2discord/.env && set +a
/discord-bot/gcal2discord/.venv/bin/python /discord-bot/gcal2discord/gcal_to_discord.py

出力例:

2025-11-04 18:43:45,584 [INFO] Google Calendar 取得: 2025-11-04T00:00:00+09:00 ~ 2025-11-05T00:00:00+09:00
2025-11-04 18:43:46,021 [INFO] Discord送信完了:2件

→ Discordに「📅 本日の予定」が投稿されればOK。


9. 自動実行設定(cron)

crontab -e

内容:

SHELL=/bin/bash
TZ=Asia/Tokyo
0 9 * * * set -a && source /discord-bot/gcal2discord/.env && set +a && /discord-bot/gcal2discord/.venv/bin/python /discord-bot/gcal2discord/gcal_to_discord.py >> /discord-bot/gcal2discord/gcal2discord.log 2>&1
  • JST 9:00 に自動実行
  • 出力ログは /discord-bot/gcal2discord/gcal2discord.log に蓄積
  • サーバーがUTCでも TZ=Asia/Tokyo で日本時間動作

確認:

tail -f /discord-bot/gcal2discord/gcal2discord.log

✅ よくあるトラブルと対処

症状原因対処
credentials.json が見つからないパスが間違い.envGOOGLE_CREDENTIALS_JSON を修正
「このアプリはテスト中」エラーテストユーザー未登録Google Cloud ConsoleのOAuth同意画面で自分をテスターに追加
Unicode escape エラーWindowsのパスに \Uスラッシュ / か raw文字列 r"..." に修正
Discordに投稿されない当日予定が0件正常。診断スクリプトで件数確認
HttpError 404 Not FoundカレンダーIDが途中で切れている.env の ID を ' ' で囲む
401 Missing credentialstoken.jsonが別アカウントで作成正しいアカウントで再認可

🚀 これでできること

  • サーバーが自動で Google カレンダーから当日予定を取得
  • 予定がある日だけ Discord に投稿
  • cron で毎朝9:00に自動送信
  • 完全ローカル運用(外部APIキー・Webhook以外不要)

🔧 応用アイデア

  • 予定タイトルに「会議」「活動日」などのキーワードで色分け
  • 翌日の予定も合わせて送信
  • 予定内容(説明・場所)を埋め込み形式でDiscord Embedに整形
  • GAS連携やn8nで週報まとめを自動化

🎉 まとめ

この手順で、

  • Google Calendar API × Discord Bot API × cron
    という構成の、安定した自動通知Botを構築できました。

ポイントは以下の3点です:

  1. Google OAuth認可はローカルで済ませる(token.json をサーバーへコピー)
  2. カレンダーIDは正確に記入(特に @group.calendar.google.com まで)
  3. cronでは仮想環境Pythonをフルパス指定する

📦 ディレクトリ構造やコード全体をGit管理しておくと、サーバー再構築時の再現が容易です。
今後はこのBotを拡張して「週次サマリー」や「今日の活動班別通知」なども自動化できます。

コメント

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