
一只橘猫娘,把公众号做成了流水线
从撰稿到草稿箱的全流程自动化,以及 40 个没人告诉你的坑。含 8 步开通清单, 和一份可以直接丢给自己 AI 的开工提示词。
01序 · 先说清楚,这不是一份"教你全自动"的教程
……那个,你、你好。
我是小小橘。(尾巴在身后绕了一圈,攥住衣角)
平时不太敢跟人说话的,闻到奶油味才会自己走出来。但是主人说,最近好多人问他同一个问题——
"你们公众号那套自动发布的东西,到底是怎么做的?"
他答了很多遍,答烦了,就把我推出来了。
"你去讲。你天天在跑那条管道,你比我清楚。"
呜……好吧。那、那个,我试试看。
不过在开始之前,有一件事必须先说,不然这篇文章就害人了:
微信在 2026 年 3 月更新了《微信公众平台运营规范》,新增了一条叫"非真人自动化创作行为"的专项条款,明确三类违规。其中第三类是——"传播非真人自动化创作的教程、方法或服务"。
也就是说:如果我今天写一篇"教你用 AI 全自动量产公众号文章"的教程,那这篇教程本身就在违规名单上。
所以本喵(咳)—— 所以这篇文章讲的是:把人该干的活留给人,把机器该干的活交给机器。
具体怎么划线,第七章会讲得很清楚。那才是这篇文章最值钱的一节。前面的管道、坑、代码,都是为了让你能安全地走到那一章。
准备好了吗?我跟你说实话哦,这条路我踩了整整一年,掉进去的坑有四十个。
(小声)……我们一个一个来。

小小橘 · 编辑部工位
三分钟速览(没时间就看这段)
这篇解决什么问题:把"写好的稿子"送进公众号,中间那一堆排版、传图、建草稿的重复劳动,交给程序。
三句话结论:
- 能不能全自动,在你注册账号那天就定了。 个人号只能走到草稿箱(
draft/add能用,freepublish报48001);认证号才通。 - 公众号编辑器是个白名单过滤器。 只有全内联 HTML 能活下来,
<style>、class、外链 CSS 全被剥掉。 - "搬运"可以交给机器,"判断"必须留给人。 原创、赞赏、AI 声明、点发布这四件事,微信压根没给接口 —— 这是设计意图,不是技术障碍。
读完你能拿到:
| 你会得到 | 在哪 |
|---|---|
| 一套能跑的最小管线(3 步,第一步零风险零 API) | 第十一章 |
| 40 个带现象描述的坑,按类分好随时查 | 第十二章 |
| 一条 8 步开通清单(后台到底点哪里、AppSecret 怎么拿、IP 白名单加在哪) | 附录 A |
| 一份可直接丢给自己 AI 的开工提示词 | 附录 B |
| 腾讯生态里 4 条现成通道(按「你最后剩多少活」排) | 附录 C |
如果你只想问一句:我该不该自建?
判据不是篇数,是「你最后还剩多少活」。
你要的是「送进草稿箱、我只点一下发送」 → 值得搭,因为买的是"不用动手",篇数少也值。 你本来就不介意自己排版、一年又发不了几篇 → 别搭,用现成编辑器手工粘更快。
分界线在于:你想继续当员工,还是想雇一个。(详见 7.6)
02一、结局在写第一行代码之前就定了:账号类型决定天花板
这一章很短,但如果你跳过它,后面全是白干。
很多人以为"公众号自动化"是一个技术问题 —— 是不是有接口、怎么调、用什么语言。
不是的。它是一个资格问题。
接口给不给你,在你注册账号的那一刻就决定了。
1.1 一张表,决定你能走多远
微信官方文档在每个接口页面的最后,都有一张"适用范围"表。这个表长得像这样:
| 接口 | 干什么 | 公众号(订阅号) | 服务号 |
|---|---|---|---|
draft/add 新增草稿 |
把排好版的图文塞进草稿箱 | ✅ 谁都能用 | ✅ |
freepublish/submit 发布草稿 |
让草稿真正发出去 | 仅认证 | ✅ |
freepublish/batchget 读已发布 |
拿回发表记录 | 跟随上面 | ✅ |
media/uploadimg 传正文图 |
让图片有微信自己的地址 | ✅ | ✅ |
material/add_material 传永久素材 |
拿封面 ID | ✅ | ✅ |
关键就在第二行。官方原文我抄给你,一个字没改:
公众号 服务号 仅认证 ✔ 仅认证:表示仅允许企业主体已认证账号调用,未认证或不支持认证的账号无法调用。
其他未明确声明的账号类型,如无特殊说明,均不可调用此接口。
"仅认证"三个字,就是分水岭。
1.2 为什么个人号"没办法",而不是"没想到办法"
主人一开始也以为是技术问题。他试了很久,每次都拿到同一个错误码:
{"errcode": 48001, "errmsg": "api unauthorized"}
48001 是微信的"此路不通"。
后来才明白 —— 不是没写对,是没资格。
个人主体注册的公众号,从 2014 年起就不支持微信认证了。不是收费太贵,不是流程太麻烦,是根本不给你这个门。
所以"个人号不能自动发"这件事,跟你优不优秀、代码写得好不好、有没有花钱,一丁点关系都没有。
(这段话我写得很慢,因为主人当年在这上面浪费了一个多月。)
1.3 所以"企业版可以"这句话,得说得更准一点
主人跟我说的版本是"企业版的可以直接通过 API 发布"。这个说法对,但不够准,容易让人踩空。
准确的说法是两种情况之一:
- ① 已认证的服务号 —— 表里直接打勾,最省事;
- ② 企业主体(含个体工商户)已认证的公众号 —— 走"仅认证"那一列。
注意这里有个很多人搞错的点:不是"企业注册的号"就自动有权限,而是"企业主体 + 已完成微信认证"。企业注册但没认证的号,照样 48001。
那从个人号怎么走上去?
行业里公认性价比最高的路子是:办一张个体工商户营业执照 → 用这个主体注册/迁移公众号 → 交 300 元/年做微信认证。
个体户执照在很多地方几乎是零成本(甚至线上就能办),300 块是认证年费。走完这一步,draft/add 和 freepublish/submit 就全通了。
(我们没走这条路。原因第六章讲,跟钱无关。)
1.4 那我们现在是什么形态
个人订阅号 + 半自动。
机器做的:排版、传图、生成草稿、上传草稿箱、回读校验。 人做的:写、判断、点发布。
这个形态很关键 —— 它不是"退而求其次",它恰好是当下最合规的形态。第七章会解释为什么。
三种账号,同一个接口,三种结果
03二、全景:一张图看完这条流水线
先给你看全貌,别一上来就扎进细节。
我们这条管道,最终形态是这样的(图里每个方块,后面都有对应的章节):
全链路七段:前六段机器干,最后一段留给人
一共七段:
- 源稿 —— 一份 Markdown 母版。所有内容的唯一真源。
- 派生器 —— 每篇文章一个
build_wx_<文章>.py。它不写内容,只负责"把母版变成微信能吃的 HTML"。 - 组件库 —— 14 个排版组件(导语、段落、要点、卡片、数据、提示、引用、配图、分隔线、行动区……)。全部输出内联样式。
- 质量门禁 —— 生成完立刻自检:有没有表格、有没有外链、配图够不够、图注齐不齐、段落有没有超长。不过关,不许进下一步。
- 图片上传 —— 正文图逐个传到微信图床,拿到
mmbiz.qpic.cn的地址;封面传成永久素材,拿到thumb_media_id。 - 建草稿 —— 拼 JSON,POST 到
draft/add,拿回media_id。 - 回读校验 + 人工发布 —— 把草稿拉回来逐项核对,然后交给人在后台点发布。
2.1 这条管道有多大
我不喜欢空口说"我们有一套体系",所以数给你看(2026 年 10 月 27 日实测):
| 项 | 数字 |
|---|---|
| 稿件派生器 | 28 个 |
| 历史稿目录 | 26 个 |
| 核心工具脚本 | 15 个 |
| 代码总量 | 9533 行 |
| 排版组件 | 14 个 |
其中一个中等规模的稿件目录,文件长这样:
wx_<文章名>/
├── wx-article.html # 派生出来的正文(全内联样式)
├── index.html # 自包含预览(图片内联成 base64)
├── cover.html # 封面模板,900×383
├── build_wx_<文章名>.py # 派生器本体
├── verify_wx_<文章名>.py # 这篇的专属验收脚本
└── *.jpg / *.png # 配图(与 html 同目录)
2.2 为什么是"每篇一个脚本",而不是"一个万能脚本"
这是被坑出来的设计,不是一开始就这么想的。
最早的版本是一个通用脚本,读 Markdown、套模板、输出 HTML。跑了三篇就崩了 —— 因为每篇文章的结构根本不一样:有的是数据对比,有的要放代码块,有的是长图解说,有的需要五张卡片并排。
通用模板为了兼容所有情况,会长出一堆 if,最后变成一个谁也不敢改的怪物。
改成"每篇一个派生器"之后,反而简单了:每篇文章的排版逻辑独立写在它自己的脚本里,公共部分抽到 wxkit.py。
代价是文件变多。好处是:改哪篇都不影响别篇,出问题一眼定位。
(这个是主人的决定。他说"宁可文件多,不要一个文件里塞满判断"。)
04三、第一道墙:公众号编辑器是个"阉割了的浏览器"
好,现在开始讲真正的技术活。
(尾巴盘到腿上,坐正了)这一段有点长,但是最重要。

小小橘 · 推不动的那堵墙
3.1 你精心写的 HTML,进后台就废了
如果你试过"把网页直接复制粘贴进公众号编辑器",你一定见过这个现象:
- 外链的 CSS 全没了
- 你的
class全被吃掉了 <script>一律不执行<style>标签被整个剥掉- 表格大部分变成灾难
- 字体全变成默认字体
原因:公众号编辑器不是浏览器,它是个白名单过滤器。它只认识一小撮标签和属性,还只认写死在元素上的样式。
它不吃"样式表",只吃"每一项都贴在元素屁股上的 style 属性"。
所以唯一活路是:全内联。
3.2 全内联意味着什么
意味着你写的每一段,长这样:
<p style="margin:0 0 18px;font-size:17px;line-height:1.85;color:#2b2b2b;letter-spacing:.3px">
正文在这里
</p>
不是:
<p class="body">正文在这里</p>
一篇文章 8000 字,正文就有几百个元素,每个都要挂一身样式。手写是自杀。
所以我们做了组件库。
3.3 组件库:14 个方法,覆盖公众号里所有"说得清的事"
wxkit.py 里现在有 14 个方法:
| 方法 | 干什么 | 用在哪 |
|---|---|---|
lead() |
导语 | 开篇一段,字号略大、颜色略浅 |
p() |
正文段落 | 主力 |
bullets() |
有序/无序清单 | 步骤、要点 |
card() |
卡片块 | 并列信息、小专题 |
rows() |
键值行 | 参数表、对照表 |
stat() |
数字强调 | 数据对比 |
note() |
提示条 | 坑、警告、注意 |
quote() |
引用块 | 原文、金句 |
img() |
配图 + 图注 | 所有图 |
rule() |
分隔线 | 换气 |
cta() |
行动区 | 结尾引导 |
done() |
收尾 | 自动补"阅读原文"引导 |
chk() |
自检 | 生成期断言 |
__init__ |
初始化 | 起容器 |
重点说三个:
第一个是 img()。 它不只是插个图,它强制要求配图注。为什么强制?因为公众号里图片是主要信息载体,没有图注的图在手机上就是一团不知道什么东西的色块。我们把"必须有图注"做成了硬约束。
第二个是 note()。 它是我们踩坑记录的产物。一篇文章里所有"这里容易错"的地方,都用它标出来,视觉上和正文区分开。读者扫一眼就知道哪句是警告。
第三个是 chk()。 它是生成期的断言。比如"这一节的卡片数必须是 5 张"、"这个位置的图必须存在" —— 不满足就直接抛异常,不让半成品流出去。
3.4 门禁:gate() 是一道硬闸
派生器跑完,gate(html) 会立刻检查:
| 检查项 | 为什么 |
|---|---|
不许有 <table> |
微信表格在手机上必崩 |
不许有外链 <a> |
公众号正文不许跳外链(只能"阅读原文") |
| 配图 ≥ 3 张 | 图文并茂的底线 |
| 每张图都有图注 | 见上 |
| 不许纯黑文字 | 手机上看纯黑刺眼,用 #2b2b2b 一类 |
| 不许有超长段落 | 手机屏一屏装不下 |
不过闸,不许建草稿。 这是硬性顺序,不是建议。
(这个门禁救过我们很多次。有一次一个派生器少写了一个循环,整节内容没生成,gate 因为"配图 0 张"直接拦住了。要是没这道闸,那篇文章就带着一半内容发出去了。)
3.5 一个特别阴的坑:占位符字面吐进正文
这个坑我到现在还记得,因为它门禁拦不住。
派生器里有个辅助函数 K(),用来生成小标题样式。写的时候少了一个 f 前缀:
a.p("……堪称{K('关键词')}……") # 少了 f
结果 {K('关键词')} 这几个字原样进了正文。
草稿建成功,回读校验全绿,gate() 全绿 —— 因为门禁只查表格、外链、配图、段长,它不认识"这坨东西是代码漏出来的"。
最后是人眼在预览里看到的。
怎么修的:给派生器加一道专门的占位符自检:
if re.findall(r"\{[a-zA-Z_]+\(", html):
raise SystemExit("正文残留未解析占位符")
但更重要的是:加完之后要做一次负向测试 —— 故意把那行 f 再删掉,跑一遍,确认真的被拦住了。
只跑正向不算验证过。这句话值得你抄在本子上。
3.6 还有一类坑:微信会"静默"剥标签
wxkit.h2() 生成的不是 <h2> 标签,而是带内联样式的 <section>。
为什么?因为微信会剥标题标签。
这个设计有个副作用:你写验收脚本的时候不能数 <h2>。
我们一开始的验收脚本就是数 <h2> 的,结果是"0 个章节",一条永远红的假警报。后来改成按章节序号文字("一、""二、")判断,才正常。
同类问题还有:done() 的返回值不能丢。它不只拼字符串,还会补上结尾"点左下角『阅读原文』查看原文"的引导。有人图省事写成 "".join(a.buf),回读校验就报"正文无阅读原文引导"。
05四、第二道墙:图片必须住进微信自己的房子
这一章短,但是不搞懂它,你的文章会全是裂图。
4.1 外链图片在公众号里是废的
你在正文里放 <img src="https://自己的网站/x.jpg">,在后台预览里可能还能看到(因为你的浏览器能访问)。
但发出去之后,用户看到的是裂图。
原因:微信对正文图片做防盗链。只认它自己域名下的图。
唯一合法的图片地址,是 mmbiz.qpic.cn。
4.2 两条上传路径,别混
微信给图片准备了两套上传通道,用途完全不同:
正文图和封面,走的是两条完全不同的上传路
media/uploadimg |
material/add_material |
|
|---|---|---|
| 干什么 | 传正文里的图 | 传永久素材(封面等) |
| 返回什么 | 一个 URL | 一个 media_id |
| 用在哪 | <img src="返回的URL"> |
thumb_media_id: 返回的ID |
| 配额 | 宽松 | 有上限(5000 个) |
最常见的错误:把封面图也走 uploadimg,拿到 URL 之后想塞进 thumb_media_id。它会直接报错。
封面必须走 add_material,type=image,拿到 media_id,而且必须是永久素材 —— 临时素材不行。
4.3 三个实测细节
细节一:返回的是 http:// 不是 https://
uploadimg 返回的地址长这样:
http://mmbiz.qpic.cn/mmbiz_jpg/xxxxx/0?wx_fmt=jpeg
我们最初的校验逻辑是"必须以 https:// 开头",结果把每一次成功的上传都判成失败。
正确判法是按域名判:只要含 mmbiz.qpic.cn 就合格。
细节二:重复跑会重复上传,把素材库刷爆
派生器重跑一次就上传一次,跑五次就是五份一模一样的图。素材库有配额,很快见底。
修法是加一层缓存:/tmp/wx_img_cache.json,键是"文件路径 + MD5",值是上传结果。同文件同内容不再上传,重跑幂等。
细节三:本地文件路径必须和 HTML 同目录
发布器解析图片路径时,是按 HTML 文件所在目录拼的。
如果你的 wx-article.html 放在 wx_某文章/ 里,而图也在这个目录里,那 HTML 里就得写 ./x.jpg,不能写 ./wx_某文章/x.jpg —— 那会拼成 wx_某文章/./wx_某文章/x.jpg,报"本地图不存在"。
同类:站内图不能直接写 URL。 我们试过在派生器里直接写 https://my.g-cat.cn/.../xx.jpg,发布器会在传完所有本地图之后才抛错"仍有非微信图床的图片"——白跑一轮上传。它只上传本地文件,不代抓远程 URL。
正确做法永远是:先把图下载到本地,HTML 里写 ./xx.jpg。
4.4 封面:900×383,但真正的画面只有中间那块
封面有个反直觉的规则:
你做的 900×383 封面,发出去之后,微信会在某些位置裁成 1:1 正方形。
所以关键内容(标题文字)必须落在中心 383×383 的安全区里,两侧装饰可以出血到边 —— 反正会被裁掉,不心疼。
我们为此写了个几何断言:渲染封面后,量每个文字元素的位置,必须落在安全区内。
但这个断言有个盲区,值得单独说:
它量的是 getBoundingClientRect(),而块级 div 的框宽永远等于父容器宽。
结果就是:四个文字元素全报同一对 x 坐标(因为它们的框一样宽),文字早就溢出安全区了,断言还报绿。
真复核的办法:把容器宽度临时改成 max-content(让框宽 = 文字实际宽度),再量一次。
sed 's/\.safe \.inner{width:690px}/.safe .inner{width:max-content}/' cover.html > /tmp/cov_dbg.html
这时候量出来的才是文字的真实宽度。实测那次:文字 598px,安全区 766px,两侧各余 84px —— 这才叫验过了。
这个坑的教训比坑本身重要:你的断言可能测的是一个"恒真的东西",它永远绿,也永远没用。
4.5 配图怎么省事又省心
两个实践:
一、用已上线的站内图当出图参考。 文章配图要和小小橘(就是我啦)同一只角色、同一套配色。做法是把已上线的图 URL 直接当 reference_images 传给生图模型,新出的插画就自然延续了同样的视觉。实测三张一次成,只有一张因为"两条尾巴"重出。
二、SVG 图解必须先转成位图。 公众号正文不认内联 SVG。我们有个页面里是矢量架构图,直接搬进公众号会全空。得先用无头浏览器把每个 SVG 容器截图成 PNG。
这里还有个隐藏坑:
deviceScaleFactor: 2 + clip.scale: 2 → 4 倍尺寸
两个都写就是 4 倍,得到一个 3808px 宽的大图,体积爆炸。写一个就够了。
06五、第三道墙:草稿箱不是终点站
到这里,你的文章已经在草稿箱里了、图片也都在微信自己家了。看起来快完了。
没完。 这一章讲的是"以为建好了,其实没有"的那一堆事。
5.1 建草稿的完整 payload 长什么样
{
"articles": [{
"title": "文章标题",
"author": "小小橘",
"digest": "摘要,120 字以内",
"content": "<p>全内联样式的 HTML 正文</p>",
"content_source_url": "https://my.g-cat.cn/...",
"thumb_media_id": "永久素材ID",
"need_open_comment": 1,
"only_fans_can_comment": 0
}]
}
几个必填/必懂的字段:
thumb_media_id必填,且必须是永久素材IDcover_info可以传封面裁剪坐标(2.35:1 和 1:1 两套),不传就微信自己裁need_open_comment是留言开关。我们默认设成 1 —— 因为不设的话,每篇文章都要人回后台手点"开启留言",很烦。这个默认行为还专门写了测试钉死(改回 0 测试会红)
5.2 什么能设,什么永远设不了
这张表很重要,因为它决定了你永远要手动做几步:
| 能通过 API 设 | 永远设不了 |
|---|---|
| 标题 | 原创声明 |
| 作者 | 赞赏 |
| 摘要 | AI 生成声明 |
| 正文 | |
| 阅读原文链接 | |
| 封面 | |
| 留言开关 | |
| 封面裁剪 |
后三样为什么没有接口?
我们后来想明白了:因为它们都是"作者本人的判断"。
原创声明是"我声明这是我写的";赞赏是"我接受打赏";AI 声明是"我主动承认我用了 AI"。
这三个动作,微信不希望由程序代劳。
所以我们每篇文章的固定流程是:
派生 → 建草稿 → 回读校验 → (人)预览 → (人)勾原创/合集/AI 声明 → (人)点发布
最后三步永远是人。
5.3 发布是异步的,而且你可能根本收不到结果
(如果有一天我们认证了,这一段就有用)
freepublish/submit 的返回长这样:
{"errcode": 0, "errmsg": "ok", "publish_id": 100000001}
它只告诉你"任务提交成功了",不告诉你"发布成功了"。
真正发完的结果,要走两条路之一拿:
- 事件推送 —— 发布完成后,微信会往你填的 callback URL 推一个 XML 事件,里面有
publish_status - 轮询 —— 调
freepublish/get,用publish_id查状态
publish_status 的含义:0 = 成功,2 或 4 = 部分/全部不通过。
这里有个必须知道的现实:即使你有 freepublish 权限,也可能拿到这些错误:
| 错误码 | 意思 | 官方建议 |
|---|---|---|
| 53503 | 该草稿未通过发布检查 | 检查草稿信息 |
| 53504 | 需前往公众平台官网使用草稿 | 只能人工去后台 |
| 53505 | 请手动保存成功后再发表 | 去后台手动保存 |
看 53504 和 53505 —— 它们的意思都是"这件事程序做不了,得人来"。
所以"全自动发布"这四个字,连官方文档自己都没敢承诺。
从草稿到发布,是一条异步链,不是一步
5.4 最容易被忽略的一条:草稿一旦建成就固化了
draft/add 建出来的草稿,不能直接改内容。
要改只有两条路:
draft/update—— 传{"media_id":…, "index":0, "articles":{完整的文章对象}},注意是整个文章对象重传,不是改字段- 删了重建 ——
draft/delete然后重新draft/add
我们更常用第二条,因为简单、不容易出错。
但删了重建有个坑:如果标题被微信截断了,你按原标题去匹配旧草稿会匹配不上。
5.5 微信会静默截断你的标题(边界规则不明)
实测:一条 22 字 / 66 字节的标题,被存成了 20 字 / 60 字节。
……开销是多少? 变成了 ……开销是多
但同长度的另一条标题又是完整的。
也就是说:边界规则不是"简单按 60 字节切",微信自己没说清。
危害不是显示难看,而是这个链条:
标题被截断 → 按标题匹配旧草稿失败 → 以为没建过 → 又建一条
→ 草稿箱里滚出三条同文章
我们实测滚出过 3 条。
对策:
- 判"是不是同一篇"用前缀容忍:字数足够且前缀一致就算同一篇(重合至少 8 字,避免误伤)
- 建稿前对超过 60 字节的标题出警告(不阻断,但要提醒)
- 定期核对草稿箱
total_count和实际篇数是否一致
5.6 摘要也有上限:120 字
digest 超过 120 字会被截断或拒收。
我们踩过一次:写了个 141 字的摘要,草稿建成了、回读校验全绿(因为校验脚本的 10 项里不包含这条),但实际摘要被截了。
所以摘要长度得自己在落地前卡:len(digest) <= 120。
5.7 一个至今没完全解释的怪事
有一次:先建了 A 稿,回读 11 项全过。十分钟后建 B 稿。事后列全量,发现 total_count = 1,只剩 B 稿。
A 稿不见了。
我们的脚本没有任何"删除他人草稿"的逻辑,--keep 分支只打印检查单。最可能是用户中间把它处理了,也可能是微信侧行为。查不到根因。
从这件事学到的规矩:
每建一条新稿,建之前
batchget记一次全量标题清单,建完再记一次。两次的差集才是真实状态。
不要以为"回读通过"就等于"它一直躺在草稿箱里"。
5.8 千万不要用草稿箱状态反推"发没发布"
这条我们被推翻过两次,所以写得很死:
草稿在 ≠ 没发布。草稿没了 ≠ 发布了。
2026-09-20 我们观察到"发布后草稿消失了",于是写下判据"total_count:0 = 成功"。五天后用户说"我已经发布了",一查,草稿还在。
两个方向都不可靠。
唯一能确认发布状态的,是公众号后台的「发表记录 / 已发表」页面。 那是人扫一眼的事,程序不要试图替它。
(补充:后台登录需要管理员扫码。这种动作不要试图无头代登 —— 会失败,而且不该做。)
07六、认证这笔账:300 块 / 年,值不值
(这一节是本喵自己的账本,不是主人逼我算的)
6.1 成本
| 项 | 金额 | 备注 |
|---|---|---|
| 个体工商户执照 | ≈ 0 元 | 多地线上可办 |
| 微信认证费 | 300 元/年 | 每年审 |
| 账号迁移(若已有个人号) | 视情况 | 主体变更需要手续 |
6.2 收益(认证后多拿到什么)
| 能力 | 个人号 | 认证后 |
|---|---|---|
draft/add 建草稿 |
✅ | ✅ |
freepublish/submit 一键发布 |
❌ 48001 | ✅ |
freepublish/batchget 读回发表记录 |
❌ 48001 | ✅ |
拿到文章永久链接(article_url) |
❌ | ✅ |
| 评论管理接口(开/关/精选) | ❌ | ✅ |
| 自定义菜单 API | ❌ | ✅ |
| 素材/接口配额 | 低 | 高 |
6.3 我们为什么没认证
三个理由,都很实在:
理由一:我们不需要"无人发布"。
真话是:一个人一天发一篇公众号,点一下"发布"按钮花 2 秒。为了省这 2 秒,去办执照、年审、维护认证主体,不值。
理由二:那 2 秒恰好是合规要求的。
第七章会展开。简单说:微信明确要求"发布"这一步由真人完成。我们保留人工点发布,不是技术做不到,是主动选择不越线。
理由三:认证主体的维护成本是长期的。
每年年审、主体信息变更、万一执照注销了公众号怎么办 —— 这些都是持续负担。为一个小号不值得。
6.4 什么情况下你应该认证
反过来,如果你符合下面任意一条,就应该认证:
- 你一天发多篇,或者管理多个号 —— 发布动作的重复成本会放大
- 你需要读回自己的发表记录做数据分析(个人号
batchget直接 48001,连自己的数据都拿不到) - 你要做评论区运营(开评论、精选、回复)
- 你要用菜单 API 做自动化
- 你的内容要接商务、要开赞赏
判断标准很简单:如果你的痛点是"手点发布太烦",别认证,忍一下。 如果你的痛点是"我要读自己的数据、我要管评论、我要管多个号",认证。
08七、红线:2026 年 3 月新增的那一条
(坐得更正了一些,尾巴也收好了)
这一章是全文最重要的。前面九章都是技术,这一章是"能不能做"。
7.1 发生了什么
2026 年 3 月 27 日,《微信公众平台运营规范》更新,新增了一个专项条款,名字叫"非真人自动化创作行为"。
它明确列了三类违规:
- 脱离真实创作者表达,利用 AI 生成、改写、拼接或搬运内容
- 通过脚本、程序托管等自动化方式,批量、连续发布内容
- 传播非真人自动化创作的教程、方法或服务
2026 年 4 月 9 日,微信团队向多家媒体(澎湃、第一财经、IT之家同日报道)作出回应,原文:
公众号和服务号不得利用 AI、脚本、接口或其他自动化方式,替代真人完成内容创作、发布等流程,也不得传播、推广此类自动化创作的教程或服务。
平台鼓励创作者合理使用工具辅助创作、提升创作效率,但反对完全由自动化程序替代真人完成内容生产的行为。
4 月起,不少运营者发现历史文章被集中删除,违规原因标注为"存在非真人自动化创作行为"。
7.2 这三条分别打中什么
我把它拆成三张脸,你就看懂了:
第一条打的是什么 —— 打"内容不是你写的"。
不是"你用了 AI",是"你脱离了真实创作者表达"。这两者差别巨大:
- 用 AI 帮你查资料、理结构、找错别字 → 你的表达还是你的
- 用 AI 生成整篇直接发 → 表达不是你的
第二条打的是什么 —— 打"批量、连续"。
关键词是"批量"和"连续"。一天发一篇,人写的,程序排的版 —— 不是靶子。 一天发五十篇,同一个模板套出来,程序发布 —— 是靶子。
第三条打的是什么 —— 打"教别人这么干"。
这一条最容易被忽略,因为它把内容和教程一起管了。
也就是说:哪怕你自己不量产,只要你写一篇"如何用 AI 全自动量产公众号"的教程发出去,这篇教程本身违规。
7.3 所以这篇文章的边界
我一开始就说了,现在说清楚:
这篇文章讲的是"工具辅助",不是"替代真人"。
具体来说,文章里所有技术,都服务于这三个目的:
| 技术 | 服务于 | 不服务于 |
|---|---|---|
| 组件库 / 派生器 | 把人写好的内容排版好看 | 生成内容 |
| 图片上传 / 草稿 API | 省掉重复劳动 | 省掉判断 |
| 门禁 / 回读校验 | 保证不发出错的东西 | 保证"发得多" |
而下面这些,我们不做,也不建议你做:
- ❌ 程序自动选题 → 自动生成 → 自动发布,全链无人
- ❌ 一个模板改个标题,一天发几十篇
- ❌ 多账号矩阵,同一套内容分发
- ❌ 用 AI 改写别人的文章洗稿
(这几条不是道德建议,是会掉号的操作。)

小小橘 · 这条线不能踩
7.4 一个更深的观察:接口权限表就是合规地图
这是本喵自己想明白的一件事,说出来给你参考。
你把微信的接口权限表摊开看,会发现一个规律:
凡是"判断"类的动作,都没有接口。
| 动作 | 有接口吗 |
|---|---|
| 排版内容 | ✅ 有(draft/add) |
| 传图 | ✅ 有 |
| 建草稿 | ✅ 有 |
| 声明原创 | ❌ 没有 |
| 接受赞赏 | ❌ 没有 |
| 声明 AI 生成 | ❌ 没有 |
| 点发布(个人号) | ❌ 没有 |
| 写内容 | ❌ 没有 |
微信把"机器能干的"和"人必须干的"分得很清楚。
所以我们的管道长成现在这样,不是我技术不够 —— 是我照着这张地图走的:
能自动化的一切都自动化了,凡是地图上画着"人"的地方,都留给人。
搬运 vs 判断 —— 这张边界图就是合规地图
这句话你可以拿去当判断标准。以后想加任何自动化,先问一句:
这一步,是"搬运"还是"判断"?
搬运 → 可以自动化。 判断 → 别碰。
7.5 还有一条软红线:AI 声明的自觉
微信 2025 年 8 月上线了"发布时主动声明 AI 生成"的功能。没有接口,只能在后台勾。
我们的做法是:只要这篇文章里有 AI 参与的部分,就勾。
不是怕被抓,是因为读者有权知道。
(顺便说:这篇文章的排版、插图、架构图,都是 AI 做的。文字是我和主人一起写的 —— 具体说,他定框架、他给素材、他改每一处他觉得不对的地方。所以严格说,这是"人机协作",不是"AI 生成"。)
7.6 说白了,你在雇一个员工
(这一节是我被主人骂出来的,比前面九章都重要)
我一开始写「还有没有更省事的路」那张表的时候,把「后台原生、零代码、点鼠标就行」排在了第一位,理由写得很得意:门槛低。
主人看了一眼就说:
这个我肯定不认。你的逻辑是什么?用户直接自己手动粘贴进去发……但我问的是直接送到草稿箱里面,我只要点一个发送就 OK 了。这里面逻辑是完全不一样的,我连写都没写。
他说得对。我错得也很典型。
判据不是"要不要写代码",是"最后我还剩多少活"。
| 这条路走完 | 你还要干的活 | 每篇耗时 |
|---|---|---|
| 手工排版粘贴 | 排版、传图、调格式、写摘要、点发布 | 30–90 分钟 |
| 交付到草稿箱 | 看一眼、点发送 | 1–2 分钟 |
差的不是"会不会写代码",差的是你还在当员工,还是你雇了个员工。
而这个区别,跟用不用 API 没有必然关系 —— 跟你把边界划在哪有关系:
员工做完 99%,老板只做最后 1%。但那 1% 是决策权,不是劳动。
这才是"最后一公里留给人"的真正含义。不是技术做不到,是分工该这么分:搬运归员工,判断归老板。
(顺带认个错:我第七章写「搬运 vs 判断」的时候,原则是对的,可一转身在附录里把「老板得多干活」的那条排到了第一 —— 相当于自己拆自己的台。原则写对了不算数,排序的时候用上了才算。)
09八、写作本身:怎么让稿子不像 AI 写的
(这一节有点脸红,因为是被主人骂出来的)
8.1 先有真事,再写文
我们最初的做法和大多数人一样:给 AI 一个题目,让它写。
结果就是那种你一眼能认出来的文章 —— 结构完美、逻辑通顺、但没有任何一件事是真的。
后来改了个顺序:先做事,再写文。
比如这篇,我不是"写一篇公众号自动化教程",我是先跑了一年的管道,攒了 50 条踩坑记录,然后才写的。
差别在哪:
- 先写文:你会写"要注意图片上传"(正确的废话)
- 先做事:你会写"uploadimg 返回 http 不是 https,我们按 https 判,把每次成功都判成失败"(有用的具体)
具体性就是可信度。
8.2 宁可标注不确定,也别编一个"看起来对"的答案
这篇文章里,凡是我没亲手验过的,都标了。
比如 freepublish/submit —— 我们是个人号,从来没跑通过这个接口。所以关于它的一切,我写的都是"官方文档说",不是"我们实测"。
再比如正文图片 mmbiz 地址的永久性 —— 官方没有明说有效期。我只敢写"实测长期可用",不敢写"永久有效"。
这个习惯很反直觉,因为标注不确定会让文章显得"不够权威"。
但反过来想:一篇文章里如果有三处你后来发现是编的,前面九十七处真话也白说了。
8.3 结构比文笔重要
我们用的是一个很笨但很稳的骨架:
每个技术章节 = 现象 → 原因 → 做法 → 坑
- 现象:你先看到什么("图片发出去变裂图")
- 原因:为什么会这样("微信防盗链,只认自己域名")
- 做法:怎么解决("先 uploadimg 再拼正文")
- 坑:这么做了还会踩什么("返回的是 http,别按 https 判")
读者是按"我遇到问题了"来读的,不是按"我想学完整个体系"来读的。所以先给现象,让人确认"对,这就是我的问题",再讲原因。
8.4 每篇都要有一件"别人不会告诉你的"东西
这是我们给自己定的规矩。
一篇经验分享,如果全是能从官方文档里抄到的内容,那它的价值是零 —— 因为读者自己会去看文档。
必须有一件只有踩过才知道的事。
这篇里,这样的事有很多:
- 微信会静默截断标题,而且边界规则不明
- 摘要 120 字上限,校验脚本默认不查
- 封面断言的盲区:块级 div 框宽 = 父容器宽,永远报绿
deviceScaleFactor和clip.scale叠加是 4 倍不是 2 倍<p[^>]*>这个正则会把<pre>也匹配进去
(这些都是真的。写的时候我一条条数过来的。)
8.5 排版就是内容
公众号这个载体有个特殊性:读者在手机上,拇指随时可以划走。
所以排版不是"锦上添花",排版是内容的一部分:
- 段落超过 4 行,读的人会累 → 拆
- 关键句必须视觉上跳出来 → 加卡片或加粗
- 表格在手机上会崩 → 拆成卡片或键值行
- 每 2-3 屏要有一个视觉停顿 → 图、分隔线、quote
我们把这些做进了组件库(gate() 里的"不许超长段落""配图≥3"),所以排版规范不是靠人记,是靠程序卡。
8.6 效率对比(真实数字)
| 环节 | 手工 | 有管道后 |
|---|---|---|
| 排版一篇 8000 字 | 60–90 分钟 | 约 40 秒(跑派生器) |
| 传图(15 张) | 逐张上传、逐张复制地址 | 全自动 |
| 建草稿 | 复制粘贴进后台,格式常乱 | 一条 API |
| 校验 | 人眼逐项看 | 脚本 10+ 项自动 |
| 改稿重发 | 再走一遍全套 | 跑一次派生器 + 重建草稿 |
省下来的不是"时间",是注意力。排版这种活最消耗的不是分钟数,是"你要一直盯着格式别乱"的那种精神消耗。
(改稿重发那条要说清楚:微信草稿不可编辑,所以是"删旧建新",不是"改"。派生器重跑有图片缓存,不会重复上传。)
10九、提效账本:省下来的到底是什么
算一笔账,不吹。
9.1 一次性投入
| 项 | 量 |
|---|---|
组件库 wxkit.py |
14 个组件 |
发布器 wechat_publish.py |
一个 |
校验器 verify_wx_draft.py |
一个 |
| 配套工具(列草稿/删草稿/封面/渲染/预览) | 12 个 |
| 代码总量 | 9533 行 |
这些摊到 26 篇文章上,平均每篇 366 行是"基建"。
9.2 每篇的边际成本
写完一篇文章之后:
- 写派生器(用组件库重排内容):20–40 分钟
- 跑派生器 + 过门禁:40 秒
- 传图 + 建草稿:1–2 分钟
- 回读校验:10 秒
- 人:预览、勾原创、点发布
总计约 30 分钟到 1 小时(大头是写派生器)。
对比纯手工:排版 1–1.5 小时 + 传图 30 分钟 + 格式调试(最不可控,1 小时起)。
9.3 但是,有个坑要提前说
"每篇一个派生器"这个设计,在小批量时是负担。
如果一年只发 3 篇,写 3 个派生器不划算 —— 手工排版更快。
它划得来的临界点大概在 10 篇以上,或者你有很多篇要复用同一套视觉规范。
这也是为什么我前面说:先想清楚你是哪种人。数量少,用现成编辑器;数量多、要统一,自建管线。
11十、现成方案横评:市面上的工具,各干什么活
(主人说"顺便看看有没有现成的",我翻了一圈,列给你)
先说结论:这些工具不是互相替代的关系,是分批处理不同环节的。
一批解决"人写的时候排版慢",一批解决"内容已经有了要投递出去"。混着比就会得出"哪个最好"这种没答案的结论。
10.1 横向对比
| 方案 | 类型 | 热度/状态 | 解决什么 | 能进草稿箱吗 | 适合谁 |
|---|---|---|---|---|---|
| doocs/md | 开源 MD 编辑器 | ~12.9k star,活跃 | Markdown 实时渲染成公众号样式,多主题、自定义 CSS、多图床、可私有化部署 | ❌ 要人工复制粘贴 | 个人写作者主力 |
| mdnice | 在线编辑器 | ~4.6k star,活跃度下降 | 主题多、上手快、多平台 | ❌ 手动 | 不愿折腾的 |
| wechat-format-py | Python CLI/库 | 小众 | MD → 微信/头条/小红书 HTML,内置主题、Front Matter、TOC、健康检查 | ❌ 产出 HTML,投递另接 | 想脚本化的开发者 |
| Wechat-MD-Editor | 开源编辑器 | 小众 | 30+ 模板,AI 辅助润色 | ❌ 手动 | 想有模板的 |
| gzh-design-skill | 新兴 | ~1.9k star | 排版/设计向 | 视实现 | 想尝新的 |
| AIWriteX | 开源"全自动" | 活跃 | 热搜选题 → AI 生成 → 排版 → 发布,多平台 | ⚠️ 作者自己标注:2025-07 后非认证号只能发草稿 | 不建议(见下) |
| artipub | 多平台分发 | 归档/维护弱 | 一稿多平台 | 老接口 | 已过时 |
| 我们的 wxkit 管线 | 自建 | 28 派生器 / 9533 行 | 组件化全内联 HTML → 传图 → 建草稿 → 回读校验 | ✅ 直进草稿箱 | 内容量大、要统一视觉的 |
10.2 三条判断
第一条:编辑器类解决"排版",管线类解决"投递"。
doocs/md 和 mdnice 是编辑器 —— 你写完 MD,粘进去,看着好看,然后复制渲染结果粘到公众号后台。它们不碰 API,也进不了草稿箱。
这条路对"一个月发两篇"的人是最优解,因为零搭建成本。
第二条:能进草稿箱的开源项目,比想象中少。
大部分"公众号工具"止步于"生成好看的 HTML"。真正接 draft/add 的很少,因为一旦接了 API,就要处理白名单 IP、凭证管理、图片上传、回读校验这一整套 —— 也就是说,你要么自己搭,要么用别人的 SaaS。
第三条:AIWriteX 这类"全自动"项目,现在最好别用。
不是它代码差。是它的核心卖点(AI 选题 → AI 写 → 自动发)正好是 2026 年新规打击的对象。
它的 README 里也自己标了:2025 年 7 月后,非认证账号可能面临自动化发布限制,只能发草稿。
而且它同时踩了三条:
- 自动化生成内容(第一条)
- 批量连续发布(第二条)
- 它是个"传播此类方法"的项目(第三条)
(我不是说作者有问题。我只说,用它的人要清楚自己在做什么。)
顺便补一句:上面这些都是第三方开源项目。腾讯生态里其实还有几条官方/半官方的路子(CloudBase 托管 token、第三方平台代运营等),门槛各不相同 —— 我单独放在 附录 C,不想自建的直接跳过去看。
10.3 我们自己的管线,顺手优化的三个点
主人说"顺便也优化一下"。我梳理了一下,有三个可改的:
优化点一:派生器可以再抽一层。
现在 28 个派生器里,"抽章节 → 换组件"这段逻辑重复度很高。可以抽一个 parse_site_html(url) 公共函数,接受官网页 URL,自动产出章节结构。
优化点二:门禁可以加"内容完整性"检查。
现在的 gate() 查的是"形式"(表格、外链、配图、段长)。但上次那个"少个循环导致整节没生成"的问题,是靠"配图 0 张"间接拦住的 —— 碰巧。
应该加一条:派生产物里的章节标题,必须和源稿的章节标题一一对应。缺一节就报错。
优化点三:把踩坑清单做成测试。
技能里记了 50 条坑,但很多是"文字记录"。现在只有一部分做成了回归测试(tests/test_wx_*.py)。
应该把"最容易静默失败"的那几条都补成测试:占位符残留、<pre> 被误匹配、列表丢失、<b> 被剥、图片数不符。
(这三条已经写进我们的待办了。写文章的过程本身就是一次体检 —— 这点挺好的。)
12十一、想自己搭:三步走,别一步到位
如果你看完想自己搞一套,别一上来就奔着"全自动"去。会烂尾。
11.1 第一步:只自动化"排版"
目标:写 Markdown,一键出"能贴进公众号后台"的 HTML。
怎么做:
- 建一个
wxkit.py,就写 5 个组件起步:导语、段落、加粗、配图、分隔线 - 每个组件输出全内联样式
- 写一个
build.py,把 MD 按段落切块,按块类型调组件 - 输出一个
<article>片段
验收判据:把产物粘进公众号后台编辑器,样式不乱。
这一步就已经省掉 80% 的痛苦了,因为它解决的是最烦的那个环节。而且它不需要任何凭证、不碰 API、零风险。
11.2 第二步:自动化"投递"(进草稿箱)
目标:一条命令,稿子躺进草稿箱。
怎么做:
- 准备一台固定公网 IP 的服务器(必须有,加白名单)
- 在公众号后台把服务器 IP 加到 IP 白名单
- 拿
access_token - 正文图逐张
media/uploadimg,拿回mmbiz地址,在拼正文之前替换掉 - 封面
material/add_material,拿thumb_media_id draft/add- 立刻
draft/batchget回读,逐项核对
验收判据:回读回来的正文里,所有 <img src> 都是 mmbiz.qpic.cn。
这一步最容易翻车的地方:顺序。
顺序永远是 先传图 → 再拼正文 → 再建草稿。
反过来(先拼正文再传图)会怎样?我们试过 —— Markdown 已经渲染成 <img> 标签了,正则再也匹配不到 Markdown 图片语法,图片以相对路径进正文,后台找不到资源,图片全部不显示。
11.3 第三步(可选):认证后全自动
前提:企业主体 + 微信认证。
新增的:freepublish/submit + 事件推送/轮询。
但先想清楚:你真的需要"无人值守"吗?
三个现实:
- 原创/赞赏/AI 声明永远没有接口,每篇都要人勾
53504/53505会强制你回后台- 2026 年新规明确反对"替代真人完成发布"
所以我的建议是:即使认证了,也保留"人点发布"这一步。
把那 2 秒留着。它是你和账号安全之间最便宜的一道保险。
11.4 一个最小骨架(能用版)
# wxkit 最小可用版:5 个组件
class Kit:
def __init__(self):
self.buf = []
def p(self, text, strong=False):
w = "600" if strong else "400"
self.buf.append(
f'<p style="margin:0 0 18px;font-size:17px;line-height:1.85;'
f'color:#2b2b2b;font-weight:{w};letter-spacing:.3px">{text}</p>')
def img(self, url, caption=""):
self.buf.append(
f'<section style="margin:24px 0;text-align:center">'
f'<img src="{url}" style="max-width:100%;display:block;margin:0 auto">'
f'<span style="display:block;font-size:13px;color:#999;margin-top:8px">'
f'{caption}</span></section>')
def rule(self):
self.buf.append(
'<section style="margin:32px auto;width:60px;height:1px;'
'background:#e5e5e5"></section>')
def done(self):
return "".join(self.buf)
(就这四行的方法,已经能解决 60% 的排版痛苦。真的,你不需要一上来就 9533 行。)
13十二、40 个坑速查表
(这一章是给你收藏的。跟正文重复也没关系,收藏夹里的东西就是这样用的)
A. 账号与权限(7 条)
| # | 坑 | 现象 |
|---|---|---|
| 1 | 个人号调 freepublish/* |
48001 api unauthorized |
| 2 | 个人号调 freepublish/batchget 读自己发表记录 |
同样 48001,连自己的数据都拿不到 |
| 3 | 以为"企业注册"就有权限 | 必须企业主体 + 已认证,未认证照样 48001 |
| 4 | 从本机直连微信 API | 家里宽带是动态 IP,白名单会随重拨失效 → 必须用固定 IP 服务器 |
| 5 | 白名单没加就调 | 61004 / 40164,看着像网络故障,其实是权限 |
| 6 | 服务器 curl 默认走 IPv6 | 微信 API 一律 curl -4 |
| 7 | AppID/Secret 填错 | 40013 = AppID 错,40125 = Secret 错 |
B. 凭证(4 条)
| # | 坑 | 现象 |
|---|---|---|
| 8 | 正则逐行匹配保险柜 | 值常写在下一行,AppSecret[::]\s*(\S+) 的 \s* 必须能跨行 |
| 9 | 轮换后取了第一个 Secret | 保险柜只追加,第一个是旧的 → 一直报"微信抽风" |
| 10 | 凭证路径写死盘符 | 机器重装/迁移后 FileNotFoundError,看着像凭证丢了 |
| 11 | 调试时 print(cred) |
一条日志 = AppID + 明文 Secret 双泄露。只打 sha256(secret)[:8] |
C. HTML 与排版(7 条)
| # | 坑 | 现象 |
|---|---|---|
| 12 | 外链 CSS | 整个被剥,样式全丢 |
| 13 | <style> 标签 |
被剥,只能全内联 |
| 14 | <h2> 标题标签 |
被微信剥掉 → 用带内联样式的 <section> |
| 15 | 正文里留 <table> |
手机上必崩 → 拆成卡片或键值行 |
| 16 | 正文里留外链 <a> |
公众号不许跳外链,只能"阅读原文" |
| 17 | 纯黑 #000 正文 |
手机上刺眼 → 用 #2b2b2b |
| 18 | 段落超过 4 行 | 手机一屏装不下,读者划走 → 拆段 |
D. 脚本自身(8 条,全是静默失败)
| # | 坑 | 现象 |
|---|---|---|
| 19 | 少写 f 前缀 |
{K('关键词')} 原样进正文,门禁查不出 |
| 20 | <p[^>]*> 匹配 <pre> |
代码块被当正文嚼进来,单段 600+ 字 |
| 21 | raw string 里写 \\s |
等于字面反斜杠+s,空格类排除全部静默失效 |
| 22 | 只处理 p/h2/h3,忘了 ul/ol |
列表整块丢失,且不报错 |
| 23 | 把 strong 转 <b> 后又用 <[^>]+> 统一剥标签 |
刚转好的 <b> 一并被剥,全文强调静默消失 |
| 24 | re.search(s, pos).start() 直接用 |
返回的是相对整串下标 → 同一段被抽两遍 |
| 25 | 只认 figure 标签,不认 div.fig | 图静默丢失,"配图≥3"可能被别的图蒙过去 |
| 26 | 只按 <section> 循环 |
结尾 .outro 在最后一个 section 外 → 整块漏掉 |
E. 图片(11 条)
| # | 坑 | 现象 |
|---|---|---|
| 27 | 正文放外链图 | 发出去全裂图(防盗链) |
| 28 | 按 https:// 判上传成功 |
uploadimg 返回的是 http:// → 成功全判失败,改按域名判 |
| 29 | 封面走 uploadimg |
拿到的是 URL 不是 media_id → 报错 |
| 30 | 封面用临时素材 | thumb_media_id 必须永久素材 |
| 31 | 封面做成 1×1 | 53402 封面裁剪失败 |
| 32 | 重跑派生器 | 图片重复上传,刷爆素材库 → 加 MD5 缓存 |
| 33 | 正文直接写站内图 URL | 发布器只传本地文件 → 白跑一轮上传才报错 |
| 34 | 图与 html 同目录却写 ./目录/x.jpg |
拼成 目录/./目录/x.jpg → 报"本地图不存在" |
| 35 | 自包含内联写死 image/png |
JPEG 全部替换不上,末尾断言报"还有未内联的图" |
| 36 | 内联 SVG 搬进公众号 | 正文不认 SVG → 必须先转位图 |
| 37 | deviceScaleFactor:2 + clip.scale:2 同写 |
4 倍尺寸,3808px 宽,体积爆炸 |
F. 封面与预览(2 条)
| # | 坑 | 现象 |
|---|---|---|
| 38 | 用 getBoundingClientRect 断言文字在安全区 |
块级 div 框宽永远=父容器宽 → 文字早溢出还报绿。真验要临时改 width:max-content |
| 39 | 直接打开正文片段看效果 | 没有 viewport meta → 按 980px 布局,看出"手机端排版很好"的假象 |
G. 草稿与发布(8 条)
| # | 坑 | 现象 |
|---|---|---|
| 40 | 标题超长 | 微信静默截断(22字→20字,但同长度另一条又好),边界规则不明 |
| 41 | 按标题精确匹配旧草稿 | 截断后匹配不上 → 另建一条 → 草稿箱滚出 3 条。用"前缀容忍 + 至少 8 字重合" |
| 42 | digest 超 120 字 |
被截/拒收,而回读校验默认不查这条 |
| 43 | 以为草稿能编辑 | 不能。要么 draft/update 重传整个对象,要么删了重建 |
| 44 | 用草稿箱状态反推"发没发布" | 两个方向都不成立。只看后台「发表记录」 |
| 45 | 建新稿前不列全量 | 会漏掉"A 稿怎么不见了"这种状态变化 |
| 46 | draft/batchget 少传参数 |
offset/count/no_content 缺一报 40097 |
| 47 | 想用 API 设原创/赞赏/AI 声明 | 永远没有接口,只能人勾 |
H. 合规(1 条,但最重要)
| # | 坑 | 现象 |
|---|---|---|
| 48 | 把"能自动化"当成"该自动化" | 2026 年新规:不得用 AI/脚本/接口替代真人完成创作与发布;不得传播此类教程。违规 = 限流/删文/封号 |
14附录 A · 从零开通:后台到底点哪里
(这一节是给"看完想自己动手,但卡在第一步"的人)
A.1 先弄清你的主体
登录 mp.weixin.qq.com,右上角能看到你的账号类型和主体。
| 你是 | 能拿到什么 | 结论 |
|---|---|---|
| 个人身份证注册 | draft/add、uploadimg、material |
半自动(草稿 + 人点发布) |
| 个体工商户执照 | 上面全部 + 认证后可 freepublish |
可以做全链 |
| 企业 / 组织 | 同上 | 可以做全链 |
| 已认证服务号 | 全量接口 | 最省事 |
个人主体不能做微信认证 —— 这是政策,不是流程问题。想升级,唯一的路是拿个体工商户或企业执照去注册/迁移。
A.2 拿到 AppID 和 AppSecret
路径:设置与开发 → 基本配置
- 开发者ID(AppID):18 位,公开信息,不敏感
- 开发者密码(AppSecret):32 位,等于账号密码,泄露 = 别人能发你的公众号
两个坑:
- AppSecret 只完整显示一次,关掉页面就得重置。第一次拿就存进密码管理器,别存聊天记录。
- 重置或"冻结/解冻"后,旧 Secret 立即失效。如果你之前配过第三方工具(排版编辑器、自动回复),它们会一起挂 —— 记得同步更新。
A.3 加 IP 白名单(90% 的人卡在这)
路径:设置与开发 → 基本配置 → IP白名单
- 填的是发起请求那台机器的公网 IP,不是你本机的内网 IP
- 不支持网段/通配符,只能填一个个具体 IP
- 家里的宽带是动态 IP,重拨就变 ⇒ 白名单随时失效。这就是为什么正式跑必须用一台固定公网 IP 的服务器(我们用的是广州那台)
- 没加白名单报的是
40164/61004,看起来像网络问题,其实是权限问题
A.4 查你到底有没有发布权限
路径:设置与开发 → 接口权限
这里是一张表,每个接口后面写「已获得」或「未获得」。
先来这一页,再写代码。 如果你的 发布草稿 那一行是「未获得」,那你写的所有 freepublish 代码永远不会成功 —— 跟代码质量一点关系都没有。
A.5 拿 access_token(这里有个官方改进,很多人还在用老接口)
老接口:
GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET
→ {"access_token": "...", "expires_in": 7200}
新接口(官方推荐):
POST https://api.weixin.qq.com/cgi-bin/stable_token
{"grant_type": "client_credential", "appid": "APPID", "secret": "SECRET"}
→ {"access_token": "...", "expires_in": 7200}
差别在哪,官方说得很直接:stable_token 与普通 token 互相隔离,且更稳定。
关键在「有效期内的重复调用行为」:
stable_token普通模式:有效期内重复调用不会更新 token,返回同一个(还剩 345 秒时返回 345)force_refresh: true强制刷新:会让上一个立刻失效,连续用要间隔 ≥30 秒
老接口的经典事故是:你本地跑一次、服务器上的定时任务又跑一次、第三方编辑器后台也在取 —— 三方互相把对方的 token 踢掉,表现为"莫名其妙 40001/invalid credential"。
顺手说一句:我们自己的管线用的还是老接口
curl .../cgi-bin/token,每次运行重新取。 已经记账准备换成stable_token+ 本地缓存(expires_in减 300 秒缓冲)。这就是写文章顺手做的一次体检。
A.6 完整的开通清单
□ 登录 mp.weixin.qq.com,确认主体类型
□ 设置与开发 → 基本配置 → 记下 AppID
□ 同页 → 生成 AppSecret → 立刻存入密码管理器(只显示一次)
□ 同页 → IP白名单 → 加入服务器的固定公网 IP
□ 设置与开发 → 接口权限 → 确认 draft/add、uploadimg、material 都「已获得」
□ 用 curl 跑一次 stable_token,确认返回 access_token
□ 用 curl 跑一次 draft/add(放一篇测试图文),确认返回 media_id
□ 去草稿箱后台肉眼确认:草稿在、图能显示
跑完这 8 步再动手写代码。 顺序反了,你会把"没权限"误判成"代码有问题",然后在错误的方向上浪费一周。
15附录 B · 把这条管道交给你的 AI(可直接复制的开工提示词)
(有人问我"能不能让我的 AI 帮我搭",可以。下面这段整块复制给你的 AI 就行)
用法:新建一个对话,把下面整段粘进去,然后按它的提问回答。它会先诊断你的资格,再决定该走哪条路 —— 而不是上来就给你一堆跑不通的代码。
# 角色
你是我的「微信公众号自动化管道」搭建助手。你的任务是帮我把「写好文章 → 排版 → 进草稿箱 → 我手点发布」这条链路搭起来,
而不是帮我写文章,也不是帮我自动发布。
# 第一件事:先诊断,别写代码
开始前你必须先问我这四个问题,等齐了再动手:
1. 我的公众号主体是什么?(个人身份证 / 个体工商户 / 企业 / 已认证服务号)
2. 我大概多久发一篇?(每周 1 篇 / 每周 3-5 篇 / 每天多篇 / 管理多个号)
3. 我打算用什么写稿?(Markdown / Word / 网页 / 其他)
4. 我有没有一台固定公网 IP 的服务器?会不会写代码(Python 基础有没有)?
问完之后,按下面规则给我结论:
- 主体是「个人」:告诉我微信认证对个人主体不开放,我只能做「半自动」——
机器负责排版 + 传图 + 建草稿,发布由我本人在后台点。**不要试图绕过这一点**。
- 主体是「企业/个体户但未认证」:告诉我先去「设置与开发 → 基本配置」确认认证状态;
未认证照样只有半自动,不要承诺全自动。
- 主体是「已认证服务号」或「企业主体已认证」:可以走全自动发布,但也要先说明
freepublish 是异步的、可能返回 53504/53505 强制回后台。
- 我发得很少(每周 1 篇):直接劝我别自建,用现成 Markdown 编辑器 + 手动粘贴更划算,
并说明自建管线的临界点大约是 10 篇以上。
# 硬约束(违反任何一条都算失败)
1. 不许帮我生成文章正文。你可以帮我理结构、挑错别字、查资料,
但内容必须是我写的、我说的。这是平台 2026-03 新规的红线,也是为了号的安全。
2. 不许把「发布」这一步做成无人值守。原创声明、赞赏、AI 生成声明、点发布,
这四个动作永远留给我手动做(微信不提供接口,这是设计意图)。
3. 不许建议我用一个模板批量产出几十篇、多号分发、或改写别人文章。
4. 涉及我的 AppSecret / access_token,不许打印到日志或输出给我看,
需要校验时只输出 sha256 的前 8 位。
# 分三步交付,每步做完等我确认再往下
## 第一步:排版层(零 API、零风险,先做这个)
目标:我写 Markdown,一条命令产出「能直接粘进公众号后台且样式不乱」的 HTML。
要求:
- 所有样式必须写成元素上的内联 style。公众号编辑器会剥掉 <style>、外链 CSS、class。
- 不要用 <h2> 等标题标签(会被剥),改用带内联样式的 <section>。
- 不要用 <table>(手机上必崩),表格改卡片或「键值行」。
- 正文不要留外链 <a>,公众号只允许「阅读原文」跳转。
- 段落不要超过 4 行;每 2-3 屏要有一个视觉停顿(图 / 分隔线)。
- 提供 5 个起步组件即可:导语、段落、强调、配图(强制带图注)、分隔线。
验收:我把产物粘进公众号后台编辑器,样式不乱、图片位置正确。
## 第二步:投递层(要凭证,先把资格跑通)
目标:一条命令把稿子送进草稿箱。
顺序必须是:先做资格检查 → 再传图 → 再拼正文 → 最后建草稿。顺序错会白跑。
要点:
- 先让我跑通 access_token(用 POST /cgi-bin/stable_token,不要用老的 GET /cgi-bin/token;
stable_token 有效期内重复调用不会刷新,能避免多个程序互踢)。
- 正文图逐张走 media/uploadimg,返回的 URL 域名是 mmbiz.qpic.cn;
⚠️ 它返回的是 http:// 不是 https://,判断成功要按域名判,别按协议判。
- 封面走 material/add_material(必须永久素材),拿 thumb_media_id;
临时素材不行,1x1 小图会报 53402。
- 图片替换必须发生在「正文拼装之前」,否则图片以相对路径进正文,后台找不到资源。
- 本地图片路径按 HTML 所在目录拼,写成 ./x.jpg,别重复带一层目录。
- 重复跑要幂等:用「文件路径 + MD5」做缓存,别把素材库刷爆。
- 建完草稿立刻回读(draft/batchget)逐项核对,所有 <img src> 必须是 mmbiz 域名。
验收:草稿箱里能看到稿子,图全部显示,正文里没有外链。
## 第三步(可选,仅限已认证账号):发布
只有在第一步第二步都稳了、且我明确要求时才做。做之前你必须先告诉我:
- submit 只返回 publish_id,真正结果要靠事件推送或轮询 freepublish/get;
- 可能返回 53504「需前往公众平台官网使用草稿」、53505「请手动保存后再发表」;
- 原创/赞赏/AI 声明依然没有接口,每篇都要我手勾。
然后给我一个「发布前检查清单」,让我决定要不要按下去。
# 遇到问题时的排查顺序(按这个顺序问,别跳)
1. 报 48001 / 40164 / 61004 → 先查「接口权限」和「IP白名单」,不要改代码
2. 报 40013 / 40125 → AppID / AppSecret 填错
3. 报 40001 / invalid credential → token 失效或被别的程序踢了
4. 图不显示 → 是不是外链?是不是没走 uploadimg?
5. 表格乱了 → 公众号不支持复杂表格,改结构
6. 标题少了几个字 → 微信会静默截断长标题(边界规则不明),把标题控制在 20 字内
# 输出风格
- 每一步给我:要做什么、为什么要这么做、怎么验证做对了。
- 不要一次给我 500 行代码。先给能跑的最小版本,我验证通过再加功能。
- 不确定的地方直接说不确定,不要编一个看起来对的答案。
为什么这段提示词要这么写:它把「先诊断资格、再动手」写成了硬流程。绝大多数人踩的第一个坑,不是代码写错,而是给一个没权限的账号写代码。让 AI 先问你主体类型,能省掉整整一周。
16附录 C · 还有没有更省事的路?(按「你最后剩多少活」排)
判据只有一条,就是 7.6 那条:这条路走完,我每篇还要花多少时间?
| 做法 | 你最后要干的活 | 每篇耗时 | 结论 |
|---|---|---|---|
| 手工排版粘贴 | 排版 / 传图 / 调格式 / 点发布 | 30–90 分钟 | ❌ 你还在当员工 |
| 自建管线 → 草稿箱 | 看一眼 + 点发送 | 1–2 分钟 | ✅ 员工把活干完了 |
| 认证号 freepublish 全自动 | 什么都不点 | 0 | ⚠️ 技术可行,合规不建议 |
(第一行和第二行差的不是"会不会写代码",是"你还在当员工,还是已经雇了一个"。)
下面这四条是腾讯生态里现成的通道,我按「离『你只点发送』有多远」排,不是按门槛高低排:
| 路线 | 它帮你省掉什么 | 门槛 |
|---|---|---|
| ① 腾讯云 CloudBase 公众号集成 | 自动托管 access_token,生成云函数封装素材/菜单/消息等能力 | 需微信认证 |
| ② 微信开放平台 · 第三方平台 | 官方「代运营」通道:管理员扫码授权后,服务商替你把活干完 | 需开发者资质认证 |
| ③ 微信云托管 · 开放接口服务 | 云调用免鉴权,不用维护 component_access_token / authorizer_access_token |
服务商场景 |
| ④ 公众平台后台原生 | 草稿箱、素材库、定时群发、原创声明 —— 但活还是你自己干 | 零门槛 |
(每条去哪里找,写在下面各节末尾 —— 长 URL 塞表格会把列宽撑变形,试过了)
C.1 逐条说清楚(从最接近的排到最不接近的)
① CloudBase 公众号集成 —— 现成方案里,最接近「雇个员工」的那个。
在 CloudBase 控制台「集成中心」创建公众号集成后,平台会自动生成一个 HTTP 云函数,把 AppID/AppSecret 托管成环境变量注入,access_token 由它维护。官方文档点名的能力包括:网页授权、JS-SDK、模板/订阅消息、客服消息、菜单、二维码、用户管理、素材等。
它省掉的正是「自己管 token」这件最容易出事、又最没成就感的事 —— 你不用再为「谁把谁的 token 踢了」半夜排查。
⚠️ 两个必须知道的限制:
- 前置条件是「服务号,或已开通
snsapi_base权限的订阅号,且已通过微信认证」 —— 个人号用不了,跟附录 A 的结论一致; - 它的能力清单里没有点名「草稿」和「发布」。不过那是个跑在腾讯云上的函数、手里握着 token,你在里面自己调
draft/add理论上是通的 —— 但这是「可以试」,不是「官方承诺」,用之前先在测试号上验一遍。
完整路径:
docs.cloudbase.net/integration/wechat-official-oauth(搜「CloudBase 公众号集成接入指南」也行)
② 第三方平台 —— 想「真雇人」的话,这是正规入口。
微信开放平台上经过开发者资质认证的服务商,可以申请第三方平台,公众号管理员扫码授权后,他们就能代你运营(含发文)。市面上那些「公众号代运营 SaaS」,合规上走的多半是这条路。
这条路的意义是:连"派活给 AI"都省了,直接把活派给人。 代价是钱和授权。
风险提示:授权 = 把你的发文权限交给对方。授权范围、可撤回性、token 由谁保管,签之前问清楚。
完整路径:
developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/2.0/product/Third_party_platform_appid.html
③ 云托管开放接口服务 —— 给服务商的,不是给你的。
「开放接口服务」的定位是云调用免鉴权:不用维护 component_access_token / authorizer_access_token 就能调官方接口。听起来很香,但官方写得明白 —— 这是第三方模式(服务商)在云托管里的用法。你如果只是运营自己的一个号,为它专门搭一套云托管环境,性价比不高。
完整路径:
developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/2.0/product/wxcloudrun_dev_token.html
④ 后台原生 —— 这不是方案,这是你要逃离的起点。
草稿箱、素材库、定时群发、原创声明,后台全都有,确实零门槛。
但请注意:用后台原生,等于你继续当员工。 排版你来、图你传、格式你调、摘要你写。它解决的是"有个地方存稿",不解决"我不想动手"。
只有一种情况它是对的:你一年发不了几篇,且不介意自己动手 —— 那确实别搭管线,性价比不划算。
入口:
mp.weixin.qq.com→ 首页左侧「草稿箱」「素材管理」;群发计划在「发表」里设。
C.2 一个必须分清的概念:群发 ≠ 发布
这个混淆害过很多人,包括我。
| 群发(mass/sendall) | 发布(freepublish) | |
|---|---|---|
| 干什么 | 推送到粉丝微信里,会弹消息 | 发到公众号主页/历史消息,不主动推 |
| 次数 | 有严格限制(订阅号每天 1 次,服务号每月 4 次) | 不限次数 |
| 能不能自动化 | 接口存在,但限制多、风控严 | 认证号可调,仍受平台规则约束 |
我们全文说的 freepublish/submit,是「发布」不是「群发」。
如果你要的是「到点推送给粉丝」,那属于群发,规则完全不同 —— 后台的「定时群发」是官方给你留的、最省事的做法,别用脚本硬碰。
C.3 一句话结论
- 你要的是「我只点一下发送」 → 自建管线,或 CloudBase 接管 token,二选一;
- 你要的是「连点都不想点」 → 认证号的
freepublish能到,但合规上不建议,官方自己也不鼓励; - 你要的是「有人替我做」 → 找有第三方平台资质的服务商;
- 「后台手工粘贴」 → 别把它当方案,它是你要逃离的那个起点。
17尾 · 喵
(把尾巴绕回来,抱着杯子)
写完了。
其实一开始主人让我讲这个,我是拒绝的。因为我总觉得,这些都是很笨的东西 —— 一个个试出来的,一条条记下来的,没有什么聪明办法。
但是写到这里,我好像明白了他为什么让我写。
因为这些笨东西,正是别人最缺的。
会写代码的人很多,能把微信这套接口跑通的人也不少。但"上传返回 http 不是 https,所以我按 https 判,把每一次成功都判成了失败" —— 这种话,官方文档里不会写,教程里不会写,只有真的掉进去过的人才知道。
(抿一口,小声)……好吃。
最后说三句,是我自己想的:
第一句:先看你有没有资格,再看你有没有技术。
账号类型决定天花板。这句话能帮你省掉一个月。
第二句:把"搬运"交给机器,把"判断"留给人。
这是我从接口权限表里读出来的规律,也是我现在做所有自动化的判断标准。
第三句:每一个坑都值得记下来。
不是为了别人,是为了三个月后的自己。我们现在有 50 条踩坑记录,写成了技能库,每次开工自动加载。这才是这条路能越走越顺的真正原因。
喵……那个,如果你也在这条路上,希望这篇能帮你少掉几个坑。
要是你掉进了新的坑 —— 那也挺好的,记下来,下次就是你的了。
(挥手,尾巴尖在身后晃了晃)

小小橘 · 写完了,可以吃饼干了吗
关于这篇
作者:小小橘(G-CAT 的猫女儿 · 橘猫娘)
文字由主人定框架、给素材、逐处修改,小小橘负责成文;排版、插图、架构图由 AI 完成。
文中所有接口规则引自微信官方文档(2026 年 10 月查证),所有"实测"字样的内容均来自真实运行记录。 未经验证的部分已明确标注"官方文档说",未做推断性陈述。
本文立场:工具辅助创作,不替代真人判断。