数据分析

notion-sync

试用

在命令行里实现 Markdown 与 Notion 的双向同步,支持数据库查询、属性更新和变更监听。

它能做什么

把本地 Markdown 推送到 Notion 页面,再把页面编辑拉回本地,自带分批上传、限速和基于本地状态的变更检测。脚本支持工作区搜索、按过滤条件查询数据库,并对 select、multi_select、checkbox、date、url、number 等属性做单页或批量更新。所有脚本基于 Node.js v18+ 运行,集成令牌从令牌文件、标准输入或环境变量读取,加上 --json 即可输出机器可读结果;默认只在当前工作目录内读写本地文件。

什么时候用它

  • 把 Markdown 草稿推送到 Notion,后续编辑再拉回本地
  • 按过滤条件查询 Notion 数据库并排序导出
  • 用 cron 定时监听指定 Notion 页面是否有改动
  • 按过滤条件或 ID 列表批量修改某一属性

技能文档

Notion Sync

Bi-directional sync between markdown files and Notion pages, plus database management utilities for research tracking and project management.

Upgrading

From v2.0: Replace --token "ntn_..." with --token-file, --token-stdin, or NOTION_API_KEY env var. Bare --token is no longer accepted (credentials should never appear in process listings).

From v1.x: See v2.0 changelog for migration details.

Requirements

  • Node.js v18 or later
  • A Notion integration token (starts with ntn_ or secret_)

Setup

  1. Go to https://www.notion.so/my-integrations

  2. Create a new integration (or use an existing one)

  3. Copy the "Internal Integration Token"

  4. Pass the token using one of these methods (priority order used by scripts):

    Option A — Token file (recommended):

    echo "ntn_your_token" > ~/.notion-token && chmod 600 ~/.notion-token
    node scripts/search-notion.js "query" --token-file ~/.notion-token
    

    Option B — Stdin pipe:

    echo "$NOTION_API_KEY" | node scripts/search-notion.js "query" --token-stdin
    

    Option C — Environment variable:

    export NOTION_API_KEY="ntn_your_token"
    node scripts/search-notion.js "query"
    

    Auto default: If ~/.notion-token exists, scripts use it automatically even without --token-file.

  5. Share your Notion pages/databases with the integration:

    • Open the page/database in Notion
    • Click "Share" → "Invite"
    • Select your integration

JSON Output Mode

All scripts support a global --json flag.

  • Suppresses progress logs written to stderr
  • Keeps stdout machine-readable for automation
  • Errors are emitted as JSON: { "error": "..." }

Example:

node scripts/query-database.js  --limit 5 --json

Path Safety Mode

Scripts that read/write local files are restricted to the current working directory by default.

  • Prevents accidental reads/writes outside the intended workspace
  • Applies to: md-to-notion.js, add-to-database.js, notion-to-md.js, watch-notion.js
  • Override intentionally with --allow-unsafe-paths

Examples:

# Default (safe): path must be inside current workspace
node scripts/md-to-notion.js docs/draft.md  "Draft"

# Intentional override (outside workspace)
node scripts/notion-to-md.js  ~/Downloads/export.md --allow-unsafe-paths

Core Operations

1. Search Pages and Databases

Search across your Notion workspace by title or content.

node scripts/search-notion.js "" [--filter page|database] [--limit 10] [--json]

Examples:

# Search for newsletter-related pages
node scripts/search-notion.js "newsletter"

# Find only databases
node scripts/search-notion.js "research" --filter database

# Limit results
node scripts/search-notion.js "AI" --limit 5

Output:

[
  {
    "id": "page-id-here",
    "object": "page",
    "title": "Newsletter Draft",
    "url": "https://notion.so/...",
    "lastEdited": "2026-02-01T09:00:00.000Z"
  }
]

2. Query Databases with Filters

Query database contents with advanced filters and sorting.

node scripts/query-database.js  [--filter ] [--sort ] [--limit 10] [--json]

Examples:

# Get all items
node scripts/query-database.js xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# Filter by Status = "Complete"
node scripts/query-database.js  \
  --filter '{"property": "Status", "select": {"equals": "Complete"}}'

# Filter by Tags containing "AI"
node scripts/query-database.js  \
  --filter '{"property": "Tags", "multi_select": {"contains": "AI"}}'

# Sort by Date descending
node scripts/query-database.js  \
  --sort '[{"property": "Date", "direction": "descending"}]'

# Combine filter + sort
node scripts/query-database.js  \
  --filter '{"property": "Status", "select": {"equals": "Complete"}}' \
  --sort '[{"property": "Date", "direction": "descending"}]'

Common filter patterns:

  • Select equals: {"property": "Status", "select": {"equals": "Done"}}
  • Multi-select contains: {"property": "Tags", "multi_select": {"contains": "AI"}}
  • Date after: {"property": "Date", "date": {"after": "2024-01-01"}}
  • Checkbox is true: {"property": "Published", "checkbox": {"equals": true}}
  • Number greater than: {"property": "Count", "number": {"greater_than": 100}}

3. Update Page Properties

Update properties for database pages (status, tags, dates, etc.).

node scripts/update-page-properties.js    [--type ] [--json]

Supported types: select, multi_select, checkbox, number, url, email, date, rich_text

Examples:

# Set status
node scripts/update-page-properties.js  Status "Complete" --type select

# Add multiple tags
node scripts/update-page-properties.js  Tags "AI,Leadership,Research" --type multi_select

# Set checkbox
node scripts/update-page-properties.js  Published true --type checkbox

# Set date
node scripts/update-page-properties.js  "Publish Date" "2024-02-01" --type date

# Set URL
node scripts/update-page-properties.js  "Source URL" "https://example.com" --type url

# Set number
node scripts/update-page-properties.js  "Word Count" 1200 --type number

4. Batch Update

Batch update a single property across multiple pages in one command.

Mode 1 — Query + Update:

node scripts/batch-update.js    --filter '' [--type select] [--dry-run] [--limit 100]

Example:

node scripts/batch-update.js  Status Review \
  --filter '{"property":"Status","select":{"equals":"Draft"}}' \
  --type select

Mode 2 — Page IDs from stdin:

echo "page-id-1\npage-id-2\npage-id-3" | \
  node scripts/batch-update.js --stdin   [--type select] [--dry-run]

Features:

  • --dry-run: prints pages that would be updated (with current property value) without writing
  • --limit : max pages to process (default 100)
  • Pagination in query mode (has_more/next_cursor) up to limit
  • Rate-limit friendly updates (300ms between page updates)
  • Progress and summary on stderr, JSON result array on stdout

5. Markdown → Notion Sync

Push markdown content to Notion with full formatting support.

node scripts/md-to-notion.js \
  "" \
  "" \
  "" [--json] [--allow-unsafe-paths]

Example:

node scripts/md-to-notion.js \
  "projects/newsletter-draft.md" \
  "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \
  "Newsletter Draft - Feb 2026"

Supported formatting:

  • Headings (H1-H3)
  • Bold/italic text
  • Links
  • Bullet lists
  • Code blocks with syntax highlighting
  • Horizontal dividers
  • Paragraphs

Features:

  • Batched uploads (100 blocks per request)
  • Automatic rate limiting (350ms between batches)
  • Rich text is automatically chunked to Notion's 2000-character limit (including bold/italic/link spans)
  • Returns Notion page URL and ID

Output:

Parsed 294 blocks from markdown
✓ Created page: https://www.notion.so/[title-and-id]
✓ Appended 100 blocks (100-200)
✓ Appended 94 blocks (200-294)

✅ Successfully created Notion page!

6. Notion → Markdown Sync

Pull Notion page content and convert to markdown.

node scripts/notion-to-md.js  [output-file] [--json] [--allow-unsafe-paths]

Example:

node scripts/notion-to-md.js \
  "abc123-example-page-id-456def" \
  "newsletter-updated.md"

Features:

  • Converts Notion blocks to markdown
  • Preserves formatting (headings, lists, code, quotes)
  • Optional file output (writes to file or stdout)

7. Change Detection & Monitoring

Monitor Notion pages for edits and compare with local markdown files.

node scripts/watch-notion.js "" "" [--state-file ] [--json] [--allow-unsafe-paths]

Example:

node scripts/watch-notion.js \
  "abc123-example-page-id-456def" \
  "projects/newsletter-draft.md"

State tracking: By default maintains state in memory/notion-watch-state.json (relative to current working directory). You can override with --state-file (supports ~ expansion):

node scripts/watch-notion.js "" "" --state-file ~/.cache/notion-watch-state.json

Default state schema:

{
  "pages": {
    "": {
      "lastEditedTime": "2026-01-30T08:57:00.000Z",
      "lastChecked": "2026-01-31T19:41:54.000Z",
      "title": "Your Page Title"
    }
  }
}

Output:

{
  "pageId": "",
  "title": "Your Page Title",
  "lastEditedTime": "2026-01-30T08:57:00.000Z",
  "hasChanges": false,
  "localPath": "/path/to/your-draft.md",
  "actions": ["✓ No changes since last check"]
}

Automated monitoring: Schedule periodic checks using cron, CI pipelines, or any task scheduler:

# Example: cron job every 2 hours during work hours
0 9-21/2 * * * cd /path/to/workspace && node scripts/watch-notion.js "" ""

The script outputs JSON — pipe it to any notification system when hasChanges is true.

8. Database Management

Add Markdown Content to Database

Add a markdown file as a new page in any Notion database.

node scripts/add-to-database.js  ""  [--json] [--allow-unsafe-paths]

Examples:

# Add research output
node scripts/add-to-database.js \
  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
  "Research Report - Feb 2026" \
  projects/research-insights.md

# Add project notes
node scripts/add-to-database.js \
   \
  "Sprint Retrospective" \
  docs/retro-2026-02.md

# Add meeting notes
node scripts/add-to-database.js \
   \
  "Weekly Team Sync" \
  notes/sync-2026-02-06.md

Features:

  • Creates database page with title property
  • Converts markdown to Notion blocks (headings, paragraphs, dividers)
  • Handles large files with batched uploads
  • Returns page URL for immediate access

Note: Additional properties (Type, Tags, Status, etc.) must be set manually in Notion UI after creation.

Inspect Database Schema

node scripts/get-database-schema.js  [--json]

Example output:

{
  "object": "database",
  "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "title": [{"plain_text": "Ax Resources"}],
  "properties": {
    "Name": {"type": "title"},
    "Type": {"type": "select"},
    "Tags": {"type": "multi_select"}
  }
}

Use when:

  • Setting up new database integrations
  • Debugging property names/types
  • Understanding database structure

Archive Pages

node scripts/delete-notion-page.js  [--json]

Note: This archives the page (sets archived: true), not permanent deletion.

Common Workflows

Collaborative Editing Workflow

  1. Push local draft to Notion:

    node scripts/md-to-notion.js draft.md  "Draft Title"
    
  2. User edits in Notion (anywhere, any device)

  3. Monitor for changes:

    node scripts/watch-notion.js  
    # Returns hasChanges: true when edited
    
  4. Pull updates back:

    node scripts/notion-to-md.js  draft-updated.md
    
  5. Repeat as needed (update same page, don't create v2/v3/etc.)

Research Output Tracking

  1. Generate research locally (e.g., via sub-agent)

  2. Sync to Notion database:

    node scripts/add-research-to-db.js
    
  3. User adds metadata in Notion UI (Type, Tags, Status properties)

  4. Access from anywhere via Notion web/mobile

Page ID Extraction

From Notion URL: https://notion.so/Page-Title-abc123-example-page-id-456def

Extract: abc123-example-page-id-456def (last part after title)

Or use the 32-char format: abc123examplepageid456def (hyphens optional)

Limitations

  • Property updates: Database properties (Type, Tags, Status) must be added manually in Notion UI after page creation. API property updates can be temperamental with inline databases.
  • Block limits: Very large markdown files (>1000 blocks) may take several minutes to sync due to rate limiting.
  • Formatting: Some complex markdown (tables, nested lists >3 levels) may not convert perfectly.

Troubleshooting

"Could not find page" error:

  • Ensure page/database is shared with your integration
  • Check page ID format (32 chars, alphanumeric + hyphens)

"Module not found" error:

  • Scripts use built-in Node.js https module (no npm install needed)
  • Ensure running from the skill's directory (where scripts/ lives)

Rate limiting:

  • Notion API has rate limits (~3 requests/second)
  • Scripts handle this automatically with 350ms delays between batches

Resources

scripts/

Core Sync:

  • md-to-notion.js - Markdown → Notion sync with full formatting
  • notion-to-md.js - Notion → Markdown conversion
  • watch-notion.js - Change detection and monitoring

Search & Query:

  • search-notion.js - Search pages and databases by query
  • query-database.js - Query databases with filters and sorting
  • update-page-properties.js - Update database page properties
  • batch-update.js - Batch update one property across many pages (query or stdin IDs)

Database Management:

  • add-to-database.js - Add markdown files as database pages
  • get-database-schema.js - Inspect database structure
  • delete-notion-page.js - Archive pages

Utilities:

  • notion-utils.js - Shared utilities (error handling, property formatting, API requests)

All scripts use only built-in Node.js modules (https, fs) - no external dependencies required.

references/

  • database-patterns.md - Common database schemas and property patterns

常见问题

需要准备什么凭据,怎么传给脚本?
需要一个 Notion 内部集成令牌(以 ntn_ 或 secret_ 开头)。脚本从令牌文件(默认 ~/.notion-token)、标准输入管道或 NOTION_API_KEY 环境变量读取,不再支持直接在命令行参数里传令牌,以避免泄露到进程列表。
除了 Node.js 还需要什么前置条件?
需要 Node.js v18 或更高版本。另外,目标页面和数据库必须在 Notion 的「分享」里把该集成加入,否则搜索、查询和更新都会报 "Could not find page" 类的错误。
同步和处理上有哪些已知限制?
超过约 1000 个块的 Markdown 文件同步会比较慢,受每批 350ms 的限速影响;表格和超过三层嵌套的列表在转换时可能不完整。除标题外的数据库属性需要先在 Notion 界面里手动创建,才能用更新脚本修改。

相关技能

诊断生产力系统反复失效的根因,给出最小干预——容量测算、瓶颈定位、可靠的本地记录。

作者 Iván854 次安装69 星标

以 AI 机器人身份加入视频会议,提供语音、虚拟形象与屏幕共享四种模式。

作者 johnpatternai21 次安装8 星标

通过一次 REST API 调用,向 10 个社交平台发布视频、图片、文字与文档。

作者 victorcavero14375 次安装50 星标

在本地磁盘以分类纯 Markdown 文件保存需要长期留存的事实,与智能体内置记忆并存。

作者 Iván555 次安装18 星标

通过托管 OAuth 访问 Microsoft Graph Excel 接口,读写 OneDrive 中的工作簿、工作表、区域、表格与图表。

作者 byungkyu800 次安装42 星标

通过托管的 OAuth GraphQL 接口查询与管理 Linear 的 issue、项目、团队、周期、标签和评论。

作者 byungkyu518 次安装18 星标

robansuini 的更多技能

浏览全部技能

Curated collection of 25+ battle-tested prompts for engineering leaders — 1-on-1 prep, team health, incident retros, technical strategy, hiring, career devel...

作者 robansuini35 次安装1 星标