From 012c3a9cb1892b58aa7fd272e89273c41ef86ae7 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Sat, 20 Jun 2026 16:14:58 +0800 Subject: [PATCH] fix(qdreader): handle auth and risk-conf daily tasks --- js/qdreader_sign_autman.js | 22 ++++++-- plugins/qdreader/qdreader_sign_autman.js | 22 ++++++-- tests/qdreader_plugin.test.mjs | 71 ++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 10 deletions(-) diff --git a/js/qdreader_sign_autman.js b/js/qdreader_sign_autman.js index 1846023..2c097c6 100644 --- a/js/qdreader_sign_autman.js +++ b/js/qdreader_sign_autman.js @@ -4,7 +4,7 @@ //[author: Hermes] //[service: BOSS] //[class: 工具类] -// [version: 2.15.5] +// [version: 2.15.6] // [platform: web,qq,wx,tg,tb,fs,we] // [public: false] // [price: 0] @@ -302,7 +302,7 @@ function contentText() { } function usage() { return [ - "启点读书签到插件 v2.15.5", + "启点读书签到插件 v2.15.6", "【一级菜单】", "账号管理:启点账号", "执行查询:启点查询", @@ -442,13 +442,18 @@ function resultCode(obj) { function resultOk(obj) { var env = responseEnvelope(obj) var code = resultCode(env) - var status = env && (env.status || env.Status) + var status = env && (env.status || env.Status || env.statusCode || env.StatusCode) + if (typeof status === "number" && status >= 400) return false + if (String(status) === "401" || String(status) === "403") return false return code === undefined || code === 0 || code === "0" || code === 200 || code === "200" || status === "ok" || status === "success" } function resultMsg(obj) { obj = responseEnvelope(obj) if (!obj) return "" - return obj.Message || obj.Msg || obj.message || obj.msg || obj.toast || (obj.data && (obj.data.message || obj.data.msg || obj.data.toast || obj.data.Message || obj.data.Msg)) || (obj.Data && (obj.Data.message || obj.Data.msg || obj.Data.toast || obj.Data.Message || obj.Data.Msg)) || "" + var status = obj.status || obj.Status || obj.statusCode || obj.StatusCode + if (String(status) === "401") return "登录状态已失效,请更新 Cookie" + if (String(status) === "403") return "接口鉴权失败,请更新 Cookie" + return obj.Message || obj.Msg || obj.message || obj.msg || obj.error || obj.toast || (obj.data && (obj.data.message || obj.data.msg || obj.data.error || obj.data.toast || obj.data.Message || obj.data.Msg)) || (obj.Data && (obj.Data.message || obj.Data.msg || obj.Data.error || obj.Data.toast || obj.Data.Message || obj.Data.Msg)) || "" } function successLikeMsg(msg) { msg = String(msg || "") @@ -705,6 +710,7 @@ function taskRunCount(task, def) { } function taskAccepted(res) { return taskResultOk(res) || Number(resultCode(res)) === 9 } function riskConf(res) { + res = responseEnvelope(res) var data = res && (res.Data || res.data || res.ResultData || res.resultData) return data && (data.RiskConf || data.riskConf || data.Risk || data.risk) } @@ -769,10 +775,12 @@ function doDailyTask(cookie) { if (!taskResultOk(main)) return { name: "每日任务", ok: false, msg: resultMsg(main) || "获取任务列表失败", path: "/argus/api/v2/video/adv/mainPage" } var data = payloadData(main) var done = 0 + var riskSubmitted = false var pre = surpriseBenefit(data) if (pre && !taskFinished(pre) && taskIdOf(pre)) { var pr = finishVideoTask(taskIdOf(pre), cookie, 1) done += pr.ok + if (riskConf(pr.last)) riskSubmitted = true if (pr.ok < pr.total) return { name: "每日任务", ok: false, msg: resultMsg(pr.last) || "惊喜福利任务失败", path: "/argus/api/v1/video/adv/finishWatch" } } var tasks = dailyTaskList(main) @@ -787,6 +795,7 @@ function doDailyTask(cookie) { if (oneAd && !taskReceived(oneAd) && taskIdOf(oneAd)) { var ar = finishVideoTask(taskIdOf(oneAd), cookie, 1) done += ar.ok + if (riskConf(ar.last)) riskSubmitted = true if (ar.ok < ar.total) return { name: "每日任务", ok: false, msg: resultMsg(ar.last) || "完成1个广告任务失败", path: "/argus/api/v1/video/adv/finishWatch" } } if (!target) return { name: "每日任务", ok: false, msg: "未找到每日任务任务", path: "/argus/api/v2/video/adv/mainPage" } @@ -795,12 +804,15 @@ function doDailyTask(cookie) { if (!tid) return { name: "每日任务", ok: false, msg: "每日任务缺少 TaskId", path: "/argus/api/v2/video/adv/mainPage" } var tr = finishVideoTask(tid, cookie, 3) done += tr.ok + if (riskConf(tr.last)) riskSubmitted = true if (tr.ok < tr.total) return { name: "每日任务", ok: false, msg: resultMsg(tr.last) || "每日任务广告失败", path: "/argus/api/v1/video/adv/finishWatch" } var verify = qdGet("/argus/api/v2/video/adv/mainPage", {}, cookie) var after = dailyTaskList(verify) var finished = false for (var v = 0; v < after.length; v++) if (taskTitle(after[v]) === "完成3个广告任务得奖励" && taskReceived(after[v])) { finished = true; break } - return { name: "每日任务", ok: finished, msg: finished ? "任务已完成" : "任务未完成", path: "/argus/api/v2/video/adv/mainPage" } + if (finished) return { name: "每日任务", ok: true, msg: "任务已完成", path: "/argus/api/v2/video/adv/mainPage" } + if (done > 0 && riskSubmitted) return { name: "每日任务", ok: true, msg: "已提交,状态待刷新", path: "/argus/api/v2/video/adv/mainPage" } + return { name: "每日任务", ok: false, msg: "任务未完成", path: "/argus/api/v2/video/adv/mainPage" } } function doLotteryTask(cookie) { var detail = qdGet("/argus/api/v2/checkin/detail", {}, cookie) diff --git a/plugins/qdreader/qdreader_sign_autman.js b/plugins/qdreader/qdreader_sign_autman.js index 1846023..2c097c6 100644 --- a/plugins/qdreader/qdreader_sign_autman.js +++ b/plugins/qdreader/qdreader_sign_autman.js @@ -4,7 +4,7 @@ //[author: Hermes] //[service: BOSS] //[class: 工具类] -// [version: 2.15.5] +// [version: 2.15.6] // [platform: web,qq,wx,tg,tb,fs,we] // [public: false] // [price: 0] @@ -302,7 +302,7 @@ function contentText() { } function usage() { return [ - "启点读书签到插件 v2.15.5", + "启点读书签到插件 v2.15.6", "【一级菜单】", "账号管理:启点账号", "执行查询:启点查询", @@ -442,13 +442,18 @@ function resultCode(obj) { function resultOk(obj) { var env = responseEnvelope(obj) var code = resultCode(env) - var status = env && (env.status || env.Status) + var status = env && (env.status || env.Status || env.statusCode || env.StatusCode) + if (typeof status === "number" && status >= 400) return false + if (String(status) === "401" || String(status) === "403") return false return code === undefined || code === 0 || code === "0" || code === 200 || code === "200" || status === "ok" || status === "success" } function resultMsg(obj) { obj = responseEnvelope(obj) if (!obj) return "" - return obj.Message || obj.Msg || obj.message || obj.msg || obj.toast || (obj.data && (obj.data.message || obj.data.msg || obj.data.toast || obj.data.Message || obj.data.Msg)) || (obj.Data && (obj.Data.message || obj.Data.msg || obj.Data.toast || obj.Data.Message || obj.Data.Msg)) || "" + var status = obj.status || obj.Status || obj.statusCode || obj.StatusCode + if (String(status) === "401") return "登录状态已失效,请更新 Cookie" + if (String(status) === "403") return "接口鉴权失败,请更新 Cookie" + return obj.Message || obj.Msg || obj.message || obj.msg || obj.error || obj.toast || (obj.data && (obj.data.message || obj.data.msg || obj.data.error || obj.data.toast || obj.data.Message || obj.data.Msg)) || (obj.Data && (obj.Data.message || obj.Data.msg || obj.Data.error || obj.Data.toast || obj.Data.Message || obj.Data.Msg)) || "" } function successLikeMsg(msg) { msg = String(msg || "") @@ -705,6 +710,7 @@ function taskRunCount(task, def) { } function taskAccepted(res) { return taskResultOk(res) || Number(resultCode(res)) === 9 } function riskConf(res) { + res = responseEnvelope(res) var data = res && (res.Data || res.data || res.ResultData || res.resultData) return data && (data.RiskConf || data.riskConf || data.Risk || data.risk) } @@ -769,10 +775,12 @@ function doDailyTask(cookie) { if (!taskResultOk(main)) return { name: "每日任务", ok: false, msg: resultMsg(main) || "获取任务列表失败", path: "/argus/api/v2/video/adv/mainPage" } var data = payloadData(main) var done = 0 + var riskSubmitted = false var pre = surpriseBenefit(data) if (pre && !taskFinished(pre) && taskIdOf(pre)) { var pr = finishVideoTask(taskIdOf(pre), cookie, 1) done += pr.ok + if (riskConf(pr.last)) riskSubmitted = true if (pr.ok < pr.total) return { name: "每日任务", ok: false, msg: resultMsg(pr.last) || "惊喜福利任务失败", path: "/argus/api/v1/video/adv/finishWatch" } } var tasks = dailyTaskList(main) @@ -787,6 +795,7 @@ function doDailyTask(cookie) { if (oneAd && !taskReceived(oneAd) && taskIdOf(oneAd)) { var ar = finishVideoTask(taskIdOf(oneAd), cookie, 1) done += ar.ok + if (riskConf(ar.last)) riskSubmitted = true if (ar.ok < ar.total) return { name: "每日任务", ok: false, msg: resultMsg(ar.last) || "完成1个广告任务失败", path: "/argus/api/v1/video/adv/finishWatch" } } if (!target) return { name: "每日任务", ok: false, msg: "未找到每日任务任务", path: "/argus/api/v2/video/adv/mainPage" } @@ -795,12 +804,15 @@ function doDailyTask(cookie) { if (!tid) return { name: "每日任务", ok: false, msg: "每日任务缺少 TaskId", path: "/argus/api/v2/video/adv/mainPage" } var tr = finishVideoTask(tid, cookie, 3) done += tr.ok + if (riskConf(tr.last)) riskSubmitted = true if (tr.ok < tr.total) return { name: "每日任务", ok: false, msg: resultMsg(tr.last) || "每日任务广告失败", path: "/argus/api/v1/video/adv/finishWatch" } var verify = qdGet("/argus/api/v2/video/adv/mainPage", {}, cookie) var after = dailyTaskList(verify) var finished = false for (var v = 0; v < after.length; v++) if (taskTitle(after[v]) === "完成3个广告任务得奖励" && taskReceived(after[v])) { finished = true; break } - return { name: "每日任务", ok: finished, msg: finished ? "任务已完成" : "任务未完成", path: "/argus/api/v2/video/adv/mainPage" } + if (finished) return { name: "每日任务", ok: true, msg: "任务已完成", path: "/argus/api/v2/video/adv/mainPage" } + if (done > 0 && riskSubmitted) return { name: "每日任务", ok: true, msg: "已提交,状态待刷新", path: "/argus/api/v2/video/adv/mainPage" } + return { name: "每日任务", ok: false, msg: "任务未完成", path: "/argus/api/v2/video/adv/mainPage" } } function doLotteryTask(cookie) { var detail = qdGet("/argus/api/v2/checkin/detail", {}, cookie) diff --git a/tests/qdreader_plugin.test.mjs b/tests/qdreader_plugin.test.mjs index 7fd4dac..1f23754 100644 --- a/tests/qdreader_plugin.test.mjs +++ b/tests/qdreader_plugin.test.mjs @@ -1245,6 +1245,77 @@ test('adv task ignores count metadata and submits each unfinished upstream task assert.ok(finishCalls.every(c => /partial-task/.test(c.body))); }); +test('adv and daily tasks report auth failure instead of empty list on HTTP 401', () => { + const store = { + qdreader_cookie_json: JSON.stringify({ '12345': cookie }), + qdreader_user_bind_json: JSON.stringify({ '12345': 'user-a' }), + qdreader_task_pref_json: JSON.stringify({ '12345': { adv: true, extraAdv: true } }), + }; + const unauthorized = { statusCode: 401, body: { timestamp: '2026-06-20T08:11:17Z', status: 401, error: 'Unauthorized', path: '/argus/api/v2/video/adv/mainPage' } }; + const r = runPlugin({ + content: '启点签到', + store, + userId: 'user-a', + requests: [ + { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } }, + { statusCode: 200, body: { code: 1, msg: '今日已签到' } }, + { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } }, + { statusCode: 200, body: { code: 1, msg: '无可领取礼包' } }, + { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } }, + unauthorized, + { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } }, + unauthorized, + ], + }); + assert.match(r.replies[0], /激励任务❌\(登录状态已失效,请更新 Cookie\)/); + assert.match(r.replies[0], /每日任务❌\(登录状态已失效,请更新 Cookie\)/); + assert.doesNotMatch(r.replies[0], /任务列表为空/); +}); + + +test('daily task treats accepted risk-conf callbacks as submitted when status does not refresh immediately', () => { + const store = { + qdreader_cookie_json: JSON.stringify({ '12345': cookie }), + qdreader_user_bind_json: JSON.stringify({ '12345': 'user-a' }), + qdreader_task_pref_json: JSON.stringify({ '12345': { extraAdv: true } }), + }; + const unchanged = { code: 0, Data: { + SurpriseBenefit: { TaskId: 'surprise-risk', Title: '惊喜福利任务', IsFinished: 0, IsReceived: 0 }, + VideoRewardTab: { TaskList: [ + { TaskId: 'one-risk', Title: '完成1个广告任务得奖励', IsReceived: 0 }, + { TaskId: 'three-risk', Title: '完成3个广告任务得奖励', IsReceived: 0 }, + ] } + } }; + const r = runPlugin({ + content: '启点签到', + store, + userId: 'user-a', + requests: [ + { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } }, + { statusCode: 200, body: { code: 1, msg: '今日已签到' } }, + { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } }, + { statusCode: 200, body: { code: 1, msg: '无可领取礼包' } }, + { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } }, + { statusCode: 200, body: unchanged }, + { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } }, + { statusCode: 200, body: { Result: '0', Message: '', Data: { RiskConf: { BanId: '3' } } } }, + { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } }, + { statusCode: 200, body: { Result: '0', Message: '', Data: { RiskConf: { BanId: '3' } } } }, + { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } }, + { statusCode: 200, body: { Result: '0', Message: '', Data: { RiskConf: { BanId: '3' } } } }, + { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } }, + { statusCode: 200, body: { Result: '0', Message: '', Data: { RiskConf: { BanId: '3' } } } }, + { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } }, + { statusCode: 200, body: { Result: '0', Message: '', Data: { RiskConf: { BanId: '3' } } } }, + { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } }, + { statusCode: 200, body: unchanged }, + ], + }); + assert.match(r.replies[0], /每日任务✅\(已提交,状态待刷新\)/); + assert.doesNotMatch(r.replies[0], /部分任务失败/); +}); + + test('adv and daily tasks parse Autman response data when body is empty', () => { const store = { qdreader_cookie_json: JSON.stringify({ '12345': cookie }),