给 notify-user 技能加上微信推送:移植 Server酱 与 PushPlus 的实战记录

举报
yd_239417839 发表于 2026/10/26 01:56:57 2026/10/26
【摘要】 从签到脚本移植两条微信服务号推送渠道:Server酱 与 PushPlus 的接入要点、成功判定、密钥打码与自动降级设计。

背景

我维护一个开源的桌面代理通知技能 notify-user,用途很简单:让 AI 干完活之后自动给用户发一条"完事了"的消息。之前已经支持 Telegram 机器人、SMTP 邮箱、Resend API 三类渠道,但有个现实问题——Telegram 在国内网络环境基本不可用,邮件又容易被折叠。最顺手的送达终端其实是微信。

这次从我自己一个跑了很久的签到脚本(GLaDOS_Checkin)里,把两条经过实战验证的微信推送渠道移植进了技能:Server酱和PushPlus。过程不复杂,但有几个坑值得记下来。

为什么是这两家

两者原理相同:你用微信扫码登录他们的平台,拿到一个 Key/Token,之后向固定端点 POST 一条消息,消息就通过微信服务号/公众号推到你手机上。优点非常明显:

  • 不需要域名、不需要服务器、不需要备案
  • 免费额度对个人提醒场景完全够用
  • 送达终端是微信本身,比邮件及时得多

Server酱接入要点

在 sct.ftqq.com 微信扫码登录后,SendKey 页面复制一串 SCTxxxx 形式的密钥,然后发一个表单 POST:

POST https://sctapi.ftqq.com/{SENDKEY}.send
Content-Type: application/x-www-form-urlencoded

title=构建完成&desp=任务已跑完,耗时 3 分钟

响应是 JSON,成功判定是业务码 code == "0",不是 HTTP 200。免费额度每天 5 条,超了会返回配额错误码,脚本里要单独识别。

PushPlus 接入要点

pushplus.plus 同样微信扫码拿 token,走 JSON POST:

POST https://www.pushplus.plus/send
Content-Type: application/json

{"token": "xxx", "title": "构建完成", "content": "任务已跑完", "template": "txt"}

成功判定是 code == 200。返回里带 trace_id,排查问题时有用。

踩坑记录

1. HTTP 200 不代表发送成功。两个平台都是"HTTP 层永远 200,成败看响应体业务码"的设计。早期版本的签到脚本就栽在这里——只检查状态码,消息实际没发出去也显示成功。所以移植时统一封装了判断:_send_json / _send_form 返回响应体,由各渠道自己的规则判定成败。

2. 密钥会出现在 URL 里。Server酱的 SendKey 是路径参数,一旦把请求 URL 打进日志就泄露了。所以发信函数的错误路径全部只输出"渠道名 + HTTP 状态 + 打码后的响应体",URL 永远不落盘。技能里还有一道 SECRET_KEY_RE 正则,凡变量名命中 TOKEN/SECRET/KEY/SENDKEY 等模式的值,一律先打码再进输出。

3. 用户没关注服务号 = 静默失败。首次使用必须先扫码关注对应的微信服务号(Server酱 或 "pushplus 推送加"),否则消息发出去了、接口也返回成功,但微信里永远收不到。这一条我直接写进了技能的排障文档。

4. 代理环境变量不要静默继承。系统里若有 http_proxy,Python 的 urllib 会悄悄走它,出问题时很难定位卡在哪一跳。脚本默认忽略环境代理,只在显式设置 NOTIFY_PROXY 时才走——故障面小很多。

设计:自动降级链

技能最终支持六种送达方式,默认按可靠性排序自动降级:

AUTO_ORDER_DEFAULT = ("telegram", "smtp", "resend", "serverchan", "pushplus")

排前面的渠道密钥不存在或发送失败时自动落到下一个,全部失败才退出非零并附人工排查指引。微信渠道排在邮件之后,作为"没配邮箱/Telegram 时开箱即用"的兜底——毕竟它的配置成本是全渠道里最低的:扫个码、贴个 Key 就完事。

小结

移植本身只花了一个多小时,大部分时间花在把"实战里踩过的坑"固化成判定逻辑:业务码而非 HTTP 状态码、密钥打码、服务号关注检查、代理不静默继承。这四条对任何做消息推送集成的项目都适用。

技能已开源,欢迎交流:github.com/ink358/notify-user

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。