feat(qdreader): add full task switches
This commit is contained in:
@@ -30,6 +30,7 @@ https://gitea.chickliu.fun/Hermes/autman-plugins/raw/branch/main/js/qdreader_sig
|
||||
```text
|
||||
启点账号
|
||||
启点查询
|
||||
启点任务
|
||||
```
|
||||
|
||||
`启点账号` 只负责账号管理:
|
||||
@@ -56,6 +57,22 @@ q. 退出
|
||||
请回复序号
|
||||
```
|
||||
|
||||
`启点任务` 负责完整任务模块开关:
|
||||
|
||||
```text
|
||||
启点完全体任务开关:
|
||||
1. 领取奖励:开启(固定)
|
||||
2. 激励任务:关闭
|
||||
3. 每日任务:关闭
|
||||
4. 每日抽奖:关闭
|
||||
5. 每周兑换:关闭
|
||||
6. 章节卡片:关闭
|
||||
7. 大咖荐书:关闭
|
||||
回复:序号 on/off 切换,例如 2 on;q 退出
|
||||
```
|
||||
|
||||
默认只执行签到 + 领取奖励;其余任务按上游完全体模块接入但默认关闭,避免广告/抽奖/兑换类接口在未确认前自动运行。开启后,签到链路会按账号依次追加对应模块,单个模块失败会记录为该账号“部分任务失败”,不会暴露 Cookie。
|
||||
|
||||
### 快速通道
|
||||
|
||||
```text
|
||||
@@ -101,6 +118,12 @@ qdreader_archive_json # yyyy-mm-dd -> 已归档批次日志,用于判断
|
||||
qdreader_sign_api # 签名网关
|
||||
qdreader_retry_count # 请求失败重试次数
|
||||
qdreader_cron_silent # 定时无账号静默
|
||||
qdreader_adv_job_enable # 激励任务开关,默认 false
|
||||
qdreader_extra_adv_job_enable # 每日任务开关,默认 false
|
||||
qdreader_lottery_enable # 每日抽奖开关,默认 false
|
||||
qdreader_weekly_exchange_enable # 每周兑换开关,默认 false
|
||||
qdreader_chapter_card_enable # 章节卡片开关,默认 false
|
||||
qdreader_message_box_enable # 大咖荐书开关,默认 false
|
||||
```
|
||||
|
||||
读取顺序:
|
||||
@@ -130,12 +153,20 @@ set(key, value)
|
||||
- 同时提取 `qdh/QDHeader/guid/qimei/qimei36` 供签名网关使用,其中 `qdh` 只取 Cookie 的 `qdh/QDH`,不再用 `QDHeader` 顶替,避免签名网关 `decodeQDHAuto` 解码失败。
|
||||
2. `POST <qdreader_sign_api>/sign` 获取请求签名头。默认签名网关基址是 `https://api.120399.xyz/qdreader`。
|
||||
3. `POST https://h5.if.qidian.com/argus/api/v3/checkin/checkin` 完成签到。
|
||||
4. 写入单账号当日结果 `qdreader_last_result_json`,包括 `ok/msg/time/source/runId`。
|
||||
5. 写入当日批次日志 `qdreader_last_run_json`,包括触发来源、开始/结束时间、成功/失败/总数和每账号结果;即使账号执行异常也会记录失败日志。
|
||||
6. 插件内只有一个 cron:`1 7 * * *`。
|
||||
7. 每日 07:01 触发时执行签到。
|
||||
8. 签到运行结束后,马上把本次 `qdreader_last_run_json` 按完成日期写入 `qdreader_archive_json`,再清空 `qdreader_last_result_json` / `qdreader_last_run_json`;手动签到同样会立即归档。
|
||||
9. 汇总每个账号签到结果,并在回复中提示归档日期。
|
||||
4. 追加完全体任务链路:
|
||||
- 固定执行领取奖励状态查询:`GET /argus/api/v3/checkin/getcurrentweekcheckininfo`;
|
||||
- 可选激励任务:`GET /argus/api/v2/video/adv/mainPage`;
|
||||
- 可选每日任务:`GET /argus/api/v2/video/adv/packageList`;
|
||||
- 可选每日抽奖:`POST /argus/api/v2/video/lottery`;
|
||||
- 可选每周兑换:`GET /argus/api/v2/video/exchange/page`,仅北京时间周日执行;
|
||||
- 可选章节卡片:`GET /argus/api/v2/video/chapterCard/info`;
|
||||
- 可选大咖荐书:`GET /ajax/message/getMessageBox`。
|
||||
5. 写入单账号当日结果 `qdreader_last_result_json`,包括 `ok/msg/time/source/runId/tasks`。
|
||||
6. 写入当日批次日志 `qdreader_last_run_json`,包括触发来源、开始/结束时间、成功/失败/总数和每账号结果;即使账号执行异常也会记录失败日志。
|
||||
7. 插件内只有一个 cron:`1 7 * * *`。
|
||||
8. 每日 07:01 触发时执行签到链路。
|
||||
9. 签到运行结束后,马上把本次 `qdreader_last_run_json` 按完成日期写入 `qdreader_archive_json`,再清空 `qdreader_last_result_json` / `qdreader_last_run_json`;手动签到同样会立即归档。
|
||||
10. 汇总每个账号签到/完整任务结果,并在回复中提示归档日期。
|
||||
|
||||
## 查询数据来源
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
//[author: Hermes]
|
||||
//[service: BOSS]
|
||||
//[class: 工具类]
|
||||
//[version: 2.5.9]
|
||||
//[version: 2.6.0]
|
||||
//[platform: web,qq,wx,tg,tb,fs,we]
|
||||
//[public: false]
|
||||
//[price: 0]
|
||||
@@ -24,12 +24,27 @@ var REMARK_KEY = "qdreader_remark_json"
|
||||
var SIGN_API_KEY = "qdreader_sign_api"
|
||||
var RETRY_KEY = "qdreader_retry_count"
|
||||
var CRON_SILENT_KEY = "qdreader_cron_silent"
|
||||
var ADV_JOB_ENABLE_KEY = "qdreader_adv_job_enable"
|
||||
var EXTRA_ADV_JOB_ENABLE_KEY = "qdreader_extra_adv_job_enable"
|
||||
var LOTTERY_ENABLE_KEY = "qdreader_lottery_enable"
|
||||
var WEEKLY_EXCHANGE_ENABLE_KEY = "qdreader_weekly_exchange_enable"
|
||||
var CHAPTER_CARD_ENABLE_KEY = "qdreader_chapter_card_enable"
|
||||
var MESSAGE_BOX_ENABLE_KEY = "qdreader_message_box_enable"
|
||||
var LAST_RESULT_KEY = "qdreader_last_result_json"
|
||||
var LAST_RUN_KEY = "qdreader_last_run_json"
|
||||
var ARCHIVE_KEY = "qdreader_archive_json"
|
||||
var DEFAULT_SIGN_API = "https://api.120399.xyz/qdreader"
|
||||
var QIDIAN_BASE = "https://h5.if.qidian.com"
|
||||
var CHECKIN_PATH = "/argus/api/v3/checkin/checkin"
|
||||
var QD_TASKS = [
|
||||
{ key: "reward", label: "领取奖励", path: "/argus/api/v3/checkin/getcurrentweekcheckininfo", method: "GET", defaultEnabled: true, builtin: true },
|
||||
{ key: "adv", label: "激励任务", path: "/argus/api/v2/video/adv/mainPage", method: "GET", settingKey: ADV_JOB_ENABLE_KEY },
|
||||
{ key: "extraAdv", label: "每日任务", path: "/argus/api/v2/video/adv/packageList", method: "GET", settingKey: EXTRA_ADV_JOB_ENABLE_KEY },
|
||||
{ key: "lottery", label: "每日抽奖", path: "/argus/api/v2/video/lottery", method: "POST", settingKey: LOTTERY_ENABLE_KEY, body: { source: "autman" } },
|
||||
{ key: "weeklyExchange", label: "每周兑换", path: "/argus/api/v2/video/exchange/page", method: "GET", settingKey: WEEKLY_EXCHANGE_ENABLE_KEY, sundayOnly: true },
|
||||
{ key: "chapterCard", label: "章节卡片", path: "/argus/api/v2/video/chapterCard/info", method: "GET", settingKey: CHAPTER_CARD_ENABLE_KEY },
|
||||
{ key: "messageBox", label: "大咖荐书", path: "/ajax/message/getMessageBox", method: "GET", settingKey: MESSAGE_BOX_ENABLE_KEY, params: { type: "qdreader" } }
|
||||
]
|
||||
|
||||
function defined(name) { try { return typeof this[name] !== "undefined" } catch (e) { return false } }
|
||||
function globalValue(name) { try { return this[name] } catch (e) { return undefined } }
|
||||
@@ -260,7 +275,7 @@ function contentText() {
|
||||
}
|
||||
function usage() {
|
||||
return [
|
||||
"启点读书签到插件 v2.5.9",
|
||||
"启点读书签到插件 v2.6.0",
|
||||
"【一级菜单】",
|
||||
"账号管理:启点账号",
|
||||
"执行查询:启点查询",
|
||||
@@ -268,9 +283,11 @@ function usage() {
|
||||
"快速提交CK:启点ck <QX抓到的cookie>",
|
||||
"直接签到:启点签到",
|
||||
"指定签到:启点签到 <uid>",
|
||||
"任务配置:启点任务",
|
||||
"【配置】",
|
||||
"签名网关:Autman 参数 hermes_qidian.qdreader_sign_api,默认 " + DEFAULT_SIGN_API,
|
||||
"定时:每日 00:01 只归档并清空日志;每日 07:01 只自动签到;QX 只负责抓 cookie。"
|
||||
"完全体任务:领取奖励默认执行;激励/每日/抽奖/兑换/章节卡/大咖荐书默认关闭,可在 启点任务 菜单开启。",
|
||||
"定时:每日 07:01 自动执行签到链路;QX 只负责抓 cookie。"
|
||||
].join("\n")
|
||||
}
|
||||
function stripCommand(text) {
|
||||
@@ -278,6 +295,7 @@ function stripCommand(text) {
|
||||
if (/^启点(?:签到|读书)(?:\s|$)/i.test(s)) return trim(s.replace(/^启点(?:签到|读书)\s*/i, ""))
|
||||
if (/^启点(?:归档|日志归档)(?:\s|$)/i.test(s)) return trim(s.replace(/^启点(?:归档|日志归档)\s*/i, ""))
|
||||
if (/^启点(?:查询)(?:\s|$)/i.test(s)) return trim(s.replace(/^启点(?:查询)\s*/i, ""))
|
||||
if (/^启点(?:任务|配置)(?:\s|$)/i.test(s)) return trim(s.replace(/^启点(?:任务|配置)\s*/i, ""))
|
||||
if (/^启点(?:账号)(?:\s|$)/i.test(s)) return trim(s.replace(/^启点(?:账号)\s*/i, ""))
|
||||
if (/^启点(?:ck|CK|cookie|Cookie)(?:\s|$)/i.test(s)) return trim(s.replace(/^启点(?:ck|CK|cookie|Cookie)\s*/i, ""))
|
||||
return trim(s.replace(/^qdreader\s*/i, ""))
|
||||
@@ -288,6 +306,7 @@ function commandName(text) {
|
||||
if (/^qdreader\s+sign(?:\s|$)/i.test(text)) return "sign"
|
||||
if (/^qdreader\s+archive(?:\s|$)/i.test(text)) return "archive"
|
||||
if (/^启点(?:查询)(?:\s|$)/i.test(text)) return "status"
|
||||
if (/^启点(?:任务|配置)(?:\s|$)/i.test(text)) return "task"
|
||||
if (/^启点(?:账号)(?:\s|$)/i.test(text)) return "account"
|
||||
return "ck"
|
||||
}
|
||||
@@ -480,14 +499,66 @@ function sourceName(source) {
|
||||
if (source === "manual") return "手动签到"
|
||||
return source || "未知"
|
||||
}
|
||||
function doCheckin(uid, cookie, source, runId) {
|
||||
var startedAt = nowIso()
|
||||
var res = qidianRequest(CHECKIN_PATH, "POST", {}, cookie)
|
||||
function taskEnabled(task) {
|
||||
if (task.defaultEnabled || task.builtin) return true
|
||||
if (task.sundayOnly) { var d = beijingDate(); if (d.getUTCDay() !== 0) return false }
|
||||
return getBool(task.settingKey, false)
|
||||
}
|
||||
function taskStatusLines() {
|
||||
var lines = ["启点完全体任务开关:"]
|
||||
for (var i = 0; i < QD_TASKS.length; i++) {
|
||||
var t = QD_TASKS[i]
|
||||
lines.push((i + 1) + ". " + t.label + ":" + (taskEnabled(t) ? "开启" : "关闭") + (t.builtin ? "(固定)" : ""))
|
||||
}
|
||||
lines.push("回复:序号 on/off 切换,例如 2 on;q 退出")
|
||||
return lines.join("\n")
|
||||
}
|
||||
function taskMenu() {
|
||||
reply(taskStatusLines())
|
||||
var op = listenInput(60000)
|
||||
if (!op || /^(q|退出|取消)$/i.test(op)) return reply("已退出")
|
||||
var m = op.match(/^(\d+)\s*(on|off|开启|关闭|启用|禁用|1|0)?$/i)
|
||||
if (!m) return reply("未识别选项,已退出")
|
||||
var idx = parseInt(m[1], 10) - 1
|
||||
if (idx < 0 || idx >= QD_TASKS.length) return reply("编号无效,已退出")
|
||||
var task = QD_TASKS[idx]
|
||||
if (task.builtin || !task.settingKey) return reply(task.label + " 为固定任务,不能关闭")
|
||||
var enable = m[2] ? /^(on|开启|启用|1)$/i.test(m[2]) : !getBool(task.settingKey, false)
|
||||
cfgSet(task.settingKey, enable ? "true" : "false")
|
||||
return reply(task.label + "已" + (enable ? "开启" : "关闭") + "\n" + taskStatusLines())
|
||||
}
|
||||
function doExtraTask(task, cookie) {
|
||||
var data = task.body || task.params || {}
|
||||
var res = qidianRequest(task.path, task.method || "GET", data, cookie)
|
||||
var ok = resultOk(res)
|
||||
var msg = resultMsg(res) || (ok ? "签到请求成功" : ("签到失败" + (resultCode(res) !== undefined ? " code=" + resultCode(res) : "")))
|
||||
var result = { uid: String(uid), ok: !!ok, msg: String(msg || ""), time: nowIso(), startedAt: startedAt, source: source || "manual", runId: runId || "" }
|
||||
var msg = resultMsg(res) || (ok ? "完成" : ("失败" + (resultCode(res) !== undefined ? " code=" + resultCode(res) : "")))
|
||||
return { name: task.label, ok: !!ok, msg: String(msg || ""), path: task.path }
|
||||
}
|
||||
function doTaskChain(uid, cookie, source, runId) {
|
||||
var startedAt = nowIso()
|
||||
var details = []
|
||||
var checkin = qidianRequest(CHECKIN_PATH, "POST", {}, cookie)
|
||||
var ok = resultOk(checkin)
|
||||
var msg = resultMsg(checkin) || (ok ? "签到请求成功" : ("签到失败" + (resultCode(checkin) !== undefined ? " code=" + resultCode(checkin) : "")))
|
||||
details.push({ name: "签到结果", ok: !!ok, msg: String(msg || ""), path: CHECKIN_PATH })
|
||||
for (var i = 0; i < QD_TASKS.length; i++) {
|
||||
var task = QD_TASKS[i]
|
||||
if (!taskEnabled(task)) continue
|
||||
try { details.push(doExtraTask(task, cookie)) }
|
||||
catch (e) { details.push({ name: task.label, ok: false, msg: e && e.message ? e.message : String(e), path: task.path }) }
|
||||
}
|
||||
var failed = []
|
||||
for (var j = 0; j < details.length; j++) if (!details[j].ok) failed.push(details[j].name + ":" + details[j].msg)
|
||||
var finalOk = failed.length === 0
|
||||
var detailMsg = []
|
||||
for (var k = 0; k < details.length; k++) detailMsg.push(details[k].name + (details[k].ok ? "✅" : "❌") + (details[k].msg ? "(" + displayMsg(details[k].msg) + ")" : ""))
|
||||
var finalMsg = (finalOk ? "完全体任务完成" : "部分任务失败") + ":" + detailMsg.join(";")
|
||||
var result = { uid: String(uid), ok: !!finalOk, msg: String(finalMsg || ""), time: nowIso(), startedAt: startedAt, source: source || "manual", runId: runId || "", tasks: details }
|
||||
setLastResult(uid, result)
|
||||
return { uid: uid, ok: ok, msg: msg, raw: res, log: result }
|
||||
return { uid: uid, ok: finalOk, msg: finalMsg, raw: checkin, log: result }
|
||||
}
|
||||
function doCheckin(uid, cookie, source, runId) {
|
||||
return doTaskChain(uid, cookie, source, runId)
|
||||
}
|
||||
function signAll(targetUid, allUsers, source, archiveAfterRun) {
|
||||
source = source || (allUsers ? "cron" : "manual")
|
||||
@@ -815,7 +886,7 @@ function main() {
|
||||
var isCronRun = !text
|
||||
var cmd = isCronRun ? cronMode() : commandName(text)
|
||||
var arg = isCronRun ? "" : trim(stripCommand(text).replace(/^(sign|archive)\s*/i, ""))
|
||||
if (!arg && cmd !== "sign" && cmd !== "archive" && cmd !== "account" && cmd !== "status") { reply(usage()); return }
|
||||
if (!arg && cmd !== "sign" && cmd !== "archive" && cmd !== "account" && cmd !== "status" && cmd !== "task") { reply(usage()); return }
|
||||
if (/^(帮助|help|h)$/i.test(arg)) { reply(usage()); return }
|
||||
|
||||
var store = getStore()
|
||||
@@ -832,7 +903,8 @@ function main() {
|
||||
}
|
||||
if (cmd === "account") { accountMenu(store, bind); return }
|
||||
if (cmd === "status") { queryMenu(); return }
|
||||
if (cmd === "ck" && /^(查询|状态|status|list|账号|管理)$/i.test(arg)) { reply("请使用一级菜单:启点账号 或 启点查询;快速提交CK:启点ck <cookie>"); return }
|
||||
if (cmd === "task") { taskMenu(); return }
|
||||
if (cmd === "ck" && /^(查询|状态|status|list|账号|管理|任务|配置)$/i.test(arg)) { reply("请使用一级菜单:启点账号 或 启点查询;快速提交CK:启点ck <cookie>"); return }
|
||||
var delMsg = handleDelete(arg, store, bind)
|
||||
if (delMsg !== null) { reply(delMsg); return }
|
||||
if (cmd === "ck") {
|
||||
|
||||
Reference in New Issue
Block a user