一文多发助手2.0开发过程记录

一、整体思路演变

1.1 浏览器插件方案

最初调研过 wechatsync 这类浏览器插件方案。它的思路是在浏览器层拦截内容,再一键同步到多个平台。

优点

  • 轻量,安装后即可使用,无需额外搭建后端
  • 支持的平台较多
  • 可直接复用浏览器中的登录态,不需要每次单独登录平台

缺点

  • 强依赖平台登录态,账号风控风险较高
  • 无法对内容做深度处理,如格式适配、AI 润色
  • 插件维护常跟不上平台接口变化,容易失效
  • 本质是"搬运",不是"适配"

最终放弃插件方案,转向基于 API 的工作流方案。核心原因是:内容适配比内容搬运更有价值。

1.2 写作工具的选型变化

阶段 写作工具 主要问题
最初 OneNote 导出 Word 再转 Markdown,流程繁琐
1.0 OneNote → Word → TextIn 解析 图片处理复杂,格式损耗大
2.0 探索 飞书文档 API 调用有限制,稳定性一般
2.0 最终 Obsidian 原生 Markdown,图片管理清晰

Obsidian 成为最终选择的核心原因是:原生 Markdown 格式 + 本地图片管理清晰,与工作流衔接最自然。


二、1.0 版本实操过程

2.1 核心流程

OneNote 写作
    ↓
导出为 Word 文档
    ↓
TextIn API 解析(提取文本 + 图片)
    ↓
DeepSeek v3.2 内容增强
    ↓
图片上传阿里云 OSS
    ↓
Hexo 博客发布 / 公众号半自动发布

2.2 主要问题

1、图片上传流程复杂

OneNote 导出的 Word 文档中,图片以嵌入方式存储。TextIn 解析后,需要再单独提取图片并上传 OSS,节点多,且容易断链。

2、Coze 平台的沙箱限制

Coze 工作流运行在沙箱环境中,部分系统调用受限,无法直接支持 MCP 协议。因此公众号发布只能做到半自动:生成内容后下载为 md 文件,再手动调用 wenyan-cli

3、扩展性不足

Coze 的节点类型有限。当需要实现更复杂的逻辑,如图片迭代上传、链接映射替换时,平台能力不足,这也直接推动了 2.0 迁移到 Dify。


三、2.0 版本搭建过程

3.1 平台迁移:Coze → Dify

迁移的核心动机:

  • Dify 支持更丰富的节点类型
  • 本地部署更灵活
  • 工作流可导出为 yml,便于版本管理

迁移的主要工作,是将 1.0 在 Coze 中实现的逻辑,按 Dify 的节点能力重新设计并重建。

3.2 输入源扩展:飞书的尝试与放弃

尝试飞书作为输入源,主要因为它的协作能力强,API 文档也比较完善,理论上是理想输入源。

实际问题主要有两点:

  • 飞书开放平台调用需要自建应用
  • 导出 Markdown 时,表格、多维表格、Mermaid、图片等内容的转换效果不稳定

最终结论是:飞书路径保留为备选输入,主力输入切换为 Obsidian 本地文档。

3.3 图片处理:几个关键坑

1、图片名称中的空格被编码为 %20

Obsidian 允许图片文件名包含空格。上传到 OSS 后,空格会被编码为 %20,导致 Markdown 中的图片链接失效。

解决方案:在工作流中增加"图片名称规范化"节点,上传前先将文件名中的空格替换为连字符 -,并同步更新 Markdown 中的引用路径。

2、图片迭代上传后的映射关系不完整

使用 Dify 迭代节点批量上传图片后,需要把"原始路径 → OSS 链接"的映射传给后续替换节点。初版实现中,映射结果传递不完整,导致部分图片替换失败。

解决方案:在迭代节点内部增加"输出链接映射关系"子节点,累积每次迭代结果,确保后续节点拿到完整映射表。

3、Obsidian 图片路径格式与标准 Markdown 不一致

Obsidian 常用 Wiki 链接格式引用图片,如 ![[图片名.png]],而标准 Markdown 使用 ![](图片路径)。因此工作流中需要先识别并转换这两种格式。

3.4 Dify 插件下载卡死问题

自部署 Dify 下载插件时,曾出现插件反复循环下载、始终无法完成的问题。

解决方式:在开发者工具中执行以下脚本,清空所有卡住的插件安装任务。

// 自动从当前页面 Cookie 中提取 CSRF Token,无需手动复制
function getCsrfToken() {
  const match = document.cookie.match(/csrf_token=([^;]+)/);
  return match ? match[1] : '';
}

const csrfToken = getCsrfToken();

// 调用 Dify 后端接口,清空所有卡住的插件安装任务
fetch("/console/api/workspaces/current/plugin/tasks/delete_all", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Accept": "application/json",
    "X-CSRF-Token": csrfToken
  },
  body: "{}"
}).then(res => res.json())
  .then(data => {
    console.log("✅ 执行成功,接口返回结果:", data);
    if (data.success || data.code === 200) {
      console.log("🎉 恭喜!所有卡住的插件安装任务已全部清空,请刷新 Dify 插件页面查看效果");
    }
  })
  .catch(err => console.error("❌ 执行失败,错误信息:", err));

3.5 公众号发布工具的选型变化

工具 阶段 放弃原因或采用原因
md2wechat(付费) 早期调研 功能简单,样式定制能力弱
wenyan-cli 1.0 版本 命令行交互方式不利于接入自动化流程
文颜(wenyan-mcp) 2.0 版本 支持 MCP 协议,可程序化调用,样式更丰富

文颜(wenyan)的 MCP 版本,是 2.0 公众号发布能力升级的关键。它将公众号发布能力封装为标准 MCP 工具,CLI 可通过 stdio 调用,从而实现真正自动化。

3.6 Claude Code 的使用体验

2.0 版本的 Node.js CLI 项目,整体由 Claude Code 生成。

顺畅的部分

  • 描述需求后,能较快生成完整项目结构
  • 标准 API 调用场景下,如 Dify API、MCP stdio,代码质量较高
  • 遇到报错时,反馈错误信息后,大多数情况下能给出有效修复方案

需要注意的部分

  • 仍需理解生成代码的基本逻辑,否则很难判断问题来自代码还是配置
  • 网络代理相关配置往往需要多次调试
  • Claude Code 生成项目后,最好主动追问一次技术栈和整体设计,避免只会用不会维护

💡 使用小技巧

  • 初始上下文较短,消耗较低;随着上下文变长,成本会明显上升
  • 一些零碎报错或小任务,可以交给普通大模型处理,不一定都放在 Claude Code 中
  • Sonnet 模型明显比 Opus 更便宜

3.7 Word 文件转带外链 Markdown 的选型过程

这一部分考虑时间比较长,主要对比了几种工具。

维度 Pandoc Docling MinerU LlamaParse(付费)
定位 通用文档格式转换工具 AI 驱动文档智能解析引擎 几乎完全依赖大模型 -
公式支持 Latex 转换效果好 不如 Pandoc - -
表格解析 - - - -
图片提取 - - - -
部署难度 - - - -
速度 - - - -

当前仍在使用云端 Dify,而自部署 Dify 会带来不少额外问题,因此工具选型也要考虑运行环境。

Docling 有两种使用方式:

  • 本地部署到电脑
  • 通过 Dify 的 code node 调用

但这两条路都有问题:

  • 云端 Dify 的 code node 运行在沙箱中,依赖配置麻烦,限制也多
  • 本地部署 Docling 内存占用较高,而当前电脑日常内存占用已经偏高,不适合继续增加本地负担

418

重新聚焦后,实际需求变得更明确:

解析文件需求

9000 字以内的技术博文,内容包含图文、表格和少量公式。

核心痛点

不要强 OCR,尤其不要把图片中的装饰性图标、无意义文字也识别出来。这是 TextIn 曾暴露过的问题。

现实判断

后续 Word 转 Markdown 的需求会明显减少。

因此最终偏好变成:性价比高、效果足够好、可接受付费。

随后尝试了 LlamaParse:

  • 每月额度 1000 页,超出按量付费
  • 可直接在网页试用:LlamaParse

试用结果如下:

  • 如果图片是思维导图等结构化内容,可以直接转成代码结构,接近"重画"
  • 富文本可以识别,但仍有误差
  • 公式识别效果较好
  • 会自动编排标题
  • 图片中的表格可转为 Markdown 表格
  • 图片 OCR 仍会识别出装饰性图标

LlamaParse 解析后,会暂时把图片保存在服务端内存中,浏览器通过临时生成的 blob 链接渲染图片。导出 Markdown 时,图片不会被一并打包,只会保留图片文件名作为相对路径引用。

因此最终还是回到 TextIn WebUI 解析。原因也很直接:价格可以接受,日常使用频率不高,而后续主流程又会逐步转向本地 Obsidian。

3.8 博客 LaTeX 数学公式渲染问题

Hexo 构建博客后,Markdown 编辑器中能正常显示的 LaTeX 公式,在浏览器里却无法正确渲染。

解决方法是按主题官方文档完成配置:

  1. 切换渲染器:从 hexo-renderer-markedhexo-renderer-kramed 切换为 hexo-renderer-markdown-it
  2. 安装 Katex 相关插件:npm install katex @renbaoshuo/markdown-it-katex
  3. 修改 Butterfly 主题配置文件 _config.butterfly.yml,开启 Katex
  4. 修改 Hexo 配置文件 _config.yml
markdown:
  plugins:
    - '@renbaoshuo/markdown-it-katex'

原因是:Hexo 默认的 hexo-render-marked 会在部分场景下处理 _\* 等字符,导致公式渲染失败。

3.9 OSS 图片无法在博客中渲染

当时使用的图片链接如下:

https://zyydgrbk.oss-cn-chengdu.aliyuncs.com/images%2FDifyWenDangTiQuQi%2F7d50d2de2705aeb8.jpg
?OSSAccessKeyId=...
&Expires=1809845172
&Signature=Z+WUqwchRtJm7sheoHqlVtIJThQ=

这类链接本质上是 预签名 URL(Presigned URL),只能在过期时间内访问。关键问题在于 Signature 中的 + 被浏览器当成空格处理。

例如:当前的签名是 Z+WUqwchRtJm7sheoHqlVtIJThQ=,浏览器实际处理成了 Z WUqwchRtJm7sheoHqlVtIJThQ=,原因是 URL 编码中的历史兼容问题,+ 应该写成 %2B

最终解决办法:**不再使用签名链接,直接使用公开 OSS 链接。**转换后的链接形式为:

https://zyydgrbk.oss-cn-chengdu.aliyuncs.com/images/DifyWenDangTiQuQi/7.jpg

3.10 Node CLI 项目遇到的问题

1、Failed: fetch failed

本地网络环境无法直接访问 Dify 云端服务,而 Node 原生 fetch 默认不会自动走系统代理,因此需要单独配置。

PowerShell 环境变量:

$env:HTTPS_PROXY = "http://127.0.0.1:7890"
$env:HTTP_PROXY = "http://127.0.0.1:7890"

安装依赖:

npm install undici

src/cli.js 开头加入:

import { setGlobalDispatcher, ProxyAgent } from "undici";

if (process.env.HTTPS_PROXY || process.env.HTTP_PROXY) {
  setGlobalDispatcher(new ProxyAgent(process.env.HTTPS_PROXY ?? process.env.HTTP_PROXY));
}

2、Failed: Dify API error 504: <!DOCTYPE html>

runDifyWorkflow 返回的 response_mode 当时使用的是 blocking,而工作流整体耗时大约在 1 分钟左右,被网关截断属于正常现象。

解决方法:改为 streaming 模式即可。