mirror of
https://github.com/cc892786825/qiandao.git
synced 2025-12-23 10:15:09 +08:00
4953 lines
182 KiB
JavaScript
4953 lines
182 KiB
JavaScript
/*
|
||
中国联通 v1.09 + 自动提取Token整合版
|
||
|
||
包含以下功能:
|
||
1. 首页签到 (话费红包/积分)
|
||
2. 联通祝福 (各类抽奖)
|
||
3. 天天领现金 (每日打卡/立减金)
|
||
4. 权益超市 (任务/抽奖/浇水/领奖)(功能暂时无效)
|
||
5. 安全管家 (日常任务/积分领取)
|
||
6. 联通云盘 (签到/抽奖/AI互动)
|
||
7. 联通阅读 (新版重构: 自动获取书籍/心跳阅读/8051抽奖/查红包)
|
||
|
||
更新说明:
|
||
v1.09:
|
||
- 移除过时的龟兔赛跑、阅光宝盒等冗余代码。
|
||
- 移植Python版阅读逻辑,采用Token加密登录,流程更简洁稳定。
|
||
|
||
配置说明:
|
||
变量名: chinaUnicomCookie
|
||
赋值方式有两种:
|
||
1. 直接填Token (旧方式):
|
||
export chinaUnicomCookie="a3e4c1ff25da2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||
2. 填账号密码 (新方式 - 推荐):
|
||
export chinaUnicomCookie="18600000000#123456"
|
||
(多账号用 & 或 换行 隔开)
|
||
|
||
cron: 0 0,7,20 * * *
|
||
const $ = new Env("中国联通");
|
||
From:yaohuo28507 (Integration by AI, Woread Refactored)
|
||
*/
|
||
const fs = require('fs');
|
||
const crypto = require("crypto"); // 新增:用于账号密码登录的RSA加密
|
||
const appName = createLogger("中国联通"),
|
||
got = require("got"),
|
||
path = require("path"),
|
||
{
|
||
exec: execCommand
|
||
} = require("child_process"),
|
||
cryptoJS = require("crypto-js"),
|
||
{
|
||
CookieJar: cookieJar
|
||
} = require("tough-cookie"),
|
||
chinaUnicom = "chinaUnicom",
|
||
delimiters = ["\n", "&", "@"],
|
||
cookieVars = [chinaUnicom + "Cookie"],
|
||
signDisabled = process.env[chinaUnicom + "Sign"] === "false",
|
||
ltzfDisabled = process.env[chinaUnicom + "Ltzf"] === "false",
|
||
requestTimeout = 50000,
|
||
retryCount = 3,
|
||
projectName = "chinaUnicom",
|
||
retryDelay = 5,
|
||
appVersion = "iphone_c@11.0503",
|
||
userAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 16_1_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 unicom{version:" + appVersion + "}",
|
||
productId = "10000002",
|
||
secretKey = "7k1HcDL8RKvc",
|
||
defaultPassword = "woreadst^&*12345",
|
||
secondProductId = "10000006",
|
||
secondSecretKey = "yQsp9gUqv7qX",
|
||
someConstant = "QzUzOUM2QTQ2MTc4",
|
||
ivString = "16-Bytes--String",
|
||
errorCode = "225",
|
||
errorNumber = "225",
|
||
partyName = "party",
|
||
apiKey = "6-WfVldfFrt3zhjHhe6kzwI-XfG5aMCzRTLI_4K7_a0",
|
||
clientId = "73b138fd-250c-4126-94e2-48cbcc8b9cbe",
|
||
anotherClientId = "7cb46449-3b11-4414-bb49-cbd15525fb88",
|
||
maxRetries = "9",
|
||
minRetries = "1",
|
||
serviceLife = "wocareMBHServiceLife1",
|
||
anotherApiKey = "beea1c7edf7c4989b2d3621c4255132f",
|
||
anotherEncryptionKey = "f4cd4ffeb5554586acf65ba7110534f5",
|
||
numbers = "0123456789",
|
||
letters = "qwertyuiopasdfghjklzxcvbnm",
|
||
uuid = process.env[chinaUnicom + "Uuid"] || appName.randomUuid(),
|
||
someArray = [9, 10, 11, 12, 13],
|
||
delayMs = 1000,
|
||
timeoutMs = 5000,
|
||
client_Id = "1001000003",
|
||
ProductId2 = "100002",
|
||
emptyString = "";
|
||
|
||
// 已清理旧变量
|
||
const maskStr = (str) => {
|
||
try {
|
||
let s = String(str);
|
||
if (s.length === 11) {
|
||
return s.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
|
||
}
|
||
return s;
|
||
} catch (e) {
|
||
return str;
|
||
}
|
||
};
|
||
const expiration_time = 7,
|
||
appMonth_28_MaxTimes = 5,
|
||
maxDrawTimes = 5;
|
||
const activityIds = {
|
||
ttlxj: "TTLXJ20210330",
|
||
card_618: "NZJK618CJHD"
|
||
};
|
||
const constellationMatchingActivity = {
|
||
name: "星座配对",
|
||
id: 2
|
||
};
|
||
const turntableActivity = {
|
||
name: "大转盘",
|
||
id: 3
|
||
};
|
||
const blindBoxActivity = {
|
||
name: "盲盒抽奖",
|
||
id: 4
|
||
};
|
||
const wocareActivities = [constellationMatchingActivity, turntableActivity, blindBoxActivity];
|
||
const card618PrizeMap = {
|
||
ZFGJBXXCY1: "空气",
|
||
GJBNZJK19: "[6]",
|
||
GJBNZJK20: "[1]",
|
||
GJBNZJK21: "[8]",
|
||
GJBNZJK22: "[狂]",
|
||
GJBNZJK23: "[欢]"
|
||
};
|
||
const card618DrawTypeSuffix = {
|
||
"抽奖": "01",
|
||
"首次进入": "02",
|
||
"卡片合成": "03",
|
||
"瓜分奖励": "04"
|
||
};
|
||
|
||
// RSA 公钥,用于密码登录
|
||
const LOGIN_PUB_KEY = `-----BEGIN PUBLIC KEY-----\n${"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDc+CZK9bBA9IU+gZUOc6FUGu7yO9WpTNB0PzmgFBh96Mg1WrovD1oqZ+eIF4LjvxKXGOdI79JRdve9NPhQo07+uqGQgE4imwNnRx7PFtCRryiIEcUoavuNtuRVoBAm6qdB0SrctgaqGfLgKvZHOnwTjyNqjBUxzMeQlEC2czEMSwIDAQAB".match(/.{1,64}/g).join('\n')}\n-----END PUBLIC KEY-----`;
|
||
|
||
function UencryptWithCryptoJS(algorithm, mode, padding, plaintext, key, iv) {
|
||
return cryptoJS[algorithm].encrypt(
|
||
cryptoJS.enc.Utf8.parse(plaintext),
|
||
cryptoJS.enc.Utf8.parse(key),
|
||
{
|
||
mode: cryptoJS.mode[mode],
|
||
padding: cryptoJS.pad[padding],
|
||
iv: cryptoJS.enc.Utf8.parse(iv)
|
||
}
|
||
).ciphertext.toString(cryptoJS.enc.Hex);
|
||
}
|
||
|
||
function decrypt(cipherMethod, mode, padding, ciphertextHex, key, iv) {
|
||
return cryptoJS[cipherMethod].decrypt({
|
||
ciphertext: cryptoJS.enc.Hex.parse(ciphertextHex)
|
||
}, cryptoJS.enc.Utf8.parse(key), {
|
||
mode: cryptoJS.mode[mode],
|
||
padding: cryptoJS.pad[padding],
|
||
iv: cryptoJS.enc.Utf8.parse(iv)
|
||
}).toString(cryptoJS.enc.Utf8);
|
||
}
|
||
|
||
let processCount = 0;
|
||
let processState = 0;
|
||
|
||
/**
|
||
* Initializes process monitoring and sets up termination handling.
|
||
*/
|
||
function initializeProcessMonitoring() {
|
||
processState = 1;
|
||
process.on("SIGTERM", () => {
|
||
processState = 2;
|
||
process.exit(0);
|
||
});
|
||
|
||
const scriptName = path.basename(process.argv[1]);
|
||
const excludedCommands = ["bash", "timeout", "grep"];
|
||
let commandList = ["ps afx"];
|
||
commandList.push(`grep ${scriptName}`);
|
||
commandList = commandList.concat(excludedCommands.map(cmd => `grep -v "${cmd} "`));
|
||
commandList.push("wc -l");
|
||
|
||
const commandString = commandList.join("|");
|
||
|
||
const checkProcessCount = () => {
|
||
execCommand(commandString, (error, stdout, stderr) => {
|
||
if (error || stderr) {
|
||
return;
|
||
}
|
||
processCount = parseInt(stdout.trim(), 10);
|
||
});
|
||
|
||
if (processState === 1) {
|
||
setTimeout(checkProcessCount, 2000);
|
||
}
|
||
};
|
||
|
||
checkProcessCount();
|
||
}
|
||
|
||
/**
|
||
* Class for managing user services with HTTP request handling and logging.
|
||
*/
|
||
class UserService {
|
||
constructor() {
|
||
this.index = appName.userIdx++;
|
||
this.name = "";
|
||
this.valid = false;
|
||
|
||
const retryOptions = {
|
||
limit: 0
|
||
};
|
||
const defaultHeaders = {
|
||
Connection: "keep-alive"
|
||
};
|
||
const httpClientOptions = {
|
||
retry: retryOptions,
|
||
timeout: requestTimeout,
|
||
followRedirect: false,
|
||
ignoreInvalidCookies: true,
|
||
headers: defaultHeaders
|
||
};
|
||
|
||
this.got = got.extend(httpClientOptions);
|
||
|
||
if (processState === 0) {
|
||
initializeProcessMonitoring();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Logs messages with an optional prefix based on user index and name.
|
||
* @param {string} message - The log message.
|
||
* @param {object} options - Additional logging options.
|
||
*/
|
||
log(message, options = {}) {
|
||
let logPrefix = "";
|
||
const userCountLength = appName.userCount.toString().length;
|
||
|
||
if (this.index) {
|
||
logPrefix += `账号[${appName.padStr(this.index, userCountLength)}]`;
|
||
}
|
||
// 新增一个参数来控制是否显示手机号
|
||
if (this.name && !options.hideName) {
|
||
logPrefix += `[${maskStr(this.name)}]`; // 使用 maskStr 包裹 this.name
|
||
}
|
||
|
||
appName.log(logPrefix + message, options);
|
||
// 如果需要通知,将日志添加到用户自己的通知数组中
|
||
if (options.notify) {
|
||
this.notifyLogs.push(logPrefix + message);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Sets a cookie in the cookie jar.
|
||
* @param {string} name - The name of the cookie.
|
||
* @param {string} value - The value of the cookie.
|
||
* @param {string} domain - The domain for the cookie.
|
||
* @param {string} url - The URL for the cookie.
|
||
* @param {object} options - Additional options.
|
||
*/
|
||
set_cookie(name, value, domain, url, options = {}) {
|
||
this.cookieJar.setCookieSync(`${name}=${value}; Domain=${domain};`, url);
|
||
}
|
||
|
||
/**
|
||
* Makes an HTTP request with retry logic.
|
||
* @param {object} requestOptions - The options for the HTTP request.
|
||
* @returns {Promise<object>} - The result of the HTTP request.
|
||
*/
|
||
async request(requestOptions) {
|
||
const networkErrors = ["ECONNRESET", "EADDRINUSE", "ENOTFOUND", "EAI_AGAIN"];
|
||
const timeoutErrors = ["TimeoutError"];
|
||
const protocolErrors = ["EPROTO"];
|
||
const validCodes = [];
|
||
|
||
let response = null;
|
||
let attemptCount = 0;
|
||
const requestName = requestOptions.fn || requestOptions.url;
|
||
|
||
let validCode = appName.get(requestOptions, "valid_code", validCodes);
|
||
requestOptions.method = requestOptions.method?.toUpperCase() || "GET";
|
||
|
||
while (attemptCount < retryCount) {
|
||
try {
|
||
attemptCount++;
|
||
let errorCode = "";
|
||
let errorName = "";
|
||
let error = null;
|
||
const timeout = requestOptions.timeout || this.got.defaults.options.timeout.request || requestTimeout;
|
||
let timeoutOccurred = false;
|
||
|
||
await new Promise((resolve) => {
|
||
setTimeout(() => {
|
||
timeoutOccurred = true;
|
||
resolve();
|
||
}, timeout);
|
||
this.got(requestOptions).then(
|
||
(res) => {
|
||
response = res;
|
||
},
|
||
(err) => {
|
||
error = err;
|
||
response = err.response;
|
||
errorCode = error?.code || "";
|
||
errorName = error?.name || "";
|
||
}
|
||
).finally(() => resolve());
|
||
});
|
||
|
||
if (timeoutOccurred) {
|
||
this.log(`[${requestName}] 请求超时(${timeout / 1000}秒),重试第${attemptCount}次`);
|
||
} else if (protocolErrors.includes(errorCode)) {
|
||
this.log(`[${requestName}] 请求错误[${errorCode}][${errorName}]`);
|
||
if (error?.message) {
|
||
console.log(error.message);
|
||
}
|
||
break;
|
||
} else if (timeoutErrors.includes(errorName)) {
|
||
this.log(`[${requestName}] 请求错误[${errorCode}][${errorName}],重试第${attemptCount}次`);
|
||
} else if (networkErrors.includes(errorCode)) {
|
||
this.log(`[${requestName}] 请求错误[${errorCode}][${errorName}],重试第${attemptCount}次`);
|
||
} else {
|
||
const statusCode = response?.statusCode || "";
|
||
const statusCategory = Math.floor(statusCode / 100);
|
||
|
||
if (statusCode) {
|
||
if (statusCategory > 3 && !validCode.includes(statusCode)) {
|
||
this.log(`请求[${requestName}] 返回[${statusCode}]`);
|
||
}
|
||
if (statusCategory <= 4) {
|
||
break;
|
||
}
|
||
} else {
|
||
this.log(`请求[${requestName}] 错误[${errorCode}][${errorName}]`);
|
||
}
|
||
}
|
||
} catch (err) {
|
||
if (err.name === "TimeoutError") {
|
||
this.log(`[${requestName}] 请求超时,重试第${attemptCount}次`);
|
||
} else {
|
||
this.log(`[${requestName}] 请求错误(${err.message}),重试第${attemptCount}次`);
|
||
}
|
||
}
|
||
}
|
||
|
||
if (response == null) {
|
||
return Promise.resolve({
|
||
statusCode: errorCode || -1,
|
||
headers: null,
|
||
result: null
|
||
});
|
||
}
|
||
|
||
let { statusCode, headers, body } = response;
|
||
if (body) {
|
||
try {
|
||
body = JSON.parse(body);
|
||
} catch { }
|
||
}
|
||
|
||
const result = {
|
||
statusCode,
|
||
headers,
|
||
result: body
|
||
};
|
||
|
||
return Promise.resolve(result);
|
||
}
|
||
}
|
||
|
||
let UserServiceClass = UserService;
|
||
try {
|
||
let LocalBasicService = require("./LocalBasic");
|
||
UserServiceClass = LocalBasicService;
|
||
} catch { }
|
||
let userServiceInstance = new UserServiceClass(appName);
|
||
class CustomUserService extends UserServiceClass {
|
||
constructor(tokenString) {
|
||
super(appName);
|
||
this.cookieString = "";
|
||
this.uuid = process.env[chinaUnicom + "Uuid"] || appName.randomUuid();
|
||
|
||
// 初始化登录信息变量
|
||
this.account_mobile = "";
|
||
this.account_password = "";
|
||
this.token_online = "";
|
||
|
||
// 自动判断是 Token 还是 账号#密码
|
||
// Token 通常较长,账号密码相对较短。这里简单通过 # 判断
|
||
if (tokenString.includes("#") && tokenString.length < 64 && !tokenString.startsWith("a3")) {
|
||
const parts = tokenString.split("#");
|
||
this.account_mobile = parts[0];
|
||
this.account_password = parts[1];
|
||
this.name = this.account_mobile; // 初始显示手机号
|
||
this.log(`识别到账号密码模式,准备自动提取Token: ${maskStr(this.account_mobile)}`);
|
||
} else {
|
||
let deftokenParts = tokenString.split("#");
|
||
this.token_online = deftokenParts[0];
|
||
}
|
||
|
||
const defaultHeaders = {
|
||
"User-Agent": userAgent
|
||
};
|
||
this.got = this.got.extend({
|
||
headers: defaultHeaders,
|
||
hooks: {
|
||
beforeRequest: [
|
||
(options) => {
|
||
if (this.cookieString) {
|
||
options.headers.cookie = this.cookieString;
|
||
}
|
||
},
|
||
],
|
||
afterResponse: [
|
||
(response) => {
|
||
const newCookies = response.headers["set-cookie"];
|
||
if (newCookies && Array.isArray(newCookies)) {
|
||
let cookieObj = {};
|
||
if (this.cookieString) {
|
||
this.cookieString.split(";").forEach((pair) => {
|
||
const parts = pair.split("=");
|
||
if (parts.length >= 2)
|
||
cookieObj[parts[0].trim()] = parts.slice(1).join("=").trim();
|
||
});
|
||
}
|
||
newCookies.forEach((str) => {
|
||
const pair = str.split(";")[0];
|
||
const parts = pair.split("=");
|
||
if (parts.length >= 2) {
|
||
const key = parts[0].trim();
|
||
const value = parts.slice(1).join("=").trim();
|
||
cookieObj[key] = value;
|
||
}
|
||
});
|
||
this.cookieString = Object.entries(cookieObj)
|
||
.map(([k, v]) => `${k}=${v}`)
|
||
.join("; ");
|
||
}
|
||
return response;
|
||
},
|
||
],
|
||
},
|
||
});
|
||
|
||
this.unicomTokenId = appName.randomString(32);
|
||
this.tokenId_cookie = "chinaunicom-" + appName.randomString(32, numbers + letters).toUpperCase();
|
||
this.rptId = "";
|
||
this.city = [];
|
||
this.t_flmf_task = 0;
|
||
this.t_woread_draw = 0;
|
||
// 尽管新版阅读已移除这些逻辑,但保留变量初始化以防调用旧代码报错
|
||
this.need_read_rabbit = false;
|
||
this.moonbox_task_record = {};
|
||
|
||
this.initialTelephoneAmount = null;
|
||
this.notifyLogs = []; // 为每个用户实例添加独立的通知日志数组
|
||
this.moonbox_notified = [];
|
||
|
||
// for security butler
|
||
this.sec_ticket1 = "";
|
||
this.sec_token = "";
|
||
this.sec_ticket = "";
|
||
this.sec_jeaId = "";
|
||
this.sec_oldJFPoints = null;
|
||
|
||
this.ttxc_token = "";
|
||
this.ttxc_userId = "";
|
||
|
||
// for new woread logic
|
||
this.wr_catid = null;
|
||
this.wr_cardid = null;
|
||
this.wr_cntindex = null;
|
||
this.wr_chapterallindex = null;
|
||
this.wr_chapterid = null;
|
||
|
||
this.cookieString = `TOKENID_COOKIE=${this.tokenId_cookie}; UNICOM_TOKENID=${this.unicomTokenId}; sdkuuid=${this.unicomTokenId}`;
|
||
}
|
||
|
||
// --- RSA 加密辅助函数 (对应原脚本2的功能) ---
|
||
rsa_encrypt(val) {
|
||
const randomStr = Array.from({ length: 6 }, () => Math.floor(Math.random() * 9)).join('');
|
||
const buffer = Buffer.from(String(val) + randomStr);
|
||
return crypto.publicEncrypt({
|
||
key: LOGIN_PUB_KEY,
|
||
padding: crypto.constants.RSA_PKCS1_PADDING
|
||
}, buffer).toString("base64");
|
||
}
|
||
|
||
// --- 使用账号密码登录获取 token_online ---
|
||
async unicom_login() {
|
||
this.log(`正在使用账号 ${maskStr(this.account_mobile)} 进行登录...`);
|
||
const now = new Date();
|
||
const pad = (n) => n.toString().padStart(2, '0');
|
||
const reqtime = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`;
|
||
|
||
try {
|
||
const payload = {
|
||
"version": "iphone_c@12.0100",
|
||
"mobile": this.rsa_encrypt(this.account_mobile),
|
||
"reqtime": reqtime,
|
||
"deviceModel": "iPhone17,2",
|
||
"password": this.rsa_encrypt(this.account_password)
|
||
};
|
||
|
||
const requestOptions = {
|
||
fn: "unicom_login",
|
||
method: "post",
|
||
url: "https://m.client.10010.com/mobileService/login.htm",
|
||
headers: {
|
||
"User-Agent": `ChinaUnicom4.x/12.0.1 (com.chinaunicom.mobilebusiness; build:120001; iOS 19.2.0) Alamofire/5.9.1 unicom{version:"iphone_c@12.0100"}`
|
||
},
|
||
form: payload
|
||
};
|
||
|
||
let response = await this.request(requestOptions);
|
||
let { result: data, statusCode } = response;
|
||
|
||
if (data && (data.code === "0" || data.code === "0000")) {
|
||
if (data.token_online) {
|
||
this.token_online = data.token_online;
|
||
this.log(`✅ 登录成功,获取到 token_online`);
|
||
return true;
|
||
} else {
|
||
this.log(`❌ 登录响应中未找到 token_online`);
|
||
return false;
|
||
}
|
||
} else {
|
||
this.log(`❌ 登录失败: ${data ? data.desc : '无响应'} (Code: ${data ? data.code : statusCode})`);
|
||
return false;
|
||
}
|
||
|
||
} catch (e) {
|
||
this.log(`❌ 登录过程异常: ${e.message}`);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
get_bizchannelinfo() {
|
||
const bizChannelInfo = {
|
||
bizChannelCode: errorNumber,
|
||
disriBiz: partyName,
|
||
unionSessionId: "",
|
||
stType: "",
|
||
stDesmobile: "",
|
||
source: "",
|
||
rptId: this.rptId,
|
||
ticket: "",
|
||
tongdunTokenId: this.tokenId_cookie,
|
||
xindunTokenId: this.unicomTokenId
|
||
};
|
||
let bizChannelInfoString = JSON.stringify(bizChannelInfo);
|
||
return bizChannelInfoString;
|
||
}
|
||
|
||
get_epay_authinfo() {
|
||
const authInfo = {
|
||
mobile: "",
|
||
sessionId: this.sessionId,
|
||
tokenId: this.tokenId,
|
||
userId: ""
|
||
};
|
||
return JSON.stringify(authInfo);
|
||
}
|
||
|
||
get_flmf_data(actCode = "welfareCenter") {
|
||
const flmfData = {
|
||
sid: this.flmf_sid,
|
||
actcode: actCode
|
||
};
|
||
return flmfData;
|
||
}
|
||
|
||
encode_woread(data, password = defaultPassword) {
|
||
let encryptedData = UencryptWithCryptoJS("AES", "CBC", "Pkcs7", JSON.stringify(data), password, ivString);
|
||
return Buffer.from(encryptedData, "utf-8").toString("base64");
|
||
}
|
||
encode_woread1(data, password = defaultPassword) {
|
||
let encryptedData = UencryptWithCryptoJS("AES", "CBC", "Pkcs7", data, password, ivString);
|
||
return Buffer.from(encryptedData, "utf-8").toString("base64");
|
||
}
|
||
|
||
// 新增:单字符串加密,用于模拟Python脚本中的参数加密
|
||
encode_woread_str(text, password = defaultPassword) {
|
||
let encryptedData = UencryptWithCryptoJS("AES", "CBC", "Pkcs7", text, password, ivString);
|
||
return Buffer.from(encryptedData, "utf-8").toString("base64");
|
||
}
|
||
|
||
get_woread_param() {
|
||
return {
|
||
timestamp: appName.time("yyyyMMddhhmmss"),
|
||
token: this.woread_token,
|
||
userid: this.woread_userid,
|
||
userId: this.woread_userid,
|
||
userIndex: this.woread_userIndex,
|
||
userAccount: this.mobile,
|
||
verifyCode: this.woread_verifycode
|
||
};
|
||
}
|
||
get_woread_m_param() {
|
||
return {
|
||
timestamp: appName.time("yyyyMMddhhmmss"),
|
||
signtimestamp: Date.now(),
|
||
source: maxRetries,
|
||
token: this.woread_token
|
||
};
|
||
}
|
||
get_ltyp_sign_header(secretKey) {
|
||
const currentTime = Date.now();
|
||
const randomSequence = Math.floor(89999 * Math.random()) + 100000;
|
||
const productId = ProductId2;
|
||
const version = emptyString;
|
||
const signature = cryptoJS.MD5(secretKey + currentTime + randomSequence + productId + version).toString();
|
||
|
||
const header = {
|
||
key: secretKey,
|
||
resTime: currentTime,
|
||
reqSeq: randomSequence,
|
||
channel: productId,
|
||
version: version,
|
||
sign: signature
|
||
};
|
||
|
||
return header;
|
||
}
|
||
async onLine(options = {}) {
|
||
// 检查是否需要先登录获取Token
|
||
if (!this.token_online && this.account_mobile && this.account_password) {
|
||
let loginSuccess = await this.unicom_login();
|
||
if (!loginSuccess) {
|
||
this.log("⚠️ 账号密码登录失败,无法继续执行 onLine");
|
||
return false;
|
||
}
|
||
}
|
||
|
||
let loginSuccess = false;
|
||
// const filePath = path.join(__dirname, 'chinaUnicom_cache.json');
|
||
|
||
try {
|
||
const androidVersion = "android@11.0000";
|
||
const deviceId = this.uuid ;
|
||
|
||
let requestOptions = {
|
||
fn: "onLine",
|
||
method: "post",
|
||
url: "https://m.client.10010.com/mobileService/onLine.htm",
|
||
headers: {
|
||
'User-Agent': `Dalvik/2.1.0 (Linux; U; Android 9; ALN-AL10 Build/PQ3A.190705.11211540);unicom{version:${androidVersion}}`
|
||
},
|
||
form: {
|
||
isFirstInstall: '1',
|
||
netWay: 'Wifi',
|
||
version: androidVersion,
|
||
// deviceId: deviceId,
|
||
token_online: this.token_online,
|
||
provinceChanel: 'general',
|
||
deviceModel: 'ALN-AL10',
|
||
step: 'dingshi',
|
||
androidId: '291a7deb1d716b5a',
|
||
reqtime: Date.now(),
|
||
}
|
||
};
|
||
|
||
let response = await this.request(requestOptions);
|
||
let { result: responseData, statusCode: responseStatus } = response;
|
||
let responseCode = appName.get(responseData, "code", responseStatus);
|
||
|
||
if (responseCode == 0) {
|
||
loginSuccess = true;
|
||
this.valid = true;
|
||
this.mobile = responseData?.["desmobile"];
|
||
this.name = responseData?.["desmobile"];
|
||
this.ecs_token = responseData?.["ecs_token"];
|
||
this.city = responseData?.["list"];
|
||
this.log("登录成功");
|
||
|
||
} else {
|
||
this.valid = false;
|
||
this.log("登录失败[" + responseCode + "]");
|
||
// 如果是因为Token失效且配置了密码,尝试重新登录(可选优化)
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
this.log("发生异常:" + error.message);
|
||
} finally {
|
||
return loginSuccess;
|
||
}
|
||
}
|
||
|
||
// ============================================
|
||
// 权益超市 NEW LOGIC
|
||
// ============================================
|
||
|
||
async get_ticket(ecs_token) {
|
||
this.log("权益超市: 正在获取 ticket...");
|
||
try {
|
||
const requestOptions = {
|
||
fn: "get_ticket",
|
||
method: "get",
|
||
url: "https://m.client.10010.com/mobileService/openPlatform/openPlatLineNew.htm?to_url=https://contact.bol.wo.cn/market",
|
||
headers: {
|
||
'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 12; leijun Pro Build/SKQ1.22013.001);unicom{version:android@11.0702}',
|
||
'Connection': "Keep-Alive",
|
||
'Accept-Encoding': "gzip",
|
||
'Cookie': `ecs_token=${ecs_token}`
|
||
},
|
||
followRedirect: false // Important: we need to capture the 302 redirect
|
||
};
|
||
const { headers, statusCode } = await this.request(requestOptions);
|
||
if (statusCode === 302 && headers?.location) {
|
||
const locationUrl = new URL(headers.location);
|
||
const ticket = locationUrl.searchParams.get("ticket");
|
||
if (ticket) {
|
||
this.log("权益超市: 获取ticket成功");
|
||
return ticket;
|
||
}
|
||
}
|
||
this.log(`权益超市: 获取ticket失败, status: ${statusCode}`);
|
||
return null;
|
||
} catch (e) {
|
||
this.log(`权益超市: 获取ticket异常: ${e.message}`);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
async get_userToken(ticket) {
|
||
this.log("权益超市: 正在获取 userToken...");
|
||
try {
|
||
const requestOptions = {
|
||
fn: "get_userToken",
|
||
method: "post",
|
||
url: `https://backward.bol.wo.cn/prod-api/auth/marketUnicomLogin?ticket=${ticket}`,
|
||
headers: {
|
||
'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 12; leijun Pro Build/SKQ1.22013.001);unicom{version:android@11.0702}',
|
||
'Connection': "Keep-Alive",
|
||
'Accept-Encoding': "gzip",
|
||
}
|
||
};
|
||
const { result, statusCode } = await this.request(requestOptions);
|
||
if (result?.code === 200) {
|
||
const userToken = result?.data?.token;
|
||
if (userToken) {
|
||
this.log("权益超市: 获取userToken成功");
|
||
return userToken;
|
||
}
|
||
}
|
||
this.log(`权益超市: 获取userToken失败: ${result?.msg || '返回数据异常'}`);
|
||
return null;
|
||
} catch (e) {
|
||
this.log(`权益超市: 获取userToken异常: ${e.message}`);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
async get_AllActivityTasks(ecs_token, userToken) {
|
||
this.log("权益超市: 正在获取任务列表...");
|
||
try {
|
||
const requestOptions = {
|
||
fn: "getAllActivityTasks",
|
||
method: "get",
|
||
url: "https://backward.bol.wo.cn/prod-api/promotion/activityTask/getAllActivityTasks?activityId=12",
|
||
headers: {
|
||
'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 12; leijun Pro Build/SKQ1.22013.001);unicom{version:android@11.0702}',
|
||
'Authorization': `Bearer ${userToken}`,
|
||
'Cookie': `ecs_token=${ecs_token}`
|
||
}
|
||
};
|
||
const { result } = await this.request(requestOptions);
|
||
if (result?.code === 200) {
|
||
const tasks = result?.data?.activityTaskUserDetailVOList || [];
|
||
this.log(`权益超市: 成功获取到 ${tasks.length} 个任务`);
|
||
return tasks;
|
||
}
|
||
this.log(`权益超市: 查询任务列表失败: ${result?.msg || '未知错误'}`);
|
||
return [];
|
||
} catch (e) {
|
||
this.log(`权益超市: 查询任务列表异常: ${e.message}`);
|
||
return [];
|
||
}
|
||
}
|
||
|
||
async do_ShareList(shareList, userToken) {
|
||
this.log("权益超市: 开始执行任务...");
|
||
for (const task of shareList) {
|
||
const { name, param1: param, triggerTime, triggeredTime } = task;
|
||
if (name.includes("购买") || name.includes("秒杀")) {
|
||
this.log(`权益超市: 🚫 ${name} [跳过]`);
|
||
continue;
|
||
}
|
||
if (triggeredTime >= triggerTime) {
|
||
this.log(`权益超市: ✅ ${name} [已完成]`);
|
||
continue;
|
||
}
|
||
|
||
let url = "";
|
||
if (name.includes("浏览") || name.includes("查看")) {
|
||
url = `https://backward.bol.wo.cn/prod-api/promotion/activityTaskShare/checkView?checkKey=${param}`;
|
||
} else if (name.includes("分享")) {
|
||
url = `https://backward.bol.wo.cn/prod-api/promotion/activityTaskShare/checkShare?checkKey=${param}`;
|
||
}
|
||
|
||
if (url) {
|
||
try {
|
||
const requestOptions = {
|
||
fn: `do_task_${name}`,
|
||
method: "post",
|
||
url: url,
|
||
headers: {
|
||
'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 12; leijun Pro Build/SKQ1.22013.001);unicom{version:android@11.0702}',
|
||
'Authorization': `Bearer ${userToken}`,
|
||
}
|
||
};
|
||
const { result } = await this.request(requestOptions);
|
||
if (result?.code === 200) {
|
||
this.log(`权益超市: ✅ ${name} [执行成功]`);
|
||
} else {
|
||
this.log(`权益超市: ❌ ${name} [执行失败]: ${result?.msg}`);
|
||
}
|
||
} catch (e) {
|
||
this.log(`权益超市: ❌ ${name} [执行异常]: ${e.message}`);
|
||
}
|
||
}
|
||
await appName.wait(2000 + Math.random() * 2000);
|
||
}
|
||
}
|
||
|
||
async get_Raffle(userToken) {
|
||
this.log("权益超市: 正在查询奖品池...");
|
||
try {
|
||
const requestOptions = {
|
||
fn: "get_Raffle",
|
||
method: "post",
|
||
url: "https://backward.bol.wo.cn/prod-api/promotion/home/raffleActivity/prizeList?id=12",
|
||
headers: {
|
||
'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 12; leijun Pro Build/SKQ1.22013.001);unicom{version:android@11.0702}',
|
||
'Authorization': `Bearer ${userToken}`
|
||
}
|
||
};
|
||
const { result } = await this.request(requestOptions);
|
||
if (result?.code === 200 && Array.isArray(result.data)) {
|
||
const keywords = ['月卡', '月会员', '月度', 'VIP月', '一个月'];
|
||
const livePrizes = result.data.filter(prize =>
|
||
keywords.some(kw => prize.name.includes(kw)) &&
|
||
parseInt(prize.dailyPrizeLimit, 10) > 0 &&
|
||
parseInt(prize.quantity, 10) > 0
|
||
);
|
||
|
||
if (livePrizes.length > 0) {
|
||
this.log("权益超市: 📢 当前已放水!可抽有库存奖品👇👇👇");
|
||
livePrizes.forEach(item => {
|
||
this.log(` - ${item.name} (日库存:${item.dailyPrizeLimit}, 总库存:${item.quantity}, 概率:${(item.probability * 100).toFixed(1)}%)`);
|
||
});
|
||
return true;
|
||
}
|
||
}
|
||
this.log("权益超市: 📢 当前未放水!终止抽奖😡😡😡");
|
||
return false;
|
||
} catch (e) {
|
||
this.log(`权益超市: 查询奖品池异常: ${e.message}`);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
async get_raffle_count(userToken) {
|
||
this.log("权益超市: 正在查询抽奖次数...");
|
||
try {
|
||
const requestOptions = {
|
||
fn: "get_raffle_count",
|
||
method: "post",
|
||
url: "https://backward.bol.wo.cn/prod-api/promotion/home/raffleActivity/getUserRaffleCount?id=12",
|
||
headers: {
|
||
'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 12; leijun Pro Build/SKQ1.22013.001);unicom{version:android@11.0702}',
|
||
'Authorization': `Bearer ${userToken}`
|
||
}
|
||
};
|
||
const { result } = await this.request(requestOptions);
|
||
let count = result?.data || 0;
|
||
if (result?.code === 200 && count > 0) {
|
||
this.log(`权益超市: ✅ 当前抽奖次数: ${count}`);
|
||
for (let i = 0; i < count; i++) {
|
||
this.log(`权益超市: 🎯 第 ${i + 1} 次抽奖...`);
|
||
const success = await this.get_userRaffle(userToken);
|
||
if (!success) {
|
||
this.log("权益超市: 抽奖失败或遇到验证, 停止后续抽奖");
|
||
break;
|
||
}
|
||
await appName.wait(3000 + Math.random() * 2000);
|
||
}
|
||
} else {
|
||
this.log(`权益超市: 当前无抽奖次数`);
|
||
}
|
||
} catch (e) {
|
||
this.log(`权益超市: 查询抽奖次数异常: ${e.message}`);
|
||
}
|
||
}
|
||
|
||
async get_userRaffle(userToken) {
|
||
try {
|
||
const requestOptions = {
|
||
fn: "get_userRaffle",
|
||
method: "post",
|
||
url: "https://backward.bol.wo.cn/prod-api/promotion/home/raffleActivity/userRaffle?id=12&channel=",
|
||
headers: {
|
||
'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 12; leijun Pro Build/SKQ1.22013.001);unicom{version:android@11.0702}',
|
||
'Authorization': `Bearer ${userToken}`
|
||
}
|
||
};
|
||
const { result } = await this.request(requestOptions);
|
||
if (result?.code === 200 && result?.data) {
|
||
const { lotteryRecordId, prizesName, message } = result.data;
|
||
if (prizesName) {
|
||
this.log(`权益超市: ✅ 抽奖成功: ${prizesName}`);
|
||
} else {
|
||
this.log(`权益超市: ⚠️ 抽奖成功, 但: ${message}`);
|
||
}
|
||
if (lotteryRecordId) { // GrantPrize is always true based on python script
|
||
this.log("权益超市: 尝试领取:${prizesName}");
|
||
await this.get_grantPrize(userToken, lotteryRecordId, prizesName || '未知奖品');
|
||
}
|
||
return true;
|
||
} else if (result?.code === 500) {
|
||
this.log("权益超市: 遇到人机验证, 尝试绕过...");
|
||
return await this.get_validateCaptcha(userToken);
|
||
} else {
|
||
this.log(`权益超市: 抽奖失败: ${result?.msg || '未知错误'}`);
|
||
return false;
|
||
}
|
||
} catch (e) {
|
||
this.log(`权益超市: 抽奖异常: ${e.message}`);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
async get_validateCaptcha(userToken) {
|
||
try {
|
||
const requestOptions = {
|
||
fn: "get_validateCaptcha",
|
||
method: "post",
|
||
url: "https://backward.bol.wo.cn/prod-api/promotion/home/raffleActivity/validateCaptcha?id=12",
|
||
headers: {
|
||
'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 12; leijun Pro Build/SKQ1.22013.001);unicom{version:android@11.0702}',
|
||
'Authorization': `Bearer ${userToken}`
|
||
}
|
||
};
|
||
const { result } = await this.request(requestOptions);
|
||
if (result?.code === 200) {
|
||
this.log("权益超市: 人机验证成功, 重新抽奖...");
|
||
return await this.get_userRaffle(userToken);
|
||
}
|
||
this.log(`权益超市: 人机验证失败: ${result?.msg}`);
|
||
return false;
|
||
} catch (e) {
|
||
this.log(`权益超市: 人机验证异常: ${e.message}`);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
async queryGeneralPrizes(userToken) {
|
||
this.log("权益超市: 正在查询待领取奖品...");
|
||
if (!userToken) {
|
||
this.log("权益超市-查通用奖品: userToken not found, skipping.");
|
||
return;
|
||
}
|
||
// 'this.mobile' is available after a successful onLine.htm call.
|
||
if (!this.mobile) {
|
||
this.log("权益超市-查待领取奖品: 手机号未找到, 跳过.");
|
||
return;
|
||
}
|
||
|
||
try {
|
||
const requestBody = {
|
||
"isReceive": "0",
|
||
"receiveStatus": "0",
|
||
"limit": 20,
|
||
"page": 1,
|
||
"mobile": this.mobile,
|
||
"businessSources": ["3", "4", "5", "6", "99"],
|
||
"isPromotion": 1,
|
||
"returnFormatType": 1
|
||
};
|
||
|
||
const requestOptions = {
|
||
fn: "queryGeneralPrizes",
|
||
method: "post",
|
||
url: `https://backward.bol.wo.cn/prod-api/market/contactReceive/queryReceiveRecord`,
|
||
headers: {
|
||
'Authorization': `Bearer ${userToken}`,
|
||
'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 12; leijun Pro Build/SKQ1.22013.001);unicom{version:android@11.0702}',
|
||
'Content-Type': 'application/json'
|
||
},
|
||
json: requestBody
|
||
};
|
||
|
||
const { result } = await this.request(requestOptions);
|
||
|
||
if (result?.code !== 200) {
|
||
this.log(`权益超市-查待领取奖品: 查询失败: ${result?.msg || '未知错误'}`);
|
||
return;
|
||
}
|
||
|
||
const prizes = result.data?.recordObjs || [];
|
||
const now = new Date();
|
||
|
||
const claimablePrizes = prizes.filter(prize => {
|
||
if (!prize.receiveEndTime) return false;
|
||
const endTime = new Date(prize.receiveEndTime.replace(/-/g, "/"));
|
||
return endTime > now;
|
||
});
|
||
|
||
if (claimablePrizes.length > 0) {
|
||
this.log(`权益超市: 查询到 ${claimablePrizes.length} 个可领取奖品:`, { notify: true });
|
||
for (const prize of claimablePrizes) {
|
||
this.log(` - ${prize.recordName} (截止: ${prize.receiveEndTime})`);
|
||
if (prize.businessId) {
|
||
await this.grantGeneralPrize(userToken, prize);
|
||
await appName.wait(1500 + Math.random() * 1000);
|
||
} else {
|
||
this.log(` └─ 缺少 businessId, 无法自动领取.`);
|
||
}
|
||
}
|
||
} else {
|
||
this.log("权益超市: 未发现可领取的奖品。");
|
||
}
|
||
|
||
} catch (e) {
|
||
this.log(`权益超市-查待领取奖品: 任务异常: ${e.message}`);
|
||
}
|
||
}
|
||
|
||
async grantGeneralPrize(userToken, prize) {
|
||
this.log(`权益超市: └─ 尝试领取: ${prize.recordName}`);
|
||
try {
|
||
const requestOptions = {
|
||
fn: "grantGeneralPrize",
|
||
method: "post",
|
||
url: "https://backward.bol.wo.cn/prod-api/promotion/home/raffleActivity/grantPrize",
|
||
headers: {
|
||
'Authorization': `Bearer ${userToken}`,
|
||
'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 12; leijun Pro Build/SKQ1.22013.001);unicom{version:android@11.0702}',
|
||
'Content-Type': 'application/json'
|
||
},
|
||
json: { "recordId": prize.businessId } // Using businessId as recordId
|
||
};
|
||
const { result } = await this.request(requestOptions);
|
||
if (result?.code === 200) {
|
||
this.log(`权益超市: └─ ✅ [领取成功]`);
|
||
} else {
|
||
this.log(`权益超市: └─ ❌ [领取失败]: ${result?.msg}`);
|
||
}
|
||
} catch (e) {
|
||
this.log(`权益超市: └─ 领取通用奖品 ${prize.recordName} 异常: ${e.message}`);
|
||
}
|
||
}
|
||
|
||
async get_grantPrize(userToken, lotteryRecordId, prizesName) {
|
||
try {
|
||
const requestOptions = {
|
||
fn: "get_grantPrize",
|
||
method: "post",
|
||
url: "https://backward.bol.wo.cn/prod-api/promotion/home/raffleActivity/grantPrize?activityId=12",
|
||
headers: {
|
||
'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 12; leijun Pro Build/SKQ1.22013.001);unicom{version:android@11.0702}',
|
||
'Authorization': `Bearer ${userToken}`,
|
||
'Content-Type': 'application/json'
|
||
},
|
||
json: { "recordId": lotteryRecordId }
|
||
};
|
||
const { result } = await this.request(requestOptions);
|
||
if (result?.code === 200) {
|
||
this.log(`权益超市: ✅ ${prizesName} [领取成功]`);
|
||
} else {
|
||
this.log(`权益超市: ❌ ${prizesName} [领取失败]: ${result?.msg}`);
|
||
}
|
||
} catch (e) {
|
||
this.log(`权益超市: 领取奖品异常: ${e.message}`);
|
||
}
|
||
}
|
||
|
||
async marketWateringTask(userToken) {
|
||
this.log("权益超市: 浇花任务开始...");
|
||
if (!userToken) {
|
||
this.log("权益超市-浇花: userToken not found, skipping.");
|
||
return;
|
||
}
|
||
|
||
try {
|
||
// 1. Get watering status
|
||
const statusOptions = {
|
||
fn: "marketGetWateringStatus",
|
||
method: "get",
|
||
url: `https://backward.bol.wo.cn/prod-api/promotion/activityTask/getMultiCycleProcess?activityId=13`,
|
||
headers: {
|
||
'Authorization': `Bearer ${userToken}`,
|
||
'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 12; leijun Pro Build/SKQ1.22013.001);unicom{version:android@11.0702}',
|
||
}
|
||
};
|
||
const { result: statusResult } = await this.request(statusOptions);
|
||
|
||
if (statusResult?.code !== 200) {
|
||
this.log(`权益超市-浇花: 获取状态失败: ${statusResult?.msg || '未知错误'}`);
|
||
return;
|
||
}
|
||
|
||
const { triggeredTime, triggerTime, createDate } = statusResult.data;
|
||
this.log(`权益超市-浇花: 当前进度 ${triggeredTime}/${triggerTime}`, { notify: true });
|
||
|
||
// 2. Conditional logic
|
||
if (triggeredTime >= triggerTime) {
|
||
this.log("权益超市-浇花: 🌟 您有鲜花权益待领取! (连续浇花已满) 🌟", { notify: true });
|
||
return;
|
||
}
|
||
|
||
// Check if watered today
|
||
const todayStr = new Date(new Date().getTime() + 8 * 3600 * 1000).toISOString().split('T')[0];
|
||
const lastWateredDateStr = createDate ? createDate.split(' ')[0] : '';
|
||
|
||
if (todayStr === lastWateredDateStr) {
|
||
this.log(`权益超市-浇花: 今日已浇水 (最后浇水时间: ${createDate})`, { notify: true });
|
||
return;
|
||
}
|
||
|
||
this.log("权益超市-浇花: 今日未浇水,执行浇水操作...");
|
||
|
||
// 3. Perform watering
|
||
const waterOptions = {
|
||
fn: "marketWatering",
|
||
method: "post",
|
||
url: "https://backward.bol.wo.cn/prod-api/promotion/activityTaskShare/checkWatering",
|
||
headers: {
|
||
'Authorization': `Bearer ${userToken}`,
|
||
'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 12; leijun Pro Build/SKQ1.22013.001);unicom{version:android@11.0702}',
|
||
'Content-Type': 'application/json'
|
||
},
|
||
json: {}
|
||
};
|
||
const { result: waterResult } = await this.request(waterOptions);
|
||
|
||
if (waterResult?.code === 200) {
|
||
this.log("权益超市-浇花: ✅ 浇水成功!");
|
||
} else {
|
||
this.log(`权益超市-浇花: ❌ 浇水失败: ${waterResult?.msg || '未知错误'}`);
|
||
}
|
||
|
||
} catch (e) {
|
||
this.log(`权益超市-浇花: 任务异常: ${e.message}`);
|
||
}
|
||
}
|
||
|
||
async marketTask() {
|
||
this.log("============= 权益超市 =============");
|
||
|
||
// The main `task` function already calls `await user.onLine()`.
|
||
// So when `marketTask` is called, `this.ecs_token` should be available.
|
||
const ecs_token = this.ecs_token;
|
||
|
||
if (!ecs_token) {
|
||
this.log("权益超市: ❌ 未获取到 ecs_token, 跳过任务");
|
||
this.log("============= 权益超市执行完毕 =============");
|
||
return;
|
||
}
|
||
|
||
// 1. Get ticket
|
||
const ticket = await this.get_ticket(ecs_token);
|
||
if (!ticket) {
|
||
this.log("============= 权益超市执行完毕 =============");
|
||
return;
|
||
}
|
||
|
||
// 2. Get userToken
|
||
const userToken = await this.get_userToken(ticket);
|
||
if (!userToken) {
|
||
this.log("============= 权益超市执行完毕 =============");
|
||
return;
|
||
}
|
||
|
||
// New: Execute watering task
|
||
await this.marketWateringTask(userToken);
|
||
await appName.wait(2000);
|
||
|
||
// 3. Get and do tasks
|
||
const shareList = await this.get_AllActivityTasks(ecs_token, userToken);
|
||
if (shareList && shareList.length > 0) {
|
||
await this.do_ShareList(shareList, userToken);
|
||
}
|
||
|
||
// 4. Check raffle and draw
|
||
const canRaffle = await this.get_Raffle(userToken);
|
||
if (canRaffle) {
|
||
await this.get_raffle_count(userToken);
|
||
}
|
||
|
||
// 5. Query and claim prizes
|
||
// await this.get_MyPrize(userToken); // For raffle prizes
|
||
await this.queryGeneralPrizes(userToken); // For general prizes
|
||
|
||
this.log("============= 权益超市执行完毕 =============");
|
||
}
|
||
|
||
|
||
async openPlatLineNew(url, options = {}) {
|
||
const defaultResult = {
|
||
ticket: "",
|
||
type: "",
|
||
loc: ""
|
||
};
|
||
|
||
let result = defaultResult;
|
||
|
||
try {
|
||
const queryParams = {
|
||
to_url: url
|
||
};
|
||
const requestOptions = {
|
||
fn: "openPlatLineNew",
|
||
method: "get",
|
||
url: "https://m.client.10010.com/mobileService/openPlatform/openPlatLineNew.htm",
|
||
searchParams: queryParams
|
||
};
|
||
|
||
const { headers, statusCode } = await this.request(requestOptions);
|
||
|
||
if (headers?.["location"]) {
|
||
const locationUrl = new URL(headers.location);
|
||
const type = locationUrl.searchParams.get("type") || "02";
|
||
const ticket = locationUrl.searchParams.get("ticket");
|
||
|
||
if (!ticket) {
|
||
this.log("获取ticket失败");
|
||
}
|
||
|
||
result = {
|
||
loc: headers.location,
|
||
ticket: ticket,
|
||
type: type
|
||
};
|
||
} else {
|
||
this.log(`获取ticket失败[${statusCode}]`);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
} finally {
|
||
return result;
|
||
}
|
||
}
|
||
async gettaskip(options = {}) {
|
||
const orderId = appName.randomString(32).toUpperCase();
|
||
|
||
try {
|
||
const requestBody = {
|
||
mobile: this.mobile,
|
||
orderId: orderId
|
||
};
|
||
|
||
const requestOptions = {
|
||
fn: "gettaskip",
|
||
method: "post",
|
||
url: "https://m.client.10010.com/taskcallback/topstories/gettaskip",
|
||
form: requestBody
|
||
};
|
||
|
||
await this.request(requestOptions);
|
||
} catch (error) {
|
||
console.log(error);
|
||
} finally {
|
||
return orderId;
|
||
}
|
||
}
|
||
async draw_28_queryChance(options = {}) {
|
||
try {
|
||
const requestConfig = {
|
||
fn: "draw_28_queryChance",
|
||
method: "post",
|
||
url: "https://m.client.10010.com/AppMonthly/appMonth/queryChance"
|
||
};
|
||
|
||
let {
|
||
result: responseResult,
|
||
statusCode: responseStatusCode
|
||
} = await this.request(requestConfig),
|
||
status = appName.get(responseResult, "status", responseStatusCode);
|
||
|
||
if (status == "0000") {
|
||
let remainingTimes = parseInt(responseResult?.["data"]?.["allRemainTimes"] || 0),
|
||
drawTimes = Math.min(maxDrawTimes, remainingTimes);
|
||
|
||
this.log("28日五折日可以抽奖" + remainingTimes + "次, 去抽" + drawTimes + "次");
|
||
|
||
let isFirstAttempt = false;
|
||
while (drawTimes-- > 0) {
|
||
if (isFirstAttempt) {
|
||
await appName.wait(8000);
|
||
}
|
||
isFirstAttempt = true;
|
||
await this.draw_28_lottery();
|
||
}
|
||
} else {
|
||
let errorMessage = responseResult?.["message"] || responseResult?.["msg"] || "";
|
||
this.log("28日五折日查询抽奖次数失败[" + status + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async draw_28_lottery(options = {}) {
|
||
try {
|
||
const requestOptions = {
|
||
fn: "draw_28_lottery",
|
||
method: "post",
|
||
url: "https://m.client.10010.com/AppMonthly/appMonth/lottery"
|
||
};
|
||
|
||
const { result: responseResult, statusCode: responseStatusCode } = await this.request(requestOptions);
|
||
const status = appName.get(responseResult, "status", responseStatusCode);
|
||
|
||
if (status === "0000") {
|
||
const data = responseResult?.["data"];
|
||
const code = appName.get(data, "code", -1);
|
||
|
||
if (data?.["uuid"]) {
|
||
await appName.wait(2000);
|
||
await this.draw_28_winningRecord(data.uuid);
|
||
} else {
|
||
const errorMessage = data?.["message"] || data?.["msg"] || "";
|
||
this.log(`28日五折日抽奖失败[${code}]: ${errorMessage}`);
|
||
}
|
||
} else {
|
||
const errorMessage = responseResult?.["message"] || responseResult?.["msg"] || "";
|
||
this.log(`28日五折日抽奖失败[${status}]: ${errorMessage}`);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async draw_28_winningRecord(requestId, options = {}) {
|
||
try {
|
||
const requestPayload = {
|
||
requestId: requestId
|
||
};
|
||
|
||
const requestOptions = {
|
||
fn: "draw_28_winningRecord",
|
||
method: "post",
|
||
url: "https://m.client.10010.com/AppMonthly/appMonth/winningRecord",
|
||
form: requestPayload
|
||
};
|
||
|
||
const { result, statusCode } = await this.request(requestOptions);
|
||
const status = appName.get(result, "status", statusCode);
|
||
|
||
if (status === "0000") {
|
||
const responseData = result?.["data"];
|
||
const resultCode = appName.get(responseData, "code", -1);
|
||
|
||
if (resultCode === "0000") {
|
||
const logOptions = {
|
||
notify: true
|
||
};
|
||
this.log("28日五折日抽奖: " + responseData?.["prizeName"]?.replace(/\t/g, ""), logOptions);
|
||
} else {
|
||
const errorMessage = responseData?.["message"] || responseData?.["msg"] || "";
|
||
this.log(`查询28日五折日抽奖结果失败[${resultCode}]: ${errorMessage}`);
|
||
}
|
||
} else {
|
||
const errorMessage = result?.["message"] || result?.["msg"] || "";
|
||
this.log(`查询28日五折日抽奖结果失败[${status}]: ${errorMessage}`);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
|
||
async ttlxj_authorize(ticket, type, refererUrl, options = {}) {
|
||
try {
|
||
const requestConfig = {
|
||
fn: "ttlxj_authorize",
|
||
method: "post",
|
||
url: "https://epay.10010.com/woauth2/v2/authorize",
|
||
headers: {
|
||
Origin: "https://epay.10010.com",
|
||
Referer: refererUrl
|
||
},
|
||
json: {
|
||
response_type: "rptid",
|
||
client_id: clientId,
|
||
redirect_uri: "https://epay.10010.com/ci-mps-st-web/",
|
||
login_hint: {
|
||
credential_type: "st_ticket",
|
||
credential: ticket,
|
||
st_type: type,
|
||
force_logout: true,
|
||
source: "app_sjyyt"
|
||
},
|
||
device_info: {
|
||
token_id: "chinaunicom-pro-" + Date.now() + "-" + appName.randomString(13),
|
||
trace_id: appName.randomString(32)
|
||
}
|
||
}
|
||
};
|
||
|
||
const { result } = await this.request(requestConfig);
|
||
const statusCode = appName.get(result, "status", -1);
|
||
|
||
if (statusCode === 200) {
|
||
await this.ttlxj_authCheck();
|
||
} else {
|
||
const errorMessage = result?.["message"] || result?.["msg"] || "";
|
||
this.log(`天天领现金获取SESSION失败[${statusCode}]: ${errorMessage}`);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
|
||
async ttlxj_authCheck(options = {}) {
|
||
try {
|
||
const requestConfig = {
|
||
fn: "ttlxj_authCheck",
|
||
method: "post",
|
||
url: "https://epay.10010.com/ps-pafs-auth-front/v1/auth/check",
|
||
headers: {
|
||
bizchannelinfo: this.get_bizchannelinfo()
|
||
}
|
||
};
|
||
|
||
const { result } = await this.request(requestConfig);
|
||
const responseCode = appName.get(result, "code", -1);
|
||
|
||
if (responseCode === "0000") {
|
||
const { mobile, sessionId, tokenId, userId } = result?.["data"]?.["authInfo"];
|
||
const authInfo = {
|
||
sessionId,
|
||
tokenId,
|
||
userId
|
||
};
|
||
Object.assign(this, authInfo);
|
||
|
||
await this.ttlxj_userDrawInfo();
|
||
await this.ttlxj_queryAvailable();
|
||
} else {
|
||
if (responseCode === "2101000100") {
|
||
const loginUrl = result?.["data"]?.["woauth_login_url"];
|
||
await this.ttlxj_login(loginUrl);
|
||
} else {
|
||
const errorMessage = result?.["msgInside"] || result?.["msg"] || "";
|
||
this.log(`天天领现金获取tokenId失败[${responseCode}]: ${errorMessage}`);
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
|
||
async ttlxj_login(loginUrl, options = {}) {
|
||
try {
|
||
const fullUrl = `${loginUrl}https://epay.10010.com/ci-mcss-party-web/clockIn/?bizFrom=${errorCode}&bizChannelCode=${errorNumber}`;
|
||
|
||
const requestConfig = {
|
||
fn: "ttlxj_login",
|
||
method: "get",
|
||
url: fullUrl
|
||
};
|
||
|
||
const { headers, statusCode } = await this.request(requestConfig);
|
||
|
||
if (headers?.["location"]) {
|
||
const locationUrl = new URL(headers.location);
|
||
this.rptId = locationUrl.searchParams.get("rptid");
|
||
if (this.rptId) {
|
||
await this.ttlxj_authCheck();
|
||
} else {
|
||
this.log("天天领现金获取rptid失败");
|
||
}
|
||
} else {
|
||
this.log(`天天领现金获取rptid失败[${statusCode}]`);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
|
||
async ttlxj_userDrawInfo(options = {}) {
|
||
try {
|
||
const requestConfig = {
|
||
fn: "ttlxj_userDrawInfo",
|
||
method: "post",
|
||
url: "https://epay.10010.com/ci-mcss-party-front/v1/ttlxj/userDrawInfo",
|
||
headers: {
|
||
bizchannelinfo: this.get_bizchannelinfo(),
|
||
authinfo: this.get_epay_authinfo()
|
||
}
|
||
};
|
||
|
||
const { result } = await this.request(requestConfig);
|
||
const responseCode = appName.get(result, "code", -1);
|
||
|
||
if (responseCode === "0000") {
|
||
const dayOfWeek = result?.["data"]?.["dayOfWeek"];
|
||
const drawKey = `day${dayOfWeek}`;
|
||
const hasNotClockedIn = result?.["data"]?.[drawKey] === "1";
|
||
|
||
const logOptions = {
|
||
notify: true
|
||
};
|
||
|
||
this.log(`天天领现金: 今天${hasNotClockedIn ? "未" : "已"}打卡`, logOptions);
|
||
|
||
if (hasNotClockedIn) {
|
||
const today = new Date().getDay();
|
||
const drawType = (today % 7 === 0) ? "C" : "B";
|
||
await this.ttlxj_unifyDrawNew(drawType);
|
||
}
|
||
} else {
|
||
const errorMessage = result?.["msg"] || "";
|
||
this.log(`天天领现金: 查询失败[${responseCode}]: ${errorMessage}`);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
|
||
async ttlxj_unifyDrawNew(drawType, options = {}) {
|
||
try {
|
||
const requestData = {
|
||
drawType: drawType,
|
||
bizFrom: errorCode,
|
||
activityId: "TTLXJ20210330"
|
||
};
|
||
|
||
const requestConfig = {
|
||
fn: "ttlxj_unifyDrawNew",
|
||
method: "post",
|
||
url: "https://epay.10010.com/ci-mcss-party-front/v1/ttlxj/unifyDrawNew",
|
||
headers: {
|
||
bizchannelinfo: this.get_bizchannelinfo(),
|
||
authinfo: this.get_epay_authinfo()
|
||
},
|
||
form: requestData
|
||
};
|
||
|
||
const { result } = await this.request(requestConfig);
|
||
const responseCode = appName.get(result, "code", -1);
|
||
|
||
if (responseCode === "0000" && result?.["data"]?.["returnCode"] === 0) {
|
||
const awardMessage = result?.["data"]?.["awardTipContent"]?.replace(/xx/, result?.["data"]?.["amount"]);
|
||
const logOptions = {
|
||
notify: true
|
||
};
|
||
this.log("天天领现金: 打卡 " + awardMessage, logOptions);
|
||
} else {
|
||
const errorMessage = result?.["data"]?.["returnMsg"] || result?.["msg"] || "";
|
||
this.log(`天天领现金: 打卡失败[${result?.["data"]?.["returnCode"] || responseCode}]: ${errorMessage}`);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
|
||
async ttlxj_help(options = {}) {
|
||
try {
|
||
const requestBody = {
|
||
bizFrom: errorCode,
|
||
activityId: activityIds.ttlxj,
|
||
uid: apiKey
|
||
};
|
||
let requestConfig = {
|
||
fn: "ttlxj_h",
|
||
method: "post",
|
||
url: "https://epay.10010.com/ci-mcss-party-front/v1/ttlxj/help",
|
||
headers: {
|
||
bizchannelinfo: this.get_bizchannelinfo(),
|
||
authinfo: this.get_epay_authinfo()
|
||
},
|
||
form: requestBody
|
||
};
|
||
await this.request(requestConfig);
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async ttlxj_queryAvailable(options = {}) {
|
||
try {
|
||
let requestConfig = {
|
||
fn: "ttlxj_queryAvailable",
|
||
method: "post",
|
||
url: "https://epay.10010.com/ci-mcss-party-front/v1/ttlxj/queryAvailable",
|
||
headers: {
|
||
bizchannelinfo: this.get_bizchannelinfo(),
|
||
authinfo: this.get_epay_authinfo()
|
||
}
|
||
};
|
||
let {
|
||
result: responseResult
|
||
} = await this.request(requestConfig);
|
||
let responseCode = appName.get(responseResult, "code", -1);
|
||
if (responseCode == "0000" && responseResult?.["data"]?.["returnCode"] == 0) {
|
||
let availableAmount = responseResult?.["data"]?.["availableAmount"] || 0;
|
||
let logMessage = `天天领现金: 可用立减金: ${(availableAmount / 100).toFixed(2)}元`;
|
||
let expiringPrizes = [];
|
||
let currentTime = Date.now();
|
||
for (let prize of responseResult?.["data"]?.["prizeList"]?.filter(p => p.status == "A")) {
|
||
let endTimeStr = prize.endTime;
|
||
let endTimeDate = new Date(endTimeStr.slice(0, 4) + "-" + endTimeStr.slice(4, 6) + "-" + endTimeStr.slice(6, 8) + " 00:00:00");
|
||
let endTimeMs = endTimeDate.getTime();
|
||
if (endTimeMs - currentTime < expiration_time * 24 * 60 * 60 * 1000) {
|
||
let formattedDate = appName.time("yyyy-MM-dd", endTimeMs);
|
||
const expiringPrize = {
|
||
timestamp: endTimeMs,
|
||
date: formattedDate,
|
||
amount: prize.amount
|
||
};
|
||
expiringPrizes.push(expiringPrize);
|
||
}
|
||
}
|
||
if (expiringPrizes.length) {
|
||
const defaultPrize = {
|
||
timestamp: 0,
|
||
amount: 0
|
||
};
|
||
let earliestExpiringPrize = defaultPrize;
|
||
let totalExpiringAmount = expiringPrizes.reduce(function (total, currentPrize) {
|
||
if (earliestExpiringPrize.timestamp == 0 || currentPrize.timestamp < earliestExpiringPrize.timestamp) {
|
||
earliestExpiringPrize = currentPrize;
|
||
}
|
||
return total + parseFloat(currentPrize.amount);
|
||
}, 0);
|
||
logMessage += `, ${expiration_time}天内过期立减金: ${totalExpiringAmount.toFixed(2)}元`;
|
||
logMessage += `, 最早过期立减金: ${earliestExpiringPrize.amount}元 -- ${earliestExpiringPrize.date}过期`;
|
||
} else {
|
||
logMessage += `, ${expiration_time}天内没有过期的立减金`;
|
||
}
|
||
this.log(logMessage, { notify: true });
|
||
} else {
|
||
let errorMessage = responseResult?.["data"]?.["returnMsg"] || responseResult?.["msg"] || "";
|
||
this.log("天天领现金: 查询可用立减金失败[" + (responseResult?.["data"]?.["returnCode"] || responseCode) + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
|
||
async epay_28_authCheck(options = {}) {
|
||
try {
|
||
let requestConfig = {
|
||
fn: "epay_28_authCheck",
|
||
method: "post",
|
||
url: "https://epay.10010.com/ps-pafs-auth-front/v1/auth/check",
|
||
headers: {
|
||
bizchannelinfo: this.get_bizchannelinfo()
|
||
}
|
||
};
|
||
let {
|
||
result: responseResult
|
||
} = await this.request(requestConfig);
|
||
let responseCode = appName.get(responseResult, "code", -1);
|
||
if (responseCode == "0000") {
|
||
let {
|
||
mobile: mobile,
|
||
sessionId: sessionId,
|
||
tokenId: tokenId,
|
||
userId: userId
|
||
} = responseResult?.["data"]?.["authInfo"];
|
||
const authInfo = {
|
||
sessionId: sessionId,
|
||
tokenId: tokenId,
|
||
userId: userId
|
||
};
|
||
Object.assign(this, authInfo);
|
||
await this.epay_28_queryUserPage();
|
||
} else {
|
||
if (responseCode == "2101000100") {
|
||
let loginUrl = responseResult?.["data"]?.["woauth_login_url"];
|
||
await this.epay_28_login(loginUrl);
|
||
} else {
|
||
let errorMessage = responseResult?.["msgInside"] || responseResult?.["msg"] || "";
|
||
this.log("联通支付日获取tokenId失败[" + responseCode + "]: " + errorMessage);
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async epay_28_login(loginUrl, options = {}) {
|
||
try {
|
||
let templateName = appName.time("yyyyMM") + "28ZFR";
|
||
loginUrl += "https://epay.10010.com/ci-mcss-party-web/rainbow/?templateName=" + templateName + "&bizFrom=225&bizChannelCode=225&channelType=WDQB";
|
||
const requestConfig = {
|
||
fn: "epay_28_login",
|
||
method: "get",
|
||
url: loginUrl
|
||
};
|
||
let {
|
||
headers: headers,
|
||
statusCode: statusCode
|
||
} = await this.request(requestConfig);
|
||
if (headers?.["location"]) {
|
||
let locationUrl = new URL(headers.location);
|
||
this.rptId = locationUrl.searchParams.get("rptid");
|
||
this.rptId ? await this.epay_28_authCheck() : this.log("联通支付日获取rptid失败");
|
||
} else {
|
||
this.log("联通支付日获取rptid失败[" + statusCode + "]");
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async epay_28_queryUserPage(options = {}) {
|
||
try {
|
||
let templateName = appName.time("yyyyMM") + "28ZFR";
|
||
const requestBody = {
|
||
templateName: templateName
|
||
};
|
||
let requestConfig = {
|
||
fn: "epay_28_queryUserPage",
|
||
method: "post",
|
||
url: "https://epay.10010.com/ci-mcss-party-front/v1/rainbow/queryUserPage",
|
||
headers: {
|
||
bizchannelinfo: this.get_bizchannelinfo(),
|
||
authinfo: this.get_epay_authinfo()
|
||
},
|
||
form: requestBody
|
||
};
|
||
let {
|
||
result: responseResult
|
||
} = await this.request(requestConfig);
|
||
let responseCode = appName.get(responseResult, "code", -1);
|
||
if (responseCode == "0000" && responseResult?.["data"]?.["returnCode"] == 0) {
|
||
for (let prizeInfo of responseResult?.["data"]?.["prizeList"]?.["rainbowMouldInfos"] || []) {
|
||
prizeInfo?.["rainbowUnitInfos"]?.[0]?.["unitActivityId"] && (await this.epay_28_unifyDraw(prizeInfo.rainbowUnitInfos[0]));
|
||
if (prizeInfo?.["day01DrawParam"]) {
|
||
await this.epay_28_queryMiddleUnit(templateName, prizeInfo.mouldName);
|
||
break;
|
||
}
|
||
}
|
||
} else {
|
||
let errorMessage = responseResult?.["message"] || responseResult?.["msg"] || "";
|
||
this.log("联通支付日进入主页失败[" + responseCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async epay_28_queryMiddleUnit(activityId, mouldName, options = {}) {
|
||
try {
|
||
const requestBody = {
|
||
activityId: activityId,
|
||
mouldName: mouldName
|
||
};
|
||
let requestConfig = {
|
||
fn: "epay_28_queryMiddleUnit",
|
||
method: "post",
|
||
url: "https://epay.10010.com/ci-mcss-party-front/v1/rainbow/queryMiddleUnit",
|
||
headers: {
|
||
bizchannelinfo: this.get_bizchannelinfo(),
|
||
authinfo: this.get_epay_authinfo()
|
||
},
|
||
form: requestBody
|
||
};
|
||
let {
|
||
result: responseResult
|
||
} = await this.request(requestConfig);
|
||
let responseCode = appName.get(responseResult, "code", -1);
|
||
if (responseCode == "0000") {
|
||
let currentDay = appName.time("dd");
|
||
responseResult?.["data"]?.[currentDay] == "1" ? this.log("联通支付日今日(" + currentDay + "号)已打卡") : await this.epay_28_unifyDrawNew(activityId, mouldName);
|
||
} else {
|
||
let errorMessage = responseResult?.["message"] || responseResult?.["msg"] || "";
|
||
this.log("联通支付日查询打卡失败[" + responseCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async epay_28_unifyDrawNew(activityId, mouldName, options = {}) {
|
||
try {
|
||
const requestBody = {
|
||
bizFrom: errorCode,
|
||
activityId: activityId,
|
||
mouldName: mouldName
|
||
};
|
||
let requestConfig = {
|
||
fn: "epay_28_unifyDrawNew",
|
||
method: "post",
|
||
url: "https://epay.10010.com/ci-mcss-party-front/v1/rainbow/unifyDrawNew",
|
||
headers: {
|
||
bizchannelinfo: this.get_bizchannelinfo(),
|
||
authinfo: this.get_epay_authinfo()
|
||
},
|
||
form: requestBody
|
||
};
|
||
let {
|
||
result: responseResult
|
||
} = await this.request(requestConfig);
|
||
let responseCode = appName.get(responseResult, "code", -1);
|
||
if (responseCode == "0000" && responseResult?.["data"]?.["returnCode"] == 0) {
|
||
let awardMessage = responseResult?.["data"]?.["awardTipContent"]?.replace(/xx/, responseResult?.["data"]?.["amount"]);
|
||
const notifyOptions = {
|
||
notify: true
|
||
};
|
||
this.log("联通支付日打卡:" + awardMessage, notifyOptions);
|
||
} else {
|
||
let errorMessage = responseResult?.["data"]?.["returnMsg"] || responseResult?.["msg"] || "";
|
||
this.log("联通支付日打卡失败[" + (responseResult?.["data"]?.["returnCode"] || responseCode) + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async epay_28_unifyDraw(unitInfo, options = {}) {
|
||
try {
|
||
const requestBody = {
|
||
activityId: unitInfo.unitActivityId,
|
||
isBigActivity: unitInfo.isBigActivity,
|
||
bigActivityId: unitInfo.bigActivityId,
|
||
bizFrom: errorCode
|
||
};
|
||
let requestConfig = {
|
||
fn: "epay_28_unifyDraw",
|
||
method: "post",
|
||
url: "https://epay.10010.com/ci-mcss-party-front/v1/rainbow/unifyDraw",
|
||
headers: {
|
||
bizchannelinfo: this.get_bizchannelinfo(),
|
||
authinfo: this.get_epay_authinfo()
|
||
},
|
||
form: requestBody
|
||
};
|
||
let {
|
||
result: responseResult
|
||
} = await this.request(requestConfig);
|
||
let responseCode = appName.get(responseResult, "code", -1);
|
||
if (responseCode == "0000" && responseResult?.["data"]?.["returnCode"] == 0) {
|
||
const notifyOptions = {
|
||
notify: true
|
||
};
|
||
this.log("联通支付日抽奖: " + (responseResult?.["data"]?.["prizeName"] || ""), notifyOptions);
|
||
} else {
|
||
let errorMessage = responseResult?.["data"]?.["returnMsg"] || responseResult?.["msg"] || "";
|
||
this.log("联通支付日抽奖失败[" + (responseResult?.["data"]?.["returnCode"] || responseCode) + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async appMonth_28_bind(shareCode, options = {}) {
|
||
try {
|
||
const requestBody = {
|
||
shareCode: shareCode,
|
||
cl: "WeChat"
|
||
};
|
||
const requestConfig = {
|
||
fn: "appMonth_28_bind",
|
||
method: "post",
|
||
url: "https://activity.10010.com/AppMonthly/appMonth/bind",
|
||
form: requestBody,
|
||
valid_code: [401]
|
||
};
|
||
let {
|
||
result: responseResult
|
||
} = await this.request(requestConfig);
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async appMonth_28_queryChance(params = {}) {
|
||
try {
|
||
const requestConfig = {
|
||
fn: "appMonth_28_queryChance",
|
||
method: "post",
|
||
url: "https://activity.10010.com/AppMonthly/appMonth/queryChance"
|
||
};
|
||
|
||
let {
|
||
result: response
|
||
} = await this.request(requestConfig),
|
||
status = appName.get(response, "status", -1);
|
||
|
||
if (status == "0000") {
|
||
let {
|
||
allRemainTimes: remainingTimes,
|
||
isUnicom: isUnicomUser
|
||
} = response?.["data"];
|
||
|
||
if (isUnicomUser) {
|
||
let drawTimes = Math.min(appMonth_28_MaxTimes, remainingTimes);
|
||
this.log("联通支付日可以开宝箱" + remainingTimes + "次, 去抽" + drawTimes + "次");
|
||
|
||
while (drawTimes-- > 0) {
|
||
await this.appMonth_28_lottery();
|
||
}
|
||
}
|
||
} else {
|
||
let errorMsg = response?.["msg"] || "";
|
||
this.log("联通支付日查询开宝箱次数失败[" + status + "]: " + errorMsg);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
|
||
async appMonth_28_lottery(options = {}) {
|
||
try {
|
||
const requestConfig = {
|
||
fn: "appMonth_28_lottery",
|
||
method: "post",
|
||
url: "https://activity.10010.com/AppMonthly/appMonth/lottery"
|
||
};
|
||
let {
|
||
result: responseResult
|
||
} = await this.request(requestConfig),
|
||
status = appName.get(responseResult, "status", -1);
|
||
if (status == "0000") {
|
||
let {
|
||
code: resultCode,
|
||
uuid: uuid
|
||
} = responseResult?.["data"];
|
||
uuid ? await this.appMonth_28_winningRecord(uuid) : this.log("联通支付日开宝箱失败[" + resultCode + "]");
|
||
} else {
|
||
let errorMessage = responseResult?.["msg"] || "";
|
||
this.log("联通支付日开宝箱失败[" + status + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async appMonth_28_winningRecord(requestId, options = {}) {
|
||
try {
|
||
const requestBody = {
|
||
requestId: requestId
|
||
};
|
||
const requestConfig = {
|
||
fn: "appMonth_28_winningRecord",
|
||
method: "post",
|
||
url: "https://activity.10010.com/AppMonthly/appMonth/winningRecord",
|
||
form: requestBody
|
||
};
|
||
let {
|
||
result: responseResult
|
||
} = await this.request(requestConfig),
|
||
status = appName.get(responseResult, "status", -1);
|
||
if (status == "0000") {
|
||
let {
|
||
code: resultCode,
|
||
prizeName: prizeName
|
||
} = responseResult?.["data"];
|
||
if (resultCode == "0000") {
|
||
const notifyOptions = {
|
||
notify: true
|
||
};
|
||
this.log("联通支付日开宝箱: " + prizeName, notifyOptions);
|
||
} else {
|
||
let errorMessage = responseResult?.["data"]?.["message"] || "";
|
||
this.log("联通支付日开宝箱[" + resultCode + "]: " + errorMessage);
|
||
}
|
||
} else {
|
||
let errorMessage = responseResult?.["msg"] || "";
|
||
this.log("联通支付日查询中奖奖品错误[" + status + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
// 签到区相关方法
|
||
async sign_getContinuous(imei, options = {}) {
|
||
try {
|
||
const requestConfig = {
|
||
fn: "sign_getContinuous",
|
||
method: "get",
|
||
url: "https://activity.10010.com/sixPalaceGridTurntableLottery/signin/getContinuous",
|
||
params: {
|
||
taskId: "",
|
||
channel: "wode",
|
||
imei: imei
|
||
}
|
||
};
|
||
let { result: responseResult } = await this.request(requestConfig),
|
||
responseCode = appName.get(responseResult, "code", -1);
|
||
|
||
if (responseCode == "0000") {
|
||
let todayIsSignIn = responseResult?.["data"]?.["todayIsSignIn"] || 'n';
|
||
this.log("签到区今天" + (todayIsSignIn == "n" ? "未" : "已") + "签到", { notify: true });
|
||
if (todayIsSignIn == "n") {
|
||
await appName.wait(1000);
|
||
await this.sign_daySign();
|
||
}
|
||
} else {
|
||
this.log("签到区查询签到状态失败[" + responseCode + "]: " + (responseResult?.["desc"] || ""));
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
|
||
async sign_daySign(options = {}) {
|
||
try {
|
||
const requestConfig = {
|
||
fn: "sign_daySign",
|
||
method: "post",
|
||
url: "https://activity.10010.com/sixPalaceGridTurntableLottery/signin/daySign",
|
||
form: {}
|
||
};
|
||
let { result: responseResult } = await this.request(requestConfig),
|
||
responseCode = appName.get(responseResult, "code", -1);
|
||
|
||
if (responseCode == "0000") {
|
||
let { statusDesc: statusDesc, redSignMessage: redSignMessage } = responseResult?.["data"];
|
||
let logMessage = "签到区签到成功: ";
|
||
if (statusDesc) logMessage += `[${statusDesc}]`;
|
||
if (redSignMessage) logMessage += `${redSignMessage}`;
|
||
this.log(logMessage);
|
||
} else if (responseCode == "0002" && responseResult?.["desc"] && responseResult["desc"].includes('已经签到')) { // 今日已签到
|
||
this.log("签到区签到成功: 今日已完成签到!");
|
||
} else {
|
||
this.log("签到区签到失败[" + responseCode + "]: " + (responseResult?.["desc"] || ""));
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
|
||
async sign_getTaskReward(taskId, options = {}) {
|
||
try {
|
||
const requestConfig = {
|
||
fn: "sign_getTaskReward",
|
||
method: "get",
|
||
url: "https://activity.10010.com/sixPalaceGridTurntableLottery/task/getTaskReward",
|
||
searchParams: {
|
||
taskId: taskId
|
||
}
|
||
};
|
||
let { result: responseResult } = await this.request(requestConfig);
|
||
let responseCode = appName.get(responseResult, "code", -1);
|
||
|
||
if (responseCode == "0000") {
|
||
let data = responseResult?.["data"];
|
||
if (data?.code == '0000') {
|
||
let prizeName = data?.prizeName || '';
|
||
let prizeNameRed = data?.prizeNameRed || '';
|
||
this.log(`签到区-领取奖励: [${prizeName}] ${prizeNameRed}`);
|
||
} else {
|
||
this.log("签到区-领取奖励失败[" + data?.code + "]: " + (responseResult?.["desc"] || data?.desc || ""));
|
||
}
|
||
} else {
|
||
this.log("签到区-领取奖励失败[" + responseCode + "]: " + (responseResult?.["desc"] || ""));
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
|
||
async sign_getTelephone(options = {}) {
|
||
try {
|
||
const requestConfig = {
|
||
fn: "sign_getTelephone",
|
||
method: "post",
|
||
url: "https://act.10010.com/SigninApp/convert/getTelephone",
|
||
form: {}
|
||
};
|
||
let { result: responseResult } = await this.request(requestConfig);
|
||
let status = appName.get(responseResult, "status", -1);
|
||
|
||
if (status == "0000" && responseResult.data) {
|
||
const currentAmount = parseFloat(responseResult.data.telephone) || 0;
|
||
|
||
if (options.isInitial) {
|
||
this.initialTelephoneAmount = currentAmount;
|
||
this.log(`签到区-话费红包: 运行前总额 ${this.initialTelephoneAmount.toFixed(2)}元`);
|
||
return;
|
||
}
|
||
|
||
if (this.initialTelephoneAmount !== null) {
|
||
const increase = currentAmount - this.initialTelephoneAmount;
|
||
this.log(`签到区-话费红包: 本次运行增加 ${increase.toFixed(2)}元`, { notify: true });
|
||
}
|
||
|
||
let totalMessage = `签到区-话费红包: 总额 ${currentAmount.toFixed(2)}元`;
|
||
if (parseFloat(responseResult.data.needexpNumber) > 0) {
|
||
totalMessage += `,其中 ${responseResult.data.needexpNumber}元 将于 ${responseResult.data.month}月底到期`;
|
||
}
|
||
this.log(totalMessage, { notify: true });
|
||
|
||
} else {
|
||
this.log(`签到区查询话费红包失败[${status}]: ${responseResult?.msg || ""}`);
|
||
}
|
||
} catch (error) {
|
||
this.log(`签到区查询话费红包异常: ${error.message}`);
|
||
}
|
||
}
|
||
|
||
async sign_getTaskList(options = {}) {
|
||
try {
|
||
const requestConfig = {
|
||
fn: "sign_getTaskList",
|
||
method: "get",
|
||
url: "https://activity.10010.com/sixPalaceGridTurntableLottery/task/taskList",
|
||
searchParams: { type: 2 },
|
||
headers: { "Referer": "https://img.client.10010.com/" }
|
||
};
|
||
|
||
// Use a loop to handle tasks dynamically, similar to how bubble tasks are handled.
|
||
// This allows us to claim rewards for tasks we've just completed in the same run.
|
||
for (let i = 0; i < 30; i++) { // Loop with a max limit to prevent infinite loops.
|
||
let { result: responseResult } = await this.request(requestConfig);
|
||
let responseCode = appName.get(responseResult, "code", -1);
|
||
|
||
if (responseCode != "0000") {
|
||
this.log("签到区-任务中心: 获取任务列表失败[" + responseCode + "]: " + (responseResult?.desc || ""));
|
||
return;
|
||
}
|
||
|
||
if (i === 0) {
|
||
this.log("签到区-任务中心: 获取任务列表成功");
|
||
}
|
||
|
||
const allTasks = [
|
||
...(responseResult.data.tagList || []).flatMap(tag => tag.taskDTOList || []),
|
||
...(responseResult.data.taskList || [])
|
||
].filter(Boolean);
|
||
|
||
if (allTasks.length === 0) {
|
||
if (i === 0) this.log("签到区-任务中心: 当前无任何任务。");
|
||
break; // Exit loop if no tasks
|
||
}
|
||
|
||
// Priority 1: Execute actionable tasks (taskState: 1 and taskType: 5).
|
||
const doTask = allTasks.find(task => task.taskState === "1" && task.taskType === "5");
|
||
if (doTask) {
|
||
this.log(`签到区-任务中心: 开始执行任务 [${doTask.taskName}]`);
|
||
await this.sign_doTaskFromList(doTask);
|
||
await appName.wait(3000);
|
||
continue; // Re-fetch task list, as the completed task might now be claimable.
|
||
}
|
||
|
||
// Priority 2: Claim rewards for completed tasks (taskState: 0).
|
||
const claimTask = allTasks.find(task => task.taskState === "0");
|
||
if (claimTask) {
|
||
this.log(`签到区-任务中心: 发现可领取奖励的任务 [${claimTask.taskName}]`);
|
||
await this.sign_getTaskReward(claimTask.id);
|
||
await appName.wait(2000);
|
||
continue; // Re-fetch task list to get the next state.
|
||
}
|
||
|
||
// If we are here, no claimable or actionable tasks were found in this iteration.
|
||
if (i === 0) {
|
||
this.log("签到区-任务中心: 没有可执行或可领取的任务。");
|
||
} else {
|
||
this.log("签到区-任务中心: 所有任务处理完毕。");
|
||
}
|
||
break; // Exit the loop
|
||
}
|
||
|
||
} catch (error) {
|
||
console.log(error);
|
||
this.log("签到区-任务中心: 获取任务列表时发生异常: " + error.message);
|
||
}
|
||
}
|
||
|
||
async sign_doTaskFromList(task, options = {}) {
|
||
try {
|
||
// this.log(`签到区-任务中心: 开始执行任务 [${task.taskName}]`);
|
||
|
||
if (task.url && task.url !== "1" && task.url.startsWith("http")) {
|
||
await this.request({
|
||
fn: "sign_doTaskFromList_visit",
|
||
method: "get",
|
||
url: task.url,
|
||
headers: {
|
||
"Referer": "https://img.client.10010.com/"
|
||
}
|
||
});
|
||
this.log(`签到区-任务中心: 浏览页面 [${task.taskName}]`);
|
||
await appName.wait(5000 + Math.random() * 2000);
|
||
}
|
||
|
||
const orderId = await this.gettaskip();
|
||
|
||
const requestConfig = {
|
||
fn: "sign_doTaskFromList_complete",
|
||
method: "get",
|
||
url: "https://activity.10010.com/sixPalaceGridTurntableLottery/task/completeTask",
|
||
searchParams: {
|
||
taskId: task.id,
|
||
orderId: orderId,
|
||
systemCode: "QDQD"
|
||
}
|
||
};
|
||
|
||
let { result: responseResult } = await this.request(requestConfig);
|
||
let responseCode = appName.get(responseResult, "code", -1);
|
||
|
||
if (responseCode == "0000") {
|
||
this.log(`签到区-任务中心: ✅ 任务 [${task.taskName}] 已完成`);
|
||
} else {
|
||
this.log(`签到区-任务中心: ❌ 任务 [${task.taskName}] 完成失败[${responseCode}]: ${responseResult.desc || '未知错误'}`);
|
||
}
|
||
|
||
} catch (error) {
|
||
console.log(error);
|
||
this.log(`签到区-任务中心: 执行任务 [${task.taskName}] 时发生异常: ${error.message}`);
|
||
}
|
||
}
|
||
async game_login(ticket, options = {}) {
|
||
try {
|
||
const requestBody = {
|
||
identityType: "esToken",
|
||
code: this.ecs_token,
|
||
ticket: ticket,
|
||
uuid: this.uuid
|
||
};
|
||
const requestOptions = {
|
||
fn: "game_login",
|
||
method: "post",
|
||
url: "https://game.wostore.cn/api/app//user/v2/login",
|
||
headers: {},
|
||
json: requestBody
|
||
};
|
||
requestOptions.headers.channelid = "GAMELTAPP_90005";
|
||
let {
|
||
result: responseResult
|
||
} = await this.request(requestOptions);
|
||
let responseCode = appName.get(responseResult, "code", -1);
|
||
if (responseCode == 200) {
|
||
this.game_token = responseResult?.["data"]?.["access_token"];
|
||
this.got = this.got.extend({
|
||
headers: {
|
||
Authorization: this.game_token
|
||
}
|
||
});
|
||
await this.game_getMemberInfo();
|
||
await this.game_signRecord();
|
||
await this.game_lottery();
|
||
await this.game_playSave();
|
||
await this.game_taskList();
|
||
await this.game_getMemberInfo();
|
||
const notifyOptions = {
|
||
notify: true
|
||
};
|
||
this.log("联通畅游币: " + this.point, notifyOptions);
|
||
} else {
|
||
let errorMessage = responseResult?.["msg"] || "";
|
||
this.log("联通畅游登录失败[" + responseCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async game_getMemberInfo(options = {}) {
|
||
try {
|
||
const requestOptions = {
|
||
fn: "game_getMemberInfo",
|
||
method: "get",
|
||
url: "https://game.wostore.cn/api/app/user/v2/getMemberInfo"
|
||
};
|
||
let {
|
||
result: responseResult
|
||
} = await this.request(requestOptions);
|
||
let responseCode = appName.get(responseResult, "code", -1);
|
||
if (responseCode == 200) {
|
||
this.point = responseResult?.["data"]?.["userIntegral"];
|
||
} else {
|
||
let errorMessage = responseResult?.["msg"] || "";
|
||
this.log("联通畅游查询积分失败[" + responseCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async game_signRecord(options = {}) {
|
||
try {
|
||
const requestOptions = {
|
||
fn: "game_signRecord",
|
||
method: "get",
|
||
url: "https://game.wostore.cn/api/app/user/v2/signRecord"
|
||
};
|
||
let {
|
||
result: responseResult
|
||
} = await this.request(requestOptions);
|
||
let responseCode = appName.get(responseResult, "code", -1);
|
||
if (responseCode == 200) {
|
||
for (let record of responseResult?.["data"]) {
|
||
if (record.now == 0) {
|
||
continue;
|
||
}
|
||
this.log("联通畅游今天" + (record.signStatus == 2 ? "未" : "已") + "签到");
|
||
if (record.signStatus == 2) {
|
||
await this.game_signIn();
|
||
}
|
||
}
|
||
} else {
|
||
let errorMessage = responseResult?.["msg"] || "";
|
||
this.log("联通畅游查询签到失败[" + responseCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async game_signIn(options = {}) {
|
||
try {
|
||
const requestOptions = {
|
||
fn: "game_signIn",
|
||
method: "get",
|
||
url: "https://game.wostore.cn/api/app/user/v2/signIn"
|
||
};
|
||
let {
|
||
result: responseResult
|
||
} = await this.request(requestOptions);
|
||
let responseCode = appName.get(responseResult, "code", -1);
|
||
if (responseCode == 200) {
|
||
this.log("联通畅游签到成功");
|
||
} else {
|
||
let errorMessage = responseResult?.["msg"] || "";
|
||
this.log("联通畅游签到失败[" + responseCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async game_checkSlider(options = {}) {
|
||
let isSuccess = false;
|
||
try {
|
||
const searchParams = {
|
||
xPos: 234
|
||
};
|
||
const requestOptions = {
|
||
fn: "game_checkSlider",
|
||
method: "post",
|
||
url: "https://game.wostore.cn/api/app/common/slider/checkSlider",
|
||
searchParams: searchParams
|
||
};
|
||
let {
|
||
result: responseResult
|
||
} = await this.request(requestOptions);
|
||
let responseCode = appName.get(responseResult, "code", -1);
|
||
if (responseCode == 200) {
|
||
this.log("联通畅游滑块验证成功");
|
||
} else {
|
||
let errorMessage = responseResult?.["msg"] || "";
|
||
this.log("联通畅游滑块验证失败[" + responseCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
} finally {
|
||
return isSuccess;
|
||
}
|
||
}
|
||
async game_lottery(options = {}) {
|
||
try {
|
||
let requestOptions = {
|
||
fn: "game_lottery",
|
||
method: "get",
|
||
url: "https://game.wostore.cn/api/app/user/v2/benefit/lottery",
|
||
searchParams: {
|
||
id: appName.get(options, "id", 1)
|
||
}
|
||
};
|
||
let {
|
||
result: responseResult
|
||
} = await this.request(requestOptions);
|
||
let responseCode = appName.get(responseResult, "code", -1);
|
||
if (responseCode == 200) {
|
||
const notifyOptions = {
|
||
notify: true
|
||
};
|
||
this.log("联通畅游抽奖: " + responseResult?.["data"]?.["productName"], notifyOptions);
|
||
} else {
|
||
let errorMessage = responseResult?.["msg"] || "";
|
||
this.log("联通畅游抽奖失败[" + responseCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async game_taskList(options = {}) {
|
||
try {
|
||
const requestOptions = {
|
||
fn: "game_taskList",
|
||
method: "get",
|
||
url: "https://game.wostore.cn/api/app/user/v2/task/list"
|
||
};
|
||
let {
|
||
result: responseResult
|
||
} = await this.request(requestOptions);
|
||
let responseCode = appName.get(responseResult, "code", -1);
|
||
if (responseCode == 200) {
|
||
for (let task of responseResult?.["data"]) {
|
||
switch (task.receiveStatus) {
|
||
case 0:
|
||
break;
|
||
case 1:
|
||
await this.game_taskReceive(task);
|
||
break;
|
||
case 2:
|
||
break;
|
||
default:
|
||
appName.log("任务[" + task.taskName + "]未知状态[" + task.receiveStatus + "]");
|
||
break;
|
||
}
|
||
}
|
||
} else {
|
||
let errorMessage = responseResult?.["msg"] || "";
|
||
this.log("联通畅游查询任务失败[" + responseCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async game_taskReceive(task, options = {}) {
|
||
try {
|
||
const searchParams = {
|
||
productId: task.productId,
|
||
taskId: task.id
|
||
};
|
||
const requestOptions = {
|
||
fn: "game_taskReceive",
|
||
method: "get",
|
||
url: "https://game.wostore.cn/api/app/user/v2/task/receive",
|
||
searchParams: searchParams
|
||
};
|
||
let {
|
||
result: responseResult
|
||
} = await this.request(requestOptions);
|
||
let responseCode = appName.get(responseResult, "code", -1);
|
||
if (responseCode == 200) {
|
||
this.log("领取任务[" + task.taskName + "]奖励成功");
|
||
} else {
|
||
let errorMessage = responseResult?.["msg"] || "";
|
||
this.log("领取任务[" + task.taskName + "]奖励失败[" + responseCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async game_playSave(options = {}) {
|
||
try {
|
||
let requestOptions = {
|
||
fn: "game_playSave",
|
||
method: "post",
|
||
url: "https://game.wostore.cn/api/app/user/v2/play/save",
|
||
json: {
|
||
cpGameId: "15000199" + appName.randomString(2, "0123456789")
|
||
}
|
||
};
|
||
let {
|
||
result: responseResult
|
||
} = await this.request(requestOptions);
|
||
let responseCode = appName.get(responseResult, "code", -1);
|
||
if (!(responseCode == 200)) {
|
||
let errorMessage = responseResult?.["msg"] || "";
|
||
this.log("联通畅游玩游戏失败[" + responseCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
|
||
async flmf_login(loginUrl, options = {}) {
|
||
try {
|
||
const requestConfig = {
|
||
fn: "flmf_login",
|
||
method: "get",
|
||
url: loginUrl
|
||
};
|
||
let {
|
||
headers: headers,
|
||
statusCode: statusCode
|
||
} = await this.request(requestConfig);
|
||
if (headers?.["location"]) {
|
||
let locationUrl = new URL(headers.location);
|
||
this.flmf_sid = locationUrl.searchParams.get("sid");
|
||
this.flmf_sid ? (await this.flmf_signInInit(), await this.flmf_taskList(), await this.flmf_scanTask()) : this.log("福利魔方获取sid失败");
|
||
} else {
|
||
this.log("福利魔方获取sid失败[" + statusCode + "]");
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async flmf_signInInit(options = {}) {
|
||
try {
|
||
let requestConfig = {
|
||
fn: "flmf_signInInit",
|
||
method: "post",
|
||
url: "https://weixin.linktech.hk/lv-apiaccess/welfareCenter/signInInit",
|
||
form: this.get_flmf_data()
|
||
};
|
||
let {
|
||
result: responseResult
|
||
} = await this.request(requestConfig);
|
||
let resultCode = appName.get(responseResult, "resultCode", -1);
|
||
if (resultCode == "0000") {
|
||
this.log("福利魔方今天" + (responseResult?.["data"]?.["isSigned"] ? "已" : "未") + "签到, 已连续签到" + responseResult?.["data"]?.["consecutiveDays"] + "天");
|
||
if (!responseResult?.["data"]?.["isSigned"]) {
|
||
await this.flmf_signIn();
|
||
}
|
||
} else {
|
||
let errorMessage = responseResult?.["resultMsg"] || "";
|
||
this.log("福利魔方查询签到失败[" + resultCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async flmf_signIn(options = {}) {
|
||
try {
|
||
let requestConfig = {
|
||
fn: "flmf_signIn",
|
||
method: "post",
|
||
url: "https://weixin.linktech.hk/lv-apiaccess/welfareCenter/signIn",
|
||
form: this.get_flmf_data()
|
||
};
|
||
let {
|
||
result: responseResult
|
||
} = await this.request(requestConfig);
|
||
let resultCode = appName.get(responseResult, "resultCode", -1);
|
||
if (resultCode == "0000") {
|
||
this.log("福利魔方签到成功");
|
||
} else {
|
||
let errorMessage = responseResult?.["resultMsg"] || "";
|
||
this.log("福利魔方签到失败[" + resultCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async flmf_taskList(options = {}) {
|
||
try {
|
||
let requestConfig = {
|
||
fn: "flmf_taskList",
|
||
method: "post",
|
||
url: "https://weixin.linktech.hk/lv-apiaccess/welfareCenter/taskList",
|
||
form: this.get_flmf_data()
|
||
};
|
||
let {
|
||
result: responseResult
|
||
} = await this.request(requestConfig);
|
||
let resultCode = appName.get(responseResult, "resultCode", -1);
|
||
if (resultCode == "0000") {
|
||
for (let taskGroup of responseResult?.["data"]?.["taskInfoList"]) {
|
||
for (let task of taskGroup.taskInfoList.filter(t => !t.done)) {
|
||
for (let i = task.hascount; i < task.count; i++) {
|
||
await this.flmf_gogLance(task.id);
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
let errorMessage = responseResult?.["resultMsg"] || "";
|
||
this.log("福利魔方查询任务失败[" + resultCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async flmf_scanTask() {
|
||
for (let taskId of someArray) {
|
||
await this.flmf_gogLance(taskId);
|
||
}
|
||
}
|
||
async flmf_gogLance(taskId, options = {}) {
|
||
try {
|
||
let requestConfig = {
|
||
fn: "flmf_gogLance",
|
||
method: "post",
|
||
url: "https://weixin.linktech.hk/lv-apiaccess/welfareCenter/gogLance",
|
||
form: {
|
||
taskId: taskId,
|
||
...this.get_flmf_data()
|
||
}
|
||
};
|
||
let {
|
||
result: responseResult
|
||
} = await this.request(requestConfig);
|
||
await appName.wait_gap_interval(this.t_flmf_task, delayMs);
|
||
let resultCode = appName.get(responseResult, "resultCode", -1);
|
||
this.t_flmf_task = Date.now();
|
||
if (resultCode == "0000") {
|
||
this.log("完成任务[" + taskId + "]成功");
|
||
} else {
|
||
let errorMessage = responseResult?.["resultMsg"] || "";
|
||
this.log("完成任务[" + taskId + "]失败[" + resultCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
|
||
// ============================================
|
||
// 联通阅读 NEW LOGIC START (移植自Python脚本)
|
||
// ============================================
|
||
|
||
// 1. 设备预登录 (获取accesstoken)
|
||
async woread_auth(options = {}) {
|
||
let authSuccess = false;
|
||
try {
|
||
// Python: timestamp = round(time() * 1000)
|
||
let timestamp = Date.now();
|
||
// Python: md5(f'100000027k1HcDL8RKvc{timestamp}')
|
||
let signStr = productId + secretKey + timestamp;
|
||
let md5Hash = cryptoJS.MD5(signStr).toString();
|
||
|
||
// Python: crypt_text = f'{{"timestamp":"{self.date}"}}'
|
||
// self.date format: %Y%m%d%H%M%S
|
||
let dateStr = appName.time("yyyyMMddhhmmss");
|
||
let cryptTextObj = { timestamp: dateStr };
|
||
|
||
// encrypt using AES (key="woreadst^&*12345")
|
||
let encodedSign = this.encode_woread(cryptTextObj);
|
||
|
||
const requestOptions = {
|
||
fn: "woread_auth",
|
||
method: "post",
|
||
url: `https://10010.woread.com.cn/ng_woread_service/rest/app/auth/${productId}/${timestamp}/${md5Hash}`,
|
||
json: { sign: encodedSign }
|
||
};
|
||
|
||
let { result: responseData } = await this.request(requestOptions);
|
||
let responseCode = appName.get(responseData, "code", -1);
|
||
|
||
if (responseCode == "0000") {
|
||
authSuccess = true;
|
||
this.woread_accesstoken = responseData?.["data"]?.["accesstoken"];
|
||
// 设置Header中的accesstoken
|
||
this.got = this.got.extend({ headers: { accesstoken: this.woread_accesstoken } });
|
||
// this.log("阅读专区: 设备认证成功");
|
||
} else {
|
||
let errorMessage = responseData?.["message"] || "";
|
||
this.log("阅读专区: 设备认证失败[" + responseCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
this.log("阅读专区: 设备认证异常:" + error.message);
|
||
} finally {
|
||
return authSuccess;
|
||
}
|
||
}
|
||
|
||
// 2. 账号登录 (使用token_online)
|
||
async woread_login(options = {}) {
|
||
let loginSuccess = false;
|
||
try {
|
||
// 1. 确保设备认证已完成
|
||
if (!this.woread_accesstoken) {
|
||
if(!await this.woread_auth()) return false;
|
||
}
|
||
|
||
// 2. 构造加密参数
|
||
if (!this.token_online) {
|
||
this.log("阅读专区: 缺少 token_online,无法进行新版登录");
|
||
return false;
|
||
}
|
||
|
||
let token_enc = this.encode_woread_str(this.token_online);
|
||
// 使用当前手机号,如果没获取到则用默认占位符
|
||
let phone_str = this.mobile || "13800000000";
|
||
let phone_enc = this.encode_woread_str(phone_str);
|
||
let timestamp = appName.time("yyyyMMddhhmmss");
|
||
|
||
// 构造内层JSON字符串: crypt_text
|
||
let innerJson = JSON.stringify({
|
||
tokenOnline: token_enc,
|
||
phone: phone_enc,
|
||
timestamp: timestamp
|
||
});
|
||
|
||
// 3. 对内层JSON再次加密生成sign
|
||
let encodedSign = this.encode_woread_str(innerJson);
|
||
|
||
const requestOptions = {
|
||
fn: "woread_login",
|
||
method: "post",
|
||
url: "https://10010.woread.com.cn/ng_woread_service/rest/account/login",
|
||
json: { sign: encodedSign }
|
||
};
|
||
|
||
let { result: responseData } = await this.request(requestOptions);
|
||
let responseCode = appName.get(responseData, "code", -1);
|
||
|
||
if (responseCode === "0000") {
|
||
loginSuccess = true;
|
||
let { userid, userindex, token, verifycode, phone } = responseData?.["data"];
|
||
this.woread_token = token;
|
||
this.woread_verifycode = verifycode;
|
||
this.woread_userid = userid;
|
||
this.woread_userindex = userindex;
|
||
|
||
// 如果返回了真实手机号,更新它
|
||
if (phone) {
|
||
this.mobile = phone;
|
||
this.name = phone; // Update display name
|
||
}
|
||
|
||
this.log(`阅读专区: 登录成功`);
|
||
} else {
|
||
let errorMessage = responseData?.["message"] || responseData?.["msg"] || "未知错误";
|
||
this.log(`阅读专区: 登录失败[${responseCode}]: ${errorMessage}`);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
this.log("阅读专区: 登录异常:" + error.message);
|
||
} finally {
|
||
return loginSuccess;
|
||
}
|
||
}
|
||
|
||
// 3. 获取书籍信息
|
||
async woread_get_book_info() {
|
||
try {
|
||
// 1. 获取推荐位信息得到 cntindex
|
||
let url1 = "https://10010.woread.com.cn/ng_woread_service/rest/basics/recommposdetail/14856";
|
||
let { result: res1 } = await this.request({ fn: "woread_book", method: "get", url: url1 });
|
||
|
||
if (res1?.code === '0000') {
|
||
this.wr_catid = res1.data.booklist.message[0].catindex;
|
||
this.wr_cardid = res1.data.bindinfo[0].recommposiindex;
|
||
this.wr_cntindex = res1.data.booklist.message[0].cntindex;
|
||
} else {
|
||
this.log("阅读专区: 获取书籍列表失败");
|
||
return false;
|
||
}
|
||
|
||
// 2. 获取章节信息得到 chapterallindex
|
||
if (!this.wr_cntindex) return false;
|
||
|
||
let param = {
|
||
curPage: 1, limit: 30, index: this.wr_cntindex, sort: 0, finishFlag: 1,
|
||
...this.get_woread_param()
|
||
};
|
||
let sign = this.encode_woread(param);
|
||
|
||
let url2 = "https://10010.woread.com.cn/ng_woread_service/rest/cnt/chalist";
|
||
let { result: res2 } = await this.request({
|
||
fn: "woread_chap", method: "post", url: url2, json: { sign }
|
||
});
|
||
|
||
if (res2?.list && res2.list.length > 0) {
|
||
this.wr_chapterallindex = res2.list[0].charptercontent[0].chapterallindex;
|
||
this.wr_chapterid = res2.list[0].charptercontent[0].chapterid;
|
||
return true;
|
||
}
|
||
return false;
|
||
|
||
} catch (e) {
|
||
this.log("阅读专区: 获取书籍信息异常");
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// 4. 阅读模拟 (心跳 + 增加时长)
|
||
async woread_read_process() {
|
||
if (!await this.woread_get_book_info()) {
|
||
this.log("阅读专区: 无法获取书籍信息,跳过阅读");
|
||
return;
|
||
}
|
||
|
||
// Python脚本循环1次
|
||
let loopCount = 1;
|
||
|
||
for (let i = 0; i < loopCount; i++) {
|
||
try {
|
||
// 4.1 发送阅读心跳 wordsDetail
|
||
let param = {
|
||
chapterAllIndex: this.wr_chapterallindex,
|
||
cntIndex: this.wr_cntindex,
|
||
cntTypeFlag: "1",
|
||
...this.get_woread_param()
|
||
};
|
||
let sign = this.encode_woread(param);
|
||
await this.request({
|
||
fn: "woread_heartbeat",
|
||
method: "post",
|
||
url: `https://10010.woread.com.cn/ng_woread_service/rest/cnt/wordsDetail?catid=${this.wr_catid}&cardid=${this.wr_cardid}&cntindex=${this.wr_cntindex}&chapterallindex=${this.wr_chapterallindex}&chapterseno=1`,
|
||
json: { sign }
|
||
});
|
||
|
||
// 4.2 增加阅读时长 addReadTime
|
||
let addParam = {
|
||
readTime: "2",
|
||
cntIndex: this.wr_cntindex,
|
||
cntType: "1",
|
||
catid: "0", pageIndex: "",
|
||
cardid: this.wr_cardid,
|
||
cntindex: this.wr_cntindex,
|
||
cnttype: "1",
|
||
chapterallindex: this.wr_chapterallindex,
|
||
chapterseno: "1",
|
||
channelid: "",
|
||
chapterid: this.wr_chapterid,
|
||
readtype: 1, isend: "0",
|
||
...this.get_woread_param()
|
||
};
|
||
let addSign = this.encode_woread(addParam);
|
||
let { result: addRes } = await this.request({
|
||
fn: "woread_addTime",
|
||
method: "post",
|
||
url: "https://10010.woread.com.cn/ng_woread_service/rest/history/addReadTime",
|
||
json: { sign: addSign }
|
||
});
|
||
|
||
if (addRes?.code === '0000') {
|
||
this.log(`阅读专区: 模拟阅读成功`);
|
||
} else {
|
||
this.log(`阅读专区: 模拟阅读失败: ${addRes?.msg}`);
|
||
}
|
||
|
||
await appName.wait(2000);
|
||
|
||
} catch (e) {
|
||
console.log(e);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 5. 新版抽奖
|
||
async woread_draw_new() {
|
||
try {
|
||
let param = {
|
||
activeindex: "8051", // Python脚本指定的活动ID
|
||
...this.get_woread_param()
|
||
};
|
||
let sign = this.encode_woread(param);
|
||
|
||
let { result: res } = await this.request({
|
||
fn: "woread_draw",
|
||
method: "post",
|
||
url: "https://10010.woread.com.cn/ng_woread_service/rest/basics/doDraw",
|
||
json: { sign }
|
||
});
|
||
|
||
if (res?.code === '0000') {
|
||
this.log(`阅读专区: 抽奖成功: ${res.data.prizedesc}`, { notify: true });
|
||
} else {
|
||
this.log(`阅读专区: 抽奖失败: ${res?.msg || res?.message}`);
|
||
}
|
||
} catch (e) {
|
||
this.log(`阅读专区: 抽奖异常: ${e.message}`);
|
||
}
|
||
}
|
||
|
||
async woread_queryTicketAccount(options = {}) {
|
||
try {
|
||
let requestParams = this.get_woread_param(),
|
||
encodedSign = this.encode_woread(requestParams);
|
||
const signData = {
|
||
sign: encodedSign
|
||
};
|
||
const requestOptions = {
|
||
fn: "woread_queryTicketAccount",
|
||
method: "post",
|
||
url: "https://10010.woread.com.cn/ng_woread_service/rest/phone/vouchers/queryTicketAccount",
|
||
json: signData
|
||
};
|
||
let {
|
||
result: responseData
|
||
} = await this.request(requestOptions),
|
||
responseCode = appName.get(responseData, "code", -1);
|
||
if (responseCode == "0000") {
|
||
let balance = (responseData?.["data"]?.["usableNum"] / 100).toFixed(2);
|
||
const notifyOptions = {
|
||
notify: true
|
||
};
|
||
this.log("阅读区话费红包余额: " + balance, notifyOptions);
|
||
} else {
|
||
let errorMessage = responseData?.["message"] || "";
|
||
this.log("查询阅读区话费红包余额失败[" + responseCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
|
||
// ============================================
|
||
// 联通阅读 NEW LOGIC END
|
||
// ============================================
|
||
|
||
async act_517_userAccount(options = {}) {
|
||
try {
|
||
const requestOptions = {
|
||
fn: "act_517_userAccount",
|
||
method: "get",
|
||
url: "https://activity.10010.com/2024517charges/lottery/userAccount"
|
||
};
|
||
{
|
||
let {
|
||
result: responseResult,
|
||
statusCode: responseStatus
|
||
} = await this.request(appName.copy(requestOptions));
|
||
let responseCode = appName.get(responseResult, "code", responseStatus);
|
||
if (responseCode == "0000") {
|
||
await this.act_517_taskList();
|
||
} else {
|
||
let errorMessage = responseResult?.["message"] || responseResult?.["msg"] || "";
|
||
this.log("517活动进入主页失败[" + responseCode + "]: " + errorMessage);
|
||
return;
|
||
}
|
||
}
|
||
{
|
||
let {
|
||
result: responseResult,
|
||
statusCode: responseStatus
|
||
} = await this.request(appName.copy(requestOptions));
|
||
let responseCode = appName.get(responseResult, "code", responseStatus);
|
||
if (responseCode == "0000") {
|
||
let {
|
||
chances: chances
|
||
} = responseResult?.["data"];
|
||
this.log("517活动可以抽奖" + chances + "次");
|
||
let isFirstDraw = false;
|
||
while (chances-- > 0) {
|
||
if (isFirstDraw) {
|
||
await appName.wait(3000);
|
||
}
|
||
isFirstDraw = true;
|
||
await this.act_517_lottery();
|
||
}
|
||
} else {
|
||
let errorMessage = responseResult?.["message"] || responseResult?.["msg"] || "";
|
||
this.log("517活动查询抽奖次数失败[" + responseCode + "]: " + errorMessage);
|
||
}
|
||
}
|
||
{
|
||
let {
|
||
result: responseResult,
|
||
statusCode: responseStatus
|
||
} = await this.request(appName.copy(requestOptions));
|
||
let responseCode = appName.get(responseResult, "code", responseStatus);
|
||
if (responseCode == "0000") {
|
||
let {
|
||
amount: amount,
|
||
targetAmount: targetAmount
|
||
} = responseResult?.["data"];
|
||
const notifyOptions = {
|
||
notify: true
|
||
};
|
||
this.log("517活动现金进度: " + amount + "/" + targetAmount, notifyOptions);
|
||
} else {
|
||
let errorMessage = responseResult?.["message"] || responseResult?.["msg"] || "";
|
||
this.log("517活动查询进度失败[" + responseCode + "]: " + errorMessage);
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async act_517_bind(shareCode, options = {}) {
|
||
try {
|
||
const requestOptions = {
|
||
fn: "act_517_bind",
|
||
method: "post",
|
||
url: "https://activity.10010.com/2024517charges/openWindows/bind",
|
||
json: {},
|
||
valid_code: [401]
|
||
};
|
||
requestOptions.json.shareCode = shareCode;
|
||
requestOptions.json.channel = "countersign";
|
||
let {
|
||
result: responseResult
|
||
} = await this.request(requestOptions);
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async act_517_lottery(options = {}) {
|
||
try {
|
||
const requestOptions = {
|
||
fn: "act_517_lottery",
|
||
method: "get",
|
||
url: "https://activity.10010.com/2024517charges/lottery/lottery"
|
||
};
|
||
let {
|
||
result: responseResult,
|
||
statusCode: responseStatus
|
||
} = await this.request(requestOptions);
|
||
let responseCode = appName.get(responseResult, "code", responseStatus);
|
||
if (responseCode == "0000") {
|
||
responseResult?.["data"]?.["uuid"] ? (await appName.wait(2000), await this.act_517_winningRecord(responseResult.data.uuid)) : this.log("517活动抽奖失败, 没有返回uuid");
|
||
} else {
|
||
let errorMessage = responseResult?.["message"] || responseResult?.["msg"] || "";
|
||
this.log("517活动抽奖失败[" + responseCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async act_517_winningRecord(requestId, options = {}) {
|
||
try {
|
||
const searchParams = {
|
||
requestId: requestId
|
||
};
|
||
const requestOptions = {
|
||
fn: "act_517_winningRecord",
|
||
method: "get",
|
||
url: "https://activity.10010.com/2024517charges/lottery/winningRecord",
|
||
searchParams: searchParams
|
||
};
|
||
let {
|
||
result: responseResult,
|
||
statusCode: responseStatus
|
||
} = await this.request(requestOptions);
|
||
let responseCode = appName.get(responseResult, "code", responseStatus);
|
||
if (responseCode == "0000") {
|
||
if (responseResult?.["data"]?.["isWin"] === "1") {
|
||
let {
|
||
prizeAmount: prizeAmount,
|
||
prizeList: prizeList,
|
||
afterAmount: afterAmount,
|
||
targetAmount: targetAmount,
|
||
showAmount = "0"
|
||
} = responseResult?.["data"],
|
||
prizeNames = (prizeList || []).filter(p => p.prizeName).map(p => p.prizeName).join(", ") || "";
|
||
const notifyOptions = {
|
||
notify: true
|
||
};
|
||
if (prizeNames) {
|
||
this.log("517活动抽奖: " + prizeNames, notifyOptions);
|
||
}
|
||
if (showAmount === "1") {
|
||
this.log("517活动抽奖现金进度: +" + prizeAmount + " (" + afterAmount + "/" + targetAmount + ")");
|
||
}
|
||
} else {
|
||
this.log("517活动抽奖: 空气");
|
||
}
|
||
} else {
|
||
let errorMessage = responseResult?.["message"] || responseResult?.["msg"] || "";
|
||
this.log("查询517活动抽奖结果失败[" + responseCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async act_517_taskList(options = {}) {
|
||
try {
|
||
const requestOptions = {
|
||
fn: "act_517_taskList",
|
||
method: "get",
|
||
url: "https://activity.10010.com/2024517charges/dotask/taskList"
|
||
};
|
||
let {
|
||
result: responseResult,
|
||
statusCode: responseStatus
|
||
} = await this.request(requestOptions);
|
||
let responseCode = appName.get(responseResult, "code", responseStatus);
|
||
if (responseCode == "0000") {
|
||
let taskList = responseResult?.["data"]?.["taskList"] || [];
|
||
for (let task of taskList) {
|
||
let {
|
||
completeNum = 0,
|
||
maxNum: maxNum,
|
||
isComplete: isComplete,
|
||
taskType: taskType
|
||
} = task;
|
||
if (isComplete) {
|
||
continue;
|
||
}
|
||
if (taskType == "5") {
|
||
continue;
|
||
}
|
||
completeNum = parseInt(completeNum);
|
||
maxNum = parseInt(maxNum);
|
||
for (let i = completeNum; i < maxNum; i++) {
|
||
await this.act_517_completeTask(task);
|
||
}
|
||
}
|
||
} else {
|
||
let errorMessage = responseResult?.["message"] || responseResult?.["msg"] || "";
|
||
this.log("查询517活动抽奖结果失败[" + responseCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async act_517_completeTask(task, options = {}) {
|
||
try {
|
||
let taskTitle = task.title;
|
||
const searchParams = {
|
||
taskId: task.taskId
|
||
};
|
||
const requestOptions = {
|
||
fn: "act_517_completeTask",
|
||
method: "get",
|
||
url: "https://activity.10010.com/2024517charges/dotask/completeTask",
|
||
searchParams: searchParams
|
||
};
|
||
let {
|
||
result: responseResult,
|
||
statusCode: responseStatus
|
||
} = await this.request(requestOptions);
|
||
let responseCode = appName.get(responseResult, "code", responseStatus);
|
||
if (responseCode == "0000") {
|
||
if (responseResult?.["data"]) {
|
||
let {
|
||
num: num,
|
||
title: title
|
||
} = responseResult.data;
|
||
this.log("完成任务[" + title + "]成功: " + num + "次抽奖机会");
|
||
} else {
|
||
this.log("完成任务[" + taskTitle + "]失败没有获得抽奖机会");
|
||
}
|
||
} else {
|
||
let errorMessage = responseResult?.["message"] || responseResult?.["msg"] || "";
|
||
this.log("完成任务[" + taskTitle + "]失败[" + responseCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
|
||
get_wocare_body(apiCode, requestData = {}) {
|
||
const timestamp = appName.time("yyyyMMddhhmmssS"),
|
||
encodedContent = Buffer.from(JSON.stringify(requestData)).toString("base64");
|
||
let body = {
|
||
version: minRetries,
|
||
apiCode: apiCode,
|
||
channelId: anotherApiKey,
|
||
transactionId: timestamp + appName.randomString(6, numbers),
|
||
timeStamp: timestamp,
|
||
messageContent: encodedContent
|
||
},
|
||
paramsArray = [];
|
||
Object.keys(body).sort().forEach(key => {
|
||
paramsArray.push(key + "=" + body[key]);
|
||
});
|
||
paramsArray.push("sign=" + anotherEncryptionKey);
|
||
body.sign = cryptoJS.MD5(paramsArray.join("&")).toString();
|
||
return body;
|
||
}
|
||
async wocare_api(apiCode, requestData = {}) {
|
||
let body = this.get_wocare_body(apiCode, requestData);
|
||
const requestOptions = {
|
||
fn: "wocare_" + apiCode,
|
||
method: "post",
|
||
url: "https://wocare.unisk.cn/api/v1/" + apiCode,
|
||
form: body
|
||
};
|
||
let response = await this.request(requestOptions);
|
||
if (response?.["result"]?.["messageContent"]) {
|
||
try {
|
||
let decodedContent = JSON.parse(Buffer.from(response.result.messageContent, "base64").toString());
|
||
response.result.data = decodedContent?.["data"] || decodedContent;
|
||
if (decodedContent?.["resultMsg"]) {
|
||
response.result.resultMsg = decodedContent.resultMsg;
|
||
}
|
||
} catch (error) {
|
||
this.log("联通祝福: 解析返回失败:");
|
||
console.log(error);
|
||
}
|
||
}
|
||
return response;
|
||
}
|
||
async wocare_getToken(ticket, options = {}) {
|
||
let isSuccess = false;
|
||
try {
|
||
let requestOptions = {
|
||
fn: "wocare_getToken",
|
||
method: "get",
|
||
url: "https://wocare.unisk.cn/mbh/getToken",
|
||
searchParams: {
|
||
channelType: serviceLife,
|
||
type: "02",
|
||
ticket: ticket,
|
||
version: appVersion,
|
||
timestamp: appName.time("yyyyMMddhhmmssS"),
|
||
desmobile: this.mobile,
|
||
num: 0,
|
||
postage: appName.randomString(32),
|
||
homePage: "home",
|
||
duanlianjieabc: "qAz2m",
|
||
userNumber: this.mobile
|
||
}
|
||
},
|
||
{
|
||
headers: headers,
|
||
statusCode: statusCode
|
||
} = await this.request(requestOptions);
|
||
if (statusCode == 302) {
|
||
if (headers?.["location"]) {
|
||
let locationUrl = new URL(headers.location),
|
||
sid = locationUrl.searchParams.get("sid");
|
||
sid ? (this.wocare_sid = sid, isSuccess = await this.wocare_loginmbh()) : this.log("联通祝福: 没有获取到sid");
|
||
} else {
|
||
this.log("联通祝福: 没有获取到location");
|
||
}
|
||
} else {
|
||
this.log("联通祝福: 获取sid失败[" + statusCode + "]");
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
} finally {
|
||
return isSuccess;
|
||
}
|
||
}
|
||
async wocare_loginmbh(options = {}) {
|
||
let isSuccess = false;
|
||
try {
|
||
let apiCode = "loginmbh";
|
||
const requestData = {
|
||
sid: this.wocare_sid,
|
||
channelType: serviceLife,
|
||
apiCode: apiCode
|
||
};
|
||
let {
|
||
result: responseResult,
|
||
statusCode: responseStatus
|
||
} = await this.wocare_api(apiCode, requestData);
|
||
let resultCode = appName.get(responseResult, "resultCode", responseStatus);
|
||
if (resultCode == "0000") {
|
||
isSuccess = true;
|
||
let {
|
||
token: token
|
||
} = responseResult?.["data"];
|
||
this.wocare_token = token;
|
||
} else {
|
||
let errorMessage = responseResult?.["resultMsg"] || responseResult?.["resultDesc"] || "";
|
||
this.log("联通祝福: 登录失败[" + resultCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
} finally {
|
||
return isSuccess;
|
||
}
|
||
}
|
||
async wocare_getSpecificityBanner(options = {}) {
|
||
try {
|
||
let apiCode = "getSpecificityBanner";
|
||
const requestData = {
|
||
token: this.wocare_token,
|
||
apiCode: apiCode
|
||
};
|
||
let {
|
||
result: responseResult,
|
||
statusCode: responseStatus
|
||
} = await this.wocare_api(apiCode, requestData);
|
||
let resultCode = appName.get(responseResult, "resultCode", responseStatus);
|
||
if (resultCode == "0000") {
|
||
let bannerList = responseResult?.["data"] || [];
|
||
for (let banner of bannerList.filter(b => b.activityStatus === "0" && b.isDeleted === "0")) {
|
||
await this.wocare_getDrawTask(banner);
|
||
await this.wocare_loadInit(banner);
|
||
}
|
||
} else {
|
||
let errorMessage = responseResult?.["resultMsg"] || responseResult?.["resultDesc"] || "";
|
||
this.log("联通祝福: 进入活动失败[" + resultCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async wocare_loadInit(activity, options = {}) {
|
||
try {
|
||
let apiCode = "loadInit";
|
||
const requestData = {
|
||
token: this.wocare_token,
|
||
channelType: serviceLife,
|
||
type: activity.id,
|
||
apiCode: apiCode
|
||
};
|
||
let {
|
||
result: responseResult,
|
||
statusCode: responseStatus
|
||
} = await this.wocare_api(apiCode, requestData);
|
||
let resultCode = appName.get(responseResult, "resultCode", responseStatus);
|
||
if (resultCode == "0000") {
|
||
let responseData = responseResult?.["data"],
|
||
activeModuleGroupId = responseData?.["zActiveModuleGroupId"],
|
||
drawCount = 0;
|
||
switch (activity.id) {
|
||
case 2:
|
||
{
|
||
let isPartake = responseData?.["data"]?.["isPartake"] || 0;
|
||
!isPartake && (drawCount = 1);
|
||
break;
|
||
}
|
||
case 3:
|
||
{
|
||
drawCount = parseInt(responseData?.["raffleCountValue"] || 0);
|
||
break;
|
||
}
|
||
case 4:
|
||
{
|
||
drawCount = parseInt(responseData?.["mhRaffleCountValue"] || 0);
|
||
break;
|
||
}
|
||
}
|
||
while (drawCount-- > 0) {
|
||
await appName.wait(5000);
|
||
await this.wocare_luckDraw(activity, activeModuleGroupId);
|
||
}
|
||
} else {
|
||
let errorMessage = responseResult?.["resultMsg"] || responseResult?.["resultDesc"] || "";
|
||
this.log("联通祝福: [" + activity.name + "]查询活动失败[" + resultCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async wocare_getDrawTask(activity, options = {}) {
|
||
try {
|
||
let apiCode = "getDrawTask";
|
||
const requestData = {
|
||
token: this.wocare_token,
|
||
channelType: serviceLife,
|
||
type: activity.id,
|
||
apiCode: apiCode
|
||
};
|
||
let {
|
||
result: responseResult,
|
||
statusCode: responseStatus
|
||
} = await this.wocare_api(apiCode, requestData);
|
||
let resultCode = appName.get(responseResult, "resultCode", responseStatus);
|
||
if (resultCode == "0000") {
|
||
let taskList = responseResult?.["data"]?.["taskList"] || [];
|
||
for (let task of taskList.filter(t => t.taskStatus == 0)) {
|
||
await this.wocare_completeTask(activity, task);
|
||
}
|
||
} else {
|
||
let errorMessage = responseResult?.["resultMsg"] || responseResult?.["resultDesc"] || "";
|
||
this.log("联通祝福: [" + activity.name + "]查询任务失败[" + resultCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async wocare_completeTask(activity, task, taskStep = "1", options = {}) {
|
||
try {
|
||
let taskTitle = task.title,
|
||
action = taskStep == "1" ? "领取任务" : "完成任务",
|
||
apiCode = "completeTask";
|
||
const requestData = {
|
||
token: this.wocare_token,
|
||
channelType: serviceLife,
|
||
task: task.id,
|
||
taskStep: taskStep,
|
||
type: activity.id,
|
||
apiCode: apiCode
|
||
};
|
||
let {
|
||
result: responseResult,
|
||
statusCode: responseStatus
|
||
} = await this.wocare_api(apiCode, requestData);
|
||
let resultCode = appName.get(responseResult, "resultCode", responseStatus);
|
||
if (resultCode == "0000") {
|
||
this.log("联通祝福: " + action + "[" + taskTitle + "]成功");
|
||
taskStep == "1" && (await this.wocare_completeTask(activity, task, "4"));
|
||
} else {
|
||
let errorMessage = responseResult?.["resultMsg"] || responseResult?.["resultDesc"] || "";
|
||
this.log("联通祝福: [" + activity.name + "]" + action + "[" + taskTitle + "]失败[" + resultCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async wocare_luckDraw(activity, activeModuleGroupId, options = {}) {
|
||
try {
|
||
let apiCode = "luckDraw";
|
||
const requestData = {
|
||
token: this.wocare_token,
|
||
channelType: serviceLife,
|
||
zActiveModuleGroupId: activeModuleGroupId,
|
||
type: activity.id,
|
||
apiCode: apiCode
|
||
};
|
||
let {
|
||
result: responseResult,
|
||
statusCode: responseStatus
|
||
} = await this.wocare_api(apiCode, requestData);
|
||
let resultCode = appName.get(responseResult, "resultCode", responseStatus);
|
||
if (resultCode == "0000") {
|
||
let drawResultCode = appName.get(responseResult?.["data"], "resultCode", -1);
|
||
if (drawResultCode == "0000") {
|
||
let {
|
||
prizeName: prizeName,
|
||
prizeDesc: prizeDesc
|
||
} = responseResult?.["data"]?.["data"]?.["prize"];
|
||
this.log("联通祝福: [" + activity.name + "]抽奖: " + prizeName + "[" + prizeDesc + "]");
|
||
} else {
|
||
let errorMessage = responseResult?.["resultMsg"] || responseResult?.["resultDesc"] || "";
|
||
this.log("联通祝福: [" + activity.name + "]抽奖失败[" + drawResultCode + "]: " + errorMessage);
|
||
}
|
||
} else {
|
||
let errorMessage = responseResult?.["resultMsg"] || responseResult?.["resultDesc"] || "";
|
||
this.log("联通祝福: [" + activity.name + "]抽奖错误[" + resultCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async card_618_authCheck(options = {}) {
|
||
try {
|
||
let requestConfig = {
|
||
fn: "card_618_authCheck",
|
||
method: "post",
|
||
url: "https://epay.10010.com/ps-pafs-auth-front/v1/auth/check",
|
||
headers: {
|
||
bizchannelinfo: this.get_bizchannelinfo()
|
||
}
|
||
};
|
||
let {
|
||
result: responseResult
|
||
} = await this.request(requestConfig);
|
||
let responseCode = appName.get(responseResult, "code", -1);
|
||
if (responseCode == "0000") {
|
||
let {
|
||
mobile: mobile,
|
||
sessionId: sessionId,
|
||
tokenId: tokenId,
|
||
userId: userId
|
||
} = responseResult?.["data"]?.["authInfo"];
|
||
const authInfo = {
|
||
sessionId: sessionId,
|
||
tokenId: tokenId,
|
||
userId: userId
|
||
};
|
||
Object.assign(this, authInfo);
|
||
await this.card_618_queryUserCardInfo();
|
||
} else {
|
||
if (responseCode == "2101000100") {
|
||
let loginUrl = responseResult?.["data"]?.["woauth_login_url"];
|
||
await this.card_618_login(loginUrl);
|
||
} else {
|
||
let errorMessage = responseResult?.["msgInside"] || responseResult?.["msg"] || "";
|
||
this.log("618集卡获取tokenId失败[" + responseCode + "]: " + errorMessage);
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async card_618_login(loginUrl, options = {}) {
|
||
try {
|
||
let templateName = appName.time("yyyyMM") + "28ZFR";
|
||
loginUrl += "https://epay.10010.com/ci-mcss-party-web/rainbow/?templateName=" + templateName + "&bizFrom=225&bizChannelCode=225&channelType=WDQB";
|
||
const requestOptions = {
|
||
fn: "card_618_login",
|
||
method: "get",
|
||
url: "https://epay.10010.com/woauth2/login",
|
||
searchParams: {}
|
||
};
|
||
requestOptions.searchParams.response_type = "web_token";
|
||
requestOptions.searchParams.source = "app_sjyyt";
|
||
requestOptions.searchParams.union_session_id = "";
|
||
requestOptions.searchParams.device_digest_token_id = this.tokenId_cookie;
|
||
requestOptions.searchParams.target_client_id = anotherClientId;
|
||
requestOptions.searchParams.position = null;
|
||
requestOptions.searchParams.redirect_url = "https://epay.10010.com/ci-mcss-party-web/cardSelection/?activityId=NZJK618CJHD";
|
||
requestOptions.searchParams.bizFrom = errorCode;
|
||
requestOptions.searchParams.bizChannelCode = errorNumber;
|
||
requestOptions.searchParams.channelType = "WDQB";
|
||
let {
|
||
headers: headers,
|
||
statusCode: statusCode
|
||
} = await this.request(requestOptions);
|
||
if (headers?.["location"]) {
|
||
let locationUrl = new URL(headers.location);
|
||
this.rptId = locationUrl.searchParams.get("rptid");
|
||
this.rptId ? await this.card_618_authCheck() : this.log("618集卡获取rptid失败");
|
||
} else {
|
||
this.log("618集卡获取rptid失败[" + statusCode + "]");
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async card_618_queryUserCardInfo(options = {}) {
|
||
try {
|
||
const requestBody = {
|
||
activityId: "NZJK618CJHD"
|
||
};
|
||
let requestConfig = {
|
||
fn: "card_618_queryUserCardInfo",
|
||
method: "post",
|
||
url: "https://epay.10010.com/ci-mcss-party-front/v1/mouldCard/queryUserCardInfo",
|
||
headers: {
|
||
bizchannelinfo: this.get_bizchannelinfo(),
|
||
authinfo: this.get_epay_authinfo()
|
||
},
|
||
form: requestBody
|
||
};
|
||
let {
|
||
result: responseResult
|
||
} = await this.request(requestConfig);
|
||
let responseCode = appName.get(responseResult, "code", -1);
|
||
if (responseCode == "0000" && responseResult?.["data"]?.["returnCode"] == 0) {
|
||
let {
|
||
userRemain = 0,
|
||
isFirst = true
|
||
} = responseResult?.["data"];
|
||
if (isFirst) {
|
||
await this.card_618_unifyDraw("首次进入");
|
||
}
|
||
this.log("618集卡可以抽奖" + userRemain + "次");
|
||
while (userRemain-- > 0) {
|
||
await this.card_618_unifyDraw("抽奖");
|
||
}
|
||
} else {
|
||
let errorMessage = responseResult?.["message"] || responseResult?.["msg"] || "";
|
||
this.log("618集卡进入主页失败[" + responseCode + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
async card_618_unifyDraw(drawType, options = {}) {
|
||
try {
|
||
let requestConfig = {
|
||
fn: "card_618_unifyDraw",
|
||
method: "post",
|
||
url: "https://epay.10010.com/ci-mcss-party-front/v1/mouldCard/unifyDraw",
|
||
headers: {
|
||
bizchannelinfo: this.get_bizchannelinfo(),
|
||
authinfo: this.get_epay_authinfo()
|
||
},
|
||
form: {
|
||
bigActivityId: activityIds.card_618,
|
||
activityId: activityIds.card_618 + card618DrawTypeSuffix[drawType],
|
||
bizFrom: errorCode
|
||
}
|
||
};
|
||
let {
|
||
result: responseResult
|
||
} = await this.request(requestConfig);
|
||
let responseCode = appName.get(responseResult, "code", -1);
|
||
if (responseCode == "0000" && responseResult?.["data"]?.["returnCode"] == 0) {
|
||
let prizeId = responseResult?.["data"]?.["prizeId"] || "空气",
|
||
prizeName = card618PrizeMap[prizeId] || prizeId;
|
||
const notifyOptions = {
|
||
notify: true
|
||
};
|
||
this.log("618集卡[" + drawType + "]: " + prizeName, notifyOptions);
|
||
} else {
|
||
let errorMessage = responseResult?.["data"]?.["returnMsg"] || responseResult?.["msg"] || "";
|
||
this.log("618集卡[" + drawType + "]失败[" + (responseResult?.["data"]?.["returnCode"] || responseCode) + "]: " + errorMessage);
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
//联通安全管家
|
||
async securityButlerTask() {
|
||
try {
|
||
this.log("============= 联通安全管家 =============");
|
||
|
||
// This replaces getOnlineStatus from the original script, as data is already available.
|
||
if (!this.ecs_token || !this.mobile) {
|
||
this.log("安全管家任务缺少 ecs_token 或 mobile,跳过。");
|
||
return;
|
||
}
|
||
|
||
// Initialize points tracking
|
||
this.sec_oldJFPoints = null;
|
||
|
||
// Get all necessary tickets and tokens
|
||
await this.getTicketByNative_sec();
|
||
await this.getAuthToken_sec();
|
||
await this.getTicketForJF_sec();
|
||
|
||
if (!this.sec_ticket || !this.sec_token) {
|
||
this.log("安全管家获取票据失败,跳过任务。");
|
||
return;
|
||
}
|
||
|
||
// this.log("安全管家CK获取完毕,等待5秒...");
|
||
await appName.wait(5000);
|
||
|
||
await this.getUserInfo_sec(); // Get initial points
|
||
await this.executeAllTasks_sec();
|
||
await appName.wait(15000);
|
||
await this.getUserInfo_sec(); // Get final points and log the difference
|
||
|
||
} catch (e) {
|
||
this.log(`联通安全管家任务出现错误: ${e.message}`);
|
||
console.log(e);
|
||
}
|
||
}
|
||
|
||
async getTicketByNative_sec() {
|
||
let requestOptions = {
|
||
"fn": "getTicketByNative_sec",
|
||
"url": `https://m.client.10010.com/edop_ng/getTicketByNative?token=${this.ecs_token}&appId=edop_unicom_3a6cc75a`,
|
||
"headers": {
|
||
"Cookie": `PvSessionId=${appName.time("yyyyMMddhhmmss")}${this.unicomTokenId};c_mobile=${this.mobile}; c_version=iphone_c@11.0800; city=036|${this.city?.[0]?.cityCode || ''}|90063345|-99;devicedId=${this.unicomTokenId}; ecs_token=${this.ecs_token};t3_token=`,
|
||
"Accept": "*",
|
||
"Connection": "keep-alive",
|
||
"Content-Type": "application/x-www-form-urlencoded",
|
||
"Accept-Encoding": "gzip;q=1.0, compress;q=0.5",
|
||
"Host": "m.client.10010.com",
|
||
"User-Agent": "ChinaUnicom4.x/12.3.1 (com.chinaunicom.mobilebusiness; build:77; iOS 16.6.0) Alamofire/4.7.3 unicom{version:iphone_c@12.0301}",
|
||
"Accept-Language": "zh-Hans-CN;q=1.0"
|
||
}
|
||
};
|
||
let { result } = await this.request(requestOptions);
|
||
this.sec_ticket1 = result ? result.ticket : null;
|
||
}
|
||
|
||
async getAuthToken_sec() {
|
||
if (!this.sec_ticket1) {
|
||
this.log("安全管家 getAuthToken_sec 缺少 ticket1,跳过");
|
||
return;
|
||
}
|
||
let requestOptions = {
|
||
"fn": "getAuthToken_sec",
|
||
"url": "https://uca.wo116114.com/api/v1/auth/ticket?product_line=uasp&entry_point=h5&entry_point_id=edop_unicom_3a6cc75a",
|
||
"method": "post",
|
||
"headers": {
|
||
"User-Agent": "ChinaUnicom4.x/12.3.1 (com.chinaunicom.mobilebusiness; build:77; iOS 16.6.0) Alamofire/4.7.3 unicom{version:iphone_c@12.0301}",
|
||
"Accept": "*",
|
||
"Accept-Encoding": "gzip;q=1.0, compress;q=0.5",
|
||
"Content-Type": "application/json",
|
||
"Accept-Language": "zh-Hans-CN;q=1.0",
|
||
"clientType": "uasp_unicom_applet"
|
||
},
|
||
"json": { "productId": "", "type": 1, "ticket": this.sec_ticket1 }
|
||
};
|
||
let { result } = await this.request(requestOptions);
|
||
if (result && result.data) {
|
||
this.sec_token = result.data.access_token;
|
||
}
|
||
}
|
||
|
||
async getTicketForJF_sec() {
|
||
if (!this.sec_token) {
|
||
this.log("安全管家 getTicketForJF_sec 缺少 token,跳过");
|
||
return;
|
||
}
|
||
let requestOptions = {
|
||
"fn": "getTicketForJF_sec_1",
|
||
"method": "post",
|
||
"url": "https://uca.wo116114.com/api/v1/auth/getTicket?product_line=uasp&entry_point=h5&entry_point_id=edop_unicom_3a6cc75a",
|
||
"headers": {
|
||
"User-Agent": "ChinaUnicom4.x/12.3.1 (com.chinaunicom.mobilebusiness; build:77; iOS 16.6.0) Alamofire/4.7.3 unicom{version:iphone_c@12.0301}",
|
||
"Content-Type": "application/json",
|
||
"auth-sa-token": this.sec_token,
|
||
"clientType": "uasp_unicom_applet"
|
||
},
|
||
"json": { "productId": "91311616", "phone": this.mobile }
|
||
};
|
||
|
||
let { result } = await this.request(requestOptions);
|
||
if (result && result.data) {
|
||
this.sec_ticket = result.data.ticket;
|
||
} else {
|
||
this.log("安全管家获取积分票据失败");
|
||
return;
|
||
}
|
||
|
||
let queryOptions = {
|
||
"fn": "getTicketForJF_sec_2",
|
||
"method": "post",
|
||
"url": "https://m.jf.10010.com/jf-external-application/page/query",
|
||
"headers": {
|
||
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 unicom{version:iphone_c@12.0301};ltst;OSVersion/16.6",
|
||
"partnersid": "1702",
|
||
"ticket": decodeURIComponent(this.sec_ticket),
|
||
"Cookie": `_jea_id=${this.sec_jeaId}`,
|
||
"clienttype": "uasp_unicom_applet",
|
||
},
|
||
"json": { "activityId": "s747395186896173056", "partnersId": "1702" }
|
||
};
|
||
|
||
let { headers } = await this.request(queryOptions);
|
||
const setCookieHeader = headers?.["set-cookie"];
|
||
if (setCookieHeader) {
|
||
const cookies = Array.isArray(setCookieHeader) ? setCookieHeader : [setCookieHeader];
|
||
const jeaCookie = cookies.find(cookie => cookie && cookie.startsWith("_jea_id="));
|
||
if (jeaCookie) {
|
||
const newJeaId = jeaCookie.split(";")[0].split("=")[1];
|
||
if (newJeaId) {
|
||
this.sec_jeaId = newJeaId;
|
||
this.log("安全管家: 更新 jeaId: " + this.sec_jeaId);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
async operateBlacklist_sec(phoneNumber, type) {
|
||
const typeName = type === 0 ? "添加" : "删除";
|
||
this.log(`安全管家: 正在执行${typeName}黑名单号码: ${phoneNumber}`);
|
||
|
||
let requestOptions = {
|
||
"fn": `operateBlacklist_sec_${typeName}`,
|
||
"method": "post",
|
||
"url": "https://uca.wo116114.com/sjgj/woAssistant/umm/configs/v1/config?product_line=uasp&entry_point=h5&entry_point_id=wxdefbc1986dc757a6",
|
||
"headers": {
|
||
"User-Agent": "ChinaUnicom4.x/12.3.1 (com.chinaunicom.mobilebusiness; build:77; iOS 16.6.0) Alamofire/4.7.3 unicom{version:iphone_c@12.0301}",
|
||
"auth-sa-token": this.sec_token,
|
||
"clientType": "uasp_unicom_applet",
|
||
"token": this.sec_token,
|
||
"Cookie": `devicedId=${this.unicomTokenId}`
|
||
},
|
||
"json": {
|
||
"productId": "91015539",
|
||
"type": 1,
|
||
"operationType": type,
|
||
...(type === 0 ? { "blacklistSource": 0 } : {}),
|
||
"contents": [{ "content": phoneNumber, "contentTag": "", "nickname": null, "configTime": null }]
|
||
}
|
||
};
|
||
|
||
let { result } = await this.request(requestOptions);
|
||
return result;
|
||
}
|
||
|
||
async addToBlacklist_sec() {
|
||
const phoneNumberToOperate = "13088888888";
|
||
let response = await this.operateBlacklist_sec(phoneNumberToOperate, 0);
|
||
|
||
// 检查多种成功条件: code 为 '0000' 或 0, 或者 msg 为 '成功'
|
||
if (response && (response.code === '0000' || response.code === 0 || response.msg === '成功')) {
|
||
this.log(`安全管家: ✅ 添加黑名单成功。`);
|
||
return;
|
||
}
|
||
|
||
const isDuplicateError = response && response.msg && response.msg.includes("号码已存在");
|
||
|
||
if (isDuplicateError) {
|
||
this.log(`安全管家: ⚠️ 检测到号码 ${phoneNumberToOperate} 已存在,执行先删除后添加流程。`);
|
||
let delResponse = await this.operateBlacklist_sec(phoneNumberToOperate, 1);
|
||
|
||
// 检查删除操作的多种成功/可接受条件
|
||
const isDelSuccess = delResponse && (delResponse.code === '0000' || delResponse.code === 0 || (delResponse.msg && (delResponse.msg.includes("成功") || delResponse.msg.includes("不在黑名单"))));
|
||
|
||
if (isDelSuccess) {
|
||
this.log(`安全管家: ✅ 删除旧记录成功,等待 2 秒后重新添加...`);
|
||
await appName.wait(2000);
|
||
let retryResponse = await this.operateBlacklist_sec(phoneNumberToOperate, 0);
|
||
|
||
// 重新检查添加操作的多种成功条件
|
||
if (retryResponse && (retryResponse.code === '0000' || retryResponse.code === 0 || retryResponse.msg === '成功')) {
|
||
this.log(`安全管家: ✅ 重新添加黑名单成功。`);
|
||
} else {
|
||
this.log(`安全管家: ❌ 重新添加失败: ${retryResponse ? retryResponse.msg : '无响应'}`);
|
||
}
|
||
} else {
|
||
this.log(`安全管家: ❌ 删除旧记录失败,无法继续添加。`);
|
||
}
|
||
} else {
|
||
// 其他未知的失败情况
|
||
this.log(`安全管家: ❌ 添加黑名单失败: ${response ? response.msg : '无响应'}`);
|
||
}
|
||
}
|
||
|
||
async markPhoneNumber_sec() {
|
||
let requestOptions = {
|
||
"fn": "markPhoneNumber_sec",
|
||
"method": "post",
|
||
"url": "https://uca.wo116114.com/sjgj/unicomAssistant/uasp/configs/v1/addressBook/saveTagPhone?product_line=uasp&entry_point=h5&entry_point_id=wxdefbc1986dc757a6",
|
||
"headers": {
|
||
"User-Agent": "ChinaUnicom4.x/12.3.1 (com.chinaunicom.mobilebusiness; build:77; iOS 16.6.0) Alamofire/4.7.3 unicom{version:iphone_c@12.0301}",
|
||
"auth-sa-token": this.sec_token,
|
||
"clientType": "uasp_unicom_applet"
|
||
},
|
||
"json": { "tagPhoneNo": "13088330789", "tagIds": [26], "status": 0, "productId": "91311616" }
|
||
};
|
||
await this.request(requestOptions);
|
||
this.log("安全管家: 执行号码标记。");
|
||
}
|
||
|
||
async syncAddressBook_sec() {
|
||
let requestOptions = {
|
||
"fn": "syncAddressBook_sec",
|
||
"method": "post",
|
||
"url": "https://uca.wo116114.com/sjgj/unicomAssistant/uasp/configs/v1/addressBookBatchConfig?product_line=uasp&entry_point=h5&entry_point_id=edop_unicom_3a6cc75a",
|
||
"headers": {
|
||
"User-Agent": "ChinaUnicom4.x/12.3.1 (com.chinaunicom.mobilebusiness; build:77; iOS 16.6.0) Alamofire/4.7.3 unicom{version:iphone_c@12.0301}",
|
||
"auth-sa-token": this.sec_token,
|
||
"clientType": "uasp_unicom_applet"
|
||
},
|
||
"json": { "addressBookDTOList": [{ "addressBookPhoneNo": "13088888888", "addressBookName": "水水" }], "productId": "91311616", "opType": "1" }
|
||
};
|
||
await this.request(requestOptions);
|
||
this.log("安全管家: 执行同步通讯录。");
|
||
}
|
||
|
||
async setInterceptionRules_sec() {
|
||
let requestOptions = {
|
||
"fn": "setInterceptionRules_sec",
|
||
"method": "post",
|
||
"url": "https://uca.wo116114.com/sjgj/woAssistant/umm/configs/v1/config?product_line=uasp&entry_point=h5&entry_point_id=wxdefbc1986dc757a6",
|
||
"headers": {
|
||
"User-Agent": "ChinaUnicom4.x/12.3.1 (com.chinaunicom.mobilebusiness; build:77; iOS 16.6.0) Alamofire/4.7.3 unicom{version:iphone_c@12.0301}",
|
||
"auth-sa-token": this.sec_token,
|
||
"clientType": "uasp_unicom_applet"
|
||
},
|
||
"json": { "contents": [{ "name": "rings-once", "contentTag": "8", "contentName": "响一声", "content": "0", "icon": "alerting" }], "operationType": 0, "type": 3, "productId": "91311616" }
|
||
};
|
||
await this.request(requestOptions);
|
||
this.log("安全管家: 执行设置拦截规则。");
|
||
}
|
||
|
||
async viewWeeklyStatus_sec() {
|
||
let requestOptions = {
|
||
"fn": "viewWeeklyStatus_sec",
|
||
"method": "post",
|
||
"url": "https://uca.wo116114.com/sjgj/unicomAssistant/uasp/configs/v1/weeklySwitchStatus?product_line=uasp&entry_point=h5&entry_point_id=wxdefbc1986dc757a6",
|
||
"headers": { "auth-sa-token": this.sec_token, "clientType": "uasp_unicom_applet" },
|
||
"json": { "productId": "91311616" }
|
||
};
|
||
await this.request(requestOptions);
|
||
}
|
||
|
||
async queryKeyData_sec() {
|
||
let requestOptions = {
|
||
"fn": "queryKeyData_sec",
|
||
"method": "post",
|
||
"url": "https://uca.wo116114.com/sjgj/unicomAssistant/uasp/report/v1/queryKeyData?product_line=uasp&entry_point=h5&entry_point_id=wxdefbc1986dc757a6",
|
||
"headers": { "auth-sa-token": this.sec_token, "clientType": "uasp_unicom_applet" },
|
||
"json": { "productId": "91311616" }
|
||
};
|
||
await this.request(requestOptions);
|
||
}
|
||
|
||
async viewWeeklySummary_sec() {
|
||
let requestOptions = {
|
||
"fn": "viewWeeklySummary_sec",
|
||
"method": "post",
|
||
"url": "https://uca.wo116114.com/sjgj/unicomAssistant/uasp/report/v1/weeklySummary?product_line=uasp&entry_point=h5&entry_point_id=wxdefbc1986dc757a6",
|
||
"headers": { "auth-sa-token": this.sec_token, "clientType": "uasp_unicom_applet" },
|
||
"json": { "productId": "91311616" }
|
||
};
|
||
await this.request(requestOptions);
|
||
this.log("安全管家: 执行查看周报。");
|
||
}
|
||
|
||
async receivePoints_sec(taskCode) {
|
||
let requestOptions = {
|
||
"fn": "receivePoints_sec",
|
||
"method": "post",
|
||
"url": "https://m.jf.10010.com/jf-external-application/jftask/receive",
|
||
"headers": {
|
||
"ticket": decodeURIComponent(this.sec_ticket),
|
||
"Cookie": `_jea_id=${this.sec_jeaId}`,
|
||
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 unicom{version:iphone_c@12.0301};ltst;OSVersion/16.6",
|
||
"partnersid": "1702",
|
||
"clienttype": "uasp_unicom_applet",
|
||
},
|
||
"json": { "taskCode": taskCode }
|
||
};
|
||
let { result } = await this.request(requestOptions);
|
||
if (result && result.data && result.data.score) {
|
||
this.log(`安全管家: ✅ 领取积分成功: +${result.data.score} (${result.msg})`);
|
||
} else if (result) {
|
||
this.log(`安全管家: ❌ 领取积分失败: ${result.msg}`);
|
||
} else {
|
||
this.log("安全管家: ❌ 领取积分API无响应");
|
||
}
|
||
}
|
||
|
||
async finishTask_sec(taskCode, taskName) {
|
||
let requestOptions = {
|
||
"fn": `finishTask_sec_${taskName}`,
|
||
"method": "post",
|
||
"url": "https://m.jf.10010.com/jf-external-application/jftask/toFinish",
|
||
"headers": {
|
||
"ticket": decodeURIComponent(this.sec_ticket),
|
||
"Cookie": `_jea_id=${this.sec_jeaId}`,
|
||
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 unicom{version:iphone_c@12.0301};ltst;OSVersion/16.6",
|
||
"partnersid": "1702",
|
||
"clienttype": "uasp_unicom_applet",
|
||
},
|
||
"json": { "taskCode": taskCode }
|
||
};
|
||
await this.request(requestOptions);
|
||
this.log(`安全管家: 开启任务 [${taskName}]`);
|
||
|
||
switch (taskName) {
|
||
case "联通助理-添加黑名单":
|
||
await this.addToBlacklist_sec();
|
||
break;
|
||
case "联通助理-号码标记":
|
||
await this.markPhoneNumber_sec();
|
||
break;
|
||
case "联通助理-同步通讯录":
|
||
await this.syncAddressBook_sec();
|
||
break;
|
||
case "联通助理-骚扰拦截设置":
|
||
await this.setInterceptionRules_sec();
|
||
break;
|
||
case "联通助理-查看周报":
|
||
await this.viewWeeklyStatus_sec();
|
||
await this.queryKeyData_sec();
|
||
await this.viewWeeklySummary_sec();
|
||
break;
|
||
default:
|
||
// No action needed as filtering is done upstream
|
||
break;
|
||
}
|
||
}
|
||
|
||
async signIn_sec(taskCode) {
|
||
let requestOptions = {
|
||
"fn": "signIn_sec",
|
||
"method": "post",
|
||
"url": "https://m.jf.10010.com/jf-external-application/jftask/sign",
|
||
"headers": {
|
||
"ticket": decodeURIComponent(this.sec_ticket),
|
||
"Cookie": `_jea_id=${this.sec_jeaId}`,
|
||
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 unicom{version:iphone_c@12.0301};ltst;OSVersion/16.6",
|
||
"partnersid": "1702",
|
||
"clienttype": "uasp_unicom_applet",
|
||
},
|
||
"json": { "taskCode": taskCode }
|
||
};
|
||
let { result } = await this.request(requestOptions);
|
||
this.log(`安全管家: 完成签到: ${result?.msg || '状态未知'}`);
|
||
}
|
||
|
||
async executeAllTasks_sec() {
|
||
let requestOptions = {
|
||
"fn": "executeAllTasks_sec",
|
||
"method": "post",
|
||
"url": "https://m.jf.10010.com/jf-external-application/jftask/taskDetail",
|
||
"headers": {
|
||
"ticket": decodeURIComponent(this.sec_ticket),
|
||
"Cookie": `_jea_id=${this.sec_jeaId}`,
|
||
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 unicom{version:iphone_c@12.0301};ltst;OSVersion/16.6",
|
||
"partnersid": "1702",
|
||
"clienttype": "uasp_unicom_applet",
|
||
},
|
||
"json": {}
|
||
};
|
||
|
||
let { result } = await this.request(requestOptions);
|
||
if (!result || !result.data || !result.data.taskDetail) {
|
||
this.log("安全管家: 查询任务列表失败或响应格式错误。");
|
||
return;
|
||
}
|
||
|
||
const taskList = result.data.taskDetail.taskList;
|
||
const executableTaskNames = [
|
||
"联通助理-添加黑名单",
|
||
"联通助理-号码标记",
|
||
"联通助理-同步通讯录",
|
||
"联通助理-骚扰拦截设置",
|
||
"联通助理-查看周报"
|
||
];
|
||
|
||
const executableTasks = [];
|
||
const skippedTasks = [];
|
||
|
||
for (const task of taskList) {
|
||
const isKnownExecutable = executableTaskNames.includes(task.taskName) || task.taskName.includes("签到");
|
||
if (isKnownExecutable) {
|
||
executableTasks.push(task);
|
||
} else {
|
||
skippedTasks.push(task);
|
||
}
|
||
}
|
||
|
||
const unfinishedSkipped = skippedTasks.filter(t => t.finishCount !== t.needCount);
|
||
if (unfinishedSkipped.length > 0) {
|
||
const skippedTaskNames = unfinishedSkipped.map(t => `[${t.taskName}]`).join(', ');
|
||
this.log(`安全管家: 跳过: ${skippedTaskNames}`);
|
||
}
|
||
|
||
for (const task of executableTasks) {
|
||
const { taskCode, taskName, finishCount, needCount, finishText } = task;
|
||
this.log(`安全管家: [${taskName}]: ${finishCount}/${needCount} - ${finishText}`);
|
||
|
||
if (finishCount !== needCount) {
|
||
const remainingCount = needCount - finishCount;
|
||
this.log(`安全管家: 任务未完成,需要再执行 ${remainingCount} 次`);
|
||
|
||
for (let i = 0; i < remainingCount; i++) {
|
||
await appName.wait(3000);
|
||
try {
|
||
if (taskName.includes("签到")) {
|
||
await this.signIn_sec(taskCode);
|
||
} else {
|
||
await this.finishTask_sec(taskCode, taskName);
|
||
}
|
||
|
||
if (!taskName.includes("签到")) {
|
||
await appName.wait(10000);
|
||
await this.receivePoints_sec(taskCode);
|
||
} else {
|
||
await this.receivePoints_sec(taskCode);
|
||
break;
|
||
}
|
||
} catch (error) {
|
||
this.log(`安全管家: 执行 ${taskCode} 时出错: ${error.message}`);
|
||
break;
|
||
}
|
||
}
|
||
} else if (finishText === "待领取") {
|
||
try {
|
||
await appName.wait(3000);
|
||
await this.receivePoints_sec(taskCode);
|
||
} catch (error) {
|
||
this.log(`安全管家: 领取 ${taskCode} 奖励时出错: ${error.message}`);
|
||
}
|
||
} else {
|
||
this.log(`安全管家: [${taskName}] 任务已完成且奖励已领取`);
|
||
}
|
||
this.log("安全管家: ---------------------");
|
||
}
|
||
}
|
||
|
||
async getUserInfo_sec() {
|
||
let requestOptions = {
|
||
"fn": "getUserInfo_sec",
|
||
"method": "post",
|
||
"url": "https://m.jf.10010.com/jf-external-application/jftask/userInfo",
|
||
"headers": {
|
||
"ticket": decodeURIComponent(this.sec_ticket),
|
||
"Cookie": `_jea_id=${this.sec_jeaId}`,
|
||
"User-Agent": "Mozilla/5.0 (Linux; Android 9; ONEPLUS A5000 Build/PKQ1.180716.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/138.0.7204.179 Mobile Safari/537.36; unicom{version:android@11.0000,desmobile:0};devicetype{deviceBrand:OnePlus,deviceModel:ONEPLUS A5000}",
|
||
"partnersid": "1702",
|
||
"clienttype": "uasp_unicom_applet",
|
||
},
|
||
"json": {}
|
||
};
|
||
|
||
let { result } = await this.request(requestOptions);
|
||
if (!result || result.code !== '0000' || !result.data || result.data.availableScore === undefined) {
|
||
this.log(`安全管家: 查询积分失败或响应格式错误。错误信息: ${result ? result.msg : '无响应'}`);
|
||
return;
|
||
}
|
||
|
||
const currentPoints = parseInt(result.data.availableScore, 10);
|
||
const todayPoints = result.data.todayEarnScore;
|
||
|
||
if (this.sec_oldJFPoints === null) {
|
||
this.sec_oldJFPoints = currentPoints;
|
||
this.log(`安全管家: 运行前积分:${currentPoints} (今日已赚 ${todayPoints})`);
|
||
} else {
|
||
if (isNaN(currentPoints) || isNaN(this.sec_oldJFPoints)) {
|
||
this.log(`安全管家: 警告:积分值无法转换为数字进行计算。`);
|
||
this.log(`安全管家: 运行后可用积分: ${result.data.availableScore}`, { notify: true });
|
||
} else {
|
||
const pointsGained = currentPoints - this.sec_oldJFPoints;
|
||
this.log(`安全管家: 运行后积分${currentPoints},本次运行获得${pointsGained}`, { notify: true });
|
||
}
|
||
}
|
||
}
|
||
|
||
// 联通云盘任务
|
||
async ltyp_task() {
|
||
try {
|
||
this.log("============= 联通云盘任务 =============");
|
||
this.cloudDisk = {}; // Reset state for this run
|
||
this.cloudDiskUrls = {
|
||
'onLine': "https://m.client.10010.com/mobileService/onLine.htm",
|
||
'getTicketByNative': "https://m.client.10010.com/edop_ng/getTicketByNative",
|
||
'userticket': "https://panservice.mail.wo.cn/api-user/api/user/ticket",
|
||
'ltypDispatcher': "https://panservice.mail.wo.cn/wohome/dispatcher",
|
||
'query': "https://m.jf.10010.com/jf-external-application/page/query",
|
||
'taskDetail': "https://m.jf.10010.com/jf-external-application/jftask/taskDetail",
|
||
'dosign': "https://m.jf.10010.com/jf-external-application/jftask/sign",
|
||
'doUpload': "https://b.smartont.net/openapi/transfer/quickTransfer",
|
||
'doPopUp': "https://m.jf.10010.com/jf-external-application/jftask/popUp",
|
||
'toFinish': "https://m.jf.10010.com/jf-external-application/jftask/toFinish",
|
||
'lottery': "https://panservice.mail.wo.cn/activity/lottery",
|
||
'activityList': "https://panservice.mail.wo.cn/activity/v1/activityList",
|
||
'userInfo': "https://m.jf.10010.com/jf-external-application/jftask/userInfo",
|
||
'ai_query': "https://panservice.mail.wo.cn/wohome/ai/assistant/query",
|
||
'lottery_times': "https://panservice.mail.wo.cn/activity/lottery/lottery-times",
|
||
};
|
||
|
||
if (!this.ecs_token || !this.mobile) {
|
||
this.log("云盘任务: 缺少 ecs_token 或 mobile,跳过。");
|
||
return;
|
||
}
|
||
|
||
const ticket = await this.getTicketByNative_cloud();
|
||
if (!ticket) {
|
||
this.log("云盘任务: 获取ticket失败,跳过。");
|
||
return;
|
||
}
|
||
|
||
const token = await this.get_ltypDispatcher_cloud(ticket);
|
||
if (!token) {
|
||
this.log("云盘任务: 获取token失败,跳过。");
|
||
return;
|
||
}
|
||
|
||
await appName.wait(500);
|
||
await this.get_userInfo_cloud(); // Initial points
|
||
await appName.wait(500);
|
||
await this.get_taskDetail_cloud();
|
||
|
||
const got_chance = await this.do_ai_query_for_lottery_cloud();
|
||
if (got_chance) {
|
||
await appName.wait(5000);
|
||
let times = await this.check_lottery_times_cloud();
|
||
if (times > 0) {
|
||
for (let i = 0; i < times; i++) {
|
||
this.log(`云盘第 ${i + 1}/${times} 次执行抽奖...`);
|
||
await this.get_ltyplottery_cloud('MjI=');
|
||
await appName.wait(5000);
|
||
}
|
||
}
|
||
}
|
||
|
||
await appName.wait(500);
|
||
await this.get_userInfo_cloud(); // Final points
|
||
|
||
} catch (e) {
|
||
this.log(`云盘任务: 出现错误: ${e.message}`);
|
||
console.log(e);
|
||
}
|
||
}
|
||
|
||
encrypt_data_cloud(data, key, iv = "wNSOYIB1k1DjY5lA") {
|
||
if (typeof data === 'object') {
|
||
data = JSON.stringify(data);
|
||
}
|
||
const keyHex = cryptoJS.enc.Utf8.parse(key.slice(0, 16));
|
||
const ivHex = cryptoJS.enc.Utf8.parse(iv);
|
||
const encrypted = cryptoJS.AES.encrypt(data, keyHex, {
|
||
iv: ivHex,
|
||
mode: cryptoJS.mode.CBC,
|
||
padding: cryptoJS.pad.Pkcs7
|
||
});
|
||
return encrypted.toString();
|
||
}
|
||
|
||
async getTicketByNative_cloud() {
|
||
let requestOptions = {
|
||
fn: "getTicketByNative_cloud",
|
||
method: 'get',
|
||
url: `${this.cloudDiskUrls.getTicketByNative}?appId=edop_unicom_d67b3e30&token=${this.ecs_token}`,
|
||
headers: {
|
||
'User-Agent': "Dalvik/2.1.0 (Linux; U; Android 12; leijun Pro Build/SKQ1.22013.001);unicom{version:android@11.0702}",
|
||
'Connection': "Keep-Alive",
|
||
'Accept-Encoding': "gzip",
|
||
}
|
||
};
|
||
let { result } = await this.request(requestOptions);
|
||
if (result?.ticket) {
|
||
this.cloudDisk.ticket = result.ticket;
|
||
return result.ticket;
|
||
}
|
||
return null;
|
||
}
|
||
|
||
async get_ltypDispatcher_cloud(ticket) {
|
||
const timestamp = Date.now().toString();
|
||
const result = Math.floor(Math.random() * (199999 - 123456 + 1)) + 123456;
|
||
const string_to_hash = "HandheldHallAutoLoginV2" + timestamp + result + "wohome";
|
||
const md5Hash = cryptoJS.MD5(string_to_hash).toString();
|
||
|
||
const payload = {
|
||
"header": {
|
||
"key": "HandheldHallAutoLoginV2",
|
||
"resTime": timestamp,
|
||
"reqSeq": result,
|
||
"channel": "wohome",
|
||
"version": "",
|
||
"sign": md5Hash
|
||
},
|
||
"body": {
|
||
"clientId": "1001000003",
|
||
"ticket": ticket
|
||
}
|
||
};
|
||
|
||
let requestOptions = {
|
||
fn: "get_ltypDispatcher_cloud",
|
||
method: 'post',
|
||
url: this.cloudDiskUrls.ltypDispatcher,
|
||
json: payload,
|
||
headers: {
|
||
'User-Agent': "Dalvik/2.1.0 (Linux; U; Android 12; leijun Pro Build/SKQ1.22013.001);unicom{version:android@11.0702}"
|
||
}
|
||
};
|
||
|
||
let { result: res } = await this.request(requestOptions);
|
||
const token = res?.RSP?.DATA?.token;
|
||
if (token) {
|
||
this.cloudDisk.userToken = token;
|
||
return token;
|
||
}
|
||
this.log(`云盘任务: 获取token失败: ${JSON.stringify(res)}`);
|
||
return null;
|
||
}
|
||
|
||
async get_userticket_cloud(is_changer = false) {
|
||
if (!this.cloudDisk.userToken) {
|
||
this.log("云盘任务: 获取userticket失败, userToken未获取");
|
||
return null;
|
||
}
|
||
|
||
let headers = {};
|
||
if (is_changer) {
|
||
headers = {
|
||
'User-Agent': "LianTongYunPan/4.0.4 (Android 12)",
|
||
'app-type': "liantongyunpanapp",
|
||
'Client-Id': "1001000035",
|
||
'App-Version': "yp-app/4.0.4",
|
||
'Sys-Version': "Android/12",
|
||
'X-YP-Client-Id': "1001000035",
|
||
'X-YP-Access-Token': this.cloudDisk.userToken,
|
||
};
|
||
} else {
|
||
headers = {
|
||
'User-Agent': "Dalvik/2.1.0 (Linux; U; Android 12; leijun Pro Build/SKQ1.22013.001);unicom{version:android@11.0702}",
|
||
'Content-Type': 'application/json',
|
||
'X-YP-Access-Token': this.cloudDisk.userToken,
|
||
'accesstoken': this.cloudDisk.userToken,
|
||
'token': this.cloudDisk.userToken,
|
||
'clientId': "1001000003",
|
||
'X-YP-Client-Id': "1001000003",
|
||
'source-type': "woapi",
|
||
'app-type': "unicom"
|
||
};
|
||
}
|
||
|
||
let requestOptions = {
|
||
fn: "get_userticket_cloud",
|
||
method: 'post',
|
||
url: this.cloudDiskUrls.userticket,
|
||
json: {},
|
||
headers: headers
|
||
};
|
||
|
||
let { result: res } = await this.request(requestOptions);
|
||
const ticket = res?.result?.ticket;
|
||
if (ticket) {
|
||
this.cloudDisk.userticket = ticket;
|
||
await appName.wait(1000);
|
||
return ticket;
|
||
}
|
||
this.log(`云盘任务: 获取userticket失败: ${JSON.stringify(res)}`);
|
||
return null;
|
||
}
|
||
|
||
async get_userInfo_cloud() {
|
||
if (!await this.get_userticket_cloud(false)) return;
|
||
|
||
let { result: res, headers } = await this.cloudRequest('userInfo', {}, false, 'post');
|
||
|
||
const setCookieHeader = headers?.["set-cookie"];
|
||
if (setCookieHeader) {
|
||
const cookies = Array.isArray(setCookieHeader) ? setCookieHeader : [setCookieHeader];
|
||
const jeaCookie = cookies.find(cookie => cookie && cookie.startsWith("_jea_id="));
|
||
if (jeaCookie) {
|
||
this.cloudDisk.jeaId = jeaCookie.split(";")[0].split("=")[1];
|
||
}
|
||
}
|
||
|
||
if (res?.data?.availableScore) {
|
||
const availableScore = res.data.availableScore;
|
||
const allEarnScore = res.data.allEarnScore;
|
||
if (this.cloudDisk.initial_score === undefined) {
|
||
this.cloudDisk.initial_score = parseInt(allEarnScore, 10);
|
||
this.log(`云盘任务: 运行前 - 已赚积分: ${allEarnScore}, 可用积分: ${availableScore}`);
|
||
} else {
|
||
const earned_this_run = parseInt(allEarnScore, 10) - this.cloudDisk.initial_score;
|
||
this.log(`云盘任务: 运行后 - 已赚: ${allEarnScore}, 可用: ${availableScore}, 本次获得: ${earned_this_run}积分`, { notify: true });
|
||
}
|
||
} else {
|
||
this.log(`云盘任务: 获取用户信息失败: ${JSON.stringify(res)}`);
|
||
}
|
||
}
|
||
|
||
async get_taskDetail_cloud() {
|
||
if (!await this.get_userticket_cloud(false)) return;
|
||
|
||
let { result: res } = await this.cloudRequest('taskDetail', {}, false, 'post');
|
||
if (res?.data?.taskDetail?.taskList) {
|
||
const taskList = res.data.taskDetail.taskList;
|
||
const taskNameList = ["浏览活动中心", "分享文件", "签到", "与AI通通互动", "打开相册自动备份"];
|
||
for (const task of taskList) {
|
||
await appName.wait(500);
|
||
if (task.finishText === "未完成" && taskNameList.some(name => task.taskName.includes(name))) {
|
||
this.log(`云盘任务: 开始执行 [${task.taskName}]`);
|
||
if (task.taskName.includes("浏览活动中心")) {
|
||
await this.toFinish_cloud(task.taskCode, task.taskName, true);
|
||
await this.activityList_cloud(task.taskCode, task.taskName);
|
||
} else if (task.taskName.includes("分享文件")) {
|
||
await this.toFinish_cloud(task.taskCode, task.taskName, false);
|
||
await this.get_ShareFileDispatcher_cloud(task.taskCode, task.taskName);
|
||
} else if (task.taskName.includes("签到")) {
|
||
await this.toFinish_cloud(task.taskCode, task.taskName, false);
|
||
await this.dosign_cloud(task.taskCode, task.taskName);
|
||
} else if (task.taskName.includes("与AI通通互动")) {
|
||
await this.toFinish_cloud(task.taskCode, task.taskName, false);
|
||
await this.do_ai_interaction_cloud(task.taskCode, task.taskName);
|
||
} else if (task.taskName.includes("打开相册自动备份")) {
|
||
await this.toFinish_cloud(task.taskCode, task.taskName, false);
|
||
|
||
// Action to simulate opening the album backup page
|
||
if (!await this.get_userticket_cloud(true)) return;
|
||
const payload = { "bizKey": "activityCenterPipeline", "bizObject": { "pageNo": 1 } };
|
||
let { result: res } = await this.cloudRequest('activityList', payload, true);
|
||
if (res?.meta?.code === 0 || res?.meta?.code === "0") {
|
||
this.log(`云盘任务: ✅ [${task.taskName}] 打开成功`);
|
||
await appName.wait(2000);
|
||
} else {
|
||
this.log(`云盘任务: ❌ [${task.taskName}] 打开失败: ${JSON.stringify(res)}`);
|
||
}
|
||
}
|
||
}
|
||
if (task.finishText === "未完成" && task.taskNameSubtitle && task.taskName.includes("手动上传文件")) {
|
||
this.log(`云盘任务: 开始执行 [${task.taskName}]`);
|
||
await this.toFinish_cloud(task.taskCode, task.taskName, false);
|
||
const subtitle = task.taskNameSubtitle;
|
||
const [current_count_str, target_count_str] = subtitle.replace(/[()]/g, "").split("/");
|
||
let current_count = parseInt(current_count_str, 10);
|
||
let target_count = parseInt(target_count_str, 10);
|
||
if (current_count < target_count) {
|
||
const remaining_times = target_count - current_count;
|
||
this.log(`云盘任务: [${task.taskName}] 需 ${remaining_times} 次`);
|
||
for (let i = 0; i < remaining_times; i++) {
|
||
if(await this.doUpload_cloud(task.taskCode, task.taskName)) {
|
||
this.log(`云盘任务: [${task.taskName}] 第 ${current_count + i + 1} 次上传完成`);
|
||
await appName.wait(500);
|
||
} else {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
this.log(`云盘任务: 获取任务列表失败: ${JSON.stringify(res)}`);
|
||
}
|
||
}
|
||
|
||
async cloudRequest(url_name, payload, is_changer = false, method = 'post') {
|
||
const url = this.cloudDiskUrls[url_name];
|
||
if (!url) {
|
||
this.log(`云盘无效的URL名称: ${url_name}`);
|
||
return { result: null, headers: null };
|
||
}
|
||
|
||
let headers = {
|
||
'User-Agent': "Dalvik/2.1.0 (Linux; U; Android 12; leijun Pro Build/SKQ1.22013.001);unicom{version:android@11.0702}",
|
||
'Connection': "Keep-Alive",
|
||
'Accept-Encoding': "gzip",
|
||
};
|
||
|
||
if (['dosign', 'userInfo', 'doPopUp', 'toFinish', 'taskDetail'].includes(url_name)) {
|
||
if (!this.cloudDisk.userticket) {
|
||
this.log(`云盘 [${url_name}] userticket 未获取`);
|
||
return { result: null, headers: null };
|
||
}
|
||
headers['ticket'] = this.cloudDisk.userticket;
|
||
headers['content-type'] = "application/json;charset=UTF-8";
|
||
headers['partnersid'] = "1649";
|
||
headers['origin'] = "https://m.jf.10010.com";
|
||
if (this.cloudDisk.jeaId) headers['Cookie'] = `_jea_id=${this.cloudDisk.jeaId}`;
|
||
|
||
if (is_changer) {
|
||
headers['clienttype'] = "yunpan_unicom_applet";
|
||
headers['x-requested-with'] = "com.sinovatech.unicom.ui";
|
||
if (url_name === 'toFinish') {
|
||
headers['User-Agent'] = "Mozilla/5.0 (Linux; Android 12; Redmi K30 Pro Build/SKQ1.220303.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/131.0.6778.39 Mobile Safari/537.36/woapp LianTongYunPan/4.0.4 (Android 12)";
|
||
headers['clienttype'] = "yunpan_android";
|
||
headers['x-requested-with'] = "com.chinaunicom.bol.cloudapp";
|
||
}
|
||
} else {
|
||
headers['clienttype'] = "yunpan_android";
|
||
headers['x-requested-with'] = "com.sinovatech.unicom.ui";
|
||
}
|
||
} else if (url_name === 'activityList') {
|
||
headers = {
|
||
'User-Agent': "Mozilla/5.0 (Linux; Android 12; Redmi K30 Pro Build/SKQ1.220303.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/131.0.6778.39 Mobile Safari/537.36/woapp LianTongYunPan/4.0.4 (Android 12)",
|
||
'Accept': "application/json, text/plain, */*",
|
||
'Accept-Encoding': "gzip, deflate, br, zstd",
|
||
'Content-Type': "application/json",
|
||
'credentials': "include",
|
||
'sec-ch-ua-platform': '"Android"',
|
||
'sec-ch-ua': '"Android WebView";v="131", "Chromium";v="131", "Not_A Brand";v="24"',
|
||
'sec-ch-ua-mobile': "?1",
|
||
'Client-Id': "1001000035",
|
||
'App-Version': "yp-app/4.0.4",
|
||
'Access-Token': this.cloudDisk.userToken,
|
||
'Sys-Version': "android/12",
|
||
'Origin': "https://panservice.mail.wo.cn",
|
||
'X-Requested-With': "com.chinaunicom.bol.cloudapp",
|
||
'Sec-Fetch-Site': "same-origin",
|
||
'Sec-Fetch-Mode': "cors",
|
||
'Sec-Fetch-Dest': "empty",
|
||
'Referer': "https://panservice.mail.wo.cn/h5/mobile/wocloud/activityCenter/home",
|
||
'Accept-Language': "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7"
|
||
};
|
||
} else if (url_name === 'doUpload') {
|
||
headers = {
|
||
'User-Agent': "okhttp-okgo/jeasonlzy LianTongYunPan/4.0.4 (Android 12)", 'client-Id': "1001000035",
|
||
'app-version': "yp-app/4.0.4", 'access-token': this.cloudDisk.userToken, 'Content-Type': "application/json;charset=utf-8"
|
||
};
|
||
} else if (url_name === 'ai_query') {
|
||
const model_id = payload.modelId || 1;
|
||
headers = {
|
||
'accept': 'text/event-stream',
|
||
'X-YP-Access-Token': this.cloudDisk.userToken,
|
||
'X-YP-App-Version': '5.0.12',
|
||
'X-YP-Client-Id': '1001000035',
|
||
'User-Agent': 'Mozilla/5.0 (Linux; Android 9; SM-N9810 Build/PQ3A.190705.11211540; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/91.0.4472.114 Mobile Safari/537.36/woapp LianTongYunPan/5.0.12 (Android 9)',
|
||
'Content-Type': 'application/json',
|
||
'Origin': 'https://panservice.mail.wo.cn',
|
||
'X-Requested-With': 'com.chinaunicom.bol.cloudapp',
|
||
'Referer': `https://panservice.mail.wo.cn/h5/wocloud_ai/?modelType=${model_id}&clientId=1001000035&touchpoint=300300010001&token=${this.cloudDisk.userToken}`,
|
||
};
|
||
} else if (url_name === 'lottery_times') {
|
||
method = 'get';
|
||
payload = { activityId: 'MjI=' };
|
||
headers = {
|
||
'X-YP-Access-Token': this.cloudDisk.userToken, 'source-type': 'woapi', 'clientId': '1001000165',
|
||
'token': this.cloudDisk.userToken, 'X-YP-Client-Id': '1001000165',
|
||
};
|
||
} else if (url_name === 'lottery') {
|
||
const activity_id_b64 = payload.activityId || '';
|
||
const activity_id_b64_encoded = encodeURIComponent(activity_id_b64);
|
||
headers = {
|
||
'User-Agent': 'Mozilla/5.0 (Linux; Android 9; SM-N9810 Build/PQ3A.190705.11211540; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/91.0.4472.114 Mobile Safari/537.36/woapp LianTongYunPan/5.0.12 (Android 9)',
|
||
'Accept': 'application/json, text/plain, */*',
|
||
'Content-Type': 'application/json',
|
||
'X-Requested-With': 'com.chinaunicom.bol.cloudapp',
|
||
'requesttime': Date.now().toString(),
|
||
'clientid': '1001000165',
|
||
'x-yp-client-id': '1001000165',
|
||
'source-type': 'woapi',
|
||
'x-yp-access-token': this.cloudDisk.userToken,
|
||
'token': this.cloudDisk.userToken,
|
||
'origin': 'https://panservice.mail.wo.cn',
|
||
'Referer': `https://panservice.mail.wo.cn/h5/activitymobile/blindBox?activityId=${activity_id_b64_encoded}&touchpoint=300300010001&clientId=1001000035&token=${this.cloudDisk.userToken}`,
|
||
};
|
||
}
|
||
|
||
let requestOptions = {
|
||
fn: `cloud_${url_name}`, method: method,
|
||
url: method === 'get' ? `${url}?${new URLSearchParams(payload)}` : url,
|
||
headers: headers,
|
||
};
|
||
|
||
if (method === 'post') {
|
||
requestOptions.json = payload;
|
||
}
|
||
|
||
if (url_name === 'ai_query') {
|
||
const { result, headers } = await this.request(requestOptions);
|
||
// The raw body is in `result` for text/event-stream. Return it as `body`.
|
||
return { result: null, body: result, headers: headers };
|
||
}
|
||
|
||
let { result, headers: resHeaders } = await this.request(requestOptions);
|
||
return { result, headers: resHeaders };
|
||
}
|
||
|
||
async dosign_cloud(taskcode, taskName) {
|
||
if (!await this.get_userticket_cloud(false)) return;
|
||
const payload = { "taskCode": taskcode };
|
||
|
||
let { result: res } = await this.cloudRequest('dosign', payload, false);
|
||
|
||
if (res?.code?.includes('0000') && res?.data?.score) {
|
||
this.log(`云盘任务: ✅ [${taskName}] 完成, 获得积分: ${res.data.score}`);
|
||
} else {
|
||
this.log(`云盘任务: ❌ [${taskName}] 失败: ${JSON.stringify(res)}`);
|
||
}
|
||
}
|
||
|
||
async toFinish_cloud(taskcode, taskName, is_changer) {
|
||
if (!await this.get_userticket_cloud(is_changer)) return null;
|
||
const payload = { "taskCode": taskcode };
|
||
|
||
let { result: res } = await this.cloudRequest('toFinish', payload, is_changer);
|
||
|
||
if (res?.code === "0000") return true;
|
||
this.log(`云盘任务: ❌ [${taskName}] toFinish失败: ${JSON.stringify(res)}`);
|
||
return false;
|
||
}
|
||
|
||
async doUpload_cloud(taskcode, taskName) {
|
||
if (!await this.get_userticket_cloud(false)) return;
|
||
const payload = {
|
||
"batchNo": "D94628B6C8593D2C6A4B52D0A5F009F4", "deviceId": "", "directoryId": "0", "familyId": 0,
|
||
"fileModificationTime": 1736861613000, "fileName": "mmexport1736861613242.jpg", "fileSize": "280800",
|
||
"fileType": "1", "height": "1174", "lat": "", "lng": "", "psToken": "",
|
||
"sha256": "9c75f5be16bbb4e17788180dfdf4b1d53ba590cb8f4c629e4b337f5f54565949",
|
||
"spaceType": "0", "width": "986"
|
||
};
|
||
|
||
let { result: res } = await this.cloudRequest('doUpload', payload, false);
|
||
|
||
if (res?.meta?.code === "0000") {
|
||
await appName.wait(1000);
|
||
return await this.doPopUp_cloud(taskcode, taskName, false);
|
||
}
|
||
this.log(`云盘任务: ❌ [${taskName}] 上传失败: ${JSON.stringify(res)}`);
|
||
return false;
|
||
}
|
||
|
||
async activityList_cloud(taskcode, taskName) {
|
||
if (!await this.get_userticket_cloud(true)) return;
|
||
const payload = { "bizKey": "activityCenterPipeline", "bizObject": { "pageNo": 1 } };
|
||
|
||
let { result: res } = await this.cloudRequest('activityList', payload, true);
|
||
|
||
if (res?.meta?.code === 0 || res?.meta?.code === "0") {
|
||
await appName.wait(2000);
|
||
return await this.doPopUp_cloud(taskcode, taskName, true);
|
||
}
|
||
this.log(`云盘任务: ❌ [${taskName}] 浏览活动失败: ${JSON.stringify(res)}`);
|
||
return false;
|
||
}
|
||
|
||
async doPopUp_cloud(taskcode, taskName, is_changer) {
|
||
if (!await this.get_userticket_cloud(is_changer)) return;
|
||
const payload = {};
|
||
await appName.wait(5500);
|
||
|
||
let { result: res } = await this.cloudRequest('doPopUp', payload, is_changer);
|
||
|
||
if ((res?.meta?.code === "0000" || res?.meta?.code === 0) || (res?.code === "0000" || res?.code === 0)) {
|
||
const score = parseInt(res?.data?.score || "0", 10);
|
||
this.log(`云盘任务: ✅ [${taskName}] 完成, ${score > 0 ? `获得积分: ${score}` : '未获得积分'}`);
|
||
return true;
|
||
}
|
||
this.log(`云盘任务: ❌ [${taskName}] 领取奖励失败: ${JSON.stringify(res)}`);
|
||
return false;
|
||
}
|
||
|
||
async get_ShareFileDispatcher_cloud(taskCode, taskName) {
|
||
const timestamp = Date.now().toString();
|
||
const randomSeq = Math.floor(Math.random() * (199999 - 123456 + 1)) + 123456;
|
||
const string_to_hash = "ShareFile" + timestamp + randomSeq + "wohome";
|
||
const md5Hash = cryptoJS.MD5(string_to_hash).toString();
|
||
|
||
const data = { "fileIds": "f89417024f2642a399fd33f2beebd7c2", "fileFolderIds": "", "days": 7, "clientId": "1001000003" };
|
||
const encrypted = this.encrypt_data_cloud(data, this.cloudDisk.userToken);
|
||
|
||
const payload = {
|
||
"header": { "key": "ShareFile", "resTime": timestamp, "reqSeq": randomSeq, "channel": "wohome", "version": "", "sign": md5Hash },
|
||
"body": { "clientId": "1001000003", "param": JSON.stringify(encrypted), "secret": true }
|
||
};
|
||
|
||
const headers = { 'client-id': "1001000174", 'x-yp-client-id': "1001000174" };
|
||
|
||
let { result: res } = await this.cloudRequest('ltypDispatcher', payload, false, 'post', headers);
|
||
|
||
if (res?.STATUS === "200" || res?.STATUS === 200) {
|
||
await this.doPopUp_cloud(taskCode, taskName, false);
|
||
} else {
|
||
this.log(`云盘任务: ❌ [${taskName}] 分享失败: ${JSON.stringify(res)}`);
|
||
}
|
||
}
|
||
|
||
async do_ai_interaction_cloud(taskCode, taskName) {
|
||
this.log("云盘任务: 执行AI通通查询请求...");
|
||
const payload = { "input": "Hi", "platform": 1, "modelId": 0, "tag": 0, "conversationId": "", "knowledgeId": "", "referFileInfo": [] };
|
||
|
||
let { body } = await this.cloudRequest('ai_query', payload, false, 'post');
|
||
|
||
if (body && body.includes('"finish":1')) {
|
||
this.log("云盘任务: AI通通查询请求成功");
|
||
return await this.doPopUp_cloud(taskCode, taskName, false);
|
||
}
|
||
this.log(`云盘任务: ❌ AI通通查询请求失败: ${body}`);
|
||
return false;
|
||
}
|
||
|
||
async do_ai_query_for_lottery_cloud() {
|
||
this.log("云盘任务: DeepSeek对话请求, 以获取抽奖资格...");
|
||
const payload = { "input": "Hi", "platform": 1, "modelId": 1, "tag": 0, "conversationId": "", "knowledgeId": "", "referFileInfo": [] };
|
||
|
||
let { body } = await this.cloudRequest('ai_query', payload, false, 'post');
|
||
|
||
if (body && body.includes('"finish":1')) {
|
||
this.log("云盘任务: DeepSeek对话请求成功");
|
||
return true;
|
||
} else {
|
||
this.log(`云盘任务: ❌ DeepSeek对话请求失败: ${body}`);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
async check_lottery_times_cloud() {
|
||
this.log("云盘任务: 正在查询抽奖次数...");
|
||
let { result: res } = await this.cloudRequest('lottery_times', {}, false, 'get');
|
||
if (res?.meta?.code === "200") {
|
||
const times = parseInt(res.result || "0", 10);
|
||
this.log(`云盘任务: 查询成功,剩余抽奖次数: ${times}`);
|
||
return times;
|
||
}
|
||
this.log(`云盘任务: ❌ 查询抽奖次数失败: ${JSON.stringify(res)}`);
|
||
return 0;
|
||
}
|
||
|
||
async get_ltyplottery_cloud(activityId_b64) {
|
||
const payload = {
|
||
"bizKey": "newLottery",
|
||
"activityId": activityId_b64,
|
||
"bizObject": { "lottery": { "activityId": activityId_b64, "type": 3 } }
|
||
};
|
||
|
||
let { result: res } = await this.cloudRequest('lottery', payload, false, 'post');
|
||
if (res?.meta?.code === '200' && res?.result?.prizeName) {
|
||
this.log(`云盘任务: ✅ 抽奖获得: ${res.result.prizeName}`);
|
||
return true;
|
||
}
|
||
this.log(`云盘任务: ❌ 抽奖失败: ${JSON.stringify(res)}`);
|
||
return false;
|
||
}
|
||
|
||
|
||
async sign_task() {
|
||
await this.sign_getTelephone({ isInitial: true });
|
||
await this.sign_getContinuous();
|
||
await this.sign_getTaskList();
|
||
await this.sign_getTelephone();
|
||
}
|
||
async ltcy_task() {
|
||
let targetUrl = "https://web.wostore.cn/web/flowGame/index.html?channelId=GAMELTAPP_90006&pushid=99",
|
||
{
|
||
ticket: ticket
|
||
} = await this.openPlatLineNew(targetUrl);
|
||
if (!ticket) {
|
||
return;
|
||
}
|
||
await this.game_login(ticket);
|
||
}
|
||
async ttlxj_task() {
|
||
this.rptId = "";
|
||
let targetUrl = "https://epay.10010.com/ci-mps-st-web/?webViewNavIsHidden=webViewNavIsHidden",
|
||
{
|
||
ticket: ticket,
|
||
type: type,
|
||
loc: location
|
||
} = await this.openPlatLineNew(targetUrl);
|
||
if (!ticket) {
|
||
return;
|
||
}
|
||
await this.ttlxj_authorize(ticket, type, location);
|
||
}
|
||
async epay_28_task() {
|
||
this.rptId = "";
|
||
let currentDay = new Date().getDate();
|
||
if (currentDay >= 26 && currentDay <= 28) {
|
||
await this.epay_28_authCheck();
|
||
if (appMonth_28_share.length) {
|
||
let randomShareCode = appName.randomList(appMonth_28_share);
|
||
await this.appMonth_28_bind(randomShareCode);
|
||
}
|
||
await this.appMonth_28_queryChance();
|
||
}
|
||
}
|
||
async draw_28_task() {
|
||
let currentDay = new Date().getDate();
|
||
currentDay == 28 && (await this.draw_28_queryChance());
|
||
}
|
||
async act_517_task() {
|
||
let startTime = new Date("2024-05-10 00:00:00"),
|
||
endTime = new Date("2024-06-09 00:00:00"),
|
||
currentTime = Date.now();
|
||
if (currentTime > startTime.getTime() && currentTime < endTime.getTime()) {
|
||
if (act_517_share.length) {
|
||
let randomShareCode = appName.randomList(act_517_share);
|
||
await this.act_517_bind(randomShareCode);
|
||
}
|
||
await this.act_517_userAccount();
|
||
}
|
||
}
|
||
async card_618_task() {
|
||
let startTime = new Date("2024-05-31 00:00:00"),
|
||
endTime = new Date("2024-06-21 00:00:00"),
|
||
currentTime = Date.now();
|
||
currentTime > startTime.getTime() && currentTime < endTime.getTime() && (this.rptId = "", await this.card_618_authCheck());
|
||
}
|
||
async flmf_task() {
|
||
if (this.city.filter(cityInfo => cityInfo.proCode == "091").length == 0) {
|
||
return;
|
||
}
|
||
let targetUrl = "https://weixin.linktech.hk/lv-web/handHall/autoLogin?actcode=welfareCenter",
|
||
{
|
||
loc: location
|
||
} = await this.openPlatLineNew(targetUrl);
|
||
if (!location) {
|
||
return;
|
||
}
|
||
await this.flmf_login(location);
|
||
}
|
||
|
||
async ltzf_task() {
|
||
let targetUrl = new URL("https://wocare.unisk.cn/mbh/getToken");
|
||
targetUrl.searchParams.append("channelType", serviceLife);
|
||
targetUrl.searchParams.append("homePage", "home");
|
||
targetUrl.searchParams.append("duanlianjieabc", "qAz2m");
|
||
let urlString = targetUrl.toString(),
|
||
{
|
||
ticket: ticket
|
||
} = await this.openPlatLineNew(urlString);
|
||
if (!ticket) {
|
||
return;
|
||
}
|
||
if (!(await this.wocare_getToken(ticket))) {
|
||
return;
|
||
}
|
||
for (let activity of wocareActivities) {
|
||
await this.wocare_getDrawTask(activity);
|
||
await this.wocare_loadInit(activity);
|
||
}
|
||
}
|
||
|
||
// 重写后的联通阅读任务入口
|
||
async woread_task() {
|
||
this.log("============= 联通阅读 =============");
|
||
|
||
// 1. 登录 (woread_login 内部已经包含了 woread_auth)
|
||
if (!await this.woread_login()) {
|
||
this.log("阅读专区: 登录失败,跳过任务");
|
||
return;
|
||
}
|
||
|
||
// 2. 执行阅读 (对应 Python 的 read_novel)
|
||
await this.woread_read_process();
|
||
await appName.wait(3000);
|
||
|
||
// 3. 抽奖 (对应 Python 的 cj)
|
||
await this.woread_draw_new();
|
||
await appName.wait(3000);
|
||
|
||
// 4. 查询红包余额 (对应 query_red)
|
||
await this.woread_queryTicketAccount();
|
||
|
||
this.log("============= 联通阅读执行完毕 =============");
|
||
}
|
||
|
||
// 旧的挂机任务,已废弃
|
||
async woread_reading_task() { }
|
||
|
||
async userLoginTask() {
|
||
if (!(await this.onLine())) {
|
||
return;
|
||
}
|
||
return;
|
||
}
|
||
async userTask() {
|
||
// 修改日志标题,包含手机号
|
||
appName.log(`\n------------------ 账号[${this.index}][${maskStr(this.name)}] ------------------`);
|
||
// 在后续的日志中隐藏手机号
|
||
this.log = (message, options = {}) => super.log(message, { ...options, hideName: true });
|
||
if (!signDisabled) {
|
||
await this.sign_task();
|
||
}
|
||
await this.ttlxj_task();
|
||
if (!ltzfDisabled) {
|
||
await this.ltzf_task();
|
||
}
|
||
await this.marketTask();
|
||
// 添加新的联通阅读任务调用
|
||
await this.woread_task();
|
||
await this.securityButlerTask();
|
||
await this.ltyp_task();
|
||
}
|
||
async userTestTask() {
|
||
appName.log("\n------------------ 账号[" + this.index + "] ------------------");
|
||
}
|
||
}
|
||
!(async () => {
|
||
// Read environment variables and create user instances.
|
||
appName.read_env(CustomUserService);
|
||
|
||
// Log the current configuration status.
|
||
appName.log("\n------------------------------------");
|
||
appName.log("首页签到设置为: " + (signDisabled ? "不" : "") + "运行");
|
||
appName.log("联通祝福设置为: " + (ltzfDisabled ? "不" : "") + "运行");
|
||
appName.log("------------------------------------\n");
|
||
|
||
// Perform login tasks for all users.
|
||
for (let user of appName.userList) {
|
||
await user.userLoginTask();
|
||
}
|
||
|
||
// Execute main tasks for all valid users.
|
||
for (let validUser of appName.userList.filter(user => user.valid)) {
|
||
await validUser.userTask();
|
||
}
|
||
|
||
// 原有的 woread_reading_task 并发挂机逻辑已移除,
|
||
// 因为新版逻辑是简单的单次阅读心跳,已集成在 userTask -> woread_task 中顺序执行。
|
||
|
||
})().catch(error => appName.log(error)).finally(() => appName.exitNow());
|
||
|
||
|
||
function createLogger(UserClass) {
|
||
return new class {
|
||
constructor(name) {
|
||
this.name = name;
|
||
this.startTime = Date.now();
|
||
this.log("[" + this.name + "]开始运行\n", { time: true });
|
||
this.notifyStr = [];
|
||
this.notifyFlag = true;
|
||
this.userIdx = 0;
|
||
this.userList = [];
|
||
this.userCount = 0;
|
||
this.default_timestamp_len = 13;
|
||
this.default_wait_interval = 1000;
|
||
this.default_wait_limit = 3600000;
|
||
this.default_wait_ahead = 0;
|
||
}
|
||
log(message, options = {}) {
|
||
const defaultOptions = { console: true, ...options };
|
||
if (defaultOptions.time) {
|
||
let format = defaultOptions.fmt || "hh:mm:ss";
|
||
message = "[" + this.time(format) + "]" + message;
|
||
}
|
||
if (defaultOptions.notify) {
|
||
this.notifyStr.push(message);
|
||
}
|
||
if (defaultOptions.console) {
|
||
console.log(message);
|
||
}
|
||
}
|
||
get(object, key, defaultValue = "") {
|
||
return object?.hasOwnProperty(key) ? object[key] : defaultValue;
|
||
}
|
||
pop(object, key, defaultValue = "") {
|
||
if (object?.hasOwnProperty(key)) {
|
||
const value = object[key];
|
||
delete object[key];
|
||
return value;
|
||
}
|
||
return defaultValue;
|
||
}
|
||
copy(source) {
|
||
return { ...source };
|
||
}
|
||
read_env(UserClass) {
|
||
const envValues = cookieVars.map(varName => process.env[varName]);
|
||
for (const envValue of envValues.filter(value => !!value)) {
|
||
const delimitersFound = delimiters.filter(delimiter => envValue.includes(delimiter));
|
||
const delimiter = delimitersFound.length > 0 ? delimitersFound[0] : delimiters[0];
|
||
for (const userInfo of envValue.split(delimiter).filter(value => !!value)) {
|
||
this.userList.push(new UserClass(userInfo));
|
||
}
|
||
}
|
||
this.userCount = this.userList.length;
|
||
if (!this.userCount) {
|
||
this.log("未找到变量,请检查变量" + cookieVars.map(varName => "[" + varName + "]").join("或"), { notify: true });
|
||
return false;
|
||
}
|
||
this.log("共找到" + this.userCount + "个账号");
|
||
return true;
|
||
}
|
||
async threads(methodName, context, options = {}) {
|
||
while (context.idx < appName.userList.length) {
|
||
const user = appName.userList[context.idx++];
|
||
if (user.valid) {
|
||
await user[methodName](options);
|
||
}
|
||
}
|
||
}
|
||
async threadTask(methodName, count) {
|
||
const tasks = [];
|
||
const context = { idx: 0 };
|
||
while (count--) {
|
||
tasks.push(this.threads(methodName, context));
|
||
}
|
||
await Promise.all(tasks);
|
||
}
|
||
time(format, date = null) {
|
||
const currentDate = date ? new Date(date) : new Date();
|
||
const timeElements = {
|
||
"M+": currentDate.getMonth() + 1,
|
||
"d+": currentDate.getDate(),
|
||
"h+": currentDate.getHours(),
|
||
"m+": currentDate.getMinutes(),
|
||
"s+": currentDate.getSeconds(),
|
||
"q+": Math.floor((currentDate.getMonth() + 3) / 3),
|
||
S: this.padStr(currentDate.getMilliseconds(), 3)
|
||
};
|
||
if (/(y+)/.test(format)) {
|
||
format = format.replace(RegExp.$1, (currentDate.getFullYear() + "").substr(4 - RegExp.$1.length));
|
||
}
|
||
for (const key in timeElements) {
|
||
if (new RegExp("(" + key + ")").test(format)) {
|
||
format = format.replace(RegExp.$1, RegExp.$1.length === 1 ? timeElements[key] : ("00" + timeElements[key]).substr(("" + timeElements[key]).length));
|
||
}
|
||
}
|
||
return format;
|
||
}
|
||
async showmsg() {
|
||
let notifyBody = "";
|
||
// 遍历所有用户,聚合他们的通知日志
|
||
for (const user of this.userList) {
|
||
if (user.notifyLogs.length > 0) {
|
||
const userHeader = `------------------ 账号[${user.index}][${maskStr(user.name)}] ------------------`;
|
||
// 移除每条日志中的手机号前缀,因为标题中已经包含了
|
||
const userLogs = user.notifyLogs.map(log => log.replace(`[${user.name}]`, '')).join("\n");
|
||
notifyBody += `${userHeader}\n${userLogs}\n`;
|
||
}
|
||
}
|
||
|
||
if (this.notifyFlag && notifyBody) {
|
||
const notify = require("./sendNotify");
|
||
this.log("\n============== 推送 ==============");
|
||
await notify.sendNotify(this.name, notifyBody);
|
||
}
|
||
}
|
||
padStr(value, length, options = {}) {
|
||
const padding = options.padding || "0";
|
||
const mode = options.mode || "l";
|
||
let strValue = String(value);
|
||
const paddingLength = length > strValue.length ? length - strValue.length : 0;
|
||
const paddingStr = padding.repeat(paddingLength);
|
||
return mode === "r" ? strValue + paddingStr : paddingStr + strValue;
|
||
}
|
||
json2str(json, delimiter, encode = false) {
|
||
return Object.keys(json)
|
||
.sort()
|
||
.map(key => {
|
||
let value = json[key];
|
||
return `${key}=${encode && value ? encodeURIComponent(value) : value}`;
|
||
})
|
||
.join(delimiter);
|
||
}
|
||
str2json(str, decode = false) {
|
||
const json = {};
|
||
str.split("&").forEach(pair => {
|
||
if (pair) {
|
||
const [key, value] = pair.split("=");
|
||
json[key] = decode ? decodeURIComponent(value) : value;
|
||
}
|
||
});
|
||
return json;
|
||
}
|
||
randomPattern(pattern, charset = "abcdef0123456789") {
|
||
return pattern.split("").map(char => {
|
||
if (char === "x") {
|
||
return charset.charAt(Math.floor(Math.random() * charset.length));
|
||
} else if (char === "X") {
|
||
return charset.charAt(Math.floor(Math.random() * charset.length)).toUpperCase();
|
||
}
|
||
return char;
|
||
}).join("");
|
||
}
|
||
randomUuid() {
|
||
return appName.randomPattern("xxxxxxxx-xxxx-4xxx-4xxx-xxxxxxxxxxxx");
|
||
}
|
||
randomString(length, charset = "abcdef0123456789") {
|
||
return Array.from({ length }, () => charset.charAt(Math.floor(Math.random() * charset.length))).join("");
|
||
}
|
||
randomList(list) {
|
||
return list[Math.floor(Math.random() * list.length)];
|
||
}
|
||
wait(ms) {
|
||
return new Promise(resolve => setTimeout(resolve, ms));
|
||
}
|
||
async exitNow() {
|
||
await this.showmsg();
|
||
const endTime = Date.now();
|
||
const duration = (endTime - this.startTime) / 1000;
|
||
this.log("");
|
||
this.log("[" + this.name + "]运行结束,共运行了" + duration + "秒", { time: true });
|
||
process.exit(0);
|
||
}
|
||
normalize_time(time, options = {}) {
|
||
const length = options.len || this.default_timestamp_len;
|
||
time = time.toString();
|
||
while (time.length < length) {
|
||
time += "0";
|
||
}
|
||
return parseInt(time.slice(0, 13));
|
||
}
|
||
|
||
async wait_gap_interval(lastWaitTime, interval) {
|
||
const elapsedTime = Date.now() - lastWaitTime;
|
||
if (elapsedTime < interval) {
|
||
await this.wait(interval - elapsedTime);
|
||
}
|
||
}
|
||
}(UserClass);
|
||
} |