GitBook/Notion集成技能Skill gitbook-notion

GitBook/Notion 集成技能用于管理托管文档平台的内容同步、导出导入、分析数据检索等,支持 GitBook 空间管理和 Notion 数据库集成,适用于文档自动化发布和版本控制。

DevOps 0 次安装 0 次浏览 更新于 2/26/2026

GitBook/Notion 集成技能

与托管文档平台的集成。

功能

  • GitBook 空间管理
  • Notion 数据库集成文档
  • 内容与 Git 同步
  • 导出/导入格式间转换
  • 嵌入和块管理
  • API 文档托管
  • 分析数据检索
  • Webhook 配置

使用方法

当你需要以下操作时,调用此技能:

  • 同步文档到 GitBook 或 Notion
  • 管理托管文档空间
  • 导出内容以进行迁移
  • 配置发布工作流
  • 检索文档分析数据

输入

参数 类型 必需 描述
platform string gitbook, notion
action string sync, export, import, analytics
spaceId string GitBook 空间或 Notion 数据库 ID
sourcePath string 源内容路径
outputPath string 导出内容路径

输入示例

{
  "platform": "gitbook",
  "action": "sync",
  "spaceId": "abc123",
  "sourcePath": "./docs"
}

GitBook 集成

GitBook 配置

# .gitbook.yaml
root: ./docs

structure:
  readme: README.md
  summary: SUMMARY.md

redirects:
  /old-page: /new-page
  /api/v1: /api/v2

SUMMARY.md 结构

# 摘要

## 快速开始

* [介绍](README.md)
* [安装](getting-started/installation.md)
* [快速开始](getting-started/quickstart.md)

## 用户指南

* [配置](user-guide/configuration.md)
* [功能](user-guide/features.md)
  * [认证](user-guide/features/auth.md)
  * [数据管理](user-guide/features/data.md)

## API 参考

* [概述](api/README.md)
* [认证](api/authentication.md)
* [端点](api/endpoints/README.md)
  * [用户](api/endpoints/users.md)
  * [项目](api/endpoints/projects.md)

## 资源

* [FAQ](resources/faq.md)
* [更新日志](CHANGELOG.md)

GitBook API 集成

const GitBook = require('gitbook-api');

class GitBookManager {
  constructor(token) {
    this.client = new GitBook({ token });
  }

  // 列出空间
  async listSpaces(organizationId) {
    return await this.client.spaces.list({
      organizationId
    });
  }

  // 获取空间内容
  async getContent(spaceId) {
    const pages = await this.client.spaces.listPages(spaceId);
    return pages;
  }

  // 更新页面
  async updatePage(spaceId, pageId, content) {
    return await this.client.pages.update(spaceId, pageId, {
      document: {
        markdown: content
      }
    });
  }

  // 创建页面
  async createPage(spaceId, title, content, parentId = null) {
    return await this.client.pages.create(spaceId, {
      title,
      parent: parentId,
      document: {
        markdown: content
      }
    });
  }

  // 从 Git 同步
  async syncFromGit(spaceId, repoUrl, branch = 'main') {
    return await this.client.spaces.sync(spaceId, {
      source: 'github',
      url: repoUrl,
      branch
    });
  }

  // 获取分析数据
  async getAnalytics(spaceId, period = '30d') {
    return await this.client.spaces.getAnalytics(spaceId, {
      period
    });
  }
}

GitBook CI/CD 同步

# .github/workflows/gitbook-sync.yml
name: 同步到 GitBook

on:
  push:
    branches: [main]
    paths:
      - 'docs/**'

jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: 同步到 GitBook
        uses: gitbook/github-action-sync@v1
        with:
          token: ${{ secrets.GITBOOK_TOKEN }}
          space: ${{ secrets.GITBOOK_SPACE_ID }}

Notion 集成

Notion 数据库模式

const notionSchema = {
  database_id: 'abc123',
  properties: {
    'Title': {
      type: 'title',
      title: {}
    },
    'Slug': {
      type: 'rich_text',
      rich_text: {}
    },
    'Category': {
      type: 'select',
      select: {
        options: [
          { name: '指南', color: 'blue' },
          { name: '参考', color: 'green' },
          { name: '教程', color: 'purple' }
        ]
      }
    },
    'Status': {
      type: 'status',
      status: {
        options: [
          { name: '草稿', color: 'gray' },
          { name: '审核', color: 'yellow' },
          { name: '已发布', color: 'green' }
        ]
      }
    },
    'Last Updated': {
      type: 'last_edited_time',
      last_edited_time: {}
    },
    'Author': {
      type: 'people',
      people: {}
    },
    'Tags': {
      type: 'multi_select',
      multi_select: {
        options: []
      }
    }
  }
};

Notion API 集成

const { Client } = require('@notionhq/client');

class NotionDocsManager {
  constructor(token) {
    this.notion = new Client({ auth: token });
  }

  // 查询文档页面
  async queryDocs(databaseId, filter = {}) {
    const response = await this.notion.databases.query({
      database_id: databaseId,
      filter: {
        and: [
          { property: 'Status', status: { equals: 'Published' } },
          ...Object.entries(filter).map(([prop, value]) => ({
            property: prop,
            [typeof value === 'string' ? 'rich_text' : 'select']: {
              equals: value
            }
          }))
        ]
      },
      sorts: [
        { property: 'Last Updated', direction: 'descending' }
      ]
    });

    return response.results;
  }

  // 获取页面内容
  async getPageContent(pageId) {
    const blocks = await this.notion.blocks.children.list({
      block_id: pageId
    });

    return this.blocksToMarkdown(blocks.results);
  }

  // 创建文档页面
  async createDocPage(databaseId, title, content, properties = {}) {
    const blocks = this.markdownToBlocks(content);

    return await this.notion.pages.create({
      parent: { database_id: databaseId },
      properties: {
        'Title': {
          title: [{ text: { content: title } }]
        },
        'Slug': {
          rich_text: [{ text: { content: this.slugify(title) } }]
        },
        'Status': {
          status: { name: 'Draft' }
        },
        ...properties
      },
      children: blocks
    });
  }

  // 更新页面
  async updatePage(pageId, content) {
    // 清除现有块
    const existing = await this.notion.blocks.children.list({
      block_id: pageId
    });

    for (const block of existing.results) {
      await this.notion.blocks.delete({ block_id: block.id });
    }

    // 添加新块
    const blocks = this.markdownToBlocks(content);
    await this.notion.blocks.children.append({
      block_id: pageId,
      children: blocks
    });
  }

  // 将 Notion 块转换为 Markdown
  blocksToMarkdown(blocks) {
    let markdown = '';

    for (const block of blocks) {
      switch (block.type) {
        case 'paragraph':
          markdown += this.richTextToMarkdown(block.paragraph.rich_text) + '

';
          break;
        case 'heading_1':
          markdown += '# ' + this.richTextToMarkdown(block.heading_1.rich_text) + '

';
          break;
        case 'heading_2':
          markdown += '## ' + this.richTextToMarkdown(block.heading_2.rich_text) + '

';
          break;
        case 'heading_3':
          markdown += '### ' + this.richTextToMarkdown(block.heading_3.rich_text) + '

',
          break;
        case 'bulleted_list_item':
          markdown += '- ' + this.richTextToMarkdown(block.bulleted_list_item.rich_text) + '
';
          break;
        case 'numbered_list_item':
          markdown += '1. ' + this.richTextToMarkdown(block.numbered_list_item.rich_text) + '
';
          break;
        case 'code':
          markdown += '```' + block.code.language + '
';
          markdown += this.richTextToMarkdown(block.code.rich_text);
          markdown += '

'; break; case ‘quote’: markdown += '> ’ + this.richTextToMarkdown(block.quote.rich_text) + ’

'; break; case ‘callout’: markdown += '> ’ + block.callout.icon?.emoji + ’ '; markdown += this.richTextToMarkdown(block.callout.rich_text) + ’

'; break; } }

return markdown;

}

// 将 Markdown 转换为 Notion 块 markdownToBlocks(markdown) { const blocks = []; const lines = markdown.split(’ ');

let i = 0;
while (i < lines.length) {
  const line = lines[i];

  if (line.startsWith('# ')) {
    blocks.push({
      type: 'heading_1',
      heading_1: { rich_text: [{ text: { content: line.slice(2) } }] }
    });
  } else if (line.startsWith('## ')) {
    blocks.push({
      type: 'heading_2',
      heading_2: { rich_text: [{ text: { content: line.slice(3) } }] }
    });
  } else if (line.startsWith('### ')) {
    blocks.push({
      type: 'heading_3',
      heading_3: { rich_text: [{ text: { content: line.slice(4) } }] }
    });
  } else if (line.startsWith('```')) {
    const lang = line.slice(3);
    let code = '';
    i++;
    while (i < lines.length && !lines[i].startsWith('```')) {
      code += lines[i] + '

‘; i++; } blocks.push({ type: ‘code’, code: { language: lang || ‘plain text’, rich_text: [{ text: { content: code.trim() } }] } }); } else if (line.startsWith(’- ')) { blocks.push({ type: ‘bulleted_list_item’, bulleted_list_item: { rich_text: [{ text: { content: line.slice(2) } }] } }); } else if (/^\d+. /.test(line)) { blocks.push({ type: ‘numbered_list_item’, numbered_list_item: { rich_text: [{ text: { content: line.replace(/^\d+. /, ‘’) } }] } }); } else if (line.trim()) { blocks.push({ type: ‘paragraph’, paragraph: { rich_text: [{ text: { content: line } }] } }); }

  i++;
}

return blocks;

} }


### Notion 导出脚本

```javascript
async function exportNotionToMarkdown(databaseId, outputDir) {
  const manager = new NotionDocsManager(process.env.NOTION_TOKEN);
  const pages = await manager.queryDocs(databaseId);

  for (const page of pages) {
    const title = page.properties.Title.title[0].plain_text;
    const slug = page.properties.Slug.rich_text[0]?.plain_text || slugify(title);
    const category = page.properties.Category.select?.name || 'uncategorized';

    const content = await manager.getPageContent(page.id);

    const frontMatter = `---
title: ${title}
notion_id: ${page.id}
last_updated: ${page.last_edited_time}
---

`;

    const filePath = path.join(outputDir, category, `${slug}.md`);
    await fs.mkdir(path.dirname(filePath), { recursive: true });
    await fs.writeFile(filePath, frontMatter + content);
  }
}

分析

GitBook 分析

async function getGitBookAnalytics(spaceId) {
  const analytics = await gitbook.getAnalytics(spaceId, '30d');

  return {
    pageViews: analytics.pageViews,
    uniqueVisitors: analytics.uniqueVisitors,
    topPages: analytics.topPages.map(p => ({
      path: p.path,
      views: p.views
    })),
    searchQueries: analytics.searches.map(s => ({
      query: s.query,
      count: s.count,
      noResults: s.noResults
    }))
  };
}

工作流程

  1. 配置 - 设置 API 凭证
  2. 连接 - 链接 Git 仓库或 Notion 数据库
  3. 同步 - 推送/拉取内容更改
  4. 发布 - 部署到托管平台
  5. 监控 - 跟踪分析和使用情况

依赖关系

{
  "devDependencies": {
    "@notionhq/client": "^2.2.0",
    "gitbook-api": "^0.8.0",
    "gray-matter": "^4.0.0"
  }
}

CLI 命令

# 从 Notion 导出
node scripts/notion-export.js --database abc123 --output ./docs

# 同步到 GitBook
gitbook sync ./docs --space abc123

# 导入到 Notion
node scripts/notion-import.js --input ./docs --database abc123

应用的最佳实践

  • 在 Git 中保持真相来源
  • 在合并到主线时同步
  • 使用一致的 Slug 模式
  • 跟踪页面分析
  • 设置 Webhook 以实现自动化
  • 优雅地处理速率限制

参考

目标流程

  • knowledge-base-setup.js
  • docs-versioning.js
  • content-strategy.js