fix(qqmusic): 通知发送失败不再静默 + 新增通知诊断工具
现象:青龙日志里「自定义发送通知消息失败!!」,pushplus 只收到一行标题。
根因排查(三处,都已实测复现):
1) 脚本里 require('../sendNotify') 是 catch{} 静默吞掉 —— 容器缺 got 时
一条通知都发不出去且日志无痕,只能靠猜。改成打印一行原因。
2) sendNotify 的 parseString 用 /(\w+):\s*((?:(?!\n\w+:).)*)/g 解析
WEBHOOK_BODY,靠「换行 + \w+:」断值。单行 JSON 没有换行,整个 body
被吞掉 —— 实测 '{"title":"$title",...}' 解析结果为 {}(0 个 key)。
畸形 body → 对方返回非 200 → 正是「自定义发送通知消息失败」的来源。
3) webhookNotify 有三个前置条件,缺一个就静默 resolve(不发也不报错):
URL/BODY 至少一个含 $title、WEBHOOK_METHOD 必须显式设、body 能被解析。
新增 _diag_notify.js(仓库根,与 sendNotify.js 同级):
- 查 sendNotify 能否加载、通知 env 是否读到(token 脱敏)
- 复刻 parseString,直接告出 WEBHOOK_BODY 会解析成什么
- 直连 pushplus 发 txt 与 html 两条,对比哪个模板正文完整
- 最后走一遍完整 sendNotify,与直连结果对照
用来区分「通道没发」和「微信侧展示折叠」两件事。
验证:node --check / 签名对拍 6 组 PASS / 加载失败时日志文案实测输出
/ _probe_meta 三元数据 PASS
This commit is contained in:
@@ -179,6 +179,53 @@ cron: 1 0,6 * * *
|
||||
明细来源是 `QMClient.steps`:每个动作调一次 `step(name, status, detail)`,
|
||||
`verdict()` 汇总。新增任务时记得补一句 `step()`,否则它在通知里不可见。
|
||||
|
||||
## 通知发不出去怎么查
|
||||
|
||||
`node _diag_notify.js`(放在仓库根,跟 `sendNotify.js` 同级)一次跑完查五件事:
|
||||
|
||||
```
|
||||
1. sendNotify 能不能加载 ← 最常见:容器里缺 got,require 抛错被静默吞掉
|
||||
2. 通知 env 有没有读到 ← 青龙「环境变量」是否真的保存了
|
||||
3. webhook 前置条件 + body 解析 ← 见下方两个坑
|
||||
4. 直连 pushplus 发 txt/html 两条 ← 对比哪个模板正文完整
|
||||
5. 走一遍 sendNotify ← 与 4 对比,定位是通道问题还是展示问题
|
||||
```
|
||||
|
||||
### 坑 1:`require('../sendNotify')` 静默失败
|
||||
|
||||
脚本里原本是 `catch { /* 仅控制台 */ }`,缺 `got` 时**一条通知都发不出去且日志无痕**。
|
||||
现在会打一行:
|
||||
|
||||
```
|
||||
[通知] sendNotify 不可用(Cannot find module 'got'),本轮不发推送
|
||||
```
|
||||
|
||||
修:`docker exec -it qinglong pnpm install got`(sendNotify 只依赖 got + 内置模块)。
|
||||
|
||||
### 坑 2:WEBHOOK_BODY 写成单行 JSON 会被解析成空
|
||||
|
||||
`sendNotify` 的 `parseString` 用 `/(\w+):\s*((?:(?!\n\w+:).)*)/g` 解析,**靠换行 + `\w+:` 断值**。
|
||||
单行 JSON 没有换行,整个 body 被吞掉,实测解析结果 `{}`(0 个 key):
|
||||
|
||||
```js
|
||||
'{"title":"$title","content":"$content"}' → {} ✗
|
||||
'title:$title\ncontent:$content' → 两个 key ✓
|
||||
```
|
||||
|
||||
body 畸形 → 对方返回非 200 → 日志出现 `自定义发送通知消息失败!!`。
|
||||
|
||||
**三个前置条件缺一不可**(`webhookNotify` 逐行 return):
|
||||
|
||||
1. `WEBHOOK_URL` 或 `WEBHOOK_BODY` **至少一个**含 `$title`
|
||||
2. `WEBHOOK_METHOD` **必须显式设**(空则走 else 分支 resolve,不发请求也不报错)
|
||||
3. body 能被 `parseString` 正确解析(多行,或干脆用 URL 传参)
|
||||
|
||||
### 坑 3:pushplus 的 html 模板可能只显示标题
|
||||
|
||||
`sendNotify` 的 pushplus 通道固定发 `template` 缺省值(html),并把 `\n` 换成 `<br>`。
|
||||
微信侧只显示一行是**展示折叠**,点开消息卡片才看全文。
|
||||
要确认是折叠还是真丢内容:`_diag_notify.js` 第 4 节会同时发 txt 和 html 两条,对比即可。
|
||||
|
||||
## 任务覆盖
|
||||
|
||||
| 层 | 内容 | 风险 |
|
||||
|
||||
@@ -861,7 +861,10 @@ async function main() {
|
||||
+ `\n节目任务(20)依赖 App 内正常收听计入(播放上报未启用)`
|
||||
+ `\n时间: ${new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })}`
|
||||
let sendNotifyFn = null
|
||||
try { sendNotifyFn = require('../sendNotify').sendNotify } catch { /* 无 sendNotify 时仅控制台 */ }
|
||||
try { sendNotifyFn = require('../sendNotify').sendNotify } catch (e) {
|
||||
// 静默吞掉会让「通知没发出去」完全不可见 —— 必须留一行,否则只能靠猜
|
||||
log(`[通知] sendNotify 不可用(${e.message.split('\n')[0]}),本轮不发推送`)
|
||||
}
|
||||
if (sendNotifyFn) {
|
||||
try { await sendNotifyFn('QQ音乐签到', desp) } catch (e) { log(`[通知] 推送失败: ${e.message}`) }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user