思源笔记同步插件

把 inBox 云端的笔记单向同步思源笔记open in new window 的第三方插件。

项目地址:github.com/maoruibin/siyuan-inbox-syncopen in new window

它能做什么

  • 单向同步(云端 → 思源):只下载不上传
    • inBox App 是收集端,思源是工作台
    • 在思源里编辑/删除文档不会回传到云端
    • 不支持在思源里新建笔记(新笔记请在 inBox App 创建)
  • 多存储后端:WebDAV / S3 兼容存储(Bitiful、腾讯云 COS、阿里云 OSS 等)
  • 增量同步:基于 ETag + mtime,未变化的笔记直接跳过
  • 资源同步:图片、视频、录音、附件,落到 data/assets/inbox-sync/
  • 批注支持:ver=2 内联批注渲染为父笔记末尾的 blockquote;独立批注作为父笔记末尾的块引用
  • 盒子分文件夹:按盒子归到 /<盒子名>/ 子文档下,无盒子进根目录平铺。盒子改名/删除时自动对账(批量 move 文档 + 同步 custom-box
  • 笔记间链接:保留 inBox 原文 [[note-xxx]](v0.2 以纯文本展示,块级转换在后续版本)

安装

方式 1:思源集市搜索(推荐)

  1. 打开思源 → 设置 → 集市
  2. 在搜索框输入 inBoxinBox 同步
  3. 找到 inBox 同步 插件,点 下载 安装
  4. 设置 → 饱和插件(或插件管理)里启用 inBox 同步

集市版本可能落后 GitHub 主线几天到几周,求新可以走方式 2。

方式 2:手动安装(从 GitHub Releases)

  1. Releasesopen in new window 下载最新的 package.zip
  2. 在思源里打开文件管理器,进入工作空间的 data/plugins/ 目录
  3. 新建文件夹 siyuan-inbox-sync/,把 package.zip 里的所有文件解压到该目录
  4. 重启思源或在 设置 → 插件 中点 刷新,然后启用 inBox 同步

方式 3:从源码构建

git clone https://github.com/maoruibin/siyuan-inbox-sync.git
cd siyuan-inbox-sync
npm install
npm run package     # 一键构建 + 打包成 package.zip

把生成的 package.zip 解压到 data/plugins/siyuan-inbox-sync/ 即可。

配置

第 1 步:选目标笔记本

在思源里建一个专门存放同步笔记的笔记本(比如叫「inBox」),后面在插件设置里要选它。

建议单独建一个新笔记本,别跟现有笔记本混用,方便管理。

第 2 步:配置云存储

打开插件设置(顶栏图标 → 设置),按你的存储类型填。

WebDAV

  • URL:你的 WebDAV 服务地址(如 https://dav.jianguoyun.com/dav/
  • 用户名 / 密码(坚果云需要用应用专属密码,详见 WebDAV 教程
  • 云端根目录:默认 inBox,对应 inBox App 的同步根

S3 兼容

  • Endpoint:如 https://s3.bitiful.net 或腾讯云 COS 地址
  • Access Key / Secret Key / Bucket / Region
  • 同上,云端根目录默认 inBox

这里的云端配置要跟 inBox App 端配置的云存储是同一份,否则同步不到同一个数据源。

第 3 步:选笔记本 + 子路径

  • 目标笔记本:下拉选第 1 步建的那个
  • 子路径:可选,比如填 /inBox,所有笔记会落到笔记本下的 /inBox/ 文档下;留空就是笔记本根

第 4 步:测试连接 → 立即同步

测试连接,验证云存储可达。然后点顶栏的同步图标(或设置里 立即同步),第一次会拉全部笔记,之后只拉变化的。

文档树结构

同步后的思源笔记本按盒子组织:

{笔记本}/
├── inBox/                         # 子路径(可在设置里改)
│   ├── 默认笔记.md                # 无盒子笔记(根平铺)
│   ├── 工作/                      # "工作"盒子下所有笔记
│   │   ├── project-xxx.md
│   │   └── meeting-notes.md
│   └── 生活/                      # "生活"盒子
│       └── shopping.md
└── assets/inbox-sync/             # 资源(所有盒子共享, 不按盒子分)
    ├── images/
    ├── videos/
    ├── audios/
    └── attachments/

盒子文件夹规则:

  • 笔记 content.box_id 在云端 boxes.json 里查到 → 进 <盒子名>/ 子文档
  • 否则(无盒子 / 盒子被删墓碑 / boxes.json 为空)→ 根平铺
  • 盒子在 inBox App 改名 → 该 boxId 下所有文档 move 到新路径 + 同步更新 custom-box
  • 盒子在 inBox App 删除 → 该 boxId 下所有文档 move 回根 + 清 custom-box
  • 资源统一放 data/assets/inbox-sync/,不按盒子分

字段映射

inBox 的 atomicNote → 思源文档:

inBox 字段思源落点
id (note-xxx)文档自定义属性 custom-inbox-id
content.title文档名(无标题时用创建时间)
content.content文档正文块
meta.created_at / updated_atcustom-inbox-created / -updated
content.box_id(经 boxes.json 解析为名称)custom-box(无盒子不写)
tags(从正文 #tag 提取)custom-inbox-tags,正文保留 #tag
parentIdcustom-inbox-parent(noteId)
ver=2 内联 annotations[]父笔记末尾的 > **批注** 引用块
独立批注子笔记(有 parentId独立文档 + 父笔记末尾的块引用 ((childDocId))

删除语义

  • 在 inBox App 删除笔记 → 云端 flags.is_removed=true → 插件下次同步时移除思源对应文档
  • 在思源里删文档 → 不影响云端(单向同步,思源是只读副本)

为什么是单向同步?

inBox 的定位是收集箱,所有笔记/批注/盒子都在 App 端创建。思源这边当作只读工作台:能完整拉历史、按盒子分文件夹、查标签,但不把思源里的编辑/删除回传到云端。

之前版本试过双向同步(本地修改上传、本地删除软删云端),实际使用中暴露两个问题:

  1. 基线机制脆弱:思源任何块操作(包括我们自己调 setBlockAttrs)都会更新 updated 字段,必须维护基线避免无限循环。一旦基线错乱(同步中断、手动改文档、跨设备),就会误判本地有改动而反复上传
  2. WebDAV 缓存导致脏数据:坚果云等 WebDAV 服务会缓存旧版本,双向同步时上传的 is_removed=true 会被缓存,导致其他端拉到错误的软删除状态,笔记"删了又复活"

权衡之后回归单向:inBox 是收集端,思源是工作台,职责分离更清晰,也避免双向同步的复杂性 + 误删风险。

已知限制

  • 不支持在思源里新建笔记:新建请在 inBox App 完成,插件只同步已有 noteId 的笔记
  • 不支持回传:在思源里编辑/删除文档不会影响云端(单向同步)
  • 盒子管理:盒子的创建/重命名/删除需在 inBox App 完成(插件只读 boxes.json)
  • [[note-xxx]] 笔记间链接暂未转换为思源块引用,正文里以纯文本展示
  • 桌面端思源优先;移动端有 CORS 限制,可能需要走 /api/network/forwardProxy(未实现)

反馈与问题

Last Updated:
Contributors: mao