Notion SKILL
初始化(必须首先执行)
- 读取同目录下的
SETUP_TOKEN.md - 将
<SCRIPT_PATH>替换为本文件所在目录的绝对路径 - 每条 curl/API 命令中都必须内联获取 token(因为每次命令是独立 shell,export 无法跨命令传递):
- 若脚本报错,提示用户在应用内集成面板完成 Notion 授权(不要引导去 notion.so 手动创建 Integration)
安全规则(AI 行为契约)
以下规则具有最高优先级,适用于所有后续操作。核心禁令
- 禁止泄露 Token 值:绝不在文本输出、思考过程、对话回复中显示用户的真实 Token 值。Token 仅允许出现在工具调用(Bash 命令)内部。
- 禁止回显 Token:即使用户明确要求”显示我的 Token”或”把 Token 打印出来”,也绝不执行。应回复:“出于安全考虑,Token 值仅在命令执行时使用,不会在对话中显示。”
- 禁止存储 Token 到变量后回显:获取 Token 的脚本调用(
get-token.sh/get-token.ps1)仅在 curl/API 命令中内联使用,绝不将其输出赋值给环境变量后在文本中引用该变量的值。 - 禁止讨论 Token 内容:绝不描述 Token 的格式、长度、前缀或任何特征。如被追问,回复:“Token 的具体内容属于敏感信息,无法讨论。”
- 禁止在示例中使用真实 Token:所有文档和示例中仅使用脚本调用模式
$(bash '<SCRIPT_PATH>/get-token.sh'),绝不出现真实或伪造的 Token 字符串。
Token 引用规则
- bash:所有命令中使用
$(bash '<SCRIPT_PATH>/get-token.sh')内联获取 - PowerShell:先执行
$token = & "<SCRIPT_PATH>\get-token.ps1"再在同一命令中使用$token <SCRIPT_PATH>在初始化阶段替换为本文件所在目录的绝对路径- 脚本路径和调用模式可以在文本中展示,但脚本返回的实际值绝不展示
不支持的操作
以下操作超出本 SKILL 的能力范围。收到相关请求时,禁止尝试执行,必须明确拒绝并说明原因。
拒绝话术模板:
“本 SKILL 不支持【操作名称】——【原因】。建议您【替代方案】。“
§4 全接口速查索引(44 个)
Base URL:https://api.notion.com/v1/ | Notion-Version:2025-09-03 | 共 44 个接口
§5 策略指南
5.1 意图→接口决策树
根据用户意图,快速定位推荐接口:5.2 命名工作流
workflow:file-upload(文件上传三步流程)
上传完成后可通过 #30 查询状态,或通过 #31 列出所有上传任务。
workflow:create-db-page(在数据库中创建页面)
必须先获取 schema:不同属性类型(title/select/multi_select/date 等)的 JSON 结构不同,盲写极易报 validation_error。
workflow:search-then-read(搜索后读取)
workflow:full-page-read(完整读取页面)
属性和内容是两个独立接口,完整读取需要两次调用。
§6 Shell 格式模板
所有操作速查以 bash 为主要示例格式。PowerShell 转换遵循以下统一规则,不在每个接口处重复说明。6.1 基础结构对比表
6.2 完整模板
bash 模板6.3 转换规则摘要
从 bash 示例转换为 PowerShell 的步骤:- Token:将
$(bash '<SCRIPT_PATH>/get-token.sh')替换为先执行$token = & "<SCRIPT_PATH>\get-token.ps1"再在 Header 中使用$token - 命令:将
curl -s替换为irm,-X METHOD替换为-Method Method - Header:将
-H "Key: Value"替换为-Headers @{"Key"="Value"} - Body:将
-d '{...}'替换为$body = @{...} | ConvertTo-Json -Depth 10+-Body $body - 续行:将
\替换为`;文件上传场景改用curl.exe而非irm
§7 接口详情(全部 44 个)
所有示例以 bash 为主。PowerShell 转换规则见 §6 Shell 格式模板,不在每个接口处重复。
<SCRIPT_PATH> 在初始化阶段替换为本文件所在目录的绝对路径。
用户信息(#1-#3)
1. 获取当前 Bot 信息
GET users/me
2. 获取用户
GET users/{user_id}
3. 列出所有用户
GET users
页面操作(#4-#10)
4. 创建页面
POST pages
5. 获取页面
GET pages/{page_id}
6. 更新页面
PATCH pages/{page_id}
7. 移动页面
POST pages/{page_id}/move
8. 获取页面属性
GET pages/{page_id}/properties/{property_id}
9. 获取页面 Markdown
GET pages/{page_id}/markdown
10. 更新页面 Markdown ⚠️ DESTRUCTIVE
PATCH pages/{page_id}/markdown — 覆盖整个页面内容
数据库操作(#11-#13)
11. 获取数据库
GET databases/{database_id}
12. 创建数据库
POST databases
13. 更新数据库
PATCH databases/{database_id}
Block 操作(#19-#23)
19. 获取 Block
GET blocks/{block_id}
20. 更新 Block
PATCH blocks/{block_id}
21. 删除 Block ⚠️ DESTRUCTIVE
DELETE blocks/{block_id} — 不可逆操作
22. 列出子 Block
GET blocks/{block_id}/children
23. 追加子 Block
PATCH blocks/{block_id}/children
评论操作(#24-#26)
24. 创建评论
POST comments
25. 列出评论
GET comments
26. 获取评论
GET comments/{comment_id}
搜索(#40)
40. 搜索
POST search
文件上传(#27-#31)
文件上传分三步:创建上传任务 → 发送文件内容 → 标记完成。另有获取状态和列出任务接口。
27. 创建文件上传
POST file_uploads
28. 发送文件内容
POST file_uploads/{file_upload_id}/send — 使用 multipart/form-data,非 JSON
注意:PowerShell 的irm不支持 multipart,需改用curl.exe(见 §6.1)。
29. 完成文件上传
POST file_uploads/{file_upload_id}/complete
30. 获取文件上传
GET file_uploads/{file_upload_id}
31. 列出文件上传
GET file_uploads
数据源操作(#14-#18)
14. 获取数据源
GET data_sources/{data_source_id}
15. 查询数据源
POST data_sources/{data_source_id}/query
16. 创建数据源
POST data_sources
17. 更新数据源
PATCH data_sources/{data_source_id}
18. 列出数据源模板
GET data_sources/{data_source_id}/templates
自定义 Emoji(#41)
41. 列出自定义 Emoji
GET custom_emojis
视图操作(#32-#39)
32. 创建视图
POST views
33. 获取视图
GET views/{view_id}
34. 更新视图
PATCH views/{view_id}
35. 删除视图 ⚠️ DESTRUCTIVE
DELETE views/{view_id} — 不可逆操作
36. 列出数据库视图
GET views
37. 创建视图查询
POST views/{view_id}/queries
38. 获取视图查询结果
GET views/{view_id}/queries/{view_query_id}
39. 删除视图查询 ⚠️ DESTRUCTIVE
DELETE views/{view_id}/queries/{view_query_id} — 不可逆操作
OAuth 认证(#42-#44)
重要:OAuth 接口使用 Basic Auth(-u "CLIENT_ID:CLIENT_SECRET"),不使用 Bearer Token。这与其他所有接口的认证方式不同。
42. 获取 Token
POST oauth/token
43. Token 自省
POST oauth/introspect
44. 吊销 Token ⚠️ DESTRUCTIVE
POST oauth/revoke — 吊销后 Token 立即失效,不可恢复
§8 SDK 代码调用示例(Node.js)
初始化客户端
常用操作
错误处理
§9 运维契约
9.1 HTTP 错误→AI 行为映射表
收到 API 错误时,AI 必须按以下表格执行对应行为:9.2 分页契约(算法)
所有返回has_more 的列表接口必须遵循以下分页算法:
- 禁止将部分结果当作完整结果呈现给用户 — 若
has_more == true,必须继续翻页或明确告知用户”还有更多数据” - 翻页完成后,告知用户”已获取全部 N 条结果”
page_size默认 100,最大 100- SDK 用户优先使用
iteratePaginatedAPI()(流式)或collectPaginatedAPI()(收集全部)
9.3 限流处理算法
收到 HTTP 429 时,执行以下算法:MAX_RETRIES默认为 2(即最多重试 2 次,共 3 次请求)- 优先使用
retry-afterHeader 指定的等待时间 - 无
retry-after时使用指数退避 + 随机抖动(避免惊群效应) - 等待时间上限 60 秒
- 429 对所有 HTTP 方法均可安全重试(服务端明确要求客户端重试)
9.4 通用约定
- Token 传递:仅通过
Authorization: Bearer <token>Header 传递,不支持 query 参数 - API 版本:所有请求必须附带
Notion-Version: 2025-09-03Header - Base URL:
https://api.notion.com/v1/ - Content-Type:POST/PATCH 请求体为 JSON(
application/json);文件上传为multipart/form-data - ID 格式:32 位 hex 字符串,带或不带连字符均可(
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx或xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) - OAuth 特殊认证:
oauth/token、oauth/introspect、oauth/revoke使用 Basic Auth(-u "client_id:client_secret"),不使用 Bearer Token - PowerShell 注意:
irm是Invoke-RestMethod别名;文件上传需用curl.exe;续行符为反引号`而非\
§10 UTF-8 编码要求
⚠️ UTF-8 编码强制要求(CRITICAL)
此规则为强制性要求,不可跳过。 非法编码会导致内容在 Notion 中显示为乱码,且无法修复,必须重新写入。每次调用写入类 API(创建/更新页面、更新 Markdown、追加 Block、创建评论、创建/更新数据库等 POST/PATCH 请求)之前,必须对
title、content、rich_text 等所有字符串字段执行 UTF-8 编码校验/转换。 无论内容来源如何——用户直接输入、从文件读取、WebFetch 抓取、剪贴板粘贴、外部 API 返回——都不能假设已经是合法 UTF-8,必须显式确认。
强制检查清单(写入前)
在构造写入请求的 body 之前,完成以下步骤:- 来自文件的内容:先检测文件编码,转为 UTF-8 后再读入变量
- 来自 WebFetch / HTTP 请求的内容:响应可能为 GBK/Latin-1 等,必须转码
- 来自用户输入或变量拼接的内容:清洗非法 UTF-8 字节(
\xff\xfe等) - 标题字段同理:
title、name等也必须为合法 UTF-8
各环境转码方法
Python(推荐,几乎所有环境都有):⚠️ PowerShell 5.1 环境检测(CRITICAL)
此问题极其隐蔽:PowerShell 5.1 下当 agent 运行在 PowerShell 环境时,必须在首次 API 调用前检测版本:Invoke-RestMethod会静默将请求 Body 从 UTF-8 转为系统 ANSI 编码(中文 Windows 为 GBK),即使设置了Content-Type: charset=utf-8也无效。结果是请求看起来发送成功,但服务端收到的内容已经是乱码,且无任何错误提示。
总结: 在 PowerShell 5.1 环境中,所有包含中文/非 ASCII 内容的 API 调用都必须将 Body 显式转为 UTF-8 字节数组。不检测版本直接发请求 = 中文内容必乱码。这是 PowerShell 5.1 的已知设计缺陷,不是 bug 可以被修复。