From ebcdc67960a16851ac2ccd2f87a35a1d63f51b90 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Sat, 20 Jun 2026 15:41:57 +0800 Subject: [PATCH] fix(qdreader): parse wrapped Autman response data --- js/qdreader_sign_autman.js | 35 ++++++++++----- plugins/qdreader/qdreader_sign_autman.js | 35 ++++++++++----- tests/qdreader_plugin.test.mjs | 55 ++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 22 deletions(-) diff --git a/js/qdreader_sign_autman.js b/js/qdreader_sign_autman.js index 98b0d2f..1846023 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.4] +// [version: 2.15.5] // [platform: web,qq,wx,tg,tb,fs,we] // [public: false] // [price: 0] @@ -302,7 +302,7 @@ function contentText() { } function usage() { return [ - "启点读书签到插件 v2.15.3", + "启点读书签到插件 v2.15.5", "【一级菜单】", "账号管理:启点账号", "执行查询:启点查询", @@ -368,11 +368,11 @@ function parseResp(res) { if (res === undefined || res === null) return null var body = null if (res && typeof res === "object") { - if (res.body !== undefined) body = res.body - else if (res.data !== undefined) body = res.data - else if (res.content !== undefined) body = res.content - else if (res.responseText !== undefined) body = res.responseText - else if (res.statusCode !== undefined || res.status !== undefined || res.headers !== undefined) body = "" + if (res.body !== undefined && res.body !== null && String(res.body) !== "") body = res.body + else if (res.data !== undefined && res.data !== null && String(res.data) !== "") body = res.data + else if (res.content !== undefined && res.content !== null && String(res.content) !== "") body = res.content + else if (res.responseText !== undefined && res.responseText !== null && String(res.responseText) !== "") body = res.responseText + else if (res.statusCode !== undefined || res.status !== undefined || res.headers !== undefined) body = res.data !== undefined ? res.data : "" else body = res } else { body = res @@ -431,6 +431,7 @@ function qidianRequest(path, method, data, cookie) { return out } function resultCode(obj) { + obj = responseEnvelope(obj) if (!obj) return undefined var keys = ["Result", "result", "Code", "code", "retcode", "RetCode"] for (var i = 0; i < keys.length; i++) if (obj[keys[i]] !== undefined) return obj[keys[i]] @@ -439,13 +440,15 @@ function resultCode(obj) { return undefined } function resultOk(obj) { - var code = resultCode(obj) - var status = obj && (obj.status || obj.Status) + var env = responseEnvelope(obj) + var code = resultCode(env) + var status = env && (env.status || env.Status) 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 && (obj.Data.message || obj.Data.msg || obj.Data.toast)) || "" + 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)) || "" } function successLikeMsg(msg) { msg = String(msg || "") @@ -618,7 +621,17 @@ function nested(obj, path) { } return cur } -function payloadData(obj) { return (obj && (obj.Data || obj.data)) || {} } +function responseEnvelope(obj) { + if (!obj || typeof obj !== "object") return obj + if ((obj.statusCode !== undefined || obj.status !== undefined || obj.headers !== undefined) && obj.data && typeof obj.data === "object") return obj.data + return obj +} +function payloadData(obj) { + obj = responseEnvelope(obj) + var data = obj && (obj.Data || obj.data || obj.ResultData || obj.resultData) + if (data && typeof data === "object" && (data.Data || data.data || data.ResultData || data.resultData) && (data.Result !== undefined || data.result !== undefined || data.Code !== undefined || data.code !== undefined || data.Message !== undefined || data.message !== undefined)) return data.Data || data.data || data.ResultData || data.resultData + return data || {} +} function looksLikeVideoTask(task) { return isObject(task) && !!taskIdOf(task) && (task["IsFinished"] !== undefined || task["IsReceived"] !== undefined || task["Title"] !== undefined || task["TaskName"] !== undefined) } function taskArrayScore(list, kind) { if (!Array.isArray(list) || !list.length) return 0 diff --git a/plugins/qdreader/qdreader_sign_autman.js b/plugins/qdreader/qdreader_sign_autman.js index 98b0d2f..1846023 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.4] +// [version: 2.15.5] // [platform: web,qq,wx,tg,tb,fs,we] // [public: false] // [price: 0] @@ -302,7 +302,7 @@ function contentText() { } function usage() { return [ - "启点读书签到插件 v2.15.3", + "启点读书签到插件 v2.15.5", "【一级菜单】", "账号管理:启点账号", "执行查询:启点查询", @@ -368,11 +368,11 @@ function parseResp(res) { if (res === undefined || res === null) return null var body = null if (res && typeof res === "object") { - if (res.body !== undefined) body = res.body - else if (res.data !== undefined) body = res.data - else if (res.content !== undefined) body = res.content - else if (res.responseText !== undefined) body = res.responseText - else if (res.statusCode !== undefined || res.status !== undefined || res.headers !== undefined) body = "" + if (res.body !== undefined && res.body !== null && String(res.body) !== "") body = res.body + else if (res.data !== undefined && res.data !== null && String(res.data) !== "") body = res.data + else if (res.content !== undefined && res.content !== null && String(res.content) !== "") body = res.content + else if (res.responseText !== undefined && res.responseText !== null && String(res.responseText) !== "") body = res.responseText + else if (res.statusCode !== undefined || res.status !== undefined || res.headers !== undefined) body = res.data !== undefined ? res.data : "" else body = res } else { body = res @@ -431,6 +431,7 @@ function qidianRequest(path, method, data, cookie) { return out } function resultCode(obj) { + obj = responseEnvelope(obj) if (!obj) return undefined var keys = ["Result", "result", "Code", "code", "retcode", "RetCode"] for (var i = 0; i < keys.length; i++) if (obj[keys[i]] !== undefined) return obj[keys[i]] @@ -439,13 +440,15 @@ function resultCode(obj) { return undefined } function resultOk(obj) { - var code = resultCode(obj) - var status = obj && (obj.status || obj.Status) + var env = responseEnvelope(obj) + var code = resultCode(env) + var status = env && (env.status || env.Status) 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 && (obj.Data.message || obj.Data.msg || obj.Data.toast)) || "" + 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)) || "" } function successLikeMsg(msg) { msg = String(msg || "") @@ -618,7 +621,17 @@ function nested(obj, path) { } return cur } -function payloadData(obj) { return (obj && (obj.Data || obj.data)) || {} } +function responseEnvelope(obj) { + if (!obj || typeof obj !== "object") return obj + if ((obj.statusCode !== undefined || obj.status !== undefined || obj.headers !== undefined) && obj.data && typeof obj.data === "object") return obj.data + return obj +} +function payloadData(obj) { + obj = responseEnvelope(obj) + var data = obj && (obj.Data || obj.data || obj.ResultData || obj.resultData) + if (data && typeof data === "object" && (data.Data || data.data || data.ResultData || data.resultData) && (data.Result !== undefined || data.result !== undefined || data.Code !== undefined || data.code !== undefined || data.Message !== undefined || data.message !== undefined)) return data.Data || data.data || data.ResultData || data.resultData + return data || {} +} function looksLikeVideoTask(task) { return isObject(task) && !!taskIdOf(task) && (task["IsFinished"] !== undefined || task["IsReceived"] !== undefined || task["Title"] !== undefined || task["TaskName"] !== undefined) } function taskArrayScore(list, kind) { if (!Array.isArray(list) || !list.length) return 0 diff --git a/tests/qdreader_plugin.test.mjs b/tests/qdreader_plugin.test.mjs index e4e216f..7fd4dac 100644 --- a/tests/qdreader_plugin.test.mjs +++ b/tests/qdreader_plugin.test.mjs @@ -1245,6 +1245,61 @@ 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 parse Autman response data when body is empty', () => { + 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 wrappedMain = { statusCode: 200, body: '', data: { Result: 0, Message: '', Data: { + DailyBenefitModule: { TaskList: [{ TaskId: 'wrapped-adv', Title: '激励碎片', IsFinished: 0 }] }, + VideoRewardTab: { TaskList: [ + { TaskId: 'wrapped-one', Title: '完成1个广告任务得奖励', IsReceived: 0 }, + { TaskId: 'wrapped-three', Title: '完成3个广告任务得奖励', IsReceived: 0 }, + ] }, + } } }; + const wrappedDone = { statusCode: 200, body: '', data: { Result: 0, Message: '', Data: { + DailyBenefitModule: { TaskList: [{ TaskId: 'wrapped-adv', Title: '激励碎片', IsFinished: 1 }] }, + VideoRewardTab: { TaskList: [ + { TaskId: 'wrapped-one', Title: '完成1个广告任务得奖励', IsReceived: 1 }, + { TaskId: 'wrapped-three', Title: '完成3个广告任务得奖励', IsReceived: 1 }, + ] }, + } } }; + 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' } } } }, + wrappedMain, + { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } }, + { statusCode: 200, body: '', data: { Result: 0, Message: '' } }, + { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } }, + wrappedDone, + { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } }, + wrappedMain, + { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } }, + { statusCode: 200, body: '', data: { Result: 0, Message: '' } }, + { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } }, + { statusCode: 200, body: '', data: { Result: 0, Message: '' } }, + { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } }, + { statusCode: 200, body: '', data: { Result: 0, Message: '' } }, + { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } }, + { statusCode: 200, body: '', data: { Result: 0, Message: '' } }, + { body: { code: 0, data: { headers: { 'QD-Sign': 'sig' } } } }, + wrappedDone, + ], + }); + assert.match(r.replies[0], /激励任务✅\(任务已完成\)/); + assert.match(r.replies[0], /每日任务✅\(任务已完成\)/); + assert.doesNotMatch(r.replies[0], /任务列表为空/); +}); + + test('adv task accepts discovered task list when upstream module name changes', () => { const store = { qdreader_cookie_json: JSON.stringify({ '12345': cookie }),