Files
ql-scripts/README.md
zhuhjay 23d35cd942 refactor(common): 通知实现搬进 common.js,所有脚本一行 require 即可用
上一版把 notify 内联在 qqmusic 脚本里,只解决了单个脚本。这次搬到仓库根的
common.js,后续任何脚本 require('../common') 就能发通知。

common.js 新增导出:
  notify(title, content, opts)   webhook + pushplus 双通道,任一成功即 ok,永不抛错
  notifyConfig(env)              读 env 并给默认值(可注入替身,方便测试)
  httpPost(url, headers, body)   通用 POST,http/https 自适应
  parseHookHeaders(raw)          一行一个 Key: Value
  buildHookBody(t, c, tpl, ct)   拼 body,JSON 不合法就重建
Env 保持原样未动(jd 与 xiequ 在用)。

顺带删掉第 1 行的 require('node-fetch') —— 它是死代码:Env 内部所有 HTTP 走的是
require('got') + require('tough-cookie'),fetch 只以 $task.fetch(...) 的形式出现在
QuantumultX 分支(宿主 API,不是 node-fetch)。留着它反而会在容器缺 node-fetch 时
让整个文件 require 抛错,连带 jd / xiequ 一起挂。

qqmusic 脚本从 125 行内联实现缩成一行 require('../common'),删掉重复的
httpPost / parseHookHeaders / buildHookBody / notify 四份副本。

测试从 qqmusic/test_notify.js 挪到仓库根 test_common_notify.js,断言从 38 加到 69:
  - parseHookHeaders 九种输入(新增重复 key 覆盖)
  - buildHookBody 五种(新增自定义模板 + urlencoded + text/plain)
  - notifyConfig 十项默认值与 trim
  - notify 八种状态(200/204/201/401/403/400/429/连不上)
  - 无配置、双通道互不牵连
  - Env 兼容性(确认 node-fetch 已移除、老接口都在)

端到端已验证:common.js 的 notify 发出的 content 与原始 desp 逐字相同(10 行完整),
title 正确,header 带 token,HTTP 204 判为成功。

README(根 + qqmusic)新增 common.js 公共库章节,列出 notify 支持的八个环境变量
与「为什么不能放 sendNotify.js」的 deps 覆盖原因。
2026-11-07 02:10:23 +08:00

133 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 青龙面板脚本库
这是一个专为青龙面板设计的脚本库,包含各种自动化脚本和工具。
## 简介
青龙面板是一个支持 Python3、JavaScript、Shell、Typescript 的定时任务管理平台。本仓库提供了一系列实用的脚本,帮助用户更好地使用青龙面板进行自动化任务管理。
## 功能特性
- 📦 丰富的脚本库
- 🔧 易于配置和使用
- 📝 详细的文档说明
- 🚀 持续更新维护
## 脚本列表
| 脚本名称 | 文件路径 | 功能描述 | 环境变量 | 定时规则 |
|---------|---------|----------|----------|----------|
| 京东Cookie辅助脚本 | `jd/scrip_moving_env_enhance.js` | 将JD CK进行重排序,保证所有账号都有助力与被助力的机会 | 需要修改脚本内域名(对应ql的域名) | `59 23 */3 * *` |
| 携趣白名单切换 | `xiequ/scrip_switch.js` | 多个携趣账号,多个IP,自动选择合适的携趣进行白名单切换 | `XQ_ACCOUNTS`<br />`XQ_WHITELIST` | `38 2,8,14,20 * * *` |
| QQ音乐自动签到 | `qqmusic/scrip_qqmusic_checkin.js` | QQ音乐会员成长值任务 + 会员福利站自动签到(签到/挂件/装扮/听书/节目/礼券/月里程碑/抽奖) | `SH_QQMUSIC_KEY`<br />(多账号同名多条,格式 `<uin>#<qm_keyst>`) | `1 0,6 * * *` |
| 通知链路诊断 | `scrip_diag_notify.js` | 排查「通知只收到标题」「自定义发送通知消息失败」:查 sendNotify 加载、env、webhook 前置条件、body 解析、直打平台、pushplus 模板对比 | 无(读现有通知 env) | `0 0 1 1 *`(等于不自动跑,手动执行) |
> **文件名约定**:订阅白名单是 `scrip_`,所有脚本文件必须带该前缀才会被拉取。
> 详见各目录下的 README。
## 公共库 `common.js`
仓库根的 `common.js` 是**依赖文件**(订阅「依赖文件」填 `common` 就会拉下来),
提供两样东西:
```js
const { Env, notify } = require('../common')
// 1. Env:四端环境封装(QuantumultX / Surge / Loon / Node),jd 与 xiequ 在用
const $ = new Env('我的脚本')
// 2. notify:发通知,webhook + pushplus 双通道,任一成功即 ok,永不抛错
const r = await notify('标题', '正文')
// → { ok: true, channels: [{name:'webhook', ok:true, detail:'HTTP 204'}, ...] }
```
`notify` 读的环境变量:
| 变量 | 说明 |
|---|---|
| `WEBHOOK_URL` | 自定义 webhook(如平台 `/api/hooks/ql`) |
| `WEBHOOK_METHOD` | 默认 `POST` |
| `WEBHOOK_CONTENT_TYPE` | 默认 `application/json` |
| `WEBHOOK_BODY` | 支持 `$title` / `$content` 占位;不填则按 Content-Type 给默认形状 |
| `WEBHOOK_HEADERS` | 一行一个 `Key: Value`,**必须是真换行** |
| `PUSH_PLUS_TOKEN` | pushplus 直发 |
| `PUSH_PLUS_USER` | pushplus 群组编码(一对多) |
| `PUSH_PLUS_TEMPLATE` | 默认 `txt`(不转义 html、不折叠) |
**为什么不放在 `sendNotify.js` 里**:青龙订阅复制文件时 `/ql/data/deps/*` 会**最后覆盖**,
而 `deps` 里正好有一份面板自带的 `sendNotify.js`。改那个文件永远不生效。
`common.js` 不在 `deps` 里,所以安全。详见 [qqmusic/README.md](qqmusic/README.md) 的「坑 0」。
自检:
```bash
node test_common_notify.js # 69 条断言,含八种 HTTP 状态码
```
## 安装使用
### 环境要求
- Node.js >= 14.0.0
- 青龙面板 >= 2.10.0
### 快速开始
1. 订阅
```bash
ql repo https://gitea.zhuhjay.cn/zhuhjay/ql-scripts.git "scrip_" "" "sendNotify|common" "js"
```
## 青龙自动建任务的元数据约定(必读)
订阅勾了「自动添加定时任务」时,青龙从**脚本正文**正则提取任务名与 cron。
两条正则都**不锚定行首、取全文第一个命中**(2026-11-04 真机踩坑实录):
| 项 | 青龙的提取规则 | 必须怎么写 |
|---|---|---|
| **任务名** | `/name:\s*(.+)/` | 文件最前面写一行 `// name: 中文任务名`。**全文任何位置都不能再出现「name + 冒号」的连写** —— `https.request({ hostname: u.hostname })` 会被抓成任务名 `u.hostname,`(已复现) |
| **cron** | `/\bcron:\s*([^\r\n]+)/`,**必须带冒号** | 写 `// cron: 1 0,6 * * *`,**独占一行、后面不跟任何注释**(同一行剩余文字会被一起吞进 schedule) |
两个都抓不到时的兜底:任务名 = 文件名;cron = 随机 `M H * * *`(这就是那次任务被建成 `18 21 * * *` 的原因)。
**自检**:
```bash
node _probe_meta.js # 扫描所有 scrip_*.js,复刻两个版本青龙的正则,验证提取结果
```
`_probe_meta.js` 是开发期工具,不带 `scrip_` 前缀,不会被订阅拉取。
新增脚本后跑一次,全 PASS 再提交。
### 各脚本的注解写法
```js
// cron: <表达式>
// name: <中文任务名>
/** 说明文字写这里,注意别写 "name:" 连写 */
```
用**行注释**而不是块注释:块注释里 cron 的 `*/` 会提前闭合注释,必须写成 `*\/`,
而青龙会把反斜杠一起提取出去导致 cron 非法。
## 脚本说明
### 使用方法
每个脚本都有详细的使用说明,请查看对应的文档或脚本内的注释。
## 注意事项
- 请确保脚本符合青龙面板的规范
- 使用前请仔细阅读脚本说明
- 定期更新脚本以获得最新功能
## 免责声明
本项目仅供学习交流使用,请勿用于非法用途。使用本项目所产生的一切后果由使用者自行承担。
---
⭐ 如果这个项目对你有帮助,请给个 Star 支持一下!