kt-tech.blog

画像

【実践】Notion API × Claude Code で自動テックブログを構築する

Share
💡
Notion APIとClaude Codeを組み合わせて、開発セッションの内容を自動でNotionに保存するシステムを構築します。データベース設計からAPI連携まで、実践的な実装方法を解説します。

はじめに

開発中に得た知見やトラブルシューティングの内容を記録したいと思っても、手動でメモを取るのは面倒です。Claude Codeで開発しながら、その内容を自動でNotionに記事として保存できたら便利ですよね。

この記事では、Notion APIを使ってClaude Codeから直接Notionにコンテンツを作成するシステムの構築方法を解説します。

この記事でわかること

  • Notion Integrationの作成と認証設定

  • テックブログ用データベースの設計とプロパティ構成

  • Notion APIでページを作成する方法(ブロック構造の理解)

  • リッチコンテンツ(見出し、コード、Callout)の追加方法

  • Claude Codeからの自動連携の実装パターン

対象読者

  • Notion APIを使ったことがない方

  • Claude Codeで自動化を試みたい方

  • 技術ブログの執筆を効率化したい方

前提条件

  • Notionアカウント(無料プランでOK)

  • Claude Codeがインストール済み

  • curlまたはHTTPクライアントの基本的な知識

システム全体像

まず、構築するシステムの全体像をmermaidで確認しましょう。

flowchart LR
    A[Claude Code] -->|API Call| B[Notion API]
    B -->|Create| C[Database]
    B -->|Create| D[Page]
    D -->|Contains| E[Blocks]
    
    subgraph Notion
        C
        D
        E
    end
    
    subgraph Block_Types
        E --> F[Heading]
        E --> G[Paragraph]
        E --> H[Code]
        E --> I[Callout]
    end

Step 1: Notion Integrationの作成

1-1. Integration作成ページにアクセス

Notion APIを使用するには、まずIntegration(統合)を作成する必要があります。

  1. https://www.notion.so/my-integrations にアクセス

  2. 「新しいインテグレーション」をクリック

  3. 名前を入力(例: claude_code_integration)

  4. 関連付けるワークスペースを選択

1-2. 権限設定

⚙️
必要な権限: • コンテンツを読み取る • コンテンツを挿入 • コンテンツを更新

1-3. シークレットトークンの取得

Integrationを作成すると、シークレットトークン(ntn_xxx…)が発行されます。このトークンは一度しか表示されないので、安全な場所に保存してください。

# 環境変数として設定(推奨)
export NOTION_API_TOKEN="ntn_xxxxxxxxxxxxx"

1-4. ページへの接続

⚠️
重要: Integrationを作成しただけでは、ページにアクセスできません! Notionで対象ページを開き、右上の「…」→「接続」から作成したIntegrationを追加する必要があります。

Step 2: データベース設計

2-1. テックブログ用プロパティ

技術記事を管理するのに適したプロパティ構成を設計します。

erDiagram
    TECH_ARTICLES {
        title Title PK
        multi_select Tags
        select Category
        select Status
        date Created
    }

2-2. カテゴリの選択肢

  • トラブルシューティング - エラー解決、デバッグ記録

  • 設定・環境構築 - 開発環境、ツール設定

  • 実装 - 機能開発、コーディング

  • 設計 - アーキテクチャ、設計パターン

  • 学習メモ - 新しい技術、概念の学び

2-3. APIでデータベースを作成

curl -X POST "https://api.notion.com/v1/databases" \
  -H "Authorization: Bearer $NOTION_API_TOKEN" \
  -H "Notion-Version: 2022-06-28" \
  -H "Content-Type: application/json" \
  -d '{
    "parent": {"page_id": "親ページのID"},
    "title": [{"text": {"content": "Tech Articles"}}],
    "properties": {
      "Title": {"title": {}},
      "Tags": {
        "multi_select": {
          "options": [
            {"name": "React", "color": "blue"},
            {"name": "TypeScript", "color": "blue"}
          ]
        }
      },
      "Category": {
        "select": {
          "options": [
            {"name": "実装", "color": "purple"},
            {"name": "設計", "color": "orange"}
          ]
        }
      },
      "Status": {
        "select": {
          "options": [
            {"name": "Draft", "color": "gray"},
            {"name": "Published", "color": "green"}
          ]
        }
      },
      "Created": {"date": {}}
    }
  }'

Step 3: ページ作成の実装

3-1. API呼び出しのシーケンス

Notion APIでページを作成する流れを図解します。

sequenceDiagram
    participant C as Claude Code
    participant A as Notion API
    participant D as Database
    participant P as Page
    
    C->>A: POST /pages
    A->>D: Validate parent
    A->>P: Create page
    A->>P: Add blocks
    A-->>C: Return page object

3-2. プロパティとブロックの指定

const pageData = {
  parent: { database_id: "データベースID" },
  icon: { type: "emoji", emoji: "📝" },
  cover: {
    type: "external",
    external: { url: "https://images.unsplash.com/..." }
  },
  properties: {
    Title: { title: [{ text: { content: "記事タイトル" } }] },
    Tags: { multi_select: [{ name: "React" }] },
    Category: { select: { name: "実装" } },
    Status: { select: { name: "Published" } },
    Created: { date: { start: "2026-01-19" } }
  },
  children: [
    // ブロックの配列(後述)
  ]
};

3-3. 主要なブロックタイプ

Notionのコンテンツは「ブロック」の集まりです。主要なブロックタイプを紹介します。

📌
見出し(heading_2, heading_3)
{
  "type": "heading_2",
  "heading_2": {
    "rich_text": [{ "text": { "content": "セクションタイトル" } }]
  }
}
💻
コードブロック(code)- 言語指定が可能
{
  "type": "code",
  "code": {
    "rich_text": [{ "text": { "content": "console.log('Hello');" } }],
    "language": "typescript"
  }
}
💡
Callout(強調ボックス)- アイコンと背景色を指定
{
  "type": "callout",
  "callout": {
    "rich_text": [{ "text": { "content": "重要なポイント" } }],
    "icon": { "type": "emoji", "emoji": "💡" },
    "color": "blue_background"
  }
}

Step 4: 実践的な記事作成

4-1. Zenn/Qiita品質のテンプレート

const articleBlocks = [
  // 概要Callout
  {
    type: "callout",
    callout: {
      rich_text: [{ text: { content: "この記事の概要..." } }],
      icon: { type: "emoji", emoji: "💡" },
      color: "blue_background"
    }
  },
  // 目次
  { type: "table_of_contents", table_of_contents: { color: "gray" } },
  // はじめに
  { type: "heading_2", heading_2: { rich_text: [{ text: { content: "はじめに" } }] } },
  { type: "paragraph", paragraph: { rich_text: [{ text: { content: "背景説明..." } }] } },
  // この記事でわかること
  { type: "heading_2", heading_2: { rich_text: [{ text: { content: "この記事でわかること" } }] } },
  { type: "bulleted_list_item", bulleted_list_item: { rich_text: [{ text: { content: "学べること1" } }] } },
  // ... 続く
];

Tips: よくあるエラーと対処法

1️⃣
  1. 「Could not find database」エラー → Integrationがページに接続されていない。Notionで「接続」を追加する。
2️⃣
  1. 「Invalid request」エラー → JSONの構造が間違っている。特にrich_textは配列である必要がある。
3️⃣
  1. 「Unauthorized」エラー → トークンが正しくない、または期限切れ。再発行を検討。

参考リンク

まとめ

  • Notion Integrationを作成し、対象ページに接続する

  • データベースは適切なプロパティ(Title, Tags, Category, Status, Created)で設計

  • ページ作成はproperties(メタデータ)とchildren(ブロック)で構成

  • ブロックタイプを理解すれば、リッチなコンテンツが作成可能

次のステップとして、Claude Code Skillsと組み合わせることで、開発セッションの内容を自動で記事化するシステムを構築できます。