Node.js 依赖名
@asunajs/quark
WPS 表名
quark
夸克网盘
通过手机抓包签到过程
活动界面找到类似,注意后面 query 需要完整 https://drive-m.quark.cn/1/clouddrive/capacity/growth/info?__t=1720880459186&sign_cyclic=true&kps=xxxxxxxxxxxxxxx,(可以在浏览器中访问链接,有效的会返回签到信息,没用的返回 401 错误)从链接中提取出 vcode、kps 和 sign
当然也可以直接查看 headers 中的 x-u-kps-wg(对应 kps)、x-u-sign-wg(对应 sign)和 x-u-vcode(对应 vcode)
脚本
// ../../core/quark/api.ts
function createApi(http) {
let driveUrl = "https://drive-m.quark.cn/1/clouddrive/capacity/growth";
return {
getInfo: function(query) {
return http.get(`${driveUrl}/info?${query}`);
},
sign: function(query) {
return http.post(`${driveUrl}/sign?${query}`, {
sign_cyclic: !0
});
}
};
}
// ../../core/quark/index.ts
function getQuery($) {
return `__t=${Date.now()}&sign_cyclic=true&fr=android&kps=${$.query.kps}&sign=${$.query.sign}&vcode=${$.query.vcode}&pr=ucpro&uc_param_str=`;
}
function getInfo($) {
try {
let { data, code, status, message } = $.api.getInfo(getQuery($));
if (code !== 0) {
$.logger.info("\u83B7\u53D6\u7528\u6237\u4FE1\u606F\u5931\u8D25", code, status, message);
return;
}
return data.cap_sign;
} catch (error) {
$.logger.error("\u83B7\u53D6\u7528\u6237\u4FE1\u606F\u5F02\u5E38", error.message);
}
}
function signIn($) {
try {
let { data, code, status, message } = $.api.sign(getQuery($));
if (code === 0) return data.sign_daily_reward;
if (code === 44210) {
$.logger.info("\u4ECA\u65E5\u5DF2\u7B7E\u5230");
return;
}
$.logger.info("\u7B7E\u5230\u5931\u8D25", code, status, message);
} catch (error) {
$.logger.error("\u7B7E\u5230\u5F02\u5E38", error.message);
}
}
function run($) {
try {
let info = getInfo($);
if (!info) {
$.logger.error("\u767B\u5F55\u5931\u8D25");
return;
}
let { sign_progress, sign_rewards, sign_target, sign_daily } = info;
if (sign_daily) {
$.logger.info(`\u4ECA\u65E5\u5DF2\u7B7E\u5230${sign_rewards[sign_progress - 1].name}\uFF0C\u8FDE\u7B7E\u8FDB\u5EA6${sign_progress}/${sign_target}\u3002`);
return;
}
let dailyReward = signIn($);
dailyReward && $.logger.info(`\u7B7E\u5230\u6210\u529F\uFF0C\u83B7\u5F97${dailyReward / 1048576}M\uFF0C\u8FDE\u7B7E\u8FDB\u5EA6${sign_progress + 1}/${sign_target}\u3002`);
} catch (error) {
$.logger.error("\u8FD0\u884C\u5F02\u5E38", error.message);
}
}
// ../../packages/utils-pure/index.ts
function createLogger(options) {
let wrap = (type, ...args)=>{
if (options && options.pushData) {
let msg = args.reduce((str, cur)=>`${str} ${cur}`, "").substring(1);
options.pushData.push({
msg: msg,
type: type,
date: /* @__PURE__ */ new Date()
});
}
console[type](...args);
}, info = (...args)=>wrap("info", ...args), error = (...args)=>wrap("error", ...args);
return {
info: info,
error: error,
fatal: error,
debug: info,
start: info,
success: info,
fail: info,
trace: info,
warn: (...args)=>wrap("warn", ...args)
};
}
// ../../core/push/index.ts
function _send({ logger, http }, name = "\u81EA\u5B9A\u4E49\u6D88\u606F", options) {
try {
let requestOptions = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
timeout: 1e4,
...options
};
Reflect.has(options, "data") && Reflect.has(options.data, "agent") && (requestOptions.agent = options.data.agent, delete options.data.agent);
let data = http.fetch(requestOptions), { errcode, code, err } = data;
if (errcode || err || ![
0,
200,
void 0
].some((c)=>code === c)) return logger.error(`${name}\u53D1\u9001\u5931\u8D25`, JSON.stringify(data));
logger.info(`${name}\u5DF2\u53D1\u9001\uFF01`);
} catch (error) {
logger.info(`${name}\u53D1\u9001\u5931\u8D25: ${error.message}`);
}
}
function pushplus(apiOption, { token, ...option }, title, text) {
return _send(apiOption, "pushplus", {
url: "http://www.pushplus.plus/send",
method: "POST",
data: {
token: token,
title: title,
content: text,
...option
}
});
}
function serverChan(apiOption, { token, ...option }, title, text) {
return _send(apiOption, "Server\u9171", {
url: `https://sctapi.ftqq.com/${token}.send`,
headers: {
"content-type": "application/x-www-form-urlencoded"
},
data: {
text: title,
desp: text.replace(/\n/g, `
`),
...option
}
});
}
function workWeixin(apiOption, { msgtype = "text", touser = "@all", agentid, corpid, corpsecret, ...option }, title, text) {
try {
let { access_token } = apiOption.http.fetch({
url: "https://qyapi.weixin.qq.com/cgi-bin/gettoken",
method: "POST",
data: {
corpid: corpid,
corpsecret: corpsecret
},
headers: {
"Content-Type": "application/json"
}
});
return _send(apiOption, "\u4F01\u4E1A\u5FAE\u4FE1\u63A8\u9001", {
url: `https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=${access_token}`,
data: {
touser: touser,
msgtype: msgtype,
agentid: agentid,
[msgtype]: {
content: `${title}
${text}`
},
...option
}
});
} catch (error) {
apiOption.logger.error("\u4F01\u4E1A\u5FAE\u4FE1\u63A8\u9001\u5931\u8D25"), apiOption.logger.error(error);
}
}
function workWeixinBot(apiOption, { url, msgtype = "text", ...option }, title, text) {
return _send(apiOption, "\u4F01\u4E1A\u5FAE\u4FE1Bot\u63A8\u9001", {
url: url,
data: {
msgtype: msgtype,
[msgtype]: {
centent: `${title}
${text}`
},
...option
}
});
}
function bark(apiOption, { key, level = "passive", ...options }, title, text) {
return _send(apiOption, "Bark ios \u63A8\u9001", {
url: `https://api.day.app/${key}`,
data: {
body: text,
title: title,
level: level,
...options
}
});
}
// ../utils/index.ts
function createSimpleRequest(headers) {
return {
get: (url)=>HTTP.get(url, {
headers: headers
}).json(),
post: (url, data)=>HTTP.post(url, typeof data == "string" ? data : JSON.stringify(data), {
headers: headers
}).json()
};
}
function getPushConfig() {
let usedRange2 = Application.Sheets.Item("\u63A8\u9001").UsedRange;
if (!usedRange2) return console.log("\u672A\u5F00\u542F\u63A8\u9001"), {};
let cells = usedRange2.Columns.Cells, columnEnd = Math.min(50, usedRange2.ColumnEnd), rowEnd = Math.min(50, usedRange2.RowEnd), pushConfig = {};
for(let option = usedRange2.Column; option <= columnEnd; option++){
let t = {}, item = cells.Item(option);
if (item.Text) {
pushConfig[item.Text] = t;
for(let kv = 1; kv <= rowEnd; kv++){
let key = item.Offset(kv).Text;
key.trim() && (t[key] = valueHandle(item.Offset(kv, 1).Text.trim()));
}
}
}
let base = pushConfig.base;
if (!base) return pushConfig;
return delete pushConfig.base, {
...pushConfig,
...base
};
function valueHandle(value) {
return value === "TRUE" || value === "\u662F" ? !0 : value === "FALSE" || value === "\u5426" ? !1 : value;
}
}
function email({ logger }, email2, title, text) {
try {
if (!email2 || !email2.pass || !email2.from || !email2.host) return;
let port = email2.port || 465, toUser = email2.to || email2.from;
SMTP.login({
host: email2.host,
// 域名
port: port,
// 端口
secure: port === 465,
// TLS
username: email2.from,
// 账户名
password: email2.pass
}).send({
from: `${title} <${email2.from}>`,
to: toUser,
subject: title,
text: text.replace(/\n/g, `\r
`)
}), logger.info("\u90AE\u4EF6\u6D88\u606F\u5DF2\u53D1\u9001");
} catch (error) {
logger.error("\u90AE\u4EF6\u6D88\u606F\u53D1\u9001\u5931\u8D25", error.message);
}
}
function sendNotify(op, data, title, text) {
let cbs = {
pushplus: pushplus,
serverChan: serverChan,
workWeixin: workWeixin,
email: email,
workWeixinBot: workWeixinBot,
bark: bark
};
for (let [name, d] of Object.entries(data))try {
let cb = cbs[name];
if (!cb) continue;
cb(op, d, title, text);
} catch (error) {
op.logger.error("\u672A\u77E5\u5F02\u5E38", error.message);
}
}
function sendWpsNotify(pushData2, pushConfig) {
if (pushData2.length && pushConfig && !(pushConfig.onlyError && !pushData2.some((el)=>el.type === "error"))) {
let msg = pushData2.map((m)=>`[${m.type} ${m.date.toLocaleTimeString()}]${m.msg}`).join(`
`);
msg && sendNotify({
logger: createLogger(),
http: {
fetch: (op)=>(op.data && typeof op.data != "string" && (op.body = JSON.stringify(op.data)), HTTP.fetch(op.url, op).json())
}
}, pushConfig, pushConfig.title || "asign \u8FD0\u884C\u63A8\u9001", msg);
}
}
// index.ts
function main(query, option) {
if (!query.kps || !query.sign) return;
let logger = createLogger({
pushData: option && option.pushData
}), $ = {
api: createApi(createSimpleRequest({
"content-type": "application/json",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0"
})),
logger: logger,
sleep: Time.sleep,
query: query
};
$.logger.info("--------------"), run($);
}
var sheet = Application.Sheets.Item("\u5938\u514B\u7F51\u76D8") || Application.Sheets.Item("quark") || ActiveSheet;
sheet || console.error("\u8BF7\u786E\u5B9A\u5355\u5143\u683C\u540D\u4E3A \u5938\u514B\u7F51\u76D8 \u6216 quark \u6216\u8005\u5DF2\u7ECF\u805A\u7126\u5230\u5BF9\u5E94\u5355\u5143\u683C");
var usedRange = sheet.UsedRange, columnA = sheet.Columns("A"), columnB = sheet.Columns("B"), columnC = sheet.Columns("C"), len = usedRange.Row + usedRange.Rows.Count - 1, pushData = [];
for(let i = 1; i <= len; i++){
let cell = columnA.Rows(i);
cell.Text && (console.log(`\u6267\u884C\u7B2C ${i} \u884C`), main({
sign: columnB.Rows(i).Text,
kps: cell.Text,
vcode: columnC.Rows(i).Text
}, {
pushData: pushData
}));
}
sendWpsNotify(pushData, getPushConfig());