Notion API 自动化实战 | Integration · 幂等写入 · Webhook | 2026
教程 产品

Notion API 自动化实战:从 Integration 到生产级幂等写入

核心结论:Notion API 不难调,难在「生产级」——Rate Limit 撞墙、Webhook 重复投递、富文本属性 PATCH 覆盖整段内容,任何一个都能让凌晨的 oncall 变成噩梦。本文用一家 40 人 SaaS 公司的工单系统案例,把 Internal Integration → 批量写入 → Webhook 增量 → 幂等防护的链路一次讲透。

开发者终端窗口显示 Notion API HTTP 请求与 JSON 响应日志
生产环境务必开启请求日志脱敏——Token 与 PII 字段不能落盘

第一步:Integration 与最小权限原则

在 Notion Settings → Connections → Develop or manage integrations 创建 Internal Integration。命名规范建议 svc-ticket-prod 这种可审计格式,dev/staging/prod 各用一个 Integration,绝不共用 Token。

权限勾选遵循最小原则:工单系统只需 Read contentUpdate contentInsert content,不要勾 Read user information without email。创建后把 Token 存入 Vault,页面级分享仅授权「工单 Database」和「客户 Directory」两个库——Integration 看不到未分享的页面,这是 Notion 的安全边界,也是很多人调试失败的原因。

第二步:Schema 设计——区分 API 字段与人工字段

工单 Database 推荐字段分工:

  • ticket_id(Rich text):外部系统主键,API 写入,只读展示
  • Status(Select):API 可写,人工可改,但需冲突策略
  • Priority(Formula):由 Severity + SLA 计算,禁止 API 直写
  • last_synced_at(Date):API 每次成功写入后更新,用于对账
  • Assignee(Person):建议人工分配,API 只写建议人选到备注

Formula 和 Rollup 字段永远不要 PATCH——Notion 会返回 400。Relation 字段可以写,但目标 page_id 必须已存在且 Integration 有权限访问。

第三步:批量写入与 Rate Limit 退避

官方限制约 3 requests/second per integration。批量导入 2000 条历史工单,朴素 for 循环会在第 400 条左右收到 429。正确做法是令牌桶 + exponential backoff:

  • 并发控制在 2,预留 burst 空间给 Webhook 触发的实时写入
  • 收到 429 时读取 Retry-After 头,没有则 2^n × 500ms 退避,上限 32 秒
  • 查询用 POST /v1/databases/{id}/query + start_cursor 分页,单页 100 条
  • 创建用 POST /v1/pages,更新用 PATCH /v1/pages/{page_id}

更新 Status 时只 PATCH 变更的属性,不要整页替换——减少 payload 体积,也降低富文本误覆盖风险。

代码编辑器展示 Notion API 批量请求的队列与退避逻辑实现
建议把 API 客户端封装成独立 npm 包,统一处理 429/503

第四步:Webhook 增量同步

在 Integration 设置里订阅 page.properties_updatedpage.created。Webhook 端点必须 HTTPS,响应 200 要在 3 秒内——耗时逻辑扔队列,别在 handler 里同步调 Salesforce。

验签流程:取 raw body,用 Integration 的 signing secret 做 HMAC-SHA256,对比 X-Notion-Signature 头。注意必须用 raw body,JSON 重序列化会导致验签失败——这是 Node.js express.json() 的经典坑,要用 express.raw() 或 verify 回调保留原文。

幂等键设计:用 event_id(Notion 每次投递唯一)存入 Redis SET,TTL 7 天。业务层再用 ticket_id + last_edited_time 做乐观锁,防止旧事件覆盖新状态。

第五步:对账与可观测性

再完美的 Webhook 也会丢事件。每小时跑对账任务:外部系统拉取 updated_since 列表,与 Notion query Filter last_synced_at < 阈值 的条目做 diff,补写差异。Metrics 必看四项:API 429 率、Webhook 验签失败数、对账补写条数、端到端延迟 P95。

告警阈值建议:429 率 > 5% 持续 10 分钟升级;对账补写 > 50 条/小时说明 Webhook 链路有问题。

常见踩坑清单

富文本 PATCH 把格式清空了?

PATCH rich_text 是整体替换,不是 append。需要先 GET 页面,合并 annotations 再 PATCH,或用官方推荐的 block children API 追加段落。

Person 字段写入失败?

Person 类型需要 Notion user ID,不是邮箱。先用 users/list 或 email→id 映射表转换。Integration 无权限的用户会静默失败。

查询结果不全?

Integration 只能看到已分享页面。新建 Database 条目默认继承父页权限,但若父页未分享,query 返回空——检查 Share 面板。

延伸阅读:Notion Workflows 2026 全景解读 · 同步引擎与 CRDT 合并策略 · 返回自动化指南