notion-caldav-sync:在Apple Calendar上显示Notion任务
Contents
虽然 Notion Calendar 和 Notion 配合更好,但实际使用中,还是更喜欢 Apple Calendar. Apple Calendar支持农历显示和法定节假日,稳定性更好,且有 iPadOS 版本。
我写了一个开源项目 notion-caldav-sync 将 Notion 所有被授权的数据库上的任务同步到 Apple Calendar 上的一个新日历 Notion.
系统结构 #
整个系统围绕“稳定性和实时性第一”的原则设计:
单向数据流:避免双向同步的复杂性和冲突(Notion → Apple Calendar)
实时响应:通过 Notion webhook 将 Notion 上的修改实时同步到 Apple Calendar
自愈机制:每30分钟执行完整校正,即使 webhook 丢失或处理失败也能恢复
轻量部署:通过Cloudflare workers + Pyodide部署
最初,我也尝试了双向同步方案,但对于 Apple Calendar 来说,双向同步容易导致数据冲突和 Notion 页面错乱。最终选择了单向同步:保持 Notion 作为唯一数据源,Apple Calendar 作为只读视图,通过点击事件链接跳转回 Notion 修改,Notion 上的变更几乎实时地通过 webhook 在 Apple Calendar 上显示。
flowchart TD
NotionDB[(Notion Task Databases)]
NotionWebhook[/Notion Webhook Events/]
Cron((Cron Full Rewrite))
Admin[[Admin Commands]]
Worker[Cloudflare Worker<br/>Pyodide Runtime]
Engine[Sync Engine<br/>force Notion→CalDAV]
KV[(Cloudflare KV STATE)]
CalDAV[(iCloud "Notion" Calendar)]
AppleCal[[Apple Calendar Views]]
NotionWebhook -->|real-time batches| Worker
Cron -->|self-healing interval| Worker
Admin -->|/admin/full-sync + settings| Worker
NotionDB -->|search/query APIs| Worker
Worker -->|persist metadata & tokens| KV
Worker --> Engine
Engine -->|overwrite events| CalDAV
Engine -->|update hashes & timestamps| KV
CalDAV --> AppleCal
任务状态emoji #
根据Notion任务状态,我在Apple Calendar日程标题中添加了emoji,更清楚地展现。其中逾期任务⚠️是根据任务截止时间自动识别和标注的:
| Notion 状态 | Emoji 标识 | 含义 |
|---|---|---|
| Not started | ⬜ | 待开始任务 |
| In progress | ⚙️ | 进行中任务 |
| Completed | ✅ | 已完成任务 |
| ⚠️ | 逾期任务 | |
| Cancelled | ❌ | 已取消任务 |
在 Apple Calendar 中搜索这些emoji,还可以快速找到对应状态的任务。
其他信息映射 #
Notion页面地址被写到Apple Calendar的日程URL中,点击可以直接打开Notion页面。另外,Data Source、Category和Description信息也会自动同步到日程备注中。
Cloudflare Workers + Python #
为了能够实现实时响应和定期全量同步,我使用了无服务器部署。
无服务器架构优势 #
选择 Cloudflare Workers 作为运行平台,主要考虑以下几个方面:
Pyodide:Cloudflare Workers 原生支持 Python(基于 Pyodide WebAssembly 实现)
Cloudflare:全球分布式部署,国内也能用
成本低:免费额度大,无需维护服务器
KV 存储:原生键值存储,使用很方便
Pyodide 的技术优势 #
Pyodide 是 CPython 的 WebAssembly 移植版本:
动态链接:多个 Worker 可共享 Python 运行时和包代码,大幅降低内存占用
JavaScript FFI:提供 Python 与 JavaScript 之间的外部函数接口,可直接调用 Web API
内存快照:支持预热和快照技术,将冷启动时间降至 1 秒以下
Python 包支持:提供了大量 Python 标准库,并支持
pywrangler打包额外的 vendor 包
pywrangler 工具链 #
pywrangler 是 Cloudflare 为 Python Workers 提供的专用 CLI 工具,封装了 wrangler 并添加了 Python 特定功能:
开发服务器:
pywrangler dev本地模拟环境,支持热重载和状态持久化部署管理:
pywrangler deploy自动打包依赖并优化 WebAssembly 文件密钥管理:
pywrangler secret put安全存储敏感配置,运行时通过env访问日志追踪:
pywrangler tail实时查看执行日志和性能指标Python 优化:自动预编译依赖、注入最小运行时、检测不兼容特性
通过 pywrangler 的封装,除了 CPU 限制和包大小限制,几乎和本地 CPython 环境一样.工具链自动处理 WebAssembly 编译、依赖管理和部署优化等复杂细节。