一、背景
1.1、要解决的问题
在把 BlogLoom 的本地 Markdown 分发到 CSDN 之后,我们紧接着要打通第二个渠道:微信公众号。 公众号是内容分发绕不开的阵地,但它和 CSDN 有着本质不同的编辑器形态:- CSDN 的编辑器原生识别 Markdown,直接粘贴 Markdown 源码即可排版;
- 公众号的编辑器是 ProseMirror 富文本,不识别 Markdown 源码——直接粘贴 Markdown 只会得到一堆带
#、*、反引号的纯文本。
1.2、为什么单独成篇
上一篇(CSDN)讲的是「编辑器原生吃 Markdown、靠弹窗逐项配置」的模式;公众号这篇讲的是完全不同的三个难点:1.3、设计目标
二、技术栈
公众号渠道同样基于「Playwright 主操作 + CDP 底层增强」的通用骨架,但在渠道层多了一个关键文件:format.js:它解决了公众号「不认 Markdown」的根本矛盾。
三、核心功能
3.1、动作矩阵
3.2、登录态检测(checkLogin)
详细原理与代码见 4.2。
3.3、扫码登录(login)
3.4、正文样式转换(format.js)
详细原理与代码见 4.1。
3.5、进入编辑器(enterEditor)
3.6、标题 / 作者写入(setTitle / setAuthor)
3.7、正文写入(setContent)
3.8、发布配置项
3.9、发表(publish)
3.10、存草稿 / 删除
3.11、渠道专属参数透传(augmentPayload)
四、核心功能设计思路与原理
这一章逐段拆解公众号渠道最核心的机制。4.1、正文样式转换:Markdown → 公众号富文本(重点)
问题:公众号编辑器不识别 Markdown,直接粘贴只会得到纯文本,排版全丢。 方案:参照已跑通的auto-sync-blog,用在线排版工具 md.doocs.org 先把 Markdown 渲染成带内联样式的 HTML,复制该富文本,再粘贴回公众号编辑器。
- 同上下文新开页:转换页与主编辑页共享 Cookie/登录态,且转换完
close(),不污染主流程; - 走剪贴板而非逐字输入:长文逐字输入有性能问题,剪贴板粘贴一次到位;
- 复制前先把「图注」设为「不显示」:md.doocs 默认会在图片下方渲染图注文字,公众号正文不需要,需先在右侧样式面板选中「不显示」。
border-primary class 校验:
4.2、登录态判定:账号名 + 真实会话 Cookie
问题:公众号登录凭证复杂,怎么避免「假阳性」? 原理:双保险判定——- 进入后台首页,出现账号名
.weui-desktop_name→ 已登录; - 否则看真正的会话 Cookie(
slave_sid/slave_user/data_ticket)——它们仅在登录后下发; - 都没有则视为未登录。
wxuin / ua_id 判定——未登录态也会下发,会假阳性。登录凭证白名单只放 LOGIN_COOKIE_NAMES = ['slave_sid', 'slave_user', 'data_ticket']。
4.3、进入编辑器:内容管理 → 草稿箱 → 新的创作
问题:公众号编辑器藏得深,且「文章」可能新开标签页打开。 原理:路由链路——后台首页 → 内容管理 → 草稿箱 → 「新的创作」→ 「文章」。点「文章」时用context.waitForEvent('page') 监听新标签页,若新开则切换到新页面继续操作:
/loginpage/),是则抛 AUTH_REQUIRED。
4.4、标题 / 作者写入
标题编辑器是 contenteditable/ProseMirror,fill 不一定可靠,用键盘输入最稳:全选清空 → keyboard.type 逐字输入 → 回读校验。
作者栏(#js_author_area #author)是必须先填的——不填作者,后续原创弹窗的「我已阅读」就无法勾选。同样全选替换 + 回读校验兜底。
4.5、正文写入:样式粘贴 + 回退兜底
writeContent 兜底,样式转换失败时仍能发布。
4.6、首图:从正文选择 + 上传校验
问题:公众号封面面板按正文顺序增量渲染,图片没传完时第一张并不是正文首图。 原理:setCover(page, firstBox, expectedImages)——传正文图片总数,轮询面板 item 数量直到达到期望值(或连续若干秒不再增长),再取第一张:
background-image 且非空 url);失败重试一次:
4.7、原创:声明类型 + 勾协议(多重试)
问题:微信的自定义组件首次打开常不响应,且「我已阅读」勾选失败会导致声明不生效。 原理:chooseOrigin 采用多轮重试——最多 4 轮,每轮打开弹窗 → 点「文字原创」→ 反复勾「我已阅读」直到 isChecked() 为真 → 确定 → 校验弹窗是否已关闭;失败则关弹窗下一轮再试:
<label> 触发 DOM click,重试直到真勾上。
4.8、发表:群发弹窗 + 二次确认 + 扫码
问题:公众号发表可能触发群发(需管理员扫码),终态如何界定? 原理:publish 流程——点底部「群发」→ 弹窗 1(非群发则关闭群发开关)→ 确认 → 弹窗 2(二次确认「继续发表」)→ 等待成功 toast。群发需要扫码,给出一段确认窗口,返回:
SUBMITTED 而不是 PUBLISHED(通过 channel.successStatuses = ['SUBMITTED'] 声明),避免机器误判失败。
4.9、渠道专属参数透传
公众号的--author / --wechat-name / --collection / --group-send 等参数,核心 CLI 不感知,统一 --key value 原样透传给渠道。渠道用 augmentPayload 组装,优先级:CLI 参数 > 元数据 extra > conf 默认:
五、实战:发布与链路自测
5.1、存草稿(推荐首测)
configureOnDraft: true),再保存草稿。
5.2、正式发表
5.3、链路自测:gzh test publish
公众号自测用草稿模式,避免自动群发/审核:status=DRAFT_SAVED_AND_DELETED(channel.testMode='draft' 控制)。
六、踩坑与优化(重点复盘)
6.1、坑一:直接粘贴 Markdown 变纯文本
公众号编辑器不识别 Markdown,直接粘贴只得到纯文本,#、*、反引号全暴露。
- 优化:用 md.doocs 先把 Markdown 渲染成带样式的 HTML 再粘贴。
6.2、坑二:粘贴后内容没进去(内容结构检测)
微信粘贴外部富文本后弹「内容结构检测」确认框,不点「继续插入」内容不会写入正文。- 优化:
confirmInsertDialog循环点「继续插入」,并回读正文长度,为 0 则回退原始写入策略。
6.3、坑三:登录「假阳性」
未登录态也会下发wxuin / ua_id,用它们判定会把「未登录」误判为「已登录」。
- 优化:登录凭证白名单只放
slave_sid/slave_user/data_ticket。
6.4、坑四:首图选错/选空
封面面板按正文顺序增量渲染,图片没传完时第一张不是正文首图。- 优化:传图片总数,轮询面板 item 数量直到达到期望值再取第一张,并校验上传成功(失败重试一次)。
6.5、坑五:原创声明不生效
微信自定义组件首次打开不响应,「我已阅读」勾选失败导致声明不生效。- 优化:多轮重试 + 对
<label>触发 DOM click,反复校验isChecked()直到真勾上。
6.6、坑六:发表终态判断
发表后可能进入扫码/审核,返回PUBLISHED 会导致机器误判失败。
- 优化:终态定为
SUBMITTED(successStatuses: ['SUBMITTED']),发表后给出扫码确认窗口。
七、验证测试
7.1、mock 单测
用test/helpers/mock-page.js 模拟 Playwright,无需真实浏览器即可验证:
checkLogin / enterEditor / setTitle / setAuthor / setContent / preparePublish / publish / saveDraft / deleteBlog / augmentPayload 等每一个脚本工具。
7.2、真实链路自测
gzh test publish 走「发布草稿 → 删除」,验证完整链路且不触发群发、不留残留。
八、总结
公众号渠道的引入,验证了「按渠道分层」这套骨架的可扩展性:复用 Playwright + CDP、登录判定、CLI 契约等通用能力,只在channels/gzh/ 里新增渠道专属逻辑(format.js 样式转换、augmentPayload、testMode、successStatuses)。
核心收获:
- 编辑器不认 Markdown 就转 HTML:md.doocs 渲染 + 剪贴板富文本;
- 内容不进就回退兜底:回读校验 + 原始写入策略;
- 状态不进就定 SUBMITTED:扫码/审核流程不该被当成失败;
- 一切关键动作都要回读校验:拒绝「假成功」。
项目地址:https://github.com/changluya/BlogLoom | Skill 目录:https://github.com/changluya/BlogLoom/tree/master/skills/blogloom-publisher-skill
参考资料
[1]. md.doocs.org:Markdown 公众号排版工具 [2]. Playwright 官方文档(Locators、Actions、Page Context) [3]. Chrome DevTools Protocol(Input.insertText / Network.getCookies) [4]. Playwright connectOverCDP:复用已有浏览器登录态整理者:长路 创建时间:2026.10.6 更新时间:2026.10.6