Files
leafTheFish-DeathNote/gqcq_wx_lottery.js
2022-12-29 16:32:16 +08:00

310 lines
10 KiB
JavaScript

/*
广汽传祺小程序抽奖
cron: 45 12 29-31 12 *
一次性抽奖, 跑一次就好
抽奖之后需要自己到app-我的-兑奖中心-年末好礼大放送 里面填兑换码
一个号只能填一次兑换码,自己选分数多的去填吧
*/
const $ = new Env('广汽传祺小程序抽奖');
const got = require('got');
const envPrefix = 'gqcqWx'
const envSplitor = ['\n','&','@'] //支持多种分割,但要保证变量里不存在这个字符
const ckNames = [envPrefix+'Cookie'] //支持多变量
const MAX_THREAD = parseInt(process.env[envPrefix+'Thread']) || 3
const DEFAULT_TIMEOUT=8000, DEFAULT_RETRY=3;
const default_UA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.31(0x18001f30) NetType/WIFI Language/zh_CN miniProgram/wx86a1eb5a53a6973b'
const Origin = 'https://mall.gacmotor.com'
const Referer = 'https://mall.gacmotor.com/act/turntable?id=147&_sasdk=fMTUzNjA1OTE2Mjc5MzM5NDE3Ng'
const channel = 'wx_channel'
const activityId_list = ['147','148','150','152']
const client = got.extend({
headers:{
Connection:'keep-alive',
'User-Agent': default_UA,
Origin,
Referer,
},
retry: {limit:0},
timeout: DEFAULT_TIMEOUT,
followRedirect: false,
})
class BasicClass {
constructor() {
this.index = $.userIdx++;
this.name = '';
}
log(msg, opt = {}) {
var m = '', n = $.userCount.toString().length;;
if (this.index) m += `账号[${$.padStr(this.index,n)}]`;
if (this.name) m += `[${this.name}]`;
$.log(m + msg, opt);
}
async request(opt) {
var resp = null, count = 0;
var fn = opt.fn || opt.url;
opt.method = opt?.method?.toUpperCase() || 'GET';
while (count++ < DEFAULT_RETRY) {
try {
await client(opt).then(t => {
resp = t
}, e => {
resp = e.response
});
if (((resp?.statusCode / 100) | 0) <= 4) break;
} catch (e) {
if (e.name == 'TimeoutError') {
this.log(`[${fn}]请求超时,重试第${count}`);
} else {
this.log(`[${fn}]请求错误(${e.message}),重试第${count}`);
}
};
}
if (resp == null) return Promise.resolve({statusCode:-1,headers:null,result:null});
let {statusCode,headers,body} = resp;
if (body) try {body = JSON.parse(body);} catch {};
return Promise.resolve({statusCode,headers,result:body})
}
}
let http = new BasicClass();
class UserClass extends BasicClass {
constructor(ck) {
super()
this.token = ck
this.headers = {
token: this.token,
}
}
async lottery(activityId) {
try {
let options = {
fn: 'lottery',
method: 'post',
url: 'https://mall.gacmotor.com/activity-app/customer/activityPrize/lotter',
searchParam: {notip:true},
headers: this.headers,
json: {activityId,channel},
}
let {result} = await this.request(options)
let code = result?.code
if(code == '0000') {
this.log(`抽奖[${activityId}]: ${result?.data?.name}`, {notify:true})
} else {
this.log(`抽奖[${activityId}]失败[${code}]: ${result?.msg}`, {notify:true})
}
} catch (e) {
$.log(e)
} finally {
return Promise.resolve()
}
}
async prizeRecords(activityId) {
try {
let options = {
fn: 'prizeRecords',
method: 'get',
url: 'https://mall.gacmotor.com/activity-app/customer/activityPrize/query/prizeRecords',
searchParam: {activityId},
headers: this.headers,
}
let {result} = await this.request(options)
let code = result?.code
if(code == '0000') {
for(let item of (result?.data||[])) {
$.log(`[${item.prizeName}] -- ${item.code}`, {notify:true})
}
} else {
this.log(`查询中奖记录失败`)
}
} catch (e) {
$.log(e)
} finally {
return Promise.resolve()
}
}
async userTask() {
for(let id of activityId_list) {
await this.lottery(id)
}
}
async userCheckTask() {
//for(let id of activityId_list) {
// await this.prizeRecords(id)
//}
await this.prizeRecords('147')
}
}
!(async () => {
$.read_env(UserClass);
$.log('\n------------- 抽奖 -------------')
await $.threadTask('userTask',MAX_THREAD)
$.log('\n------------- 中奖记录 -------------')
await $.threadTask('userCheckTask',MAX_THREAD)
})()
.catch((e) => $.log(e))
.finally(() => $.exitNow())
function Env(name) {
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;
}
log(msg, options = {}) {
let opt = {console: true};
Object.assign(opt, options);
if (opt.time) {
let fmt = opt.fmt || 'hh:mm:ss';
msg = `[${this.time(fmt)}]` + msg;
}
if (opt.notify) this.notifyStr.push(msg);
if (opt.console) console.log(msg);
}
read_env(Class) {
let envStrList = ckNames.map(x => process.env[x]);
for (let env_str of envStrList.filter(x => !!x)) {
let sp = envSplitor.filter(x => env_str.includes(x));
let splitor = sp.length > 0 ? sp[0] : envSplitor[0];
for (let ck of env_str.split(splitor).filter(x => !!x)) {
this.userList.push(new Class(ck));
}
}
this.userCount = this.userList.length;
if (!this.userCount) {
this.log(`未找到变量,请检查变量${ckNames.map(x => '['+x+']').join('或')}`, {notify: true});
return false;
}
this.log(`共找到${this.userCount}个账号`);
return true;
}
async threads(taskName, conf, opt = {}) {
while (conf.idx < $.userList.length) {
let user = $.userList[conf.idx++];
await user[taskName](opt);
}
}
async threadTask(taskName, thread) {
let taskAll = [];
let taskConf = {idx:0};
while(thread--) taskAll.push(this.threads(taskName, taskConf));
await Promise.all(taskAll);
}
time(t, x = null) {
let xt = x ? new Date(x) : new Date;
let e = {
"M+": xt.getMonth() + 1,
"d+": xt.getDate(),
"h+": xt.getHours(),
"m+": xt.getMinutes(),
"s+": xt.getSeconds(),
"q+": Math.floor((xt.getMonth() + 3) / 3),
S: this.padStr(xt.getMilliseconds(), 3)
};
/(y+)/.test(t) && (t = t.replace(RegExp.$1, (xt.getFullYear() + "").substr(4 - RegExp.$1.length)));
for(let s in e) new RegExp("(" + s + ")").test(t) && (t = t.replace(RegExp.$1, 1 == RegExp.$1.length ? e[s] : ("00" + e[s]).substr(("" + e[s]).length)));
return t;
}
async showmsg() {
if(!this.notifyFlag) return;
if(!this.notifyStr.length) return;
var notify = require('./sendNotify');
this.log('\n============== 推送 ==============');
await notify.sendNotify(this.name, this.notifyStr.join('\n'));
}
padStr(num, length, opt = {}) {
let padding = opt.padding || '0';
let mode = opt.mode || 'l';
let numStr = String(num);
let numPad = (length > numStr.length) ? (length - numStr.length) : 0;
let pads = '';
for (let i=0; i < numPad; i++) {
pads += padding;
}
if (mode == 'r') {
numStr = numStr + pads;
} else {
numStr = pads + numStr;
}
return numStr;
}
json2str(obj, c, encode = false) {
let ret = [];
for (let keys of Object.keys(obj).sort()) {
let v = obj[keys];
if(v && encode) v = encodeURIComponent(v);
ret.push(keys + '=' + v);
}
return ret.join(c);
}
str2json(str, decode = false) {
let ret = {};
for (let item of str.split('&')) {
if(!item) continue;
let idx = item.indexOf('=');
if(idx == -1) continue;
let k = item.substr(0, idx);
let v = item.substr(idx + 1);
if(decode) v = decodeURIComponent(v);
ret[k] = v;
}
return ret;
}
randomPattern(pattern, charset = 'abcdef0123456789') {
let str = '';
for (let chars of pattern) {
if (chars == 'x') {
str += charset.charAt(Math.floor(Math.random() * charset.length));
} else if (chars == 'X') {
str += charset.charAt(Math.floor(Math.random() * charset.length)).toUpperCase();
} else {
str += chars;
}
}
return str;
}
randomString(len, charset = 'abcdef0123456789') {
let str = '';
for (let i = 0; i < len; i++) {
str += charset.charAt(Math.floor(Math.random() * charset.length));
}
return str;
}
randomList(a) {
let idx = Math.floor(Math.random() * a.length);
return a[idx];
}
wait(t) {
return new Promise(e => setTimeout(e, t));
}
async exitNow() {
await this.showmsg();
let e = Date.now();
let s = (e - this.startTime) / 1000;
this.log('');
this.log(`[${this.name}]运行结束,共运行了${s}`, {time: true});
process.exit(0);
}
}
(name)
}