Googleカレンダー予定をGoogle Chatに通知する方法|Apps Script実装レシピ

Googleカレンダーの予定をGoogle Chatへ通知する方法を、Apps Scriptのコード、通知方式の比較、重複防止、非公開予定、変更検知、湯田Q&Aで解説します。

著者: SakuraAI 編集部監修: 湯田英也公開: 最終更新: 10
目次
30秒でわかる結論

Googleカレンダーの予定は、Apps Scriptで対象期間を検索し、Google Chatの受信Webhookへ送信できます。最初に作るなら、チーム用カレンダーの当日予定を1日1回まとめて通知する構成が適しています。個人カレンダーのタイトルをそのまま流さず、日次一覧、会議前リマインド、予定変更通知を別の仕組みとして設計してください。

本記事は2026年6月29日時点のGoogle公式情報をもとにしています。Calendar、Apps Script、Google Chatの仕様、割り当て、管理者設定は変更される可能性があります。実装前に公式ドキュメントと自社環境を確認してください。

Expert Q&A

カレンダー通知を作る前に確認すること

湯田英也SakuraAI株式会社 代表 / ソフトウェアエンジニア

Q. 最初に作るなら日次一覧と会議前通知のどちらですか?

A. 日次一覧です。1日1回なら通知量と重複を管理しやすく、チーム用カレンダーで効果を確認できます。会議前通知は、誰に何分前に知らせるかを決めてから追加します。

Q. 個人の予定タイトルをチームChatへ流してよいですか?

A. 原則として流しません。個人カレンダーには面談、通院、顧客名などが入ります。共有目的なら専用のチームカレンダーを作るか、タイトルを予定ありへ置き換えます。

Q. 更新トリガーで変更された予定をすぐ取れますか?

A. トリガーから分かるのは、対象カレンダーで更新が起きたことまでです。どの予定がどう変わったかはCalendar APIの増分同期で取得します。

Googleカレンダーの通知は、予定を取得してChatへ投稿するだけなら短いコードで作れます。難しいのは、通知する範囲です。個人予定のタイトルをどこまで見せるか、変更や削除をどう扱うか、同じ予定を何度も通知しないかを決める必要があります。

この記事では、当日予定の一覧を基本形にして、開始前リマインドと変更通知の違いまで整理します。Webhookの準備はWebhookの使い方、Apps Scriptの基礎はApps Scriptで通知する方法も参照してください。

一つ立場をはっきりさせておくと、予定をたくさん通知するのが良い通知ではありません。チーム用カレンダーから必要な情報だけをまとめて送る——ここを外すと、個人の予定タイトルが漏れたり、通知が増えて誰も見なくなったりします。

3つの通知方式を分ける

通知方式実行方法向く用途状態管理主な注意点
日次・翌日一覧時間主導トリガー朝会、当番、チーム予定共有同じ日に1回送ったか指定時刻からずれることがある
開始前リマインド短い間隔の定期検索会議準備、締切前通知予定IDと開始時刻重複防止と変更後の再通知が必要
作成・変更・削除通知更新トリガーと増分同期共有予定の監査、連携処理nextSyncTokenと予定の差分トリガーだけでは変更予定を特定できない

この記事の実装例は日次一覧です。開始前リマインドは通知済み状態の保存が必要になり、変更通知はCalendar APIの増分同期が必要です。要件が違うため、同じ関数へ詰め込みません。

日次一覧の処理フロー

01

時間主導トリガー

朝の時間帯に定期実行

標準機能
02

対象カレンダー

チーム用カレンダーを指定

標準機能
03

当日予定を取得

終日と時刻指定を分ける

要開発
04

公開範囲を調整

タイトルや参加者を絞る

要開発
05

受信Webhook

固定スペースへ一方向送信

要開発
06

Google Chat

1日分をまとめて共有

標準機能
標準機能で対応開発・設定が必要

予定1件につき1投稿すると通知が増えるため、日次一覧は1つのメッセージへまとめます。予定の詳細確認はCalendarへ戻し、Chatを予定情報の正本にしません。

対象カレンダーと公開範囲を決める

通知先より先に、どのカレンダーを対象にするかを決めます。

対象推奨度通知する内容注意点
チーム用共有カレンダー高い時刻、予定タイトル、担当運用目的と参加者が一致しやすい
プロジェクト用カレンダー高い締切、会議、リリース予定プロジェクト外の情報を混ぜない
会議室・設備カレンダー予約時間、利用状況予約者名を出す必要があるか確認する
個人のメインカレンダー低い原則は時間帯だけ顧客名、面談、私用予定が混ざる
組織全体のカレンダー用途次第全社行事、休業日投稿頻度と対象スペースを絞る

個人カレンダーの内容をチームへ出す必要がある場合も、初期設定ではタイトルを予定ありに置き換えます。予定の説明、参加者、添付、Meet URLは、業務上必要な場合だけ追加します。

項目Chatへの掲載判断理由
開始・終了時刻掲載するチームの行動判断に必要
予定タイトル共有カレンダーだけ掲載個人・顧客情報を含む可能性がある
主催者・参加者原則掲載しない個人情報と組織情報を広げない
説明欄掲載しない会議メモや機密情報が入りやすい
Meet URL参加者が一致する場合だけURLを知る範囲を広げない
添付ファイルChatへ複製しないDrive側の権限で管理する
場所必要な場合だけ訪問先や個人情報を含む可能性がある

Webhookと設定値を用意する

ブラウザ版Google Chatで通知先スペースを開き、アプリとインテグレーションから受信Webhookを追加します。Webhook URLはApps ScriptのスクリプトプロパティへCHAT_WEBHOOK_URLとして保存します。

対象カレンダーのIDもCALENDAR_IDとして保存します。コードへ直接書かず、環境ごとに設定を切り替えられるようにします。

Google ChatとGoogleカレンダーの設定画面は、公開前に運用環境で手動撮影した実画面へ差し替えます。アカウント名、予定名、参加者、カレンダーID、Webhook URLをマスキングしてから掲載してください。

当日の予定をまとめて通知する

次のコードは、指定カレンダーの当日予定を取得し、1つのChatメッセージへまとめます。SHOW_TITLESfalseにすると、タイトルを予定ありへ置き換えます。

const SHOW_TITLES = false;

function notifyTodayEvents() {
  const properties = PropertiesService.getScriptProperties();
  const calendarId = properties.getProperty('CALENDAR_ID');

  if (!calendarId) {
    throw new Error('CALENDAR_IDが設定されていません。');
  }

  const calendar = CalendarApp.getCalendarById(calendarId);
  if (!calendar) {
    throw new Error('対象カレンダーが見つからないか、権限がありません。');
  }

  const events = calendar.getEventsForDay(new Date())
    .sort((a, b) => a.getStartTime().getTime() - b.getStartTime().getTime());
  const timeZone = calendar.getTimeZone();
  const dateLabel = Utilities.formatDate(new Date(), timeZone, 'M月d日');

  const lines = events.length === 0
    ? ['予定はありません。']
    : events.map((event) => formatEvent(event, timeZone));

  sendToChat([
    `*${dateLabel}の予定*`,
    ...lines,
  ].join('\n'));
}

function formatEvent(event, timeZone) {
  const time = event.isAllDayEvent()
    ? '終日'
    : Utilities.formatDate(event.getStartTime(), timeZone, 'HH:mm');
  const title = SHOW_TITLES
    ? truncate(event.getTitle(), 80)
    : '予定あり';

  return `${time} ${title}`;
}

function truncate(value, maxLength) {
  const text = String(value || '名称未設定');
  return text.length <= maxLength
    ? text
    : `${text.slice(0, maxLength)}...`;
}

function sendToChat(message) {
  const url = PropertiesService.getScriptProperties()
    .getProperty('CHAT_WEBHOOK_URL');

  if (!url) {
    throw new Error('CHAT_WEBHOOK_URLが設定されていません。');
  }

  const response = UrlFetchApp.fetch(url, {
    method: 'post',
    contentType: 'application/json; charset=UTF-8',
    payload: JSON.stringify({ text: message }),
    muteHttpExceptions: true,
  });

  const status = response.getResponseCode();
  if (status < 200 || status >= 300) {
    throw new Error(`Chat通知に失敗しました。HTTP ${status}`);
  }
}

getCalendarByIdは、カレンダーが存在しない場合だけでなく、実行者がアクセスできない場合や購読していない場合もnullを返します。取得結果を確認せずに処理を続けないようにします。

Apps Scriptのタイムゾーンとカレンダーのタイムゾーンが違うと、日付や表示時刻がずれる可能性があります。対象カレンダー、Apps Scriptプロジェクト、通知先チームの基準タイムゾーンを確認してください。

時間主導トリガーを設定する

Apps Scriptのトリガー画面からnotifyTodayEventsを時間主導トリガーへ登録します。毎朝の予定共有なら、日付ベースのタイマーで希望する時間帯を選びます。

Google公式では、時間主導トリガーの実行時刻は指定時間帯の中で多少ずれると案内されています。8時台の通知には使えますが、8時00分ちょうどの実行を前提にしません。

通知タイミング向く用途実装注意点
当日朝朝会、当番、チーム予定1日1回の時間主導トリガー実行時刻は時間帯内でずれる
前日夕方翌日の準備、会議資料確認翌日の日付で予定を取得夜間の予定変更は反映されない
15〜30分前会議前リマインド短い間隔で今後の予定を検索重複防止が必要
変更直後変更・中止の連絡更新トリガーと増分同期CalendarAppだけでは差分を特定できない

インストール型トリガーは作成者の権限で実行されます。作成者の退職やアカウント停止で止まらないよう、所有者、対象カレンダー、プロパティ、通知先を引き継ぎ資料へ残します。

会議前リマインドでは重複を防ぐ

会議前リマインドは、5分ごとなど短い間隔で対象期間を検索します。同じ予定が複数回の検索窓に入るため、予定IDと開始時刻を組み合わせたキーを保存します。

状態管理利点限界向く規模
PropertiesServiceApps Scriptだけで完結する保存容量と監査性に限界がある小規模なリマインド
スプレッドシート通知履歴を人が確認できる同時更新と行数増加に注意部門単位の運用
データベース・キュー再送、期限、監査を設計しやすい構築と監視が必要大量・重要な通知

予定時刻が変更された場合、同じ予定IDでも開始時刻が変わります。開始時刻をキーへ含めれば、変更後の時刻で再通知できます。中止予定や繰り返し予定の扱いもテストが必要です。

変更通知には増分同期が必要

Apps Scriptのカレンダー更新トリガーは、予定が作成、編集、削除されたときに動きます。ただし、イベントオブジェクトから分かるのは対象カレンダーIDまでで、どの予定がどう変わったかは分かりません。

Google公式が案内する変更検知の流れは次のとおりです。

  1. Calendarの高度なサービスを有効にする
  2. 対象カレンダーを初回同期する
  3. 取得したnextSyncTokenを保存する
  4. 更新トリガーが動いたら、保存済みトークンで増分同期する
  5. 作成、更新、削除された予定を判定する
  6. 新しいnextSyncTokenへ更新する
  7. 410でトークンが無効になった場合は完全同期し直す

予定変更通知は、当日一覧のコードへ数行追加するだけでは実装できません。変更前後の比較、削除、繰り返し予定、同期トークンの失効まで扱う別機能として設計します。

テストで確認する項目

確認項目テスト方法合格条件
終日予定終日と複数日の予定を登録する終日として日次一覧へ表示される
タイムゾーン異なるタイムゾーンの予定を登録する基準タイムゾーンで正しく表示される
非公開予定個人情報を含む予定を登録するタイトルや参加者がChatへ出ない
予定なし対象日の予定をゼロにする期待した文言または無通知になる
送信失敗テスト用の無効Webhookで実行する失敗が実行履歴に残る
権限不足対象カレンダーの共有を外す分かるエラーで停止する
引き継ぎ別の管理担当が設定を追跡するカレンダーID、プロパティ、トリガーを確認できる

本番運用で見る指標

Decision chart

カレンダー通知で優先して監視する項目

予定共有への影響をもとにSakuraAIが整理した優先度です。

通知失敗件数100/100

予定があってもチームへ届かない

非公開情報の誤掲載99/100

個人情報や顧客情報の漏えいにつながる

重複通知件数93/100

通知疲れと見落としを増やす

時刻・日付のずれ92/100

会議への遅刻や準備不足につながる

通知後の確認率78/100

通知が行動に結び付いているかを見る

投稿数ではなく、失敗、誤掲載、重複、時刻ずれを追います。

Apps Scriptの実行履歴と失敗通知を確認し、Calendar、URL Fetch、トリガーの割り当ても公式資料で確認します。大量の予定を同じスペースへ1件ずつ送らず、一覧へ集約します。

Apps Script方式が向かないケース

  • 秒単位の正確な通知時刻が必要
  • 大量のカレンダーを組織横断で監視する
  • 変更前後の履歴を監査対象として保存する
  • 通知の再送、配信保証、失敗キューが必要
  • 複数のシステムへ同じ予定イベントを配信する

この場合は、Calendar API、Cloud Scheduler、キュー、データベース、監視基盤を含めて設計します。Apps Scriptは小規模な日次共有には向きますが、厳密なイベント配信基盤ではありません。

専門家に聞く運用判断

Q. どのカレンダーから始めますか?

A. 個人カレンダーではなく、目的と閲覧者が決まっているチーム用カレンダーです。当日の予定を1日1回まとめ、通知量と公開範囲を確認します。

Q. 予定の説明をAIで要約して通知してもよいですか?

A. 説明欄には機密情報が入りやすいため、最初からAIへ渡しません。要約が本当に必要な用途だけを選び、入力範囲、保存先、誤要約時の確認方法を決めます。

Q. 会議前リマインドが二重に飛びます。なぜ?

A. 多くは、同じ予定に対してリマインド送信済みかどうかを記録していないためです。予定IDと通知種別を組みにして『送ったか』を保存し、送る前に確認する。これだけで重複はほぼ止まります。タイムゾーンの取り違えも時刻ずれの定番なので、あわせて確認してください。

Q. 運用を始めてから何を改善しますか?

A. 通知の件数ではなく、失敗・重複・非公開情報の誤掲載・時刻ずれを見ます。使われない通知を増やすより、対象カレンダーとタイミングを絞るほうが、結局よく読まれます。

関連レシピ

日程調整と予定作成まで含めた設計はカレンダー日程調整の自動化、フォーム回答の通知はフォーム回答をChatに通知する方法、Drive更新の通知はDrive更新をChatに通知する方法を参照してください。

SakuraAIで支援できること

SakuraAIは、Googleカレンダーの日次共有、会議前リマインド、変更検知、Google Chat通知を設計・実装します。通知を作るだけで終わらせず、公開範囲、タイムゾーン、重複防止、増分同期、失敗監視、担当者の引き継ぎまで含めて構築します。

よくある質問

会議の前にリマインドできますか?

できます。時間主導トリガーで今後の一定時間内に始まる予定を検索し、予定IDと開始時刻をキーに通知済み状態を管理します。ただし、時間主導トリガーは厳密な秒単位の実行を保証しません。

特定のカレンダーだけ通知できますか?

できます。CalendarApp.getCalendarByIdで対象カレンダーを指定します。取得結果がnullの場合は、IDの誤り、権限不足、未購読を確認します。

予定の変更も通知できますか?

できますが、カレンダー更新トリガーだけでは変更された予定を特定できません。Google公式が案内するCalendar APIの増分同期を使い、nextSyncTokenで差分を取得する必要があります。

毎朝8時ちょうどに通知できますか?

Apps Scriptの時間主導トリガーは指定時間帯の中で実行時刻がずれることがあります。8時台の共有には使えますが、8時00分ちょうどが業務要件なら別のスケジューラを検討します。

非公開予定のタイトルもChatへ流れますか?

実装次第です。個人カレンダーをチームへ通知する場合は、初期設定ではタイトルを出さず予定ありと表示する方が安全です。タイトルを載せるなら、通知先の参加者と予定の公開範囲を確認します。

参考・一次情報

湯田英也

Reviewed by

監修者: 湯田英也

SakuraAI株式会社 代表 / ソフトウェアエンジニア

Google Chatの導入・移行、Google Workspace連携、Google Chat API / Webhook / Bot、Gmail・Meet・Drive・Calendarをまたぐ業務自動化領域を監修しています。

Google公式情報、各プロダクトの仕様、実務での運用・開発観点をもとに、企業が導入判断・運用設計・自動化設計を行える内容になるよう確認しています。

開発相談

Google Chat Bot・Webhook開発を相談する

通知・承認・問い合わせ連携のBotとAPI実装を支援します。

開発を相談する