用微信 ClawBot 做订阅推送:独立后台、可靠队列与发送边界

我想把关注的频道更新、项目上线和设备告警汇总到微信里:自己能收到,愿意关注的人也能主动订阅。为此,我把微信 ClawBot 当成一个通知通道,搭了一套独立的订阅推送后台。它不负责 AI 聊天,也不向没有订阅的人发送消息。

管理入口是 notify.bismih520.com,运行在 CCS 的独立容器中,用 GitHub 登录保护。当前阶段是私有试运行,支持文字和链接、主题订阅、发布预览、持久队列,以及用户主动确认的回执。公众自助订阅入口和图片发送还没有在这套新后台开放。

先分清楚:订阅群发不是微信群机器人

这里的“群发”指同一条消息分别投递给多个明确订阅的接收者。每位接收者使用自己的微信授权和会话上下文,不是把一个二维码发给所有人共享,更不是读取通讯录后给陌生联系人发广告。本项目不做微信群投递。

腾讯已经开源 openclaw-weixin,提供微信接入能力。它支持多个账号,并要求按账号和对话隔离会话。只做通知时,可以围绕其 iLink 通信方式写一个轻量适配器,不必启动完整的 AI 代理系统。官方说明适合作为接入能力的起点。

选哪些 GitHub 项目参考

截至 2026 年 10 月 13 日,腾讯仓库的 package.json 标注版本为 2.4.10,许可证为 MIT。我优先核对官方源码,再参考第三方的工程组织方式,而不是直接把一个陌生网关接到自己的微信凭据上。

项目 适合参考什么 使用取舍
Tencent/openclaw-weixin 扫码、通信接口、消息结构、上下文处理 协议主参考;完整插件还依赖 OpenClaw
nightsailer/wechat-clawbot Python SDK、多用户网关、路由和交付模块 适合研究服务结构;仍需跟进腾讯协议变化
lroolle/wxclawbot-cli 在脚本里发送通知的命令行用法 适合个人工具,不直接等于多人订阅后台
epiral/weixin-bot 独立 Node 和 Python 客户端示例 适合理解最小链路;采用前核对更新、许可证和安全处理
SiverKing/weixin-ClawBot-API 独立 API 封装与调用例子 用作交叉参考,不代替官方接口行为

这些仓库是研究材料,不是腾讯对第三方商业群发服务的授权承诺。接口可调用、代码开源、允许长期主动通知,是三个不同的问题。

扫码凭据和会话上下文不是一回事

接入时至少有三类状态:短期扫码二维码、账号的 bot_token,以及对话中的 context_token。二维码用于建立授权,账号凭据用于通信,会话上下文关联最近的用户交互。二维码过期,并不等于已经登录的账号立即失效。

官方 扫码实现调用 get_bot_qrcode 和 get_qrcode_status,处理等待、已扫描、确认、过期、验证码和接入地址切换等状态。二维码应该现用现生成;不能把它当成一个长期固定的公共订阅码。

更容易踩坑的是主动推送。当前 官方发送代码在没有上下文时会记录警告并继续请求,但这只说明客户端会发起请求,不能推出微信服务器一定接受,更不能推出可以无限期给用户主动发消息。服务端发心跳也不是用户发消息,不能宣称它会自动延长用户的发送许可。

接口返回成功,手机为什么还可能收不到

发送记录至少要区分三层:HTTP 和接口是否接受请求、是否返回服务端消息 ID、微信客户端是否真的显示。前两层不是第三层的替代品。

腾讯仓库的 Issue 264 和 Issue 290里,有使用者报告 ret=0 但客户端不可见,换另一个账号后表现不同。这是问题报告,不足以确定统一原因或官方修复结论,却说明后台不能把“接口成功”写成“已送达”。

这套后台分别显示“接口已接受”和“用户确认”。如果通知带有 收到 ABCD1234 这样的可选回执,接收者回复后才记为已确认;未回复不会被当成失败或成功。即使记录到了服务端消息 ID,也仍然不是微信已读回执。

一套适合小规模订阅通知的架构

公开频道或自己的业务系统
        ↓
    通知草稿与主题
        ↓ 管理员核对接收者
    持久化投递队列
        ↓ 逐账号串行发送
    腾讯 iLink 接口
        ↓
    各自授权且主动订阅的微信用户

用户回复 → 指令缓冲与游标事务 → 订阅 / 取消 / 回执

后台用 Node 22 和 SQLite,前端使用同源静态资源。数据库开启 WAL 和 FULL 同步,敏感字段单独加密。一个容器只负责这一项服务,网站经 Caddy 和 Cloudflare 转发,服务本地端口不直接向公网开放。

接收消息时,先把最小通知指令写入缓冲,并在同一事务更新接收游标;再处理订阅和回复队列。这样进程崩溃时不会因为先推进游标而丢掉尚未处理的订阅指令。发送侧则按账号串行,发布任务使用唯一标识去重,出队时再确认用户没有取消订阅。

当前按本站策略限制为最多 25 个授权账号、10 个接收长轮询、4 个不同账号同时发送;同一账号每 5 秒至多发送一条,每 24 小时最多接受 30 条发布通知。这是本项目的保护策略,不是腾讯公布的发送额度,也不是已经压测得出的容量上限。

怎么连接和发送第一条通知

  1. 打开管理台,通过站主的 GitHub 身份验证。在“微信接入”填写别名,生成新的微信授权二维码。
  2. 用对应的微信扫码并确认授权。如果微信要求验证码,在同一接入页面填写。每次接入都独立授权,不导入共享 Cookie。
  3. 在微信 ClawBot 对话里发送 订阅。扫码只是连接账号,这一步才表示同意接收默认的 Codex 重置通知。
  4. 若要收项目更新,发送 订阅 updates;用 主题查看其他主题。
  5. 在“消息发布”选择相应主题,填写标题和正文,先保存草稿,再核对真实订阅人数并确认发布。主题没有订阅者时,保留草稿,不发送。
  6. 在“发送记录”查看接口接受、服务端 ID 和用户确认;手机收到后,可按通知中的指令回复回执。

不想继续接收时,发送 取消订阅;只想取消一个主题,可以发送 取消订阅 updates。发送 确认删除账号会删除当前接入、订阅和关联投递记录。正在上游处理的消息不能靠取消订阅撤回。

把自己的项目接进来

通知入口采用“保存草稿 → 预览接收者 → 确认发布”三步,不开放任意指定微信用户 ID 的接口。业务系统按主题调用,可以减少误发和账号串号。

接口 用途
GET /api/admin/state 统计、主题、订阅者、草稿和投递记录
POST /api/admin/topics 新增自己的订阅主题
POST /api/admin/drafts 保存标题、正文和主题,返回草稿 ID
POST /api/admin/preview 核对某个主题的接收者
POST /api/admin/publications/:id/publish 确认发布,重复调用不会重复创建任务

保存草稿的请求体例如:

{
  "topic": "updates",
  "title": "PDF 工具站已增加新功能",
  "text": "本次增加合并、拆分和图片导出,入口见项目主页。"
}

发布时提交 {"confirm":true}。网站调用需要有效的 GitHub Access 身份;可信服务器内部脚本可使用独立的后台操作令牌。不要把该令牌写进前端、公开 GitHub 仓库、截图或请求 URL。跨域写入会被拒绝。

为什么先放在服务器,而不是全部塞进 Worker

频道检查可以被所有订阅者共用:每 5 分钟检查一次,一个频道每天约 288 次。微信接收则需要按接入账号维持轮询和游标,用户增加后不再是一个共享请求。

举个估算:假设每个账号持续做一次约 35 秒的空长轮询,一天约为 86400 ÷ 35 ≈ 2469 次;100 个账号约为 24.7 万次。这个数字只是请求量估算,不是容量测试,实际返回时间、退避和并发策略都会改变它。官方接收实现采用长轮询和错误退避。

已有 CCS 时,持续连接、持久队列和后台一起放服务器更容易管理。以后可以把公开介绍页放 Pages,把接入控制和队列留在服务器;没必要为了“全无服务器”把状态恢复和请求成本复杂化。

加密要做到哪一层

网站走 HTTPS,后台通过 HTTPS 请求腾讯接口。账号凭据、微信标识、上下文、游标和通知正文用 AES 256 GCM 加密入库;身份查找使用另外派生的 HMAC 密钥。后台页面只拿别名和统计,不返回微信登录密钥。

Cloudflare Access 不只是入口登录页。应用还验证 JWT 的签名、issuer、audience 和有效期,源站限制访问来源,防止绕过入口伪造身份头。其校验方法可参考 Cloudflare 官方文档。

但必须说清:服务端为了发送消息,需要解密必要信息;腾讯也参与传输。因此这不是“对本站和腾讯都不可见”的端到端加密。加密数据库的密钥必须单独安全保留,不能以为只备份数据库就一定能恢复。

通知指令缓冲只保存最小命令,不保存无关私人文字和附件,处理后保留 7 天;投递和运行事件保留 30 天,本地快照最多保留 14 份。账号删除后,当前库中的关联数据清除,旧快照按保留期过期。本地快照不是异地灾备。

图文消息和长期推送还要继续验证

旧的 ResetNow 项目曾做过文字加图片转发,新后台没有直接复用它的账号。微信媒体协议涉及上传后的下载参数和媒体密钥,不能把一个临时图片链接当成永久可见的图片。新后台目前只发送文字和链接,图文仍需独立接入和手机验收。

同样,网络发送超时会产生“可能已经被接受,但本地没拿到结果”的情况。当前把这类记录标为“结果不明”,不盲目自动重发。稳定的客户端消息 ID 有助于追踪,但不能据此保证上游永远去重。

进一步开放给多人使用前,应该完成两个自有测试账号的订阅隔离、取消订阅、重启恢复和图文测试,并分别观察 24 小时、72 小时、7 天的主动通知表现。再增加限时邀请码、公开自助接入、发布者权限和容量压测,而不是把登录凭据集中到一个来历不明的第三方接口。

这套方案适合低频、明确订阅的小规模通知。若业务必须保证重要消息长期可靠触达,应提供额外通知渠道,并把微信 ClawBot 当作其中一条通道,而不是唯一的交付保证。

上一篇
下一篇