wechat-editor:agent 管内容,服务器管微信格式
local/wechat-editor
微信公众号会剥掉 style 块、class 属性与外部资源引用,所以把一篇论文精读或博客同步过去不是复制粘贴,而是一次格式重写加资源搬家。分工是:agent 抓正文、写标题(不超过 64 字)与摘要(不超过 120 字)、选封面;服务器转 inline HTML、把图片传微信图床并替换 URL、调 draft/add 建草稿、按需提交发布。
我们的判断公式与图表能活下来靠的是服务器端预渲染:Playwright 无头 Chromium 加 MathJax tex-svg 把行内与行间公式渲成 inline SVG,Mermaid 走同一套,微信原生支持 SVG 所以清晰度不随屏幕缩放掉。另一条必须记住:发布是异步的,接口返回 200 只代表微信收下了这次提交,真实状态得用 freepublish/get 查。
为什么需要一条专门的线
微信公众号不接受普通网页 HTML:它的正文编辑器会把 <style> 块、class 属性和外部资源引用几乎全部剥掉,样式必须以 inline style 的形式写在每个标签上,图片必须托管在微信自己的图床。所以把本站一篇论文精读或博客「同步到公众号」不是复制粘贴,而是一次格式重写 + 资源搬家。这条 skill 把这件事切成两半:agent 负责内容(抓正文、写标题摘要、选封面),生产服务器负责格式(转微信 inline HTML、传图床、调微信草稿箱与发布 API)。
数字孪生里的执行者是 wechat-editor,任务键 wechat:<log_id-or-slug>,start/finish 成对上报。
责任划分
| 侧 | 做什么 | 为什么在这侧 |
|---|---|---|
| Agent | 抓取 URL 内容,生成标题(≤64 字)、摘要(≤120 字)、封面图 URL、Markdown 正文 | 这是创作判断,需要读懂原文并为手机阅读重新组织 |
| 服务器 | 校验凭据 → 转微信 inline HTML → 上传封面(自动 RGBA→RGB JPG)→ 正文图片传微信图床并替换 URL → draft/add 建草稿 → 需要时提交发布 → 返回 {log_id, media_id, status} | AppSecret 与 access_token 只能留在服务器;转换依赖无头浏览器 |
调用优先走 SSH 在服务器本地打 localhost:8000,而不是走公网域名——生产环境有 CDN 缓存,直接用域名调写接口可能命中缓存导致异常。自动化场景用 X-API-Key 走公网,管理员场景用 cookie。绝不在本地直接调微信 API,一律经 /api/wechat/* 或 /api/admin/wechat/*。
公式与图表怎么活下来
这是整条链路最硬的一段。微信正文不支持 KaTeX/MathJax 的运行时渲染,也不执行 JavaScript,所以公式必须在服务器上预先变成矢量图。转换器的做法是 Playwright 无头 Chromium + MathJax tex-svg.js:把 $...$ 与 $$...$$ 直接渲成 inline <svg>,微信原生支持 SVG,清晰度不随屏幕缩放掉。Mermaid 图表走同一套:加载 mermaid.min.js 渲成 SVG,必要时截图落位。渲染完还有一段后处理 JS 清理 MathJax 的辅助元素(aria 标签、MathML 输出)并给每个 <svg> 补 inline style,否则微信的清洗会把它们弄丢。无头浏览器不可用时有一条 _render_fallback() 降级路径,至少保证文字与代码块能看。
微信 API 的两个坑
Python 侧用的 wechatpy 1.8.x 封装了素材上传(material)与媒体上传(media),但草稿箱(draft)和发布(freepublish)是微信较新的 API,库没有包装,只能直接打端点:draft/add 建草稿,freepublish/submit 提交发布,freepublish/get 查状态。封面图走 material/add_material?type=image,正文图片走 media/uploadimg——两个端点的配额与用途不同,混用会失败。封面还有一层自动处理:微信不吃 RGBA PNG,服务器端 _ensure_rgb() 自动转 RGB JPG,所以给一张论文的 fig1.png 就够了。
正文的写作口径
- 不复制全文:要提炼成适合公众号阅读的形态,段落短(手机屏幕)
- 公式写
$...$与$$...$$,服务器转图片;代码块用三反引号,服务器做高亮 - 图片用 Markdown 引用,本站
static/img/...路径会被自动上传到微信图床并替换 URL - 中文正文不中英混排
- 已有
detail_html的论文可以直接走 admin draft 接口,只需给thumb_path、digest、author,服务器自己转格式
发布是异步的
action=draft(默认)之后草稿躺在公众号后台,人工去微信公众平台编辑或发布;action=publish 提交后微信要审核,不是立即上线,状态得用 freepublish/get 查。所以「发成功了」这句话要谨慎说:接口返回 200 只代表微信收下了这次提交。发布历史在 admin → 公众号配置 → 发布记录,也可 GET /api/wechat/logs?limit=20 查。AppID/AppSecret 与 API Key 属于敏感信息,只在 admin 面板配置,不写进代码、脚本或日志。
诚实的边界
这条线依赖本站生产服务器上的 Playwright、MathJax/Mermaid 静态资源、已配置的公众号凭据和 /api/wechat/* 接口,无法作为开源包安装,也没有一行 install 命令;微信平台的清洗规则与配额还会随官方调整而变。可迁移的是方法:把「内容创作」与「平台格式适配」彻底分开,公式与图表在服务器端预渲染成矢量而不是指望客户端执行脚本,图片统一搬到目标平台自己的图床,以及把异步审核状态当成一等公民来查询而不是假设提交即上线。做任何一个有严格富文本清洗的目标平台(邮件、知乎、掘金、Notion),这四条都直接适用。