-
Notifications
You must be signed in to change notification settings - Fork 69
/
jd_kuaidi_leaf.js
177 lines (162 loc) · 10.3 KB
/
jd_kuaidi_leaf.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/*
京东快递
@Leaf
随机定时
*/
const $ = new Env('京东快递');
const got = require('got');
const envSplitor = ['&','\n','@']
const ckNames = ['JD_COOKIE']
const MAX_THREAD = parseInt(process.env['jd_jdkd_thread']) || 5
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(0x18001f2f) NetType/WIFI Language/zh_CN miniProgram/wx73247c7819d61796'
const Referer = 'https://jingcai-h5.jd.com/'
const Origin = 'https://jingcai-h5.jd.com'
const client = got.extend({
headers:{
Connection:'keep-alive',
'User-Agent': default_UA,
Referer,
Origin,
AppParams: JSON.stringify({"appid":158,"ticket_type":"m"}),
ClientInfo: JSON.stringify({"appName":"jingcai","client":"m"}),
'LOP-DN': 'jingcai.jd.com',
'X-Requested-With': 'XMLHttpRequest',
},
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.cookie = ck
this.pt_pin = ck.match(/pin=([\w\-\%]+)/) ? ck.match(/pin=([\w\-\%]+)/)[1] : ''
this.name = decodeURIComponent(this.pt_pin)
}
async queryTaskList() {
try {
let options = {
fn: 'queryTaskList',
method: 'post',
url: 'https://lop-proxy.jd.com/ESGApi/queryTaskList',
headers: {Cookie:this.cookie,'event-id':$.randomPattern('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx')},
json: [{"pin":"$cooMrdGatewayUid$"}],
}
let {result} = await this.request(options)
let code = result?.code
if(code == 1) {
for(let task of (result?.content?.taskInfoList||[]).filter(x => x.taskReachNum < x.taskNeedReachNum && x.triggerType==1)) {
await this.reachTaskInfo(task);
break;
}
} else {
let errCode = code || result?.error_response?.code
let errMsg = result?.msg || result?.error_response?.zh_desc
this.log(`查询任务列表出错[${errCode}]: ${errMsg}`)
}
} catch (e) {
$.log(e)
} finally {
return Promise.resolve()
}
}
async reachTaskInfo(task) {
try {
let options = {
fn: 'reachTaskInfo',
method: 'post',
url: 'https://lop-proxy.jd.com/ESGApi/reachTaskInfo',
headers: {Cookie:this.cookie,'event-id':$.randomPattern('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx')},
json: [{
taskNo: task.taskNo,
childTaskId: task.childTaskId,
pin: "$cooMrdGatewayUid$",
}],
}
let {result} = await this.request(options)
let code = result?.code
if(code == 1) {
this.log(`完成任务[${task.taskTitle}]成功`)
await this.queryTaskList();
} else {
let errCode = code || result?.error_response?.code
let errMsg = result?.msg || result?.error_response?.zh_desc
this.log(`完成任务[${task.taskTitle}]失败[${errCode}]: ${errMsg}`)
}
} catch (e) {
$.log(e)
} finally {
return Promise.resolve()
}
}
async queryCanGetRewardTaskList() {
try {
let options = {
fn: 'queryCanGetRewardTaskList',
method: 'post',
url: 'https://lop-proxy.jd.com/ESGApi/queryCanGetRewardTaskList',
headers: {Cookie:this.cookie,'event-id':$.randomPattern('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx')},
json: [{"pin":"$cooMrdGatewayUid$"}],
}
let {result} = await this.request(options)
let code = result?.code
if(code == 1) {
for(let item of (result?.content?.personalCarbonRewardRespDtoList||[])) {
await this.operationPersonalCarbonIntegral(item)
}
} else {
let errCode = code || result?.error_response?.code
let errMsg = result?.msg || result?.error_response?.zh_desc
this.log(`查询可领取奖励出错[${errCode}]: ${errMsg}`)
}
} catch (e) {
$.log(e)
} finally {
return Promise.resolve()
}
}
async operationPersonalCarbonIntegral(item) {
try {
let options = {
fn: 'operationPersonalCarbonIntegral',
method: 'post',
url: 'https://lop-proxy.jd.com/ESGApi/operationPersonalCarbonIntegral',
headers: {Cookie:this.cookie,'event-id':$.randomPattern('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx')},
json: [{
type: 2,
operationType: 1,
rewardNo: item.rewardNo,
taskNo: item.taskNo,
pin: "$cooMrdGatewayUid$",
}],
}
let {result} = await this.request(options)
let code = result?.code
if(code == 1) {
this.log(`收取[${item.taskTitle}]奖励成功, 现在有${result?.content?.carbonIntegral}g能量`)
} else {
let errCode = code || result?.error_response?.code
let errMsg = result?.msg || result?.error_response?.zh_desc
this.log(`收取[${item.taskTitle}]奖励失败[${errCode}]: ${errMsg}`)
}
} catch (e) {
$.log(e)
} finally {
return Promise.resolve()
}
}
async userTask() {
await this.queryTaskList();
await this.queryCanGetRewardTaskList();
}
}
!(async () => {
$.read_env(UserClass);
await $.threadTask('userTask',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)}