Pythonの基礎知識(実践編)

【Pythonの基礎知識】LINEに送るだけで予定が登録されるAI執事

LINEに「明日の13時に歯医者」と送るだけで、Googleカレンダーにその予定が自動で登録される。 そんな“自分専用のAI執事”を、Pythonと無料のAPIだけで実現するシリーズ第4弾です。

これまでの構成では、「LINEから予定を確認する」まででしたが、今回はついに“予定を追加できる”ステージに進みます。

自然な文章から日時と予定名を抽出し、Googleカレンダーに直接登録してくれるこの仕組みは、日々の小さなタスク管理を圧倒的に効率化します。

スマホを開かずに予定を登録したい。 PCや手帳に向かう時間も惜しい。 そんなあなたのための“本物の時短ツール”を一緒に作っていきましょう。

この記事で作るものと進化ポイント

この記事では、LINEに自然文を送るだけで、予定をGoogleカレンダーに自動登録してくれる「進化型AI執事ボット」を構築します。

これまでの記事では“予定を確認する”までの構成でしたが、今回は“予定を作る”という能動的な処理へと進化します。 それにともない、コード構成も大きく進化し、より実践的なスタイルへと移行しています。

LINEで送るだけで予定を登録できるAIボット

本記事で構築するAIボットは、ユーザーがLINEに送信した「明日10時に会議」などの自然な文章を受け取り、 Googleカレンダーに予定として自動登録してくれる仕組みです。

これまでと違い、カレンダーに対して“確認する”のではなく“書き込む”側へと回ることで、 単なる便利ツールではなく「生活に溶け込む自動化パートナー」へと機能が進化します。

予定“確認”だけでは物足りない

これまでの記事(第1〜2弾)では、LINEからの自然文に対して「ChatGPTで返信」や「Googleカレンダーの予定を確認」する機能を作ってきました。 しかし、実際の利用シーンでは「予定を知る」だけでなく「予定を入れる」ニーズの方が圧倒的に多く、 このステップがなければAIボットは“ただの便利なメモ代わり”に留まってしまいます。

本記事では、その物足りなさを解消し、ユーザーの入力をトリガーに「予定を自動生成・登録」する 真の意味で実用性の高いAI執事へと昇華させていきます。

前回の「予定参照」Botとの違い

前回の記事①では、「今日の予定は?」と聞くと、Googleカレンダーから当日の予定を返してくれるAI執事を構築しました。 これは“確認”までの機能であり、ユーザーのスケジュールを参照することが目的でした。

今回はその続編として、“予定を登録する”機能を追加します。 たとえば、「明日の15時に歯医者の予約を入れて」とLINEに送るだけで、Googleカレンダーに登録されます。

この進化により、AI執事は単なるリマインダーから“スケジュール管理の実行役”へと進化を遂げました。

なぜ構成を分けるのか(自然な進化)

予定の登録処理は、自然文の解析・日時の抽出・Google APIとのやり取りなど、複数の複雑な処理が関わるため、 これまでのようにすべてを1つのファイル(app.py)に詰め込むと、メンテナンス性が著しく低下します。

そのため、この記事からは「処理の役割に応じてファイルを分割する」構成へと進化します。 構造が整理されることで、コード全体の見通しがよくなり、今後の拡張(削除・リマインド・代理登録など)にも耐えられる実装になります。

これは“技術的な都合”ではなく、「予定を登録できるようになったからこそ、構成も進化するのが自然である」という設計思想に基づいた判断です。

モジュール構成の全体像

今回のボットは、自然文から予定を解析してGoogleカレンダーに登録するという、複数の処理が組み合わさった構成になります。 そのため、すべての処理を1つのファイルに押し込むのではなく、処理の責任ごとに分けて設計することで、コード全体の見通しを明確にしています。

ファイル構成一覧と役割

以下は、本記事で使用するPythonファイルとディレクトリ構成の一覧です。各ファイルには明確な役割があり、将来的な機能追加や修正にも対応しやすい構成になっています。

project_root/
    ├── app.py        # Flask本体・Webhookの受信と分岐
    ├── .env         # APIキーや認証設定(非公開)
    ├── logic/
    │    ├── chatgpt_logic.py # ChatGPT応答・意図分類ロジック
    │    └── calendar_utils.py # Googleカレンダー予定確認+登録
    └── credentials.json   # Googleサービスアカウント認証ファイル

モジュールごとの責務(役割分担が読める表形式)

各ファイルが担う役割と、他モジュールとの関係性を以下の表にまとめます。読者がコードを拡張・保守する際に、どこを見ればよいかが一目でわかる構成になっています。

ファイル名役割主な処理内容
app.py司令塔(Flask本体)LINEからのメッセージを受け取り、意図を分類して処理を分岐
chatgpt_logic.py応答処理(AI担当)ChatGPTへの問い合わせと自然文応答の生成、意図の判定
calendar_utils.py予定管理今日の予定取得、自然文から日時を抽出しGoogleカレンダーに登録
.env環境設定APIキー、カレンダーID、認証ファイルパスなどの秘匿変数

必要なライブラリと前提環境

本記事では、LINE Botによる「予定登録」機能を実装するにあたり、従来の環境に加えていくつかのライブラリが新たに必要となります。 以下に、今回追加でインストールすべきライブラリと、その導入方法をまとめます。

使用するPythonライブラリ一覧

今回の機能(予定登録)に最低限必要なライブラリは以下の通りです。

ライブラリ名用途
flaskWebhookサーバ構築
python-dotenv.envファイルから環境変数を読み込む
line-bot-sdkLINE Messaging APIの操作(v3対応)
openaiChatGPT応答(予定確認以外の会話処理)
google-api-python-clientGoogle Calendar APIの操作
google-authGoogle APIの認証用

requirements.txt の記述例

これらを requirements.txt にまとめておくことで、再インストールや別環境構築がスムーズになります。

flask
python-dotenv
line-bot-sdk>=3.0.0
openai
google-api-python-client
google-auth

コピペで動く完成コード(予定登録対応)

このセクションでは、前提知識や背景説明よりも先に「とにかく動かしてみたい!」という読者のために、すぐに実行可能なコード一式を提示します。 すべてのファイルはモジュール分割されており、1つずつ貼り付けることでそのまま再現できます。

app.py(本体:Webhook + 処理分岐)

このファイルはFlaskアプリケーションのエントリーポイントであり、LINEからのWebhookを受け取り、メッセージの意図に応じて各処理へ振り分ける“司令塔”です。

logic/chatgpt_logic.py(ChatGPT応答・意図分類)

このファイルは、ユーザーからの自然文メッセージに対して、ChatGPTを用いた応答や“予定”などの意図分類を担当するモジュールです。

logic/calendar_utils.py(予定確認 + 予定登録)

のファイルは、Googleカレンダーと連携して「今日・明日・明後日など任意の日付の予定を取得」したり、「自然文から予定を登録する」処理をまとめたユーティリティモジュールです。

.env(環境変数の例)

APIトークンやGoogle認証情報などの機密設定は`.env`ファイルに分離することで、コードの安全性と可搬性を保ちます。

以下の内容を `.env` ファイルに保存することで、アプリ全体で使用するAPIキーや認証パスを安全に管理します。 ソースコードには直接値を記述せず、この `.env` を通して値を読み込む構成にしています。

# LINE Messaging API トークン(v3対応)
LINE_CHANNEL_ACCESS_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
LINE_CHANNEL_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# OpenAI APIキー(ChatGPT応答用)
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# Googleカレンダーの認証用JSONファイルのパス
GOOGLE_SERVICE_ACCOUNT_JSON=credentials.json

# 登録対象のGoogleカレンダーID(通常は "primary")
GOOGLE_CALENDAR_ID=primary

なお、Googleの認証JSONファイル(例: credentials.json)は、Google Cloud Console で 「サービスアカウントの鍵を発行」し、予定を登録したいカレンダーと共有設定を行ったうえで作成します。

実行結果の確認(LINE→登録完了メッセージ→Googleカレンダー反映)

すべてのコードを正しく貼り付け `.env` の設定も完了したら、実際にLINEからメッセージを送って動作確認を行います。 ここでは、予定を含んだ自然文をLINEで送信し、ボットがGoogleカレンダーに正しく予定を登録できるかを検証します。

LINEでの送信内容

明日15時に歯医者の予約を入れて

LINEからの返信メッセージ(Bot側)

予定『明日15時に歯医者の予約を入れて』を登録しました。

Googleカレンダー側に反映された予定(確認画面)

下記のように、Googleカレンダーに予定が1件登録されていれば成功です。

開始時刻予定名
2025-04-21 15:00明日15時に歯医者の予約を入れて

もし登録されていない、またはLINEからの返信が「登録に失敗しました」などになっている場合は、 以下の確認ポイントを見直してください。

  • LINE Developers でWebhook URLが正しく設定されているか
  • .env 内の GOOGLE_SERVICE_ACCOUNT_JSON や CALENDAR_ID が正しいか
  • credentials.json のサービスアカウントがカレンダーに「予定の編集権限」を持っているか
  • 自然文の中に「日付や時間を示す表現」が含まれているか(例:「明日」「13時」など)

問題がなければ、これであなたのAI執事は「予定を作る」能力を正式に手に入れました。 次回はこの仕組みを土台に、さらに人間らしい対話や調整機能へと進化させていきます。

ソースコードの補足と注意点

このセクションでは、記事で紹介したソースコードにおける注意点と、読者が実装・運用時に理解しておくべきポイントを記載します。

ChatGPTのエラー処理について

ChatGPTとの連携中に発生しうるエラー(特にAPI制限など)に対しては、 try-exceptブロックによるエラーハンドリングが実装されています。

たとえば、以下のようなエラーはChatGPT APIの利用制限(クォータ超過)によって発生します。

❌ ChatGPT応答エラー:Error code: 429 - {'message': 'You exceeded your current quota...'}

このような状況下でも、本システムは「現在AI応答が制限されています。」といった案内文を返し、処理全体が停止することを回避する設計になっています。

【補足】Quota(利用制限)が発生する原因と解消条件

OpenAIのAPIには「Usage Tier(利用階層)」という仕組みが存在し、Tier 1の段階では以下の制限があります。

  • 月間利用量が一定に達すると一時的に制限(エラーコード 429)が発生
  • たとえ残高があっても制限される(段階的リスク管理のため)

これを解除して、より柔軟な利用が可能な「Tier 2」に昇格するには、次の2条件を満たす必要があります。

条件説明
① $50以上の課金実績初回から累計で$50を超える必要があります。
② 初回課金から7日経過課金してすぐには昇格できません。待機期間が必要です。

つまり、$10や$20などの少額課金では、残高があってもTier 1の制限内でしか利用できません。頻繁に開発・テストを行う場合は、最初から$50を超える課金を行っておくことが推奨されます。

詳細については OpenAI公式のUsageページ を確認してください。

.envに記述すべき環境変数一覧

本システムでは、以下の環境変数を .env ファイルに記述して管理します。環境ごとの値を正しく設定しておくことが必須です。

これらが正しく設定されていない場合、システムは正常に動作しません。

変数名用途
OPENAI_API_KEYChatGPTとの連携に使用するAPIキー
GOOGLE_CALENDAR_ID予定の登録・更新・削除を行う対象のGoogleカレンダーID
GOOGLE_SERVICE_ACCOUNT_JSONGoogle APIへの認証に必要なサービスアカウント情報のJSONファイルパス
LINE_CHANNEL_ACCESS_TOKENLINE BOTからの送受信処理に必要なトークン(Messaging API用)
LINE_CHANNEL_SECRETWebhook署名検証用のシークレットキー

各処理の仕組みと工夫

本セクションでは、AI執事ボットが「自然文を受け取って予定登録を行う」までの処理フローと、そこに込められた設計上の工夫を解説します。 ユーザーの負担を最小限に抑えつつ、確実にカレンダー登録まで行うためのロジック構成がテーマです。

自然文をどう処理して日時+予定名を抜き出しているか

LINE経由で送られてくるユーザーの入力は、次のような自然文です:

明日の15時に歯医者の予約を入れて

このメッセージをそのまま ChatGPT に渡すと、ChatGPT は文脈を理解し、 予定登録に必要な2つの要素 ――「予定名」と「日時」―― を返してきます。

予定名: 歯医者の予約
日時: 2025-04-21 15:00:00

このような形式で返ってくることを前提に、アプリ側では次のような処理で値を取り出します:

「予定名: 歯医者の予約」 → title = "歯医者の予約"
「日時: 2025-04-21 15:00:00」 → start_time = "2025-04-21T15:00:00" (ISO形式に変換)

このように、ChatGPTが「予定名」と「日時」を構造的に返す設計にしておくことで、多少ユーザーの文言に揺れがあっても、アプリ側では安定して情報を抽出・登録することができます。

また、この処理では、日付や時刻の抽出を外部ライブラリに依存せず、ChatGPTの構文解析力だけで成立させています。これにより、「明後日の昼」「金曜日の夜8時」「来週の会議」といった、多様な表現にも柔軟に対応できる設計となっています。

たとえば以下のようなカッコ付きの予定が入力された場合:

予定名: 面談(人事部)
日時: 2025-05-01 14:00:00

人間にとっては「面談(人事部)」のような予定名も自然に読めますが、AIにとっては「()」が意味の区切りと誤解される可能性があります。そのため、こうした表現でも正しく予定名を抽出できるよう、返答形式を明確に設計しています。

予定名に「(人事部)」のような補足情報がカッコ付きで含まれている場合でも、ChatGPTからこのように構造的な返答を得ることで、アプリ側では確実に titlestart_time を抽出できます。

このように、予定名が単語だけでなく少し複雑な表現であっても問題なく対応できるよう、あらかじめ ChatGPT の返答形式を明確に設計しておくことが、システムの安定性につながります。 

よくあるエラーと切り分けのコツ

このボットは、LINE・ChatGPT・Google Calendar・自然文解析など複数の要素が連携して動作しているため、 どれか1つが正しく設定されていないだけでも「動かない」「反応がない」という現象が発生します。 ここでは、読者がよく直面するエラーと、その原因の切り分けポイントを整理します。

Googleカレンダーへの書き込み権限を必ず付与してください

サービスアカウントにはデフォルトで読み取り権限しかありません。 予定を追加するには、Googleカレンダー側で明示的に共有設定を行い、 予定の変更権限または 共有の管理権限を与える必要があります。

共有の手順は以下のとおりです:

  1. Googleカレンダーを開く
  2. 左の「マイカレンダー」一覧から対象カレンダーの「︙」→「設定と共有」
  3. 「特定のユーザーと共有」→ サービスアカウントのメールアドレスを追加
  4. 権限を「予定の変更権限」に設定

※ サービスアカウントのメールアドレスは、認証用JSON内の "client_email" に記載されています。

LINE Webhookが反応しない場合

LINEにメッセージを送っても、Botからの返信が全く返ってこない場合、最も可能性が高いのがWebhook周りの設定ミスです。 以下の項目を確認してください。

  • Webhook URLがLINE Developersに正しく登録されているか
  • Webhook URLがHTTPSで始まっており、SSL証明書が有効か
  • LINEアカウントがBotとの「1:1トーク」で有効になっているか
  • LINE Developersのチャネル設定で「応答メッセージ」が無効化されているか(Botとの二重応答を避けるため)
  • VPSやサーバーでFlaskが正しく起動しているか

Google APIで登録に失敗する場合

LINEから「予定を入れて」と送っても「登録に失敗しました」や応答がない場合、Google API連携が正しく設定されていない可能性があります。 主なチェックポイントは以下のとおりです。

  • credentials.json がサーバー上に存在しているか
  • そのファイルパスが .env の GOOGLE_SERVICE_ACCOUNT_JSON に正しく設定されているか
  • サービスアカウントにカレンダーの「編集権限(共有)」が与えられているか
  • .env の GOOGLE_CALENDAR_ID がカレンダーのIDと一致しているか(通常は "primary")


また、日付の書式が崩れていると Google API 側でエラーが発生することがあります。
ログにエラーメッセージが出力されていれば、スタックトレースも含めて確認してください。

まとめ:AI執事は“実用フェーズ”に入った

ここまでで、AI執事ボットは単なる「ChatGPTとLINEを繋げて喋らせるだけのツール」から脱却し、 自分の予定を管理し、記録し、整える“生活の一部”として機能するフェーズに突入しました。 コードは確かに複雑になりましたが、そのぶん得られる体験はまったく別物です。

自分の手で作った仕組みが日常に機能する喜び

予定が思い浮かんだ瞬間に「LINEで送るだけ」で登録できる。 この体験は、もはや“プログラムを動かす”という感覚ではなく、“自分の暮らしを作る”という実感に近づいてきます。

そしてその仕組みは、あなた自身の手で作られています。 これは「誰かが作ったアプリを使う」のではなく、「自分で作った仕組みが、自分の生活に馴染んでいる」という唯一無二の喜びです。

次回の予告(予定削除・確認応答などの双方向性)

今回の構成は、意図分類→分岐→処理実行という柔軟な土台をすでに備えています。 この構造を活かせば、次は「予定を削除したい」「日付を変更したい」「○○って何時だったっけ?」といった “対話型のスケジューラー”への進化がすぐにでも可能です。

ただし、「予定の変更」については技術的な制約があります。 特に、指定された変更先の時間帯にすでに別の予定が入っている場合、現在の構成では“そのまま上書きする”ことは避け、以下のようなメッセージを返して変更を中止する設計としています。

指定された時間にはすでに『会議』があります。
先に衝突する予定を削除してください。

今後は、LINEのテンプレートメッセージや状態管理を取り入れることで、 「上書きしてもよいかをBotが確認し、ユーザーが応答で判断する」ような双方向の処理も検討可能です。 まずは安全で破綻しない構成をベースに、段階的に進化を続けていきます。

  • ✅ 「〇日の歯医者をキャンセルして」→ 自動で予定を削除
  • ✅ 「今日の予定まとめて教えて」→ ChatGPTで整形されたカレンダー一覧

“便利”を超えて、“頼れる”。 AI執事は、ついにそこまで来ました。

よく読まれている記事

1

IT入門シリーズ 🟢 STEP 1: ITの基礎を知る(ITとは何か?) 📌 IT初心者が最初に学ぶべき基本知識。ITの概念、ネットワーク、OS、クラウドの仕組みを学ぶ ...

2

「私たちが日々利用しているスマートフォンやインターネット、そしてスーパーコンピュータやクラウドサービス――これらの多くがLinuxの力で動いていることをご存じですか?無料で使えるだけでなく、高い柔軟性 ...

3

この記事は、Linuxについて勉強している初心者の方向けに「Shellスクリプト」について解説します。最後まで読んで頂けましたら、Shellスクリプトはどのような役割を担っているのか?を理解出来るよう ...

-Pythonの基礎知識(実践編)