fix: drop qdreader legacy compatibility

This commit is contained in:
2026-05-17 18:42:57 +08:00
parent 3a7f85a412
commit 4c819abd5a
4 changed files with 13 additions and 98 deletions
+4 -37
View File
@@ -9,19 +9,18 @@
//[public: false]
//[price: 0]
//[disable: false]
//[description: 启点读书(QDReader) Autman 签到插件:保存 QX 抓到的 H5 Cookie,支持手动“启点签到”和每日 07:15 定时签到;带多环境存储兼容、请求重试、签名响应兼容、结果摘要和安全脱敏。]
//[description: 启点读书(QDReader) Autman 签到插件:保存 QX 抓到的 H5 Cookie,支持手动“启点签到”和每日 07:15 定时签到;带独立 bucket、多用户隔离、请求重试、签名响应解析、结果摘要和安全脱敏。]
//[rule: ^启点(账号|查询|ck|CK|cookie|Cookie|签到|读书)(.*)$]
//[rule: ^qdreader(.*)$]
//[admin: true]
//[priority: 600]
//[cron: 15 7 * * *]
//[param: {"required":false,"key":"hermes_qidian.qdreader_cookie_json","bool":false,"placeholder":"{\"uid\":\"cookie\"}","name":"QDReader Cookie JSON","desc":"机器人交互维护,JSON Map 格式;兼容读取旧 otto bucket"}]
//[param: {"required":false,"key":"hermes_qidian.qdreader_sign_api","bool":false,"placeholder":"https://api.120399.xyz/qdreader","name":"QDReader 签名网关","desc":"默认 https://api.120399.xyz/qdreader;插件会自动追加 /sign,可替换为兼容 /sign 的网关"}]
//[param: {"required":false,"key":"hermes_qidian.qdreader_cookie_json","bool":false,"placeholder":"{\"uid\":\"cookie\"}","name":"QDReader Cookie JSON","desc":"机器人交互维护,JSON Map 格式"}]
//[param: {"required":false,"key":"hermes_qidian.qdreader_sign_api","bool":false,"placeholder":"https://api.120399.xyz/qdreader","name":"QDReader 签名网关","desc":"默认 https://api.120399.xyz/qdreader;插件会自动追加 /sign"}]
//[param: {"required":false,"key":"hermes_qidian.qdreader_retry_count","bool":false,"placeholder":"1","name":"请求失败重试次数","desc":"默认 1,最大 3,仅对网络异常/非业务异常重试"}]
//[param: {"required":false,"key":"hermes_qidian.qdreader_cron_silent","bool":true,"placeholder":"false","name":"定时无账号时静默","desc":"true 时定时触发且没有账号不回复"}]
var BUCKET = "hermes_qidian"
var LEGACY_BUCKET = "otto"
var STORE_KEY = "qdreader_cookie_json"
var BIND_KEY = "qdreader_user_bind_json"
var REMARK_KEY = "qdreader_remark_json"
@@ -44,7 +43,6 @@ function lower(s) { return String(s || "").toLowerCase() }
function cfgGet(key, def) {
try { if (typeof bucketGet === "function") { var bv = bucketGet(BUCKET, key); if (bv !== undefined && bv !== null && String(bv) !== "") return bv } } catch (e) {}
try { if (typeof get === "function") { var v = get(key); if (v !== undefined && v !== null && String(v) !== "") return v } } catch (e) {}
try { if (typeof bucketGet === "function") { var lv = bucketGet(LEGACY_BUCKET, key); if (lv !== undefined && lv !== null && String(lv) !== "") return lv } } catch (e) {}
return def
}
function cfgSet(key, value) {
@@ -283,44 +281,13 @@ function normalizeSignHeaders(signed) {
if (!ok || !isObject(headers)) throw new Error("签名失败:" + JSON.stringify(signed).slice(0, 500))
return headers
}
function signBaseCandidates(rawBase) {
rawBase = String(rawBase || DEFAULT_SIGN_API).replace(/\/+$/, "")
var out = [rawBase]
if (/^https?:\/\/api\.120399\.xyz$/i.test(rawBase)) out.push(rawBase + "/qdreader")
if (/^https?:\/\/api\.120399\.xyz\/QDReader$/i.test(rawBase)) out.push(rawBase.replace(/\/QDReader$/i, "/qdreader"))
var seen = {}
return out.filter(function (x) { if (seen[x]) return false; seen[x] = true; return true })
}
function signErrorRetriable(e) {
var msg = e && e.message ? e.message : String(e || "")
return /签名网关无返回|Cannot\s+POST|404|Not\s+Found/i.test(msg)
}
function isLikelyEmptyHttpResponse(x) {
return !x || (typeof x === "string" && !trim(x))
}
function requestSignHeaders(rawBase, payload) {
var bases = signBaseCandidates(rawBase)
var lastErr = null
for (var i = 0; i < bases.length; i++) {
try {
var signed = postJson(bases[i] + "/sign", payload)
if (i + 1 < bases.length && isLikelyEmptyHttpResponse(signed)) throw new Error("签名网关无返回")
return normalizeSignHeaders(signed)
} catch (e) {
lastErr = e
debug("QDReader sign gateway " + bases[i] + "/sign failed: " + (e && e.message ? e.message : String(e)))
if (!signErrorRetriable(e)) break
}
}
throw lastErr || new Error("签名网关无返回")
}
function qidianRequest(path, method, data, cookie) {
method = String(method || "GET").toUpperCase()
var info = normalizeCookie(cookie)
if (!info.uid) throw new Error("Cookie 缺少 uid/QDHeader")
var signApi = String(cfgGet(SIGN_API_KEY, DEFAULT_SIGN_API)).replace(/\/+$/, "")
var payload = { qdh: info.qdh, qdheader: info.qdheader, url: QIDIAN_BASE + path, method: method, data: data || {}, uid: info.uid, guid: info.guid, qimei: info.qimei, qimei36: info.qimei36 }
var headers = requestSignHeaders(signApi, payload)
var headers = normalizeSignHeaders(postJson(signApi + "/sign", payload))
headers.Cookie = info.cookie
if (!headers["User-Agent"]) headers["User-Agent"] = "Mozilla/5.0 (iPhone; CPU iPhone OS 16_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/QDReaderiOS/5.9.456/728/QDReaderAppstore"
var req = { url: QIDIAN_BASE + path, method: lower(method), dataType: "json", timeOut: 10000, headers: headers }