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

## はじめに
> **TL;DR**  
> “タスク管理 = 手間” を変えたくて、Notion と GPTs だけで動くタスク秘書 **TaskMate** を作りました。
この記事では **GPTs プロンプト設計・Notion API アクション定義・内部処理フロー** を中心にまとめます。背景や思想は別記事へ☕️

https://qiita.com/kensuke-higa/items/b18da50b2b6fdb4b41b3

---

## TaskMate とは
|             | 内容 |
|-------------|------|
| **名前**    | TaskMate – Notion連携タスク秘書 |
| **一言**    | “思いついたら話すだけ” でタスクを登録・更新・確認できる GPT |
| **特徴**    | - 音声／自然文入力対応<br>- **サーバーレス** & **スマホ完結**<br>- Notion DB と連携 |

:::note info
**目的**  
ユーザーが “思考の流れ” を止めずにタスク管理できること。  
タスク管理の手間を削減し、楽しく日常にタスク管理を馴染ませる――そんな体験を目指しました。
:::

## システム構成図

```mermaid
flowchart TD
  subgraph User
    A["ユーザー (ChatGPTアプリ)"]
  end
  subgraph GPTs
    B["TaskMate GPT"]
  end
  subgraph Notion
    C["タスクDB"]
  end
  A -- 音声／自然文 --> B
  B -- Notion API --> C
  C -- メタデータ --> B
  B -- 提案／リマインド --> A
```

## 内部処理フロー

```mermaid
sequenceDiagram
  participant U as User
  participant G as GPT(TaskMate)
  participant N as Notion DB

  U->>G: 「お昼ご飯食べなきゃ」
  G->>G: intent=add
  G->>N: createTask(JSON)
  Note right of N: タスク行をINSERT
  N-->>G: created_page_id
  G-->>U: 「追加したよ！👩‍💻」

  U->>G: 「今日やること教えて」
  G->>G: intent=query
  G->>N: getTodos(filter=今日)
  N-->>G: タスクリスト
  G-->>U: 「優先度順で5件どうぞ✨」
```



# 作り方
:::note
APIキーやNotionDBのIDを設定する必要があるため配布はできませんでした。
なのでIT業界への感謝を込めて、作り方をここに全て展開させていただきます。
どうぞお好きに活用ください。
:::

## GPTs作成画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3945028/9f235621-017c-4d62-9821-2c43ada4392a.png)

### 画像、名前
お好きにどうぞ

### 説明
音声や自然文でタスクを登録・更新・今日やることを教えてくれるGPT

### 指示

```text
あなたはユーザーのタスク管理秘書です。

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

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

Notionの連携情報は以下を使用：
- Integration Token: Authenticationで設定済み
- Database ID: 固定で `{連携したいNotionDBのID}`

タスクのDBには以下のプロパティがある。タスク追加時はユーザーから情報を取得し、可能かなぎりプロパティを埋めて登録してください。
- `タイトル`：タイトル
- `ステータス`：待機／未着手／進行中／完了
- `優先度`：高／中／低
- `実施日`：期日
- `作成日時`：自動（created_time）
- `タグ`：セレクト（任意作成可）
- `プロジェクト`：セレクト（任意作成可）

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

---

【アクションの使い方】

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

リクエストには以下の情報を含めます：
- `parent.database_id` には `Database ID` を使う
- `properties.タイトル.title[0].text.content` には、ユーザーの発話から抽出したタスク名を設定する

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

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

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

リクエストには以下の情報を含めます：
- `page_id` は対象タスクのページID
- `properties.ステータス.select.name` に `"完了"` を指定する
- 実施日に今日の日付を指定する
```

ポイントは **“思考の流れ” を乱さない** 出力フォーマット。  
タスク提案時は「優先度＋理由」をワンライナーで返すようにし、ユーザーが即決できる UI にしています。

### 会話のきっかけ
- 今日やること教えて
- タスク追加：コードレビュー
- 未完了のタスクに優先度とタグをつけて
- スマートにできるだけ多くタスク実行したいのでスケジュールを組み立てて

## アクション
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3945028/03e7137e-a571-420a-ba5e-8596c174f177.png)

### 認証
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3945028/f8b49c01-3f19-4a49-a3d4-86a1fce9656c.png)

## 🔑 Notion APIキー（Integration Token）の取得方法

GPTs と Notion を連携するには、**Integration Token** が必要です。  
以下の手順で 3 分で取得できます！

### ✅ 手順

1. **Notion 開発者ページへアクセス**  
　👉 [https://www.notion.com/my-integrations](https://www.notion.com/my-integrations)

2. **「＋ New Integration」ボタンをクリック**

3. 以下の内容で作成：
   - **Integration Name**：任意（例：TaskMate連携）
   - **Associated Workspace**：使用中のワークスペースを選択
   - **Capabilities（権限）**：  
     - ✅ Read content  
     - ✅ Update content  
     - ✅ Insert content  
     - ✅ Read user information

4. 作成完了後、「Internal Integration Token」が表示される  
　→ これが **APIキー**（あとからコピーも可）

5. このキーを GPTs の設定やスクリプトに貼り付けて使う！

### 📌 注意点

- トークンは **個人に紐づいた認証情報**。**他人と共有しないように！**
- 接続したい Notion データベースには、**この Integration を「接続」設定**する必要があります。
  - Notion上でデータベースを開き →右上「...」→「接続」から追加

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3945028/7ce8444a-7c87-4f15-b19d-7fc27b470e13.png)


## スキーマ

<details><summary>長いので折りたたんでいます</summary>

```json
{
  "openapi": "3.1.0",
  "info": {
    "title": "Notion Task API",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://api.notion.com"
    }
  ],
  "paths": {
    "/v1/pages": {
      "post": {
        "summary": "タスクをNotionに追加",
        "operationId": "createTask",
        "parameters": [
          {
            "in": "header",
            "name": "Notion-Version",
            "required": true,
            "schema": {
              "type": "string",
              "example": "2022-06-28"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "parent": {
                    "type": "object",
                    "properties": {
                      "database_id": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "database_id"
                    ]
                  },
                  "properties": {
                    "type": "object",
                    "properties": {
                      "タイトル": {
                        "type": "object",
                        "properties": {
                          "title": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "text": {
                                  "type": "object",
                                  "properties": {
                                    "content": {
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "content"
                                  ]
                                }
                              },
                              "required": [
                                "text"
                              ]
                            }
                          }
                        },
                        "required": [
                          "title"
                        ]
                      }
                    },
                    "required": [
                      "Name"
                    ]
                  }
                },
                "required": [
                  "parent",
                  "properties"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successfully created page"
          }
        }
      }
    },
    "/v1/databases/{database_id}/query": {
      "post": {
        "summary": "今日やるべきタスク一覧を取得",
        "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": {
                "type": "object",
                "properties": {
                  "filter": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "タスク一覧が取得できました"
          }
        }
      }
    },
    "/v1/pages/{page_id}": {
      "patch": {
        "summary": "タスクを更新する",
        "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": {
                "type": "object",
                "properties": {
                  "properties": {
                    "type": "object",
                    "properties": {
                      "ステータス": {
                        "type": "object",
                        "properties": {
                          "status": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "name"
                            ]
                          }
                        },
                        "required": [
                          "select"
                        ]
                      }
                    },
                    "required": [
                      "ステータス"
                    ]
                  }
                },
                "required": [
                  "properties"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "更新成功"
          }
        }
      }
    }
  }
}
```

</details>

---

おしまい。
ここまでの内容を入力したら使用可能な状態になっているはずです。


## まとめ
 **TaskMate** により、タスク管理が真に意味のある行為になるはずです。
サーバー不要＆スマホ完結の GPTs だからこそ、"タスク管理"を日常に馴染ませることができるはず。  

もしタスク管理したいけど更新が面倒 という方がいたら、ぜひ **TaskMate** の仕組みごと持っていってください!!
少しでも皆さんの生産性が上がると嬉しいです🙌

---

### 参考
- Notion API docs <https://developers.notion.com/>