Skip to content

Latest commit

 

History

History
235 lines (175 loc) · 6.94 KB

File metadata and controls

235 lines (175 loc) · 6.94 KB

notion2md

将 Notion 页面和数据库导出为本地 Markdown 文件,支持增量更新和附件下载。

特性

  • 增量同步 — 仅导出上次同步后有变更的页面,无需每次全量重新开始
  • 流式写入--all 模式下边获取边写入,无需等待全部完成
  • 附件下载 — 自动下载图片、PDF、文件等附件到本地,Markdown 中使用相对路径引用
  • 数据库按目录分组 — 数据库的每条记录生成独立 .md 文件,统一放在数据库名称的子目录下
  • data_source API — 支持 Notion 2025-09-03+ 新 API
  • 速率限制 — 自动遵守 Notion 3 req/s 限制,429 响应自动重试
  • file_upload 解析 — 自动解析 Notion 新版文件上传类型,获取临时下载链接
  • 20+ Block 类型 — 支持段落、标题、列表、代码、引用、表格、数学公式、Callout、Toggle 等

安装

go install github.com/luoshuhui/notion2md@latest

或从源码构建:

git clone https://github.com/luoshuhui/notion2md.git
cd notion2md
go build -o notion2md .

前置条件

  1. 创建 Notion Integration:https://www.notion.so/my-integrations
  2. 获取 Integration Token(以 ntn_secret_ 开头)
  3. 在 Notion 中将 Integration 添加到要导出的页面/数据库(页面右上角 ··· → Connections → 添加你的 Integration)

快速开始

# 方式一:通过 .env 文件配置(推荐)
echo 'NOTION_TOKEN=ntn_your_token_here' > .env

# 方式二:通过环境变量配置
export NOTION_TOKEN="ntn_your_token_here"

# 列出可访问的页面和数据库
notion2md list

# 导出指定页面
notion2md sync -p <PAGE_ID>

# 导出指定数据库
notion2md sync -d <DATABASE_ID>

# 导出所有可访问内容
notion2md sync --all

# 增量导出(默认模式,仅导出变更部分)
notion2md sync -p <PAGE_ID>

使用说明

notion2md list

列出 Integration 可访问的所有页面和数据库。

notion2md list
notion2md list --ids-only    # 仅输出 ID,便于脚本处理

输出示例:

Found 5 accessible resources:

1. 📄 项目文档
   ID: abc123def456-...
   Type: page
   URL: https://notion.so/...

2. 📊 任务跟踪
   ID: 789ghi012-...
   Type: database
   URL: https://notion.so/...

notion2md sync

将 Notion 内容同步导出为本地 Markdown 文件。

notion2md sync [flags]
Flag 环境变量 默认值 说明
--token NOTION_TOKEN (必填) Notion Integration Token
--base-url NOTION_BASE_URL https://api.notion.com API 基地址(用于代理)

配置优先级:命令行 flag > 环境变量 > .env 文件

在当前目录创建 .env 文件即可自动加载:

NOTION_TOKEN=ntn_your_token_here
NOTION_BASE_URL=https://api.notion.com   # 可选
Flag 默认值 说明
-o, --output ./notion-export 输出目录
--mode incremental 同步模式:fullincremental
-p, --page 页面 ID(可重复指定多个)
-d, --database 数据库 ID(可重复指定多个)
--all false 导出所有可访问内容
--download-images true 下载图片到本地
--download-files true 下载 PDF/文件到本地
-v, --verbose false 启用调试日志

至少需要指定 --page--database--all 之一。

示例:

# 全量导出指定页面
notion2md sync -p abc123def456 --mode full

# 增量导出多个页面
notion2md sync -p page1 -p page2 -p page3

# 导出所有内容到指定目录
notion2md sync --all -o ~/notion-backup

# 仅导出 Markdown,不下载附件
notion2md sync -p abc123 --download-images=false --download-files=false

# 启用调试日志
notion2md sync --all -v

notion2md status

查看同步状态信息。

notion2md status
notion2md status -o /path/to/output

输出示例:

=== Notion2md Sync State ===
Output directory: ./notion-export
State file: ./notion-export/.notion2md/sync-state.json
Total pages tracked: 23
Total syncs: 5
Last sync: 2026-05-26 14:30:00
Last full sync: 2026-05-25 09:00:00

notion2md reset-state

重置同步状态,下次运行将执行全量同步。

notion2md reset-state --force

输出结构

notion-export/                        # 输出目录
  .notion2md/
    sync-state.json                   # 增量同步状态(自动管理)
  项目文档.md                          # 页面 → Markdown 文件
  项目文档/
    screenshot.png                    # 该页面的图片附件
    design-spec.pdf                   # 该页面的文件附件
  ReadItLater/                        # 数据库 → 以数据库名命名的子目录
    某篇文章标题.md                    # 每条记录独立 Markdown 文件
    另一篇文章标题.md
    ...
  另一个数据库/
    记录1.md
    记录2.md
  独立页面.md
  独立页面/
    photo.jpg
  • 普通页面生成一个 .md 文件,附件存放在同名子目录中
  • 数据库的每条记录生成独立 .md 文件,统一放在数据库名称的子目录下
  • Markdown 中使用相对路径引用附件(如 ./项目文档/screenshot.png),离线可用
  • 同步状态保存在 .notion2md/sync-state.json 中,删除输出目录即重新开始

增量同步原理

  1. 首次运行执行全量同步,记录每个页面的 last_edited_time
  2. 后续运行调用 Notion Search API 获取所有页面的最新 last_edited_time
  3. 逐页对比时间戳,仅对变更的页面重新获取内容
  4. 数据库级别的增量:检测到数据库变更时,逐记录对比时间,仅重新获取变更的记录
  5. 自动检测删除:上轮存在但本轮消失的页面标记为已删除,本地文件同步移除
首次同步:  全量导出 100 页         → 100 个 Markdown 文件
增量同步:  仅 3 页有变更           → 只重写 3 个文件,97 个跳过

代理配置

如需通过代理访问 Notion API:

export NOTION_BASE_URL="https://your-proxy.example.com"
notion2md sync --all

与 WeKnora 的关系

本项目从 WeKnora 的 Notion Connector 提取而来,主要变更:

变更 说明
移除框架依赖 替换 types.FetchedItemtypes.SyncCursorlogger 等为独立实现
添加 CLI 层 基于 cobra + viper 的命令行界面
添加文件输出 Markdown 写入本地文件 + 附件下载 + URL 重写为相对路径
添加状态持久化 同步状态保存为 JSON 文件,重启后可恢复增量同步
流式写入 --all 模式下边获取边写入,不累积内存
数据库按目录分组 每条记录独立 .md 文件,放在数据库同名的子目录下
日志替换 logger.Infoflog/slog,零外部日志依赖

License

MIT