Files
ql-scripts/qqmusic
zhuhjay 87debf37a9 chore(meta): 三个脚本统一青龙元数据注解,新增 _probe_meta.js 自检
继 3531437 修好 qqmusic 之后,把同一问题在另两个脚本上一并清掉 ——
它们原本都没写 name 注解(任务名会退回文件名),且 jd 脚本的 cron 写在块注释里
用了 */ 转义,青龙会把反斜杠一起提取出去。

改动(三个脚本统一成同一形态:文件最前面两行行注释):
  // cron: <表达式>
  // name: <中文任务名>

- jd/scrip_moving_env_enhance.js: 补 name 注解;cron 从块注释移到行注释
  (原来写的 \*/ 转义会产出非法表达式)
- xiequ/scrip_switch.js: 补 name 注解;正文两处日志里的「name: xxx」改成「账号 xxx」
  (青龙的任务名正则不锚定行首、取全文第一个命中,正文命中会盖掉注解)
- qqmusic/scrip_qqmusic_checkin.js: 注解从块注释改成行注释,与另两个统一
- 新增 _probe_meta.js: 扫描所有 scrip_*.js,复刻旧版(/name:\s*(.+)/ 不锚定)
  与新版(cli/src/internal/subscription 的 cronMetadata)两条提取逻辑,
  断言任务名不是代码片段、cron 是合法表达式。不带 scrip_ 前缀,订阅不会拉取

验证:_probe_meta.js RESULT: PASS(3 个文件,两个版本青龙提取都正确)/
三个脚本 node --check 全过 / qqmusic 签名对拍 6 组 PASS / 空 env 优雅跳过
2026-11-04 21:22:38 +08:00
..

QQ音乐自动签到(scrip_qqmusic_checkin.js)

QQ音乐会员成长值任务 + 会员福利站 自动签到,青龙面板 Node 零依赖。 协议底座与 LDP924/auto-checkin(Python)逐字节同源: u6.y.qq.com/cgi-bin/musics.fcg 网关 + zzc 签名(sha1 重组 + 置乱表 + b64 去尾)+ qm_keyst cookie。

文件名必须带 scrip_ 前缀:本仓库的青龙订阅规则白名单是 scrip_, 不带前缀的文件不会被订阅拉取(脚本、测试、文档同一约定)。

环境变量

变量 必填 说明
SH_QQMUSIC_KEY ✅ 多账号:青龙同名 env 加多条(注入自动 & 连接)。单条格式 <uin>#<qm_keyst>,如 123456789#Q_H_L_xxxx。也接受整串 cookie(含 qm_keyst= 与 uin=o...)
QM_KEY / QM_UIN 备选 单账号兼容形态(SH_QQMUSIC_KEY 优先)
QM_CACHE_DIR 可选 key 缓存目录,默认 /ql/data/qqmusic_cache(青龙)/ qqmusic/.cache(本地)
QM_PLAY_REPORT 可选 on 才启用任务20播放上报(本版未实现模板,挂了开关占位)

凭证获取(web 抓一次,之后无限续)

  1. 浏览器打开 y.qq.com 登录(QQ/微信均可)
  2. F12 → Application → Cookies → https://y.qq.com → 复制 qm_keyst 与 uin(o123456789 去掉 o)
  3. 青龙新建环境变量 SH_QQMUSIC_KEY,值 uin#qm_keyst

为什么抓一次就够:签名/g_tk 全是本地算法(无盐、无设备绑定、无动态 token); qm_keyst 名义 72h,但续期接口 QQConnectLogin.LoginServer.QQLogin 旧 key 不吊销—— 脚本每次运行先续期,新 key 写缓存滚动,环境变量永远不用再动。 只有脚本断跑超 72h 且缓存丢失(推送出现 🔴 2000)才需要重新抓。

缓存与订阅安全

续期产物存 /ql/data/qqmusic_cache/qm_<uin>.json(订阅仓库之外)。 git 的 reset/clean 只动 tracked 文件,untracked 目录在 git pull 下天然安全; 且脚本读缓存优先、env 兜底,缓存丢失仅退化为"72h 内重新抓一次"。

定时

cron: 1 0,6 * * *

每天 00:01 + 06:02 双轮:任务20(收听节目)跨天滚动翻账本 + 福利站 0 点翻新兜底。

青龙自动建任务的元数据约定(踩坑记录 2026-11-04)

订阅勾了「自动添加定时任务」时,青龙从脚本内容里正则提取任务名与 cron,两个坑:

项 青龙的提取规则 必须怎么写
任务名 /name:\s*(.+)/(不锚定行首),取全文第一个命中 脚本第 3 行写 * name: QQ音乐自动签到。全文任何位置都不能再出现「name+冒号」的连写——https.request({ hostname: u.hostname }) 会被抓成任务名 u.hostname,(真机已复现)
cron /\bcron:\s*([^\r\n]+)/(必须带冒号) 写 * cron: 1 0,6 * * *,且独占一行、后面不跟注释(同一行剩余文字会被一起吞进 schedule)

两个都抓不到时的兜底:任务名 = 文件名 scrip_qqmusic_checkin.js;cron = 随机 M H * * *。

所以脚本里:

  • https.request 的选项用 host:(Node 的 hostname 别名)而不是 hostname:
  • cron 注解独占一行

任务覆盖

层 内容 风险
任务中心 签到(15) / 挂件(5) / 装扮(5) / 听书(5) / 节目StartTask 低(等价 App 点击)
会员福利站 每日签到(15) / 礼券(+10心愿值) / 旅程激励 / 月里程碑 / 月度好礼 / 臻享抽奖 低(先探后做,无硬编码 ID)
播放上报 任务20 完整 +10 需 App 正常收听(伪造统计默认关) 中(默认关闭)
支付流水任务 4/5/6/12/14/18/21 不可伪造,不碰

状态三态机:Y=已完成零请求(防风控)/ W=进行中直接领 / N=执行动作。 错误码处置:20020 冷却3s重领 · 30005 只读探测后补领 · 10006 写锁即停次日恢复 · 2000 登录态失效推送提示。

本地测试

node --check scrip_qqmusic_checkin.js     # 语法
node scrip_qqmusic_checkin.js             # 无 env 时优雅跳过
SH_QQMUSIC_KEY='123#Q_H_L_x' node -e "console.log(require('./scrip_qqmusic_checkin').parseAccounts())"