Hermes Agent 对接微信公众号:从踩坑到跑通的全过程

admin 📖 8 分钟阅读
## 前言 上周折腾了一个事:用 Hermes Agent 自动往微信公众号发文章。 听起来很简单对吧?调个 API 就完事了。但实际上踩了不少坑,记录一下给同样想搞的人参考。 先说结论:**能跑通,但没认证的订阅号只能推到草稿箱,不能直接发布。** --- ## 你需要准备什么 - 一个微信公众号(订阅号或服务号都行) - 公众号的 AppID 和 AppSecret - 一台服务器(或者本地电脑也行) - Hermes Agent 已经装好 AppID 和 AppSecret 在 mp.weixin.qq.com → 设置与开发 → 基本配置 里找。 **注意:** 一定要把服务器 IP 加到白名单里,不然调 API 会报 `IP white list` 错误。 --- ## 整体流程 说白了就三步: 1. 用 AppID + AppSecret 换 access_token 2. 把文章做成草稿(调 draft/add 接口) 3. 发布(调 freepublish/submit 接口) 但每一步都有坑。 --- ## 第一步:获取 access_token 这个最简单,但也最容易出问题。 ```java String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" + "&appid=" + appId + "&secret=" + appSecret; ``` 返回的 JSON 里有 `access_token`,有效期 2 小时。 **踩坑记录:** - AppSecret 输错了会报 `invalid credential` - IP 没加白名单会报 `IP white list` - access_token 有调用频率限制,别每次都重新获取,缓存起来用 --- ## 第二步:创建草稿 这一步是核心。微信的草稿接口是 `/cgi-bin/draft/add`。 请求体大概长这样: ```json { "articles": [{ "title": "文章标题", "author": "作者", "digest": "摘要", "content": "HTML格式的正文", "thumb_media_id": "封面图的media_id" }] } ``` **坑来了:** ### 坑1:content 必须是 HTML 不能直接丢 Markdown 过去,微信不认。得先转换成 HTML。 我用的是语义化标签,不加内联样式: ```html

一级标题

正文内容

引用内容
代码块
``` 微信编辑器会自动识别这些标签,比写一堆 `style="..."` 靠谱多了。 ### 坑2:thumb_media_id 必须有 没有封面图?微信不让你过。得先上传一张图片拿到 media_id。 上传接口是 `/cgi-bin/material/add_material?type=image`,注意是永久素材接口,不是临时的。 我一开始用的临时素材接口,返回的 media_id 不能用,白折腾了半小时。 ### 坑3:content 里的 $ 符号 如果你的文章里有 `$` 符号(比如代码里的变量),Java 的 `String.replaceAll` 会把它当成正则引用符,直接报 `Illegal group reference` 错误。 解决办法:用 `Matcher.quoteReplacement()` 包一下。 ```java // 错误写法 String safe = content.replaceAll("$", "\\$"); // 正确写法 String safe = content.replaceAll("$", Matcher.quoteReplacement("\\$")); ``` 这个坑我踩了两次才记住。 --- ## 第三步:发布 草稿创建成功后,会返回一个 `media_id`,用这个调发布接口: ``` POST https://api.weixin.qq.com/cgi-bin/freepublish/submit ``` 但是—— **未认证的订阅号调这个接口会返回 48001(api unauthorized)。** 也就是说,你的公众号得认证过(300 块/年),或者你是服务号,才能用这个接口。 没认证怎么办? 只能创建草稿,然后自己去 mp.weixin.qq.com 后台手动点「发布」。 说实话也就多一步,能接受。 --- ## 我的最终方案 因为我的号没认证,所以最终方案是: 1. Hermes 生成文章内容 2. 调 API 推到公众号草稿箱 3. 我去后台点一下发布 整个过程大概 10 秒钟,比手动复制粘贴快多了。 --- ## 完整代码片段 核心逻辑大概 50 行,贴一下关键部分: ```java // 1. 获取 access_token String token = getAccessToken(appId, appSecret); // 2. 上传封面图 String thumbMediaId = uploadThumb(token, coverImageUrl); // 3. 转换 Markdown → HTML String htmlContent = markdownToHtml(article.getContent()); // 4. 创建草稿 String draftMediaId = createDraft(token, title, author, digest, htmlContent, thumbMediaId); // 5. 发布(如果账号支持) // publishDraft(token, draftMediaId); ``` 完整的 Controller 我放在下面,可以直接抄: ```java @PostMapping("/publish/{id}") public Object publish(@PathVariable Long id, @RequestBody Map body) { String appId = body.get("appId"); String appSecret = body.get("appSecret"); // 获取文章 Article article = articleService.getById(id); // 获取token String token = getAccessToken(appId, appSecret); if (token == null) return Map.of("error", "获取token失败"); // 上传封面图 String thumbId = uploadDefaultThumb(token); // 创建草稿 String mediaId = createDraft(token, article, thumbId); if (mediaId == null) return Map.of("error", "创建草稿失败"); return Map.of("success", true, "message", "已推送到草稿箱,请去后台发布"); } ``` --- ## 常见错误码 | 错误码 | 含义 | 解决办法 | |--------|------|----------| | 40001 | access_token 无效 | 重新获取,检查 AppID/AppSecret | | 40002 | 不合法的凭证 | 同上 | | 40164 | IP 不在白名单 | 去后台加 IP 白名单 | | 48001 | 接口未授权 | 公众号没认证,只能推草稿 | | 45009 | 接口调用超限 | 降低调用频率,缓存 token | --- ## 总结 折腾了一天,总结几个教训: 1. **先搞清楚你的号是什么类型**,能不能用发布接口 2. **封面图必须有**,不能跳过 3. **$ 符号在 Java 里是雷**,处理 Markdown 时一定要注意 4. **access_token 要缓存**,2 小时内重复获取会报错 5. **未认证订阅号只能推草稿**,别白费力气调发布接口 希望这篇能帮到同样在折腾的人。 --- *如果觉得有用,欢迎关注公众号「情韵博客」,后续会分享更多 AI 实战经验。*
🤖 本文内容由AI辅助整理生成,仅供参考
← 上一篇 假期最后两天,我逼自己学了下 AI 下一篇 → 我把 AI 编程助手从 OpenClaw 换成了 Hermes,账单终于没那么吓人了