Notion APIでメモ管理を作ったら、最初の壁はコードではなくデータベースIDでした

Notion APIでメモを送るだけなら簡単だと思っていました。

実際には、最初の40分をデータベースID探しに使いました。コードを書く前に迷子です。しかも原因は、URLのどこを見ればいいか分かっていなかっただけでした。

夜中にコーヒーを飲みながら、長いURLを3回見直す時間は、なかなか地味です。

目次

作りたかったもの

作りたかったのは、Pythonから短いメモをNotionのデータベースへ追加する仕組みです。

ObsidianのようにローカルMarkdownで書くのも好きですが、スマホから見るならNotionは便利です。そこで、技術メモの要点だけをNotionへ送る小さな入口を作りました。

最初から同期システムを作る気はありません。まずは1件追加できれば勝ちです。

事前準備で必要な3つ

必要なのは、Notionのインテグレーショントークン、データベースID、対象データベースへの接続です。

ここで3つ目を忘れると、コードが正しくても403で落ちます。私はここで15分使いました。

Notion側でインテグレーションを作り、対象データベースに接続しておきます。トークンは環境変数に入れます。

$env:NOTION_TOKEN="secret_xxxxxxxxx"
$env:NOTION_DATABASE_ID="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

実際の値は画面上で確認してください。チャットや記事に本物の値を書く必要はありません。

動く最小コード

Pythonから1件追加するコードです。

import os
import requests


NOTION_VERSION = "2022-06-28"


def create_note(title: str, body: str) -> dict:
    token = os.environ["NOTION_TOKEN"]
    database_id = os.environ["NOTION_DATABASE_ID"]

    headers = {
        "Authorization": f"Bearer {token}",
        "Notion-Version": NOTION_VERSION,
        "Content-Type": "application/json",
    }
    payload = {
        "parent": {"database_id": database_id},
        "properties": {
            "Name": {
                "title": [{"text": {"content": title}}],
            },
        },
        "children": [
            {
                "object": "block",
                "type": "paragraph",
                "paragraph": {
                    "rich_text": [{"text": {"content": body}}],
                },
            }
        ],
    }

    response = requests.post(
        "https://api.notion.com/v1/pages",
        headers=headers,
        json=payload,
        timeout=20,
    )

    # ハマりポイント: 403と400は本文にかなり重要な理由が出る
    if response.status_code >= 400:
        raise RuntimeError(f"{response.status_code}: {response.text}")

    return response.json()


if __name__ == "__main__":
    created = create_note("APIメモ", "Pythonから追加したメモです。")
    print(created["id"])

まずはこれで1件入るかを見ます。タグや日付は後でいいです。

4つのつまずき

1つ目は、データベースIDです。URLの中にある長い文字列を使いますが、ビューIDなど別のIDと混同しやすいです。

2つ目は、データベースへの接続忘れです。インテグレーションを作っただけでは足りません。対象データベースで接続する必要があります。

3つ目は、プロパティ名です。コードでは "Name" と書いていますが、Notion側のタイトル列名が違えば落ちます。ここは自分のデータベースに合わせます。

4つ目は、メモ本文を長くしすぎたことです。最初から長文や複数ブロックを送ると、どこで失敗したか分かりにくくなります。最初は1段落だけが安全です。

メモ管理にしてよかったこと

APIで送れるようになると、メモの入口が増えます。

Pythonスクリプトから送る。ログの要点だけ送る。あとで読むURLだけ送る。手入力では続かないことも、1コマンドなら続く可能性が上がります。

ただし、Notionを万能倉庫にしないことも大事です。何でも入れると、あとで探せません。私は「あとで読む」「技術メモ」「エラー対処」の3種類に絞りました。

1週間後に検索できる形で残す

メモは、入れる瞬間より探す瞬間に価値が決まります。

私は最初、タイトルに「メモ」「気づき」「あとで」ばかり付けていました。1週間後に検索すると、同じようなタイトルが12件並びます。これはかなりつらいです。

そこで、タイトルの型を決めました。

[分類] 具体名 - 何が分かったか

例:
[Python] CSV - utf-8-sigでBOMを避ける
[API] Notion - 403はDB接続を確認する
[自動化] Playwright - sleepよりexpectを使う

この型にすると、一覧で内容が見えます。Notionは見た目がきれいなので、つい整った気になります。でも、検索できなければメモは沈みます。

APIで追加するなら、コード側でタイトルの型を強制してもいいです。

def build_title(category: str, topic: str, lesson: str) -> str:
    # ハマりポイント: あいまいな「メモ」だけのタイトルを作らない
    return f"[{category}] {topic} - {lesson}"

小さな制約ですが、30件を超えたあたりから効いてきます。

まとめ

Notion APIの最初の壁は、難しいコードではありません。

トークン、データベースID、接続権限、プロパティ名。この4つが合っていれば、1件追加はかなり素直に動きます。

メモ管理で大事なのは、完璧な整理術ではなく、忘れる前に1件残せる入口です。

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

この記事を書いた人

コメント

コメントする

目次