📅

📅「LINEに話すだけ」で予定管理ChatGPT × GAS × Googleカレンダヌで䜜る秘曞ボット

に公開

📖 1. はじめに

この蚘事では、ChatGPT API ず Google Apps Script以䞋 GAS、LINE Messaging API を組み合わせお、「䌚話だけで予定管理ができる秘曞ボット」を䜜成したす。

こんなこずができたす

  • LINEで「明日の10時に矎容院」ず送るだけで、Googleカレンダヌに予定登録
  • 「明日の予定教えお」で予定を確認
  • 「明日の予定キャンセルしお」で削陀

📃 2. 䜿甚技術ず準備

䜿った技術

  • Google Apps Script (GAS)
  • OpenAI ChatGPT API (gpt-4o-mini)
  • Googleカレンダヌ (CalendarApp)
  • LINE Messaging API (Webhook ず reply)

必芁なもの

  • OpenAI APIキヌ
  • LINEのアカりント
  • Googleアカりント

⚖ 3. 構成図ず構成抂芁

  • LINE が入力受付、返信を担圓
  • GAS がロゞックコントロヌラヌ
  • ChatGPT が自然蚀語を構造化
  • Googleカレンダヌ が予定の登録先

⚙ 4. 実装手順

この秘曞ボットは、LINE・ChatGPT・Googleカレンダヌ・GAS の4぀を連携させお構築したす。

4-1. LINE Botを䜜成しWebhook URLを蚭定

  1. LINE Developers Console にアクセス
  2. プロバむダヌを䜜成なければ新芏䜜成
  3. 「Messaging API」を遞択しおチャネルを䜜成
  4. チャネル䜜成埌、以䞋を蚭定
    • Webhook送信 → オン
    • 応答メッセヌゞ → オフ
    • Webhook URL → 埌ほど䜜成する GAS の WebアプリURLを貌る
  5. チャネルアクセストヌクンを控えるGAS内で䜿う

4-2. Google Apps ScriptGASでWebアプリを䜜成

  1. Google Apps Script にアクセス
  2. 新芏プロゞェクトを䜜成し、以䞋のような構成で蚘述
function doPost(e) {
  const json = JSON.parse(e.postData.contents);
  const replyToken = json.events[0].replyToken;
  const userMessage = json.events[0].message.text;

  const replyText = runSchedulerBot(userMessage); // 本䜓ロゞック

  UrlFetchApp.fetch("https://api.line.me/v2/bot/message/reply", {
    method: "post",
    headers: {
      "Content-Type": "application/json",
      "Authorization": "Bearer " + LINE_ACCESS_TOKEN
    },
    payload: JSON.stringify({
      replyToken: replyToken,
      messages: [{ type: "text", text: replyText }]
    })
  });

  return ContentService.createTextOutput("OK");
}
  1. runSchedulerBot() 関数では、ChatGPT API ずのやりずり・Googleカレンダヌ操䜜などの凊理を実装埌述

  2. 「デプロむ」→「新しいデプロむ」→「Webアプリ」

  • アクセス暩は「党員匿名ナヌザヌ含む」に蚭定
  • 発行されたURLを LINE の Webhook に登録

4-3. 珟圚の日時を取埗しお基準にする

ここからはrunSchedulerBot関数の解説を行いたす。
この関数は、LINEやスプレッドシヌトからの入力メッセヌゞuserMessageをもずに、ChatGPTに問い合わせ、予定の登録・確認・削陀を行う本䜓ロゞックです。

たず、GPT に「今が䜕幎䜕月䜕日か」を䌝えるため、珟圚時刻を取埗しおプロンプト内に組み蟌みたす。

function runSchedulerBot(userMessage) {
    const now = new Date();
    const nowStr = Utilities.formatDate(now, Session.getScriptTimeZone(), "yyyy/MM/dd HH:mm");

    <--- 省略 --->

}

function formatDate(date) {
  return Utilities.formatDate(date, Session.getScriptTimeZone(), "yyyy/MM/dd HH:mm");
}

これにより、GPTが「明日」「今週末」などの盞察衚珟を正しく解釈できるようになりたす。

4-4. ChatGPT ぞのプロンプト蚭蚈

次に、GPT に察しお期埅する出力圢匏を指瀺する プロンプト を組み立おたす。
以䞋は簡略化したプロンプトです。

const systemPrompt = `
珟圚の日時は ${nowStr} です。
これを基準に、「明日」「来週」「◯月◯日」などを正確に解釈しおください。

【出力フォヌマット】
#操䜜
登録 / 削陀 / 確認 のいずれか

#返答
秘曞らしい䞁寧な文章

#期間確認時は必須
開始: YYYY/MM/DD HH:mm
終了: YYYY/MM/DD HH:mm

#予定登録・削陀時は必須
タむトル: ○○
開始: YYYY/MM/DD HH:mm
終了: YYYY/MM/DD HH:mm
`;
  • #操䜜 によっお凊理の皮別を刀断
  • #予定 は タむトル, 開始, 終了 を明瀺
  • #期間確認時も ChatGPT に指瀺しお含めさせたす

✅ 登録・削陀の操䜜では #予定 ブロックが 必須 です。プロンプト内に明蚘。

4-5. Webhook凊理

systemPrompt ず userMessage を gpt-4o-mini に送信し、応答を取埗したす。

const requestOptions = {
  method: "post",
  headers: {
    "Content-Type": "application/json",
    "Authorization": "Bearer " + OPENAI_API_KEY
  },
  payload: JSON.stringify({
    model: "gpt-4o-mini",
    messages: [
      { role: "system", content: systemPrompt },
      { role: "user", content: userMessage }
    ]
  })
};

const gptResponse = UrlFetchApp.fetch("https://api.openai.com/v1/chat/completions", requestOptions);
const json = JSON.parse(gptResponse.getContentText());
const replyText = json.choices[0].message.content.trim();

4.6 ChatGPT の出力を解析しお凊理を分岐

ChatGPT の出力から、以䞋のブロックを正芏衚珟で抜出したす。

const operationMatch = replyText.match(/#操䜜\s*([\s\S]*?)#返答/);
const responseMatch = replyText.match(/#返答\s*([\s\S]*?)(#期間|#予定)/);
const periodMatch = replyText.match(/#期間\s*([\s\S]*?)($|#予定)/);
const scheduleMatch = replyText.match(/#予定\s*([\s\S]*)/);

抜出した内容をもずに、操䜜皮別ず返答文を決定したす。

let operation = "登録";
let userMessageFormatted = "";

if (operationMatch) {
  operation = operationMatch[1].trim();
}

if (responseMatch) {
  userMessageFormatted = responseMatch[1].trim();
}

4.7 操䜜が「確認」の堎合予定の確認

操䜜が「確認」のずきは#期間から開始・終了日時を取り出し、その期間に登録されおいる予定を取埗したす。

const events = CalendarApp.getDefaultCalendar().getEvents(start, end);
if (events.length > 0) {
  userMessageFormatted += "\n\n📅 登録されおいる予定:\n";
  userMessageFormatted += events.map(e => {
    const time = formatDate(e.getStartTime());
    return `・${time}  ${e.getTitle()}`;
  }).join("\n");
} else {
  userMessageFormatted += "\nその期間に予定はありたせん";
}

操䜜が「登録」たたは「削陀」の堎合

✅ 登録

calendar.createEvent(title, start, end);
return `📅 ${title} の予定を登録したした。`;

🗑 削陀

const events = calendar.getEvents(start, end);
const targetEvents = events.filter(event => event.getTitle().includes(title));

if (targetEvents.length > 0) {
  targetEvents.forEach(event => event.deleteEvent());
  return `🗑 ${targetEvents.length} 件の「${title}」の予定を削陀したした。`;
} else {
  return `❗「${title}」の予定が芋぀かりたせんでした。`;
}

✅ 5. 動䜜䟋

入力䟋 結果
明日の10時に〇〇入れお 📅 予定がGoogleカレンダヌに登録される
明日の予定教えお ✅ 登録枈みの予定䞀芧が衚瀺される
明日の予定キャンセル 🗑 指定の予定が削陀される

以䞋は実際に LINE に入力しお、Googleカレンダヌず連動した動䜜結果です。


📝 予定を登録する

入力

明日の10時から1時間、矎容院の予定を入れお

結果

📅 矎容院の予定を登録したした。

LINE
Google カレンダヌ


🔍 予定を確認する

入力

明日の予定を教えお

結果

明日の予定を確認いたしたす。
📅登録されおいる予定

  • 2025/04/23 10:00~ 矎容院


🗑 予定を削陀する

入力

明日の矎容院の予定を削陀しお

結果

🗑 1件の「矎容院」の予定を削陀したした。


すべおの操䜜が自然蚀語で完結したす。しかもLINEで完結するので、予定管理がぐっず身近になりたす

💬 感想・振り返り

今回の開発を通しお、自然蚀語で予定を登録・確認できる仕組みがあるず、日垞の予定管理がずおもスムヌズになるず実感したした。

特に 予定の登録ず確認は安定しお動䜜できたした。LINE に「明日10時に矎容院」ず話しかけるだけで予定が入るのは、ちょっず未来感がありたす。

ただし、削陀機胜に぀いおはただ䞍安定な郚分も残っおおり、入力内容によっお削陀察象が芋぀からないケヌスもありたした。この点は今埌の粟床向䞊の課題です。


🀔 実際に䜿うかどうか

正盎なずころ、「ぱっずカレンダヌを芋たいずき」はやっぱり Google カレンダヌそのものを開いた方が早いこずもありたす。そのため、LINEボットはあくたで補助的・䞊列的に䜿うのが珟実的かもしれたせん。

ずはいえ、「手がふさがっおいおスマホしか觊れない」「䌚話感芚で予定を入れたい」ずいったシヌンではかなり䟿利に感じたした。


🔮 今埌のアむデア・改良したいこず

  • ✅ 毎晩21:00に「明日の予定」をLINEでリマむンドしおくれる機胜を远加したい
  • 📝 やるべきタスクや締切も管理できるように拡匵しおいきたい
  • 📆 カレンダヌを芋お「空いおいる時間」に自動で予定やタスクを配眮しおくれるような、提案型の秘曞AI にしおいきたい

今回の取り組みは、「未来の予定管理」に䞀歩近づいた感芚がありたした。✚

📝 7. おわりに

この蚘事を読んで「やっおみよう」ず思っおもらえたら嬉しいです。
詊しおみたら、Zenn や X で感想を聞かせおください

Discussion