MENU

GAS×ChatGPT×Googleカレンダー連携|予定を自動分析してリマインド

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カレンダー連携で、毎日のスケジュール確認と準備が自動化できた。朝の時間に余裕が生まれるだけでなく、会議への準備漏れも減る。

次のステップ:

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

目次