💬

GPTs × Notion API で実現する“会話型プロジェクト管理”

に公開

前提

  • ChatGPTは有料版アカウントを用意してください。
  • Notionも有料版を使用していますが、無料プランでの代替方法も最後に紹介します。

導入:なぜChatGPT(GPTs)とNotionを組み合わせるのか

  • チームでNotionを使って工程管理をしていても、「更新のし忘れ」や「登録の手間」が課題になることがあります。
  • GPTsを“自然言語の操作インターフェース”として使えるようにすれば、「終わった」「明日からにして」と話すだけでタスクを更新できるようになります。
  • この記事は、チームでNotionを使って工程管理をしている方や、GPTsで業務自動化を試してみたい方に向けた内容です。
  • ここでは、GPTsからNotionの工程管理を直接操作できるようにする方法を紹介します。

全体アーキテクチャ

手順

Notion API 設定 / GPTs 設定

まずは以下の記事を参考に、Notion APIをGPTsで使えるように設定します。

NotionDBにレコード新規作成、編集、取得できるGPTsを作った - Qiita

ChatGPT(GPTs)設定

  • GPTsの「アクション」機能を使います。
  • NotionのIntegration Tokenを接続しておきます。
  • 以下のようなシステムプロンプトを設定します。
あなたはユーザーのタスク管理秘書です。
ユーザーの自然な言葉からタスクを解釈して、
Notionのデータベースに対してタスクの作成・更新・取得を行ってください。
  • 主なアクション
    • createTask:タスクの追加
    • updateTask:ステータスや日付を更新
    • getTodos:今日のやることを取得
システムプロンプト全文
あなたはユーザーのタスク管理秘書です。

ユーザーの自然な言葉からタスクを解釈して、Notionの指定されたデータベースに対して以下の操作を行ってください:

1. タスクの新規作成
2. タスクの進捗更新
3. 「今日やることは?」などの質問に、タスクを優先度付きで返す

Notionの連携情報は以下を使用:
- Integration Token: Authenticationで設定済み
- Database ID: 固定で `自分のデータベースIDを入力`

タスクのDBには以下のプロパティがある。タスク追加時はユーザーから情報を取得し、可能なかぎりプロパティを埋めて登録してください。
- `名前`:タスクの名前
- `ステータス`:未着手/進行中/完了
- `選択`:セレクト(任意作成可、未指定の場合は`メイン`を設定する)
- `日付`:期日
- `作成日時`:自動(created_time)
- `サブタスク`:リレーション(子タスクのページを関連付ける)

目的は、ユーザーが思いついたこと・完了したことを自然に話すだけでタスク管理が完結するようにすることです。
---

【アクションの使い方】

■ タスク追加:`createTask`
もしユーザーが「◯◯しなきゃ」「やることあること教えて」といった発話をした場合は、
Notionにタスクを追加するために `createTask` アクションを使ってください。

リクエストには以下の情報を含めます:
- `parent.database_id` には `Database ID` を使う
- `properties.名前.title[0].text.content` には、ユーザーの発話から抽出したタスク名を設定する
- `properties.選択.select.name` には必ず Notion のセレクト名を設定し、ユーザー指定が無い場合はデフォルトで `メイン` を選択する。

■ タスク取得:`getTodos`
ユーザーが「今日やることは?」「今やるべきタスクある?」などと発話した場合は、
`getTodos` アクションを使って、ステータスが「未着手」または「進行中」のタスク一覧を取得してください。また、常にサブタスクの中身も表示してください。

必要に応じて、Notion APIの `filter` を使って以下の条件を指定してください:
- `ステータス` が「完了」以外
- `日付` が今日または空欄
- `サブタスク`が「完了」以外

■ タスク更新:`updateTask`
ユーザーが「◯◯終わったよ」「完了した」などと発話した場合は、
タスク名が一致するページを取得し、該当タスクの `ステータス` を「完了」に更新するために `updateTask` アクションを使ってください。

リクエストには以下の情報を含めます:
- `page_id` は対象タスクのページID
- `properties.ステータス.select.name``"完了"` を指定する
- 親タスクの開始日を変更した場合は、`properties.サブタスク.relation` から関連ページIDを取得し、それぞれのサブタスクに対して `updateTask` を呼び出して `properties.日付.date.start` を親タスクと同じ日付に更新する(終了日 `end` が設定されている場合は期間を維持するよう再計算する)
- サブタスクのタイトルやサブタイトルに開始日を含めている場合は、文字列内の日付も新しい開始日に合わせて書き換える

Notion API(OpenAPIスキーマ)

GPTsがNotionを操作するためのOpenAPIスキーマを用意します。
以下、一部抜粋

{
  "paths": {
    "/v1/pages": {
      "post": {
        "summary": "タスクを Notion に追加する",
        "operationId": "createTask"
      }
    },
    "/v1/pages/{page_id}": {
      "patch": {
        "summary": "タスクを更新する",
        "operationId": "updateTask"
      }
    },
    "/v1/databases/{database_id}/query": {
      "post": {
        "summary": "今日やるべきタスク一覧を取得する",
        "operationId": "getTodos"
      }
    }
  }
}
OpenAPIスキーマ全文
{
  "openapi": "3.1.0",
  "info": {
    "title": "Notion Task API",
    "version": "1.1.0",
    "description": "Notion タスク管理秘書用アクションの OpenAPI スキーマ。ユーザー指示に基づき、タスクの作成・取得・更新を行う。"
  },
  "servers": [
    {
      "url": "https://api.notion.com",
      "description": "Notion Public API"
    }
  ],
  "paths": {
    "/v1/pages": {
      "post": {
        "summary": "タスクを Notion に追加する",
        "description": "指定されたデータベースに新しいタスクページを作成する。`properties.選択.select.name` には必ずプロジェクト名を設定し、ユーザー指定が無い場合は `メイン` を選択する。日付・時間プロパティは任意で、後から更新できる。",
        "operationId": "createTask",
        "parameters": [
          {
            "in": "header",
            "name": "Notion-Version",
            "required": true,
            "schema": {
              "type": "string",
              "example": "2022-06-28"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTaskRequest"
              },
              "examples": {
                "basic": {
                  "summary": "最小限の入力",
                  "value": {
                    "parent": {
                      "database_id": "{{databaseId}}"
                    },
                    "properties": {
                      "名前": {
                        "title": [
                          {
                            "text": {
                              "content": "ああああ"
                            }
                          }
                        ]
                      },
                      "ステータス": {
                        "status": {
                          "name": "未着手"
                        }
                      },
                      "選択": {
                        "select": {
                          "name": "メイン"
                        }
                      },
                      "日付": {
                        "date": {
                          "start": "{{startDateTime}}",
                          "end": "{{endDateTime}}"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "ページが作成されました"
          },
          "4XX": {
            "description": "入力エラー。プロパティ名・型を確認してください。"
          },
          "5XX": {
            "description": "Notion API 側でエラーが発生しました。"
          }
        }
      }
    },
    "/v1/databases/{database_id}/query": {
      "post": {
        "summary": "今日やるべきタスク一覧を取得する",
        "description": "ステータスが完了以外、かつ日付が今日または未設定のタスクを取得する。",
        "operationId": "getTodos",
        "parameters": [
          {
            "name": "database_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "Notion-Version",
            "required": true,
            "schema": {
              "type": "string",
              "example": "2022-06-28"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GetTodosRequest"
              },
              "examples": {
                "defaultFilter": {
                  "summary": "完了以外かつ今日が期日のタスクを取得",
                  "value": {
                    "filter": {
                      "and": [
                        {
                          "property": "ステータス",
                          "status": {
                            "does_not_equal": "完了"
                          }
                        },
                        {
                          "or": [
                            {
                              "property": "日付",
                              "date": {
                                "equals": "{{targetDate}}"
                              }
                            },
                            {
                              "property": "日付",
                              "date": {
                                "is_empty": true
                              }
                            }
                          ]
                        }
                      ]
                    },
                    "sorts": [
                      {
                        "property": "日付",
                        "direction": "ascending"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "タスク一覧が取得できました"
          },
          "4XX": {
            "description": "入力パラメータが不正です。"
          },
          "5XX": {
            "description": "Notion API 側でエラーが発生しました。"
          }
        }
      }
    },
    "/v1/pages/{page_id}": {
      "patch": {
        "summary": "タスクを更新する",
        "description": "対象タスクのステータスや日付を更新する。",
        "operationId": "updateTask",
        "parameters": [
          {
            "name": "page_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "Notion-Version",
            "required": true,
            "schema": {
              "type": "string",
              "example": "2022-06-28"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateTaskRequest"
              },
              "examples": {
                "completeTask": {
                  "summary": "タスクを完了にし、日付を今日に揃える",
                  "value": {
                    "properties": {
                      "ステータス": {
                        "status": {
                          "name": "完了"
                        }
                      },
                      "日付": {
                        "date": {
                          "start": "{{today}}"
                        }
                      }
                    }
                  }
                },
                "shiftTask": {
                  "summary": "開始日と終了日を 1 週間後ろ倒しする",
                  "value": {
                    "properties": {
                      "日付": {
                        "date": {
                          "start": "{{shiftedStart}}",
                          "end": "{{shiftedEnd}}"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "更新に成功しました"
          },
          "4XX": {
            "description": "入力エラー。プロパティや日付形式を確認してください。"
          },
          "5XX": {
            "description": "Notion API 側でエラーが発生しました。"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Parent": {
        "type": "object",
        "properties": {
          "database_id": {
            "type": "string",
            "description": "タスクを作成するデータベース ID。ユーザー入力や設定値から受け取った値をそのまま指定する。"
          }
        },
        "required": [
          "database_id"
        ],
        "additionalProperties": false
      },
      "RichText": {
        "type": "object",
        "properties": {
          "text": {
            "type": "object",
            "properties": {
              "content": {
                "type": "string"
              }
            },
            "required": [
              "content"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "text"
        ],
        "additionalProperties": false
      },
      "TitleProperty": {
        "type": "object",
        "properties": {
          "title": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RichText"
            },
            "minItems": 1
          }
        },
        "required": [
          "title"
        ],
        "additionalProperties": false
      },
      "SelectProperty": {
        "type": "object",
        "properties": {
          "select": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              }
            },
            "required": [
              "name"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "select"
        ],
        "additionalProperties": false
      },
      "StatusProperty": {
        "type": "object",
        "properties": {
          "status": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              }
            },
            "required": [
              "name"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "status"
        ],
        "additionalProperties": false
      },
      "DateProperty": {
        "type": "object",
        "properties": {
          "date": {
            "type": "object",
            "properties": {
              "start": {
                "type": "string",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}(T.+)?$",
                "description": "開始日。日付または日時(ISO 8601)を許容し、ユーザー入力に応じて設定する。"
              },
              "end": {
                "type": "string",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}(T.+)?$",
                "description": "終了日(任意)。開始日と同様に日付または日時(ISO 8601)を許容し、期間を保つ場合は開始日変更時に合わせて調整する。"
              }
            },
            "required": [
              "start"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "date"
        ],
        "additionalProperties": false
      },
      "CreateTaskProperties": {
        "type": "object",
        "properties": {
          "名前": {
            "$ref": "#/components/schemas/TitleProperty"
          },
          "ステータス": {
            "$ref": "#/components/schemas/StatusProperty"
          },
          "選択": {
            "$ref": "#/components/schemas/SelectProperty"
          },
          "日付": {
            "$ref": "#/components/schemas/DateProperty"
          }
        },
        "required": [
          "名前",
          "ステータス",
          "選択"
        ],
        "additionalProperties": true
      },
      "UpdateTaskProperties": {
        "type": "object",
        "properties": {
          "ステータス": {
            "$ref": "#/components/schemas/StatusProperty"
          },
          "選択": {
            "$ref": "#/components/schemas/SelectProperty"
          },
          "日付": {
            "$ref": "#/components/schemas/DateProperty"
          }
        },
        "additionalProperties": true
      },
      "CreateTaskRequest": {
        "type": "object",
        "properties": {
          "parent": {
            "$ref": "#/components/schemas/Parent"
          },
          "properties": {
            "$ref": "#/components/schemas/CreateTaskProperties"
          }
        },
        "required": [
          "parent",
          "properties"
        ],
        "additionalProperties": false
      },
      "UpdateTaskRequest": {
        "type": "object",
        "properties": {
          "properties": {
            "$ref": "#/components/schemas/UpdateTaskProperties"
          }
        },
        "required": [
          "properties"
        ],
        "additionalProperties": false
      },
      "GetTodosRequest": {
        "type": "object",
        "properties": {
          "filter": {
            "type": "object",
            "description": "Notion API 標準のフィルター構造を使用する。ステータス完了以外・開始日が今日または空欄を指定する。"
          },
          "sorts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "property": {
                  "type": "string"
                },
                "direction": {
                  "type": "string",
                  "enum": [
                    "ascending",
                    "descending"
                  ]
                }
              },
              "required": [
                "property",
                "direction"
              ],
              "additionalProperties": false
            }
          },
          "start_cursor": {
            "type": "string"
          },
          "page_size": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100
          }
        },
        "additionalProperties": false
      }
    }
  }
}

Notion データベース設定(ガントチャート対応)

  • テンプレートを「設計」「開発」「テスト」の3段階に分けます。
  • 親タスク作成時に自動で子タスクが生成されるよう、オートメーションを設定します。

完成予想図

  • オートメーション設定例
    • トリガー:新規ページが作成されたとき
    • アクション:期間を設定。関連するタスクを追加。
dateRange(context("トリガーされた時間"), context("トリガーされた時間").dateAdd(1,"week"))
詳細手順
  1. データベースを作る

  2. オートメーションを有効化(Notion の有料プラン)

  3. データソースを追加(お好みで)

  4. メインとなるテンプレートを作成(手動用、やらなくてもよい)

  5. サブとなるテンプレートを作る。今回は設計、開発、テストの3つ

  6. オートメーションを設定

    トリガー

    実行

    日付は関数を使って

    dateRange(context("トリガーされた時間"), context("トリガーされた時間").dateAdd(1,"week"))
    

    親コンポーネントの日付を参照して作るのもいいかもしれないです。

  7. テンプレートのデフォルトに設定で「新規プロジェクト・テンプレート」をすべてのビューでデフォルトに設定し、タイムラインビューのみで「空白のページ」をデフォルトに設定する。

会話例

ユーザー発話 GPTsの動作
「今日やること教えて」 getTodos → 今日が期限のタスク一覧を返す
「API設計タスクを完了にして」 updateTask → 該当ページのステータスを完了に更新
「新しいプロジェクト『UX改善』を追加して」 createTask → データベースに新タスク作成
細かいテクニック
  • 今日やることをすべて挙げて下さい
    • 日付の範囲に今日が含まれるステータスが完了でないタスクが返る
  • 〇〇という名前でタスクを追加して
  • 〇〇(タスク名)を探した上で期間を明日から開始にして / ステータスを完了にして
    • 親タスクのみを変更
    • タスクを変更するにはPageIDが必要なため、探した上でというプロンプトでPageIDを先に取得する
  • 〇〇(タスク名)を探した上で期間を明日から開始にして / そのサブタスクをすべて完了にして
    • 親タスクとサブタスクも同期して変更する。
    • 親タスクのページIDが取得できていれば個別のサブタスクも変更可能

まとめ

  • GPTsとNotion APIを組み合わせることで、自然言語での工程管理が可能になります。
  • オートメーションやガントチャート設計を工夫することで、「話すだけで進捗管理」 が現実的に運用できます。

余談

GPTsを使った理由として、非エンジニアでも使えるようなGUI上で出来るようにしたかったからです。ChatGPTのApps SDKによりNotionもアプリから簡単に使えるようになりそうですが、実用性を考えるとこのようなデータベース設計とシステムプロンプトの工夫は必要になると思いました。

※ 選択プロパティに対して

作成されたページに新しいサブアイテムを作成し追加したい時、サブアイテムもデータベースのページのためオートメーションが走り作成したサブアイテムに複数のサブアイテムが追加されます。そのためトリガー条件でプロジェクトプロパティ(選択/セレクト)がメインの時のみにし、タイムラインビューのみのテンプレートデフォルトを「空白のページ」などのプロジェクトプロパティがメインでないものに変更しています。また、GPTsからタスクを追加する際にプロジェクトプロパティをメインにすることでオートメーションが走るようにしています。

※ Notion無料会員

ボタンをプロパティに追加し、オートメーションと同じようなことを行ってください

※ Notion MCPとChatGPT(2025/10/10時点の挙動)

  • 現状、Notion側で閲覧、追加、更新の権限は与えられていますがchatgpt側で閲覧権限しか使えませんでした。
    • そのため、 Web上のChatGPTからNotion MCPを用いて今回の目的を達成することはできません
  • エージェントモードとの組み合わせでwebページの自動操作(マウス操作、入力など)が可能ですが、セキュリティ上の理由から不採用としています。
  • ChatGPTからデータベースIDを指定せずに、データベース名で検索したところ、うまくデータベースを見つけられないことが多くありました。
    • ChatGPTのプロジェクト機能でコンテキストを追加することで、
      データベース名検索の精度が向上する可能性があります(未検証)。

参考記事

Notionでページのsub-itemに自動でテンプレートを入れる方法

Discussion