duanzhang377 downloadsSync notes to Confluence pages on a schedule, bound by a confluence_url field in frontmatter.
Push Obsidian notes to Confluence on a schedule — one frontmatter field, zero mapping files.
![[image.png]] embeds become Confluence attachments; regular images display at a configurable width (192px by default) without resizing the uploaded source.[!summary]+ 目录 callout in Obsidian; on sync it becomes Confluence's official H2-H3 table-of-contents macro.confluence_parent_url and the first sync creates the page, then writes the URL back.[!TIP] The plugin is published in the Obsidian community plugin browser. The community-plugin path is the fastest.
From the community plugin browser
Sync Confluence.From a GitHub release (manual)
main.js, manifest.json, styles.css from the latest release.<vault>/.obsidian/plugins/sync-confluence/.Via BRAT (for beta tracking)
dzplus/obsidian-sync-confluence.1. Get a token from Confluence
| You're on… | Get this | Where |
|---|---|---|
| Atlassian Cloud | API token | id.atlassian.com → Security → API tokens |
| Server / Data Center 7.9+ | Personal Access Token | Confluence → Profile picture → Settings → Personal Access Tokens |
| Server (legacy) | Your login password | (same as your domain login) |
2. Store the token in Obsidian's secret vault (Obsidian 1.11.4+)
Settings → Key vault → Create new secret → paste the token → name it (e.g. confluence-token).
3. Plug it into the plugin
Settings → Sync Confluence → Confluence authentication:
https://xxx.atlassian.net/wiki. Server/DC: https://confluence.your-corp.com (usually no /wiki).4. Bind a note
Open any note and add to its frontmatter:
---
confluence_url: https://xxx.atlassian.net/wiki/spaces/XXX/pages/12345/Title
---
Or use the command palette: Insert Confluence frontmatter into current note — the plugin will stub the fields for you.
5. Sync
Any of these works:
Sync current note / Sync all notes.Sync to Confluence.The status-bar pill shows the last result: ☁ Idle / ☁ Syncing / ☁ Synced / ☁ Failed.
Add another server with Settings → Sync Confluence → Confluence authentication → Add Confluence instance. Each instance has its own name, base URL, authentication, secret, and legacy-character compatibility switch.
Targets are index-aligned across confluence_url, confluence_parent_url, and confluence_page_id. An existing target is routed by confluence_url; confluence_parent_url is used only while its URL is empty and the child page still needs to be created. Overlapping base URLs use the longest valid URL-prefix match. A multi-target note may therefore sync to several instances, while each engine updates only its own targets and cache slice.
Up to 10 instances can be configured. A fully unmatched note is listed as
Unmatched; an unmatched target inside an otherwise matched note is reported as a target failure instead of being silently skipped.
Existing page — bind by URL
---
confluence_url: https://xxx.atlassian.net/wiki/spaces/DOC/pages/12345/My-Page
---
New page — let the plugin create it under a parent
---
confluence_parent_url: https://xxx.atlassian.net/wiki/spaces/DOC/pages/100/Parent
confluence_url:
---
On the first sync the plugin creates the child page (titled after the note's filename) and writes the new URL back into confluence_url. Subsequent syncs hit that URL directly.
Multi-parent example — create or update copies under multiple parents
---
confluence_parent_url:
- https://xxx.atlassian.net/wiki/spaces/DOC/pages/100/Parent-A
- https://xxx.atlassian.net/wiki/spaces/DOC/pages/200/Parent-B
confluence_url:
- https://xxx.atlassian.net/wiki/spaces/DOC/pages/12345/My-Page
- ""
confluence_page_id:
- "12345"
- ""
---
CSV-format multi-parent example
---
confluence_parent_url: https://xxx.atlassian.net/wiki/spaces/DOC/pages/100/Parent-A, https://xxx.atlassian.net/wiki/spaces/DOC/pages/200/Parent-B
confluence_url: https://xxx.atlassian.net/wiki/spaces/DOC/pages/12345/My-Page, ""
confluence_page_id: 12345, ""
---
Fields written back by the plugin — leave these blank, they're maintained automatically:
confluence_page_id — resolved page ID.confluence_last_synced — ISO timestamp of the last successful push.confluence_last_hash — instance ID → page ID → content hash; equal hash = sync is a no-op for that target.confluence_attachments — instance ID → page ID → filename → {hash, id} cache, used to skip re-uploading unchanged attachments.Wikilinks. [[Other Note]] / [[Other Note|alias]] (and standard [text](note.md) links) are resolved through Obsidian's metadata cache. If the target note has a confluence_url for the current instance, the link becomes a hyperlink to that instance's page; otherwise it degrades to plain text. Batch syncs pre-create placeholder pages for parent-only notes first, so cross-references inside the same batch resolve on the first sync.
Heading anchors. Same-page [[#Heading]] / [text](#heading) and cross-page [[Other Note#Heading]] / [text](note.md#heading) links are converted to native Confluence heading anchors. Heading matching is case-sensitive, following Confluence behavior.
User mentions (Server / DC only). Write @[[John Doe]] to mention a Confluence user. The plugin looks up the linked note (John Doe.md) and reads the current instance's username from its frontmatter:
---
confluence_username:
default: john.d
work: j.doe
---
The keys are the stable instance IDs shown on each settings card. If the current instance has an entry, the mention becomes a real Confluence user link; otherwise it degrades to plain @John Doe. Legacy scalar usernames are migrated to every configured instance once. Cloud is not supported yet (Cloud storage format requires ri:account-id).
| Source | Plugin behavior |
|---|---|
mermaid block |
On by default. Renders to an image attachment using one of two engines (see below). |
plantuml block |
Off by default; on → renders via a PlantUML server, uploads PNG. |
Pick one in Settings → Diagrams → Renderer:
| Engine | Output | Best for |
|---|---|---|
| Obsidian built-in engine (default) | SVG rendered locally with Obsidian's mermaid runtime | Pixel-identical to your editor preview, no network needed, time-axis diagrams scale to content width. Trade-off: SVG output — older Confluence Server (≤5.x) may not render it inline; fonts follow your Obsidian theme. |
| Kroki remote service | PNG via https://kroki.io/mermaid/png (or self-hosted) |
Maximum compatibility — works on every Confluence version, full CJK / emoji font coverage. Trade-off: mermaid source is sent to the configured server. The public kroki.io instance is a third party; use a self-hosted Kroki for confidential diagrams. Time-axis diagrams (gantt / timeline) also render at a cramped width and date labels overlap. |
For corporate networks using kroki, point Kroki service URL at a self-hosted kroki instance (a single docker run will do). The same privacy warning applies to PlantUML: enabling it sends source to the configured PlantUML server (public plantuml.com by default).
| Command | What it does |
|---|---|
Sync all notes |
Walks scan folders and syncs every bound note. |
Sync current note |
Syncs only the active note. |
Insert Confluence frontmatter into current note |
Stubs the 5 frontmatter fields so you only have to paste the URL. |
Create bound note |
Prompts for path + URL, then creates a new note already bound. |
Export storage preview of current note |
Writes the converted Confluence storage XHTML to <note>.preview.xml — useful for debugging parser errors. |
Validate credentials |
Pings Confluence with the current settings and shows your account name. |
Right-click menus:
Properties panel: when a note has a confluence_url property, the plugin adds two icons next to the property key — sync this note and open in Confluence (multiple bound pages pop a picker menu). There is deliberately no one-click "unbind" button; destructive actions don't belong one click away in the properties panel.
401 / Authentication failed — Cloud uses email + API token, not your Atlassian password. Server 7.9+ should use Bearer with a PAT, not Basic.
XSRF rejection on Server — The plugin already routes around this by using Node https for POST + JSON / multipart uploads. If you still hit it, your reverse proxy may be stripping headers; check X-Atlassian-Token: no-check.
Mermaid block shows source instead of image — turn on Render Mermaid diagrams in settings. The default engine (Obsidian built-in) renders locally. If you switched to kroki, it needs network access to the configured server; on a corporate network either self-host kroki or switch back to Obsidian built-in (SVG).
Gantt / timeline dates overlap on Confluence — kroki renders these at a fixed narrow width so the date axis labels collide. Switch the engine to Obsidian built-in (SVG) to let the chart scale to content width.
Cannot find secret vault — requires Obsidian 1.11.4+. On older versions the plugin falls back to a plaintext field; upgrade Obsidian to use the encrypted vault.
The plugin keeps syncing the same note — check confluence_last_hash; if you're editing in the Confluence UI too, every sync will overwrite Confluence and reset the hash. This plugin is one-way (Obsidian → Confluence) by design.
https modules the plugin relies on for XSRF-safe uploads.[!summary]+ 目录 callout containing same-page heading links becomes the native Confluence TOC; manually curated ordering and inline grouping are replaced by Confluence's automatic H2-H3 hierarchy.bun install
bun test
bun run dev # watch mode, writes dist/main.js
bun run build # production build (typecheck + bundle)
bun run build also copies manifest.json and styles.css into dist/, so the directory can be dropped straight into .obsidian/plugins/sync-confluence/ for local testing.
Release flow:
npm version 0.2.1 # bumps package.json + manifest.json + versions.json
git push && git push --tags
The release.yml workflow builds and attaches the three required files to a GitHub Release.
按定时把 Obsidian 笔记推到 Confluence 对应页面 —— 一个 frontmatter 字段搞定绑定,不需要单独的映射文件。
![[image.png]] 形式引用的本地图片自动上传为 Confluence 附件;普通图片默认显示宽度为 192px(可配置),上传原图不压缩。confluence_parent_url,首次同步时插件自动建子页面并把新 URL 回写到 confluence_url。[!TIP] 插件已发布到 Obsidian 官方社区插件库,优先用这条路径。
从社区插件库安装
Sync Confluence。从 GitHub Release 手动安装
main.js、manifest.json、styles.css。<vault>/.obsidian/plugins/sync-confluence/。通过 BRAT(跟踪 beta 版)
dzplus/obsidian-sync-confluence。1. 从 Confluence 拿一个 token
| 你的环境 | 需要什么 | 在哪拿 |
|---|---|---|
| Atlassian Cloud | API token | id.atlassian.com → Security → API tokens |
| Server / DC 7.9+ | Personal Access Token | Confluence → 头像 → 设置 → Personal Access Tokens |
| Server(老账号体系) | 登录密码 | (和你登录 Confluence 的密码一致) |
2. 把 token 存到 Obsidian 密钥库(需 Obsidian 1.11.4+)
设置 → 密钥库 → 创建新密钥 → 把 token 粘到密钥值 → 给它起个名字(如 confluence-token)。
3. 在插件里连起来
设置 → Sync Confluence → Confluence 认证:
https://xxx.atlassian.net/wiki;Server / DC 通常无 /wiki 后缀,如 https://confluence.your-corp.com。4. 给一篇笔记加 frontmatter 绑定
打开任意笔记,在 frontmatter 里加:
---
confluence_url: https://xxx.atlassian.net/wiki/spaces/XXX/pages/12345/Title
---
也可以用命令面板:在当前笔记插入 frontmatter,插件会把所有字段都准备好。
5. 同步
下面任意一种:
同步当前笔记 / 同步全部笔记。同步到 Confluence。状态栏小图标会显示最近一次结果:☁ 空闲 / ☁ 同步中 / ☁ 已同步 / ☁ 失败。
通过 设置 → Sync Confluence → Confluence 认证 → 新增 Confluence 实例 添加服务器。每个实例独立保存名称、Base URL、认证、密钥和旧版字符兼容开关。
confluence_url、confluence_parent_url、confluence_page_id 按下标组成 target。已有页面只按 confluence_url 路由;仅当 URL 为空、需要新建子页面时才使用 confluence_parent_url。Base URL 重叠时采用合法的最长 URL 前缀匹配。因此一篇多 target 笔记可进入多个实例,但每个同步引擎只写自己的 target 和缓存切片。
单个 vault 最多配置 10 个实例。整篇完全无法匹配时列为
Unmatched;已匹配笔记中的单个未知 target 会明确报失败,不会静默跳过。
已有页面 —— 用 URL 直接绑
---
confluence_url: https://xxx.atlassian.net/wiki/spaces/DOC/pages/12345/My-Page
---
还没建页面 —— 让插件在指定父页下建子页面
---
confluence_parent_url: https://xxx.atlassian.net/wiki/spaces/DOC/pages/100/Parent
confluence_url:
---
首次同步时插件以本笔记文件名为标题创建子页面,并把新页面 URL 回写到 confluence_url。之后同步直接走这个 URL。
多父页面示例 —— 同一篇笔记同步到多个父页面下的副本
---
confluence_parent_url:
- https://xxx.atlassian.net/wiki/spaces/DOC/pages/100/Parent-A
- https://xxx.atlassian.net/wiki/spaces/DOC/pages/200/Parent-B
confluence_url:
- https://xxx.atlassian.net/wiki/spaces/DOC/pages/12345/My-Page
- ""
confluence_page_id:
- "12345"
- ""
---
CSV 格式多父页面示例
---
confluence_parent_url: https://xxx.atlassian.net/wiki/spaces/DOC/pages/100/Parent-A, https://xxx.atlassian.net/wiki/spaces/DOC/pages/200/Parent-B
confluence_url: https://xxx.atlassian.net/wiki/spaces/DOC/pages/12345/My-Page, ""
confluence_page_id: 12345, ""
---
插件自动回写的字段 —— 你不用填,留空即可:
confluence_page_id —— 解析出的 Page ID。confluence_last_synced —— 上次成功推送的 ISO 时间戳。confluence_last_hash —— 实例 ID → Page ID → 内容哈希;相同 target 的哈希一致就跳过。confluence_attachments —— 实例 ID → Page ID → 文件名 → {hash, id} 附件缓存,用于跳过未变附件。Wikilink。 [[另一篇笔记]] / [[另一篇笔记|别名]](以及标准 [文本](note.md) 链接)会经 Obsidian metadata cache 解析:目标笔记在当前实例有 confluence_url → 替换为该实例页面的超链接;没有 → 降级为纯文本。批量同步会先给“仅有 parent”的笔记预建占位页,同批笔记互相引用首次同步即可解析。
标题锚点。 同页 [[#标题]] / [文本](#标题) 和跨页 [[另一篇笔记#标题]] / [文本](note.md#标题) 会转换为 Confluence 原生标题锚点。标题匹配遵循 Confluence 规则,区分大小写。
用户 mention(仅 Server / DC)。 写 @[[张三]] 即可 mention Confluence 用户。插件查找被链接的笔记(张三.md),按当前实例读取 confluence_username:
---
confluence_username:
default: zhangsan
work: zhang.san
---
键是每张设置卡里显示的稳定实例 ID。当前实例有值时会生成真实 Confluence 用户链接;缺失时只在该实例降级为纯文本 @张三。旧版单值 username 会一次性迁移到全部已配置实例。Cloud 暂不支持(Cloud storage 格式要求 ri:account-id)。
| 源 | 插件行为 |
|---|---|
mermaid 块 |
默认开。同步前渲染成图片附件,用两个引擎之一(见下)。 |
plantuml 块 |
默认关;开 → 走 PlantUML Server 渲染为 PNG 上传。 |
在 设置 → 图表渲染 → 渲染方式 二选一:
| 引擎 | 输出 | 适用 |
|---|---|---|
| Obsidian 内置引擎(默认) | SVG,本地用 Obsidian 自带的 mermaid 渲染 | 跟编辑器预览像素级一致、无网络依赖、时间轴图表按内容宽度自然撑开。代价:产物是 SVG,老版本 Confluence Server(≤5.x)可能不 inline 显示;字体跟随你当前主题。 |
| Kroki 远端服务 | PNG,走 https://kroki.io/mermaid/png(或自建实例) |
兼容性最好——任何 Confluence 版本都能 inline 渲染,中文/emoji 字体齐全。代价:mermaid 源码会发送到配置的服务器。公共 kroki.io 是第三方,机密图表请改用自建 Kroki。时间轴类图表(gantt / timeline)还会被压缩到固定窄宽度,日期标签挤在一起。 |
走 kroki 的企业内网用户,把 Kroki 服务 URL 指向自建 kroki 实例(一条 docker run 即可)。PlantUML 同样:开启后源码会发到配置的 PlantUML 服务器(默认公共 plantuml.com)。
| 命令 | 作用 |
|---|---|
同步全部笔记 |
遍历扫描目录,同步所有已绑定的笔记 |
同步当前笔记 |
仅同步当前活动笔记 |
在当前笔记插入 frontmatter |
把 5 个 frontmatter 字段填好,你只需要粘 URL |
创建绑定笔记 |
填路径 + URL,直接生成一篇已绑定的笔记 |
导出当前笔记的 storage 预览 |
把转换后的 Confluence storage XHTML 写到 <笔记>.preview.xml,便于排查转换报错 |
验证认证信息 |
用当前设置 ping Confluence,回显你的账号显示名 |
右键菜单:
属性面板:笔记有 confluence_url 属性时,插件在属性名旁注入两个图标 —— 同步当前笔记 和 在 Confluence 中打开(绑定多个页面时弹菜单选择)。有意不做一键"解绑"按钮:破坏性操作不该在属性面板一击可达。
401 / 认证失败 —— Cloud 用 邮箱 + API token,不要填 Atlassian 登录密码。Server 7.9+ 走 PAT 的话要选 Bearer,不是 Basic。
Server 上 XSRF 拒绝 —— 插件已经走 Node https 模块绕过 requestUrl 的 XSRF 限制了。如果还报,多半是你的反代剥了 header,检查一下 X-Atlassian-Token: no-check 透传。
Mermaid 代码块没渲成图 —— 在设置里把 渲染 Mermaid 图表 打开。默认引擎(Obsidian 内置)本地渲染、不走网络。如果切到了 kroki,需要能访问配置的服务器;企业内网要么自建 kroki,要么把引擎切回 Obsidian 内置引擎(SVG)。
Confluence 上 Gantt / timeline 的日期挤在一起 —— kroki 渲染这类时间轴图表用的画布太窄,日期标签互相重叠。把引擎切到 Obsidian 内置引擎(SVG),让图表按内容宽度自然撑开。
找不到密钥库 —— 需要 Obsidian 1.11.4+。老版本会回退到明文输入;升级 Obsidian 即可走加密密钥库。
插件一直在同步同一篇笔记 —— 看 confluence_last_hash;如果你也在 Confluence 端直接改,每次同步都会被插件覆盖回 Obsidian 的内容,hash 会循环变化。本插件单向(Obsidian → Confluence),不读回 Confluence 改动。
https 模块。[!summary]+ 目录 callout 才会转成 Confluence 官方目录;手工排序和同一行分组会由 Confluence 自动生成的 H2-H3 层级取代。bun install
bun test
bun run dev # watch 模式,写 dist/main.js
bun run build # 生产构建(typecheck + 打包)
bun run build 会把 manifest.json 和 styles.css 一起拷到 dist/,整个目录可以直接拖到 .obsidian/plugins/sync-confluence/ 本地测试。
发版:
npm version 0.2.1 # 同步 package.json + manifest.json + versions.json
git push && git push --tags
release.yml 会自动构建并把三个必备文件挂到 GitHub Release 上。