Webhook 满天飞的时代,我用一个面板做"通知收口"
0. 引子
最开始只是几行 GitHub 通知——我维护几个 repo 想第一时间知道 star / PR / CI。后来给 Kimi 加任务结束通知,再后来自己搭监控,磁盘、Cron、证书过期都要告警。4 个工具、4 个 webhook、4 个 key,散落在 4 个地方。
再往后事情失控:渠道从 Bark 切到飞书(iPhone + Mac),飞书里又分 A 群 B 群 C 群,国际项目准备切 Slack,告警风暴时有发生……到这一步我才意识到问题不在"用哪个渠道",而在信息源和分发渠道都在我代码里。
我决定自己写一个——叫 Bluebird,把散落的 webhook 收在一起,配置和查看都在一个面板里。
1. 痛点:双线散落
故事里的痛点其实是普遍现象:信息源侧散落(每个工具单独配推送目标)+ 分发侧散落(key 散落在脚本 / CI / Prometheus 等各处),衍生四个具体问题——改接收人难、临时静音难、失败审计难、多渠道分发难。
2. 思路:二段抽象
既然痛点是"两端都散落",解法就是两端都集中:

- 信息源:每类应用做一层适配,统一成"带认证的 HTTP 端点 + 字段映射 + 事件过滤";
- 分发渠道:每种渠道做成实例,密钥和接收人都集中在面板里,改接收人不改脚本。
两段之间靠矩阵挂钩——"哪些源走哪些渠道"在面板里勾,改完即生效。
3. 信息源与分发侧
通用 HTTP——任何能发 POST 的应用都能用:
curl -X POST https://你的域名/hooks/<来源 ID> \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"title":"备份完成","body":"server-01 ok","event":"backup"}'
GitHub 适配层内置(不需要 Actions),HMAC 校验、按事件类型过滤、本人操作过滤、卡片渲染都在面板里开关。新增一类信息源(GitLab / Sentry / Grafana),在 server.py 加 _dispatch_<source_type> 注册点即可。

Bluebird 内置 6 类渠道:
| 渠道 | 实例字段 | 卡片能力 |
|---|---|---|
| Bark | device key | iOS 推送 |
| 飞书 | App ID/Secret + receive_id | 彩色卡片(按事件类型配色) |
| 企业微信 | webhook URL | 文本/Markdown |
| Slack | Webhook URL + 可选签名密钥 | Block Kit(同套配色) |
| PushDeer | push key | iOS 推送 |
| 通用 Webhook | URL + 签名密钥 | 任意 HTTP 接收端 |
渠道实例化之后,改接收人 = 编辑渠道 = 改一处——换群、换频道、加新渠道都面板操作,零改脚本。单渠道失败不影响其他渠道到达,失败进审计面板可追溯。
4. 集中编排与查看

信息源和分发渠道的关系是在面板里勾的,不是写死的——一条通知并行推到多个渠道。临时静音、换接收群、加新渠道,改完即生效;整源静音关掉来源行开关就行。


所有推送进审计面板,按来源 / 渠道 / 成败筛选;趋势图按日折线,三视角切换。配置与查看都在同一面板,"集中管理"才算闭环。
5. 几个有意思的设计取舍
-
stdlib 单文件、零依赖:部署成本优先。跑 NAS / 树莓派 / 临时 VPS 一行命令起,不强制 Docker。
-
单渠道失败不影响其他:不是重试(解决不了"目标服务真挂了"),是隔离——一个渠道挂掉不该影响告警的可达性。
-
配置进 DB、每次请求读最新:"改完即生效"的承诺,避免缓存失效复杂度。代价是每次请求多一次 DB 读,单文件自托管规模够用。
-
渠道实例化允许重名、不强制 ID 唯一:渠道名只作展示名和分组名,不进 URL。允许中文、emoji、≤32 字符;ID 是后端生成的稳定标识,对用户透明。
6. 方案对比:为什么没选它们
| 方案 | 形态 | 信息源集中 | 分发集中 | 即改即生效 | 部署门槛 | 适合规模 |
|---|---|---|---|---|---|---|
| 自建散落脚本 | 代码 | ❌ | ❌ key 硬编码 | — | 无 | 1-3 个项目 |
| IM 后台 webhook | SaaS | ❌ | ⚠️ 单渠道多端 | ⚠️ 进后台改 | 无 | 单渠道多接收人 |
| Server 酱 / PushPlus / 方糖 | SaaS | ⚠️ 模板化 | ⚠️ 单一端 | ✅ | 无 | 个人轻量通知 |
| Apprise | Python 库 | ⚠️ 自封装 | ✅ 几十渠道 | ⚠️ 自己写 web 层 | 中 | 开发者自己集成 |
| Gotify | 自托管服务 | ❌ 偏 push 端 | ⚠️ 渠道少 | ✅ | 低 | 安卓端集中收通知 |
| Bluebird | 自托管单文件 | ✅ 二段抽象 | ✅ 6 渠道 | ✅ | ⭐ | 个人/小团队多项目 |
为什么没选 Apprise:好库,但库形态——要自己写 web 层、UI、DB、缓存失效,做完等于自己发明 Bluebird。
为什么没继续用 Server 酱系:多渠道并行 × 多接收人分组 × 推送审计,不在它的设计目标里;付费后仍是单一接收端。
为什么不做 IM 交互机器人:Bluebird 只做单向 webhook 出站,slash command / 按钮 / OAuth 是另一段位复杂度,目前用不上。
7. 适用边界
不是所有人都需要 Bluebird:
- 只有 1 个项目要接推送 → 直接配 IM 后台 webhook 就够;
- 要完整交互(slash command / 按钮 / OAuth)→ 用原厂机器人;
- 要 RBAC / SSO / 审计合规 → 买企业级 SaaS;
- 要 100+ SaaS 集成 → 别指望。
目标用户很窄:自托管玩家,手里一堆项目和脚本要接通知,曾经被散落的 webhook 配置折磨过。
8. 最后
我做 Bluebird 的取舍就四个字——免费、轻量、自托管、可定制。stdlib 单文件跑 NAS / VPS / 树莓派都一行命令起;想要新适配层、新渠道、新事件类型,fork 一下加 _dispatch_<source_type> 即可。
最重要——我自己就是它的第一个用户。日常 GitHub 通知、Kimi 任务结束、自建监控告警全在用,至今没找到更合适的替代。
- GitHub 仓库:https://github.com/hancic128/bluebird
- 部署 / 接入文档:仓库
docs/目录下——装的步骤可以让 AI 帮你跑,更快
issue 和 PR 都欢迎。下一类适配(GitLab / Sentry / Grafana)想在仓库里讨论优先级。
寒蝉 Hancic


