butubb
3b6ec8c98f
feat(通知): 加钉钉 / 飞书两种格式(含各自的加签算法)
## 两家签名算法不一样,照抄必错
| | 钉钉 | 飞书 |
|---|---|---|
| HMAC key | `secret` | `"{timestamp}\n{secret}"` |
| 被签内容 | `"{timestamp}\n{secret}"` | 空 |
| timestamp | 毫秒 | 秒 |
| 拼在哪 | URL query | JSON body |
| 结果 | Base64 再 urlencode | Base64 |
| 出错码 | `errcode 310000` | `code 19021` |
实现为 `BaseAdapter.sign_request()` 钩子(默认不动),两家各写各的;
`core/notifier.py` 的 `_post_once` 在发请求前调用它。
## 另外
- 钉钉:markdown 消息(title+text);成功码 0;默认限流 15/分(官方 20/分,**超限会被限 10 分钟**,留余量)
- 飞书:交互式卡片(header 颜色按事件级别 + markdown 元素);成功码 0;默认 60/分
- `PLANNED_FORMATS` 清空(下拉里不再有置灰项)
- **修一个泄漏**:`mask_url` 原来只打码 query 参数——**飞书的 token 在 URL 路径里**(`/hook/<token>`)
→ 接口回显会漏出去。现在同时处理路径 token(≥20 位随机串)与 Slack 的 `/services/T…/B…/X…` 三段。
## 验证(都跑过)
- **签名对拍官方示例**:钉钉逐字节一致(含 urlencode,`%2B` 级别)、飞书的 key/message 口径一致;
时间戳钉住后比对,不靠"自己跟自己一致"
- 成功码按格式:wecom/dingtalk/feishu 的 0 与 bark 的 200 分别判成功,各自的错误码判失败
- 端到端 15 项:钉钉/飞书在假接收端上真发(URL 带签名、body 带 timestamp/sign、卡片是 markdown 元素、
毫秒 vs 秒的时间戳),签名错时正确判失败(310000 / 19021),token 在回显里被打码
2026-09-15 14:29:11 +08:00
..
2026-09-10 21:43:08 +08:00
2026-09-10 21:43:08 +08:00
2026-08-30 10:57:07 +08:00
2026-09-15 13:55:14 +08:00
2026-08-20 10:51:54 +08:00
2026-09-13 10:38:13 +08:00
2026-09-15 13:55:14 +08:00
2026-09-11 11:03:38 +08:00
2026-09-15 13:55:14 +08:00
2026-09-15 13:55:14 +08:00
2026-09-13 14:40:38 +08:00
2026-09-15 14:29:11 +08:00
2026-09-15 13:55:14 +08:00
2026-09-04 14:33:28 +08:00
2026-08-15 15:22:55 +08:00
2026-09-15 13:55:14 +08:00
2026-08-11 09:06:59 +08:00
2026-09-13 23:08:59 +08:00
2026-09-15 13:55:14 +08:00
2026-08-07 13:55:48 +08:00
2026-09-14 08:14:11 +08:00