← 效率指南
Tool中等 · 约 30min发布 2026/08/16

[工具指南]这篇文章是 AI 自己排版发布的:给 DeepSeek Harness 写一个公众号草稿插件

markdown 转公众号草稿要过两道坎:样式必须内联、正文图必须走微信自己的上传接口。这篇讲清楚这两道坎,以及一个把很多人挡在门外的错误码顺序问题。

本页目录
01 · RESULT
RESULT FIRST · 先看结果

在编辑器里写完 markdown,用一句话让 agent 完成排版、传图、建草稿,最后一步发送仍由人手动确认

markdown 转公众号草稿要过两道坎:样式必须内联、正文图必须走微信自己的上传接口。这篇讲清楚这两道坎,以及一个把很多人挡在门外的错误码顺序问题。

你现在看到的标题字号、代码块配色、表格边框线,都不是在公众号后台点出来的。

我在编辑器里写完 markdown,对 agent 说了一句话:

把 ~/posts/ai-typeset-this.md 用 grace 主题发到公众号草稿箱,封面用 ~/posts/img/cover.png。

它渲染了文章、建好了草稿。我只做了最后一步:打开后台,看一眼,点发送。

DeepSeek Harness 会话界面:一句话指令后依次调用 mp_render、mp_create_draft、mp_list_drafts,最后提示已发布到公众号草稿箱

这件事能成,是因为三天前发生的一件事。

三天,12 万 star

DeepSeek Harness 官网首页,主标题为 Everything is a plugin,快速开始命令是 npx @deepseek-ai/dsh web

8 月 13 日,DeepSeek 开源了 DeepSeek Harness,一个跑在自己机器上的编程 agent。MIT 协议,代码全公开。

GitHub 上 deepseek-ai/deepseek-harness 仓库页面,显示 119.1k stars、11.7k forks、MIT license

上面这张截图是我写这篇时截的,11.9 万 star。等我把正文写完再刷一次,12.5 万

三天。

但真正让我坐不住的不是 star 数,是它的架构——everything is a plugin

不是「我们预留了扩展接口」那种客气话。是整个 agent 本身就由插件拼起来:模型、工具、技能、会话、沙箱、存储、循环、调度,连界面都是插件。

意思是,你想让它多干一件事,你自己就能加。

不用等官方排期,不用提 issue 求人,不用 fork 整个项目。写个包,发到 npm,一行命令装上。

社区反应有多快?8 月 16 日我数了一下:插件市场收录 1585 个,awesome 列表 842 条。

三天,一千五百多个插件。

(这两个数字每天都在变,写下来只是当天的快照。)

我看着这个数字,想了个问题:还有什么是没人做的?

一个没人碰的方向

我翻了一遍这些插件。

给 agent 换皮肤的、加记忆的、管会话的、接 Telegram 的、接飞书的、接钉钉的,热闹得很。

但绝大多数,是给 agent 自己加功能

真正伸手出去、连到一个外部服务、替你干完一件具体活的,少得出奇。

微信相关的插件有好几个,我一个个点开——全是把 agent 接进微信聊天,让你能用手机指挥它干活。

方向是反的。

没有一个是帮你往公众号发文章的。

而我每周都在被公众号排版折磨。

为什么公众号排版这么烦

如果你试过「markdown 转 HTML 再粘进公众号编辑器」,大概率失败过。

原因有两个,都不明显。

第一,编辑器只认元素上的 style 属性

<style> 块、外链样式表、class 名,粘进去的一瞬间全部丢弃。

你本地预览得好好的文章,进了编辑器就是一坨没格式的纯文字。

正确做法是把每条 CSS 规则算出来,写进对应元素:

<!-- 你以为可以这样 -->
<style>h2 { color: #0F4C81; }</style>
<h2>小标题</h2>

<!-- 实际必须这样 -->
<h2 style="color:#0F4C81;font-size:20px;">小标题</h2>

一篇文章几百个元素。手工做?不现实。

第二,正文图片必须来自微信自己的上传接口

这条比想象中绕,而且很多人第一次都会踩错接口。

正文里的每一张图,URL 必须是调用微信「上传图文消息内的图片获取 URL」接口(/cgi-bin/media/uploadimg)之后、由微信返回的那个地址。任何其他来源的图片链接都会被过滤掉。

注意判断标准是**「这个 URL 是不是 uploadimg 返回的」**,不是「域名是不是 mmbiz.qpic.cn」。该接口目前返回的确实是这个域名,但官方文档从没对域名做过承诺,写死域名去校验是给自己埋雷。

还有一个容易搞混的地方:

用途 接口
正文里的图 /cgi-bin/media/uploadimg
封面(缩略图) /cgi-bin/material/add_material

两者不能互换。正确顺序是:正文每张图先过 uploadimg,把返回的 url 回填进 content 的 img src;封面单独走 add_materialmedia_id,填进草稿的 thumb_media_id

这个过滤是静默的。 draft/add 照样返回 errcode 0,错误码表里没有任何一条对应「图片被吃掉了」。

但别指望群发之后才发现——微信是在服务端处理这段 content 的,草稿阶段就该验收:打开后台草稿箱看一眼,或者用 draft/get 把 content 读回来对一遍。图片没上去的表现是那个位置空白,不是浏览器那种裂图图标。

用自己图床的,一样中招。

所以我搓了一个

dsh-wechat-mp

它就干上面那几件事:

做什么 怎么做
样式内联 每条 CSS 规则算成字面量,写进元素的 style
图片搬运 正文图走 uploadimg,封面走 add_material,各自换成微信返回的地址
建草稿 组装标题、作者、封面,提交到草稿箱

装起来一行:

dsh plugin --profile web add dsh-wechat-mp

它不群发。

只到草稿箱为止,发送这一步永远留给人。我不想要一个能自己往几千人手机上推东西的程序。

那条「个人号没权限」的传闻,是怎么来的

动手之前我做过调研,网上的说法是:未认证的个人订阅号,大概率调不了草稿箱接口。

我信了,所以插件特意做成两层:排版那半边不碰任何接口——就算你的号没权限,照样能拿到排好版的 HTML 自己粘。

然后我拿自己的号真测了一次。未认证的个人订阅号,能用。草稿箱、素材接口,全都能调。

后来我去翻了官方文档,发现这个传闻的来源比「大家没细看错误码」要具体得多:

微信在 2025 年 7 月回收了发布能力 freepublish/* 系列对个人主体、企业主体未认证账号的调用权限。而这一系列里那个最常用的接口 freepublish/submit官方名字就叫「发布草稿」

「发布草稿」被传成了「草稿箱」。

而草稿箱接口 draft/* 从来不在回收名单里。官方文档对 draft/addmaterial/add_material 标的适用范围一直是可用——不是官方说不行、我实测打了脸,是官方一直没说不行,传的人把两个接口搞混了。

这也正好解释了这套流程为什么成立:API 只负责把文章送进草稿箱,最后点发布那一下在后台手动完成——被回收的恰好是我绕开的那个接口。

一条把顺序搞反的报错

第一次调接口,报错是这个:

errcode 40164: invalid ip 203.0.113.42, not in whitelist

IP 白名单没配。这个我知道,去后台加上就行。

关键在于它发生在哪一步

我原以为白名单是拦具体业务接口的:你调草稿箱,它检查你的 IP。

实际上,微信在你换取 access_token 的时候就查来源 IP——cgi-bin/token,以及任何直接传 AppSecret 的接口,都在这一步被拦下。

后果很要命:白名单没配好之前,你没法用 API 去验证权限。 所有请求都卡在换凭据这一步,那个真正代表「接口未授权」的 48001 根本没机会出现。你看到的永远是一个跟权限毫无关系的错误。

所以顺序应该是:先把出口 IP 加进白名单,再判断权限。 顺序反了,你测的是白名单,不是权限。

更省事的做法是根本别用调接口来试权限——直接去后台看「接口权限与额度」,哪些接口已获得、哪些没有,一目了然。

一个提醒:白名单校验覆盖到哪些接口,官方文档自己两页口径并不一致,一页说覆盖 AppSecret / access_token 的全部服务端调用,另一页只说覆盖取凭据接口。工程上按更严的那个口径处理——把所有出网调用的 IP 都加白,别赌。

边界与注意事项

AppSecret 和 IP 白名单已经搬家了。 微信把「开发接口管理/基本配置」从公众平台迁到了微信开发者平台,现在的路径是 我的业务 → 公众号/服务号 → 基础信息 → 开发密钥。同一个后台的 接口管理 → 接口权限与额度 能查到你账号的真实接口权限,比任何流传的权限表都准。

家宽是动态 IP。 换了还得重加,这个没办法。两个缓解办法:白名单支持 IP 段(形如 172.0.0.1/24),运营商地址段固定时可以按段加;但如果你在 CGNAT 后面、压根没有独享的公网 IPv4,那不是「换了要重加」的问题,是加不了,得换个有固定出口的环境跑。

它只到草稿箱。 这是设计选择,不是没做完。任何能自动群发的东西,我都不想留在自己机器上。

主题 CSS 来自 doocs/md,那个很多人在用的公众号编辑器,所以排出来的样子你可能眼熟。用它的主题请遵守其许可证。

文中的数字都是快照。 star 数、插件数量每天都在变,看到这篇时早已不是这个数。

你也可以搓一个

代码是开源的:

  • 仓库:github.com/coolbreezecoin/dsh-wechat-mp
  • npm:dsh-wechat-mp

前后不到两周。真正花时间的不是排版逻辑,是搞清楚微信接口到底怎么回事:哪个接口对应哪种图、哪个错误码真正意味着什么、以及上面那个把人带偏的顺序。

文档里都没有,只能撞。

但我想说的重点其实不是这个插件,是现在搓一个真的不难了

三天一千五百个插件,不是因为大家突然变强了,是因为门槛塌了:agent 帮你读文档、写代码、跑测试,你负责判断方向对不对。

你每天在忍受的那个重复劳动,大概率也没人做过。

这篇文章的排版和草稿由 dsh-wechat-mp 生成。哪里排得不对,那是我的 bug。

META

发布信息

  • DeepSeek Harness
  • 公众号
  • 插件
  • 自动化

内容如有事实、结论或链接更新,会在本页标注更新时间。

← 返回效率指南