noteTb: 341
This data as json
| id | user_id | content | tags | created_at | updated_at | enable | pinned | folder_id | comment | position | visibility |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 341 | 1 1 | # 笔记搬家 TOP10 分析 - 日期:2026-05-18 - 目标:梳理主流笔记软件/网站的 API、导出方式,以及 keng 后续如何把对方笔记搬进来 --- ## 结论 现在 keng 只实现了 Simplenote 搬家,下一步最值得做的是: 1. **Obsidian / Logseq / Joplin**:本地 Markdown 或开放导出,成本最低,成功率最高。 2. **Notion / OneNote**:有官方 API,适合做 OAuth 连接后自动同步/导入。 3. **Evernote / Standard Notes / Google Keep / Apple Notes / Bear**:更适合先支持“用户导出文件上传”,再考虑半自动或平台脚本。 统一策略:keng 不要为每个平台单独写一堆散逻辑,而是做 `NoteSourceAdapter`:每个来源只负责列笔记、取正文、取附件/标签、返回标准结构,最终都走现有 `/api/other-notes/{source}/import`。 --- ## TOP10 平台与搬家方式 | 排名 | 平台 | 官方 API | 推荐搬家方式 | 难度 | 备注 | |------|------|----------|--------------|------|------| | 1 | Notion | 有,Notion API | OAuth 后读取 page/block/database,转 Markdown | 中 | API 稳定,但 block 转 Markdown 要做映射 | | 2 | Microsoft OneNote | 有,Microsoft Graph | OAuth 后读取 notebooks/sections/pages,正文 HTML 转 Markdown | 中 | Graph 权限配置较复杂 | | 3 | Evernote | 有历史 API,但现代接入受限 | 优先支持 ENEX 导入 | 中 | 用户从客户端导出 `.enex` 最稳 | | 4 | Google Keep | 无正式公开 API | Google Takeout 导出 JSON/HTML 后导入 | 中 | 不建议依赖非官方接口 | | 5 | Apple Notes | 无公开 Web API | macOS 导出/AppleScript/第三方导出 Markdown 后上传 | 高 | iCloud 网页不适合作为稳定 API | | 6 | Obsidian | 本地 Markdown 文件夹 | 直接上传 vault zip 或选目录导入 `.md` | 低 | 最适合先做,几乎无需平台账号 | | 7 | Joplin | 有本地 Web Clipper API | JEX/Markdown 导出,或本地 token 调 Joplin API | 低 | 开源,字段和附件好处理 | | 8 | Bear | 有 x-callback-url/导出 | Markdown/TextBundle 导出后上传 | 中 | macOS/iOS 生态,自动化需本机配合 | | 9 | Simplenote | 有 API | 已实现 | 低 | 当前 keng 已接入 | | 10 | Standard Notes | 无稳定公开导入 API | App 内导出 decrypted backup JSON 后导入 | 中 | 加密产品,必须让用户本地导出明文备份 | --- ## 各平台实现要点 ### 1. Notion - 获取 API:到 Notion Developers 创建 integration,或做 OAuth public integration。 - 数据读取:`/v1/search` 找页面和数据库,`/v1/blocks/{block_id}/children` 递归读取 block。 - 搬出方式:把 heading、paragraph、bulleted_list_item、numbered_list_item、to_do、code、quote、table 等 block 转 Markdown。 - keng 映射:页面标题 → `title`,正文 Markdown → `content`,database/page 标签属性 → `tags`。 - 风险:Notion block 类型多,初版只支持常用块,复杂嵌入先转成链接占位。 ### 2. Microsoft OneNote - 获取 API:Azure Portal 注册应用,开启 Microsoft Graph 权限,如 `Notes.Read`。 - 数据读取:Graph `/me/onenote/notebooks`、`/sections`、`/pages`,页面正文通常是 HTML。 - 搬出方式:HTML 转 Markdown,section 名可映射到 folder。 - 风险:OAuth 配置和企业/个人账号权限差异较多。 ### 3. Evernote - 获取 API:Evernote 历史 API/SDK 存在,但新应用接入不如以前稳定。 - 推荐搬出方式:用户从 Evernote 客户端导出 `.enex`。 - keng 实现:解析 ENEX XML,`<title>` 作标题,`<content>` 是 ENML,需要转 Markdown;`<tag>` 映射 tags。 - 风险:附件资源需要额外解析 `<resource>`,初版可先导入正文和标签。 ### 4. Google Keep - 官方 API:没有适合第三方迁移的公开 Keep API。 - 推荐搬出方式:Google Takeout 导出 Keep,通常包含 JSON/HTML。 - keng 实现:上传 Takeout zip,解析 Keep 的 JSON/HTML,checkbox/list/image 先转 Markdown。 - 风险:Takeout 格式可能变化;不能把非官方抓取当长期方案。 ### 5. Apple Notes - 官方 API:没有公开 API。 - 推荐搬出方式:macOS 本地导出,或通过 AppleScript/快捷指令/第三方工具导出 Markdown。 - keng 实现:先支持 Markdown/HTML/目录 zip 导入,不直接连 iCloud。 - 风险:自动化强依赖用户本机环境,服务器端无法稳定完成。 ### 6. Obsidian - 官方 API:不需要,核心数据就是本地 Markdown vault。 - 推荐搬出方式:用户上传 vault zip 或一组 `.md` 文件。 - keng 实现:保留 Markdown 原文,YAML frontmatter 可提取 tags,目录名可映射 folder。 - 风险:双向链接 `[[xxx]]` 可先保留文本,后续映射到 keng 的 `linkTb`。 ### 7. Joplin - 获取 API:本地 Joplin Web Clipper API,需要用户提供本机 token;也可导出 JEX/Markdown。 - 推荐搬出方式:JEX 或 Markdown 导出优先。 - keng 实现:解析 Markdown 目录最简单;JEX 需要解析 tar/元数据。 - 风险:服务器无法直接访问用户本机 Joplin API,除非用户运行中继工具。 ### 8. Bear - 获取 API:Bear 主要支持 x-callback-url 和系统自动化,不是服务器 REST API。 - 推荐搬出方式:Bear 导出 Markdown/TextBundle。 - keng 实现:上传 zip,解析 Markdown 和资源文件。 - 风险:iCloud 同步数据不应直接抓取,优先让用户主动导出。 ### 9. Simplenote - 获取 API:Simplenote API,可用账号登录后列笔记、读正文。 - keng 状态:已实现 `simplenote` 来源。 - 后续优化:补齐标题标准化、回收站去重只看 `enable='T'`、按用户隔离外部来源账号。 ### 10. Standard Notes - 官方 API:不建议直接接,数据端到端加密,服务端 API 不适合作明文迁移入口。 - 推荐搬出方式:用户在 App 中导出 decrypted backup JSON。 - keng 实现:上传 JSON,解析 items,note 内容按 Markdown/Plain Text 保存。 - 风险:必须明确只处理用户主动导出的明文备份,不能索要主密码。 --- ## keng 统一架构建议 ### 标准数据结构 所有来源最终都转换成: ```json { "source": "notion", "source_id": "第三方稳定 id", "title": "标题", "content": "Markdown 正文", "tags": ["标签"], "folder": "可选文件夹", "created_at": "可选", "updated_at": "可选", "attachments": [] } ``` ### Adapter 接口 建议每个平台一个 adapter: ```python class NoteSourceAdapter: source = "notion" async def list_notes(self) -> list[dict]: ... async def get_note(self, source_id: str) -> dict: ... async def import_notes(self, ids: list[str], team_id: int | None = None) -> dict: ... ``` ### 去重规则 - 主规则:`comment LIKE 'source=<source>; source_id=<id>'`,且只匹配 `enable='T'`。 - 辅助规则:标题标准化后相同 + 内容 hash 相同,可提示 already exists。 - 回收站笔记不阻止重新导入。 ### 优先级 | 优先级 | 来源 | 原因 | |--------|------|------| | P0 | Obsidian Markdown zip | 成本最低,用户最多能马上试 | | P0 | Joplin Markdown/JEX | 开源且导出规范 | | P1 | Notion API | 用户量大,API 稳定,有展示价值 | | P1 | Evernote ENEX | 经典迁移场景,文件导入比 API 稳 | | P2 | Google Takeout Keep | 需要处理 zip/JSON/HTML | | P2 | OneNote Graph | 企业生态重要,但 OAuth 配置复杂 | | P3 | Apple Notes/Bear/Standard Notes | 主要靠本地导出,后做 | --- ## 车间落地建议 第一阶段不要一下接十个平台,先把“文件导入型”框架做稳: 1. 新增通用 `/api/other-notes/upload`,支持 zip/md/enex/json。 2. 实现 Obsidian Markdown zip 导入。 3. 实现 Joplin Markdown/JEX 或 Evernote ENEX(二选一)。 4. 把导入结果统一写入现有 `noteTb/teamNoteTb`,comment 标记 `source/source_id`。 5. 再做 Notion OAuth/API。 这样 keng 会从“只支持 Simplenote”升级成“支持本地 Markdown/ENEX/JSON 文件搬家 + 少数官方 API 搬家”的结构,后面每加一个来源只是补 adapter。 | [] | 2026-05-18 23:53:00 | 2026-05-18 23:53:48 | T | F | 41 41 | 0 | friends |