100 lines
3.4 KiB
JavaScript
100 lines
3.4 KiB
JavaScript
/*
|
|
* 启点读书 Cookie 自动获取/更新 - Quantumult X
|
|
* 只负责抓取 Cookie 并弹窗展示“复制给 Autman 机器人”的快速登录命令,不主动请求 Autman,也不本地持久化。
|
|
*
|
|
* 抓取:打开起点读书 App → 我的 → 福利中心。
|
|
* 抓到后会:
|
|
* 1. 解析 uid 用于确认账号已识别
|
|
* 2. 通知/弹窗里展示原项目风格 JSON Map 快速登录命令,便于直接复制
|
|
*/
|
|
|
|
function getHeader(headers, name) {
|
|
const lower = String(name).toLowerCase()
|
|
for (const k in (headers || {})) if (String(k).toLowerCase() === lower) return headers[k]
|
|
return ''
|
|
}
|
|
function parseCookie(cookie) {
|
|
const jar = {}
|
|
String(cookie || '').split(';').forEach(part => {
|
|
const i = part.indexOf('=')
|
|
if (i <= 0) return
|
|
const k = part.slice(0, i).trim()
|
|
const v = part.slice(i + 1).trim()
|
|
if (k) jar[k] = v
|
|
})
|
|
return jar
|
|
}
|
|
function b64decode(s) {
|
|
let raw = String(s || '').trim()
|
|
try { raw = decodeURIComponent(raw) } catch (e) {}
|
|
raw = raw.replace(/-/g, '+').replace(/_/g, '/')
|
|
while (raw.length % 4) raw += '='
|
|
try { return decodeURIComponent(escape(atob(raw))) } catch (e) { return '' }
|
|
}
|
|
function isRealUid(uid) {
|
|
uid = String(uid === undefined || uid === null ? '' : uid).trim()
|
|
return /^\d{5,}$/.test(uid) ? uid : ''
|
|
}
|
|
function uidFromQDHeader(qdheader) {
|
|
const decoded = b64decode(qdheader)
|
|
if (!decoded) return ''
|
|
const parts = decoded.split('|').map(x => String(x || '').trim())
|
|
// QDReader 抓包里 QDHeader 第一段可能是 (null),真实 UserId 常在第 12 段(索引 11)。
|
|
// 只接受足够长的数字,避免把 1179/2556/版本号等设备字段误当账号。
|
|
for (const idx of [0, 11]) {
|
|
const uid = isRealUid(parts[idx])
|
|
if (uid) return uid
|
|
}
|
|
return ''
|
|
}
|
|
function parseJson(s, def) { try { return JSON.parse(s) } catch (e) { return def } }
|
|
function findUid(obj) {
|
|
if (!obj || typeof obj !== 'object') return ''
|
|
const keys = ['UserId', 'userId', 'UserID', 'userid', 'uid', 'UID']
|
|
for (const key of keys) {
|
|
const uid = isRealUid(obj[key])
|
|
if (uid) return uid
|
|
}
|
|
for (const key in obj) {
|
|
const val = obj[key]
|
|
if (val && typeof val === 'object') {
|
|
const found = findUid(val)
|
|
if (found) return found
|
|
}
|
|
}
|
|
return ''
|
|
}
|
|
function getUid(cookie, body) {
|
|
const jar = parseCookie(cookie)
|
|
let uid = uidFromQDHeader(jar.QDHeader || jar.qdheader || jar.QDHEADER || '')
|
|
if (uid) return uid
|
|
uid = isRealUid(jar.uid || jar.userid || jar.userId || jar.UserId)
|
|
if (uid) return uid
|
|
const obj = parseJson(body || '', null)
|
|
uid = findUid(obj)
|
|
if (uid) return uid
|
|
return isRealUid(jar.ywguid || jar.gwguid || jar.guid)
|
|
}
|
|
function notify(title, sub, msg) {
|
|
$notify(title, sub || '', msg || '')
|
|
}
|
|
|
|
const cookie = getHeader($request && $request.headers, 'Cookie')
|
|
if (!cookie) {
|
|
notify('启点读书', 'Cookie 获取失败', '请求中没有 Cookie')
|
|
$done({})
|
|
} else {
|
|
const body = typeof $response !== 'undefined' ? ($response.body || '') : ''
|
|
const uid = getUid(cookie, body)
|
|
if (!uid) {
|
|
notify('启点读书', 'Cookie 获取失败', '无法识别 uid,请确认已登录并进入福利中心')
|
|
$done({})
|
|
} else {
|
|
// 发给 Autman 机器人的完整快速登录命令,保持原项目 {"uid":"cookie"} 数据格式。
|
|
const submitText = `启点ck ${JSON.stringify({ [uid]: cookie })}`
|
|
const msg = submitText
|
|
notify('启点读书', '抓取成功', msg)
|
|
$done({})
|
|
}
|
|
}
|