为了公众号这碟醋,我用 Rust 包了顿饺子
不久前在极客时间做直播,有位听众抛来一问,颇有些“明知故问而求其所以然”的意味:“程序君日常都从何处汲取新知?”
这一问,倒逼我反躬自省。盘点近来光景,竟发觉自己已然成了个“数字隐士”。往日里流连于 Hacker News、Product Hunt、Reddit 或是知乎的时光,好比是赶集似的,自己拎着个篮子,在人声鼎沸中捡拾些瓜果蔬菜,虽也热闹,却不免劳神费力;如今却大不同了,与 AI 清谈的时刻与日俱增,倒像是在书斋里请了位博闻强识的 Know-it-all 先生。许多灵光乍现的念头,并非苦思冥想所得,而是在与这位“先生”一来一往的对谈中偶得之。多数时候,我只消启动 Gemini 的“深度研究”(deep research)功能,它便能代我遍览群书,将所需信息条分缕析,呈于案前。比如我想用 Rust 构建一个类似 autogen 的 framework:

比如我想了解 AI 时代新的沟通软件该是什么样子的?

甚至有时候我会给定一个框架,让 AI 自己思考,自己判断是否成立:

我觉得此等妙趣,不可不与众人知。所谓“独乐乐不如众乐乐”,若能将这些与 AI 的机锋对答公之于众,岂不快哉?
但这趟从清谈雅趣到公之于众的旅程,半道上却横亘着一道繁文缛节的鸿沟。整理对话不过是举手之劳,可要将之妥帖地搬运到微信公众号这方小天地,却比西天取经还多出几道关隘,尤其是那些文中的配图,简直成了“磨人的小妖精”。寻遍市面上的各路“搬运神器”,竟无一能趁我心意,个个不是缺斤少两,就是使起性子来罢工。我自个索性挽起袖子,自己种麦、磨面、和馅,硬是为了这碟醋,包了整桌的饺子 —— 是的,我上头了,一不做二不休,决定亲手打造一个合用的工具。
万丈高楼平地起,这工具的基石,便是微信公众号的软件开发工具包(SDK)。可惜放眼偌大的互联网,竟无一个 Rust 版本可用。作为一位剑客,没有趁手的兵器,那就自己开炉锻造。于是,我参照 Go 语言的实现,祭起我花了 200 刀请来的 Claude Code,风风火火锻造起来。我所求者,无非“大巧若拙”,期望它用起来能如臂使指,简洁至此:
#[tokio::main]
async fn main() -> Result<()> {
// 创建公众号实例
let client = WeChatClient::new("your_app_id", "your_app_secret").await?;
// 上传 markdown 文件(主题和元数据从 frontmatter 中获取)
let draft_id = client.upload("./article.md").await?;
println!("草稿创建成功,ID: {}", draft_id);
Ok(())
}
此中三行两语,看似寻常,背后却是一套“少即是多”的哲学。我素来偏爱用 Markdown 行文,清爽直接。文稿与图片同置一处,如同书房里的书与画,井然有序。我所期盼的,便是这工具能有双“慧眼”,自动辨识文中的图片,将其妥善上传云端,再悄然换上新址;然后,它又能化身为一位“裁缝”,依据我选定的样式,将 Markdown 这块“素布”裁剪缝制成华丽的 HTML“锦衣”,最后恭恭敬敬地呈入公众号的草稿箱。整个过程,一气呵成,无需我再费半点心神。
于是,看似简约的 API 下,隐藏着不少设计考量:
- 上传图片时,要小心别重复了。公众号接口不能按名字找,只能一个个翻看。我只翻看最近的二十张,给每张图片贴上内容的 blake3 哈希值标签,这样只要内容相同,且在这二十张里,就不会重复上传。
- 上传图文草稿时,也得防止重复。我用标题来判断是否已经上传过。如果发现已经有了,就更新它。
- css 主题我用了 wenyan-mcp 里的样式。这个 mcp 是专门用来上传公众号文章的,但不知为何它总是罢工。
- 公众号对 css 有限制,只能内嵌。我就想了些办法(使用 css-inline 和 regex),把全局 css 变成内嵌。
这样,当我的文章长这个样子时:
---
title: 把我跟 AI 的有意思的对话总结成文章发布出来
description: 为了这壶醋,我包了这顿饺子(写了几千行 Rust,做了个工具)
published: draft
author: 陈小天
cover: images/01-cover.png
theme: lapis
---
bla bla
SDK 便能如同一位得力的助手,将文稿妥帖地化作草稿,呈于微信公众号之上。个中奥妙,可移步至此细品:https://github.com/tyrchen/wechat-pub-rs
有了趁手的 SDK,那命令行工具,倒也不必费太多心思,只需可遍历文章目录,凡是尚未发表的篇章,进行上传即可。细节在此:https://github.com/tyrchen/wx-uploader。若你对此也感兴趣,可以 cargo install wx-uploader,然后获取微信公众号的 appid/secret,添加 IP 白名单即可。
该命令行使用指南:

至此,万事俱备,只欠“清谈”。从今往后,我便可安坐书斋,与我的 Know-it-all 先生纵论古今,再将这些思想的火花,整理成文,一键上传,以飨同好。
敬请期待。