GAS×ChatGPT×Googleカレンダー連携|予定を自動分析してリマインド
朝起きて「今日の会議、何を準備すればいいんだっけ」と焦った経験はないだろうか。予定が詰まった日ほど、準備の抜け漏れが起きやすい。
GAS×ChatGPT×Googleカレンダーを連携させると、翌日の予定を自動分析し、準備事項をリマインドしてくれる。毎朝自動で「今日のアジェンダと準備リスト」がメールで届く仕組みを、ゼロから組み上げていく。
目次
この記事でできること
完成すると、以下のような自動化が動く。
1. 毎朝7時にGASが自動実行
↓
2. Googleカレンダーから今日の予定を取得
↓
3. ChatGPTが各予定を分析
- 予定の種類を判定(会議/面談/作業等)
- 必要な準備事項を提案
- 優先度を判定
↓
4. 整理されたアジェンダがメールで届く
活用例:
- 毎朝の「今日やること」を自動整理
- 会議前の準備漏れを防止
- 1日のスケジュールを俯瞰
事前準備
必要なもの
| 項目 | 詳細 | 取得方法 |
|---|---|---|
| Googleアカウント | カレンダー、GAS、Gmail用 | お持ちのもの |
| OpenAI APIキー | ChatGPT連携用 | platform.openai.com |
Googleカレンダーは追加設定不要で、GASから直接アクセスできる。
実装手順
STEP 1: GASプロジェクトを作成
- script.google.com にアクセス
- 「新しいプロジェクト」をクリック
- プロジェクト名を変更(例: カレンダーリマインダー)
STEP 2: コードを設置
// ===================================================
// 設定
// ===================================================
const CONFIG = {
OPENAI_API_KEY: PropertiesService.getScriptProperties().getProperty('OPENAI_API_KEY'),
// リマインドメールの送信先(自分のメールアドレス)
EMAIL_TO: Session.getActiveUser().getEmail(),
// 分析対象のカレンダーID(メインカレンダーは 'primary')
CALENDAR_ID: 'primary',
// ChatGPTモデル
MODEL: 'gpt-4o-mini'
};
// ===================================================
// メイン処理: 今日の予定を分析してメール送信
// ===================================================
function sendDailyAgenda() {
// 1. 今日の予定を取得
const events = getTodayEvents();
if (events.length === 0) {
sendEmail('今日の予定はありません', '予定のない1日です。自由に使える時間を有効活用しましょう!');
return;
}
// 2. ChatGPTで予定を分析
const analysis = analyzeEvents(events);
// 3. メールを送信
sendEmail('📅 今日のアジェンダ', analysis);
console.log('デイリーアジェンダを送信しました');
}
// ===================================================
// 今日の予定を取得
// ===================================================
function getTodayEvents() {
const calendar = CalendarApp.getCalendarById(CONFIG.CALENDAR_ID);
const today = new Date();
const startOfDay = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0);
const endOfDay = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 23, 59, 59);
const events = calendar.getEvents(startOfDay, endOfDay);
return events.map(event => ({
title: event.getTitle(),
startTime: Utilities.formatDate(event.getStartTime(), 'Asia/Tokyo', 'HH:mm'),
endTime: Utilities.formatDate(event.getEndTime(), 'Asia/Tokyo', 'HH:mm'),
location: event.getLocation() || 'なし',
description: event.getDescription() || '',
isAllDay: event.isAllDayEvent()
}));
}
// ===================================================
// ChatGPTで予定を分析
// ===================================================
function analyzeEvents(events) {
const eventList = events.map((e, i) =>
`${i + 1}. ${e.startTime}-${e.endTime} ${e.title}${e.location !== 'なし' ? ` @${e.location}` : ''}`
).join('\n');
const prompt = `以下は今日のスケジュールです。
各予定について分析し、以下の形式でまとめてください。
【出力形式】
## ⏰ 今日のスケジュール概要
(1日の流れを2-3文で簡潔に説明)
## 📋 予定ごとの準備事項
### 1. [予定名] (時間)
- 📌 種類: (会議/面談/作業/移動/その他)
- ⚡ 優先度: (高/中/低)
- ✅ 準備すること:
- (具体的な準備項目を箇条書き)
- 💡 ポイント:
- (この予定で意識すべきこと)
(以下、全ての予定について同様に)
## 🎯 今日のフォーカスポイント
(今日特に意識すべきこと、注意点を2-3点)
---
今日の予定:
${eventList}
補足情報:
${events.map((e, i) => e.description ? `${i + 1}. ${e.description}` : '').filter(d => d).join('\n')}`;
return callChatGPT(prompt);
}
// ===================================================
// ChatGPT API呼び出し
// ===================================================
function callChatGPT(prompt) {
const url = 'https://api.openai.com/v1/chat/completions';
const payload = {
model: CONFIG.MODEL,
messages: [
{
role: 'system',
content: 'あなたは優秀なパーソナルアシスタントです。ユーザーの1日を効率的に過ごせるよう、予定の分析と準備事項の提案を行います。'
},
{ role: 'user', content: prompt }
],
max_tokens: 2000,
temperature: 0.7
};
const options = {
method: 'post',
contentType: 'application/json',
headers: { 'Authorization': 'Bearer ' + CONFIG.OPENAI_API_KEY },
payload: JSON.stringify(payload),
muteHttpExceptions: true
};
const response = UrlFetchApp.fetch(url, options);
const json = JSON.parse(response.getContentText());
if (json.error) throw new Error(json.error.message);
return json.choices[0].message.content;
}
// ===================================================
// メール送信
// ===================================================
function sendEmail(subject, body) {
const today = Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy年M月d日(E)');
const htmlBody = `
<div style="font-family: 'Helvetica Neue', Arial, sans-serif; max-width: 600px; margin: 0 auto;">
<h2 style="color: #1a73e8; border-bottom: 2px solid #1a73e8; padding-bottom: 10px;">
${today}
</h2>
<div style="white-space: pre-wrap; line-height: 1.8;">
${body.replace(/## /g, '<h3 style="color: #333; margin-top: 20px;">').replace(/\n### /g, '</h3>\n<h4 style="color: #555;">').replace(/\n- /g, '<br>• ')}
</div>
<hr style="margin-top: 30px; border: none; border-top: 1px solid #ddd;">
<p style="color: #888; font-size: 12px;">
このメールはGAS×ChatGPTカレンダーアシスタントから自動送信されています。
</p>
</div>
`;
GmailApp.sendEmail(CONFIG.EMAIL_TO, `${subject} - ${today}`, body, {
htmlBody: htmlBody
});
}
// ===================================================
// 翌日の予定を前日夜に送信(オプション)
// ===================================================
function sendTomorrowAgenda() {
const calendar = CalendarApp.getCalendarById(CONFIG.CALENDAR_ID);
const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
const startOfDay = new Date(tomorrow.getFullYear(), tomorrow.getMonth(), tomorrow.getDate(), 0, 0, 0);
const endOfDay = new Date(tomorrow.getFullYear(), tomorrow.getMonth(), tomorrow.getDate(), 23, 59, 59);
const events = calendar.getEvents(startOfDay, endOfDay);
if (events.length === 0) {
console.log('明日の予定はありません');
return;
}
const eventData = events.map(event => ({
title: event.getTitle(),
startTime: Utilities.formatDate(event.getStartTime(), 'Asia/Tokyo', 'HH:mm'),
endTime: Utilities.formatDate(event.getEndTime(), 'Asia/Tokyo', 'HH:mm'),
location: event.getLocation() || 'なし',
description: event.getDescription() || '',
isAllDay: event.isAllDayEvent()
}));
const analysis = analyzeEvents(eventData);
const tomorrowStr = Utilities.formatDate(tomorrow, 'Asia/Tokyo', 'M月d日');
sendEmail(`📅 明日(${tomorrowStr})の予定`, analysis);
}
STEP 3: スクリプトプロパティを設定
- 「プロジェクトの設定」→「スクリプトプロパティ」
OPENAI_API_KEYを追加
STEP 4: トリガーを設定
毎朝7時に今日のアジェンダを送信
- 「トリガー」→「トリガーを追加」
- 設定:
– 実行する関数: sendDailyAgenda
– イベントのソース: 時間主導型
– 時間ベース: 日付ベースのタイマー
– 時刻: 午前7時〜8時
(オプション)前日夜に翌日の予定を送信
- 実行する関数:
sendTomorrowAgenda - 時刻: 午後9時〜10時
[画像: トリガー設定画面]
出力サンプル
実際に送信されるメールの例を見てみよう。
📅 2026年2月2日(月)
## ⏰ 今日のスケジュール概要
今日は午前中に重要なクライアント会議があり、午後は開発作業に集中できる時間があります。
夕方にはチーム定例があるので、週次報告の準備を忘れずに。
## 📋 予定ごとの準備事項
### 1. クライアントA社 提案会議 (10:00-11:30)
- 📌 種類: 会議
- ⚡ 優先度: 高
- ✅ 準備すること:
- 提案資料の最終確認
- 過去の議事録を確認
- 想定質問への回答を準備
- 💡 ポイント:
- 予算に関する質問が来る可能性あり
### 2. 開発作業 (13:00-17:00)
- 📌 種類: 作業
- ⚡ 優先度: 中
- ✅ 準備すること:
- タスクの優先順位を確認
- 集中できる環境を整える
- 💡 ポイント:
- 途中でSlackを見すぎないよう注意
## 🎯 今日のフォーカスポイント
1. 午前の会議で良い印象を残すこと
2. 午後の開発時間を最大限活用すること
カスタマイズ例
特定のキーワードで優先度を上げる
// 「重要」「緊急」などのキーワードがある予定を強調
const importantKeywords = ['重要', '緊急', 'CEO', '役員'];
const isImportant = importantKeywords.some(kw => event.title.includes(kw));
LINE通知に変更
メールではなくLINEで通知したい場合は、sendEmail関数をsendLineNotifyに置き換える。
トラブルシューティング
| エラー | 原因 | 対処法 |
|---|---|---|
Calendar not found |
カレンダーIDが無効 | ‘primary’を使用するか、正しいIDを設定 |
You do not have permission |
カレンダー権限エラー | GASに権限を付与(初回実行時に承認) |
メールが届かない |
迷惑メールフォルダ | Gmailの迷惑メールを確認 |
まとめ
GAS×ChatGPT×Googleカレンダー連携で、毎日のスケジュール確認と準備が自動化できた。朝の時間に余裕が生まれるだけでなく、会議への準備漏れも減る。
次のステップ:
- GAS×ChatGPT入門 で基礎を復習
- GAS×Slack連携 でチームにも共有
- GAS×Notion連携 で記録を蓄積
コメント