├── JDJRValidator_Pure.js ├── USER_AGENTS.js ├── ZooFaker_Necklace.js ├── cleancart_activity.js ├── gua_MMdou.js ├── gua_cleancart.js ├── gua_opencard206.js ├── gua_wealth_island.js ├── gua_wealth_island_help.js ├── jdCookie.js ├── jd_sendBeans.js ├── jd_sign_graphics.js ├── sendNotify.js └── sign_graphics_validate.js /JDJRValidator_Pure.js: -------------------------------------------------------------------------------- 1 | const https = require('https'); 2 | const http = require('http'); 3 | const stream = require('stream'); 4 | const zlib = require('zlib'); 5 | const vm = require('vm'); 6 | const PNG = require('png-js'); 7 | let UA = `jdapp;iPhone;10.1.0;14.3;${randomString(40)};network/wifi;model/iPhone12,1;addressid/4199175193;appBuild/167774;jdSupportDarkMode/0;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1`; 8 | const validatorCount = process.env.JDJR_validator_Count ? process.env.JDJR_validator_Count : 100 9 | 10 | function randomString(e) { 11 | e = e || 32; 12 | let t = "abcdef0123456789", a = t.length, n = ""; 13 | for (i = 0; i < e; i++) 14 | n += t.charAt(Math.floor(Math.random() * a)); 15 | return n 16 | } 17 | 18 | Math.avg = function average() { 19 | var sum = 0; 20 | var len = this.length; 21 | for (var i = 0; i < len; i++) { 22 | sum += this[i]; 23 | } 24 | return sum / len; 25 | }; 26 | 27 | function sleep(timeout) { 28 | return new Promise((resolve) => setTimeout(resolve, timeout)); 29 | } 30 | 31 | class PNGDecoder extends PNG { 32 | constructor(args) { 33 | super(args); 34 | this.pixels = []; 35 | } 36 | 37 | decodeToPixels() { 38 | return new Promise((resolve) => { 39 | this.decode((pixels) => { 40 | this.pixels = pixels; 41 | resolve(); 42 | }); 43 | }); 44 | } 45 | 46 | getImageData(x, y, w, h) { 47 | const {pixels} = this; 48 | const len = w * h * 4; 49 | const startIndex = x * 4 + y * (w * 4); 50 | 51 | return {data: pixels.slice(startIndex, startIndex + len)}; 52 | } 53 | } 54 | 55 | const PUZZLE_GAP = 8; 56 | const PUZZLE_PAD = 10; 57 | 58 | class PuzzleRecognizer { 59 | constructor(bg, patch, y) { 60 | // console.log(bg); 61 | const imgBg = new PNGDecoder(Buffer.from(bg, 'base64')); 62 | const imgPatch = new PNGDecoder(Buffer.from(patch, 'base64')); 63 | 64 | // console.log(imgBg); 65 | 66 | this.bg = imgBg; 67 | this.patch = imgPatch; 68 | this.rawBg = bg; 69 | this.rawPatch = patch; 70 | this.y = y; 71 | this.w = imgBg.width; 72 | this.h = imgBg.height; 73 | } 74 | 75 | async run() { 76 | await this.bg.decodeToPixels(); 77 | await this.patch.decodeToPixels(); 78 | 79 | return this.recognize(); 80 | } 81 | 82 | recognize() { 83 | const {ctx, w: width, bg} = this; 84 | const {width: patchWidth, height: patchHeight} = this.patch; 85 | const posY = this.y + PUZZLE_PAD + ((patchHeight - PUZZLE_PAD) / 2) - (PUZZLE_GAP / 2); 86 | // const cData = ctx.getImageData(0, a.y + 10 + 20 - 4, 360, 8).data; 87 | const cData = bg.getImageData(0, posY, width, PUZZLE_GAP).data; 88 | const lumas = []; 89 | 90 | for (let x = 0; x < width; x++) { 91 | var sum = 0; 92 | 93 | // y xais 94 | for (let y = 0; y < PUZZLE_GAP; y++) { 95 | var idx = x * 4 + y * (width * 4); 96 | var r = cData[idx]; 97 | var g = cData[idx + 1]; 98 | var b = cData[idx + 2]; 99 | var luma = 0.2126 * r + 0.7152 * g + 0.0722 * b; 100 | 101 | sum += luma; 102 | } 103 | 104 | lumas.push(sum / PUZZLE_GAP); 105 | } 106 | 107 | const n = 2; // minium macroscopic image width (px) 108 | const margin = patchWidth - PUZZLE_PAD; 109 | const diff = 20; // macroscopic brightness difference 110 | const radius = PUZZLE_PAD; 111 | for (let i = 0, len = lumas.length - 2 * 4; i < len; i++) { 112 | const left = (lumas[i] + lumas[i + 1]) / n; 113 | const right = (lumas[i + 2] + lumas[i + 3]) / n; 114 | const mi = margin + i; 115 | const mLeft = (lumas[mi] + lumas[mi + 1]) / n; 116 | const mRigth = (lumas[mi + 2] + lumas[mi + 3]) / n; 117 | 118 | if (left - right > diff && mLeft - mRigth < -diff) { 119 | const pieces = lumas.slice(i + 2, margin + i + 2); 120 | const median = pieces.sort((x1, x2) => x1 - x2)[20]; 121 | const avg = Math.avg(pieces); 122 | 123 | // noise reducation 124 | if (median > left || median > mRigth) return; 125 | if (avg > 100) return; 126 | // console.table({left,right,mLeft,mRigth,median}); 127 | // ctx.fillRect(i+n-radius, 0, 1, 360); 128 | // console.log(i+n-radius); 129 | return i + n - radius; 130 | } 131 | } 132 | 133 | // not found 134 | return -1; 135 | } 136 | 137 | runWithCanvas() { 138 | const {createCanvas, Image} = require('canvas'); 139 | const canvas = createCanvas(); 140 | const ctx = canvas.getContext('2d'); 141 | const imgBg = new Image(); 142 | const imgPatch = new Image(); 143 | const prefix = 'data:image/png;base64,'; 144 | 145 | imgBg.src = prefix + this.rawBg; 146 | imgPatch.src = prefix + this.rawPatch; 147 | const {naturalWidth: w, naturalHeight: h} = imgBg; 148 | canvas.width = w; 149 | canvas.height = h; 150 | ctx.clearRect(0, 0, w, h); 151 | ctx.drawImage(imgBg, 0, 0, w, h); 152 | 153 | const width = w; 154 | const {naturalWidth, naturalHeight} = imgPatch; 155 | const posY = this.y + PUZZLE_PAD + ((naturalHeight - PUZZLE_PAD) / 2) - (PUZZLE_GAP / 2); 156 | // const cData = ctx.getImageData(0, a.y + 10 + 20 - 4, 360, 8).data; 157 | const cData = ctx.getImageData(0, posY, width, PUZZLE_GAP).data; 158 | const lumas = []; 159 | 160 | for (let x = 0; x < width; x++) { 161 | var sum = 0; 162 | 163 | // y xais 164 | for (let y = 0; y < PUZZLE_GAP; y++) { 165 | var idx = x * 4 + y * (width * 4); 166 | var r = cData[idx]; 167 | var g = cData[idx + 1]; 168 | var b = cData[idx + 2]; 169 | var luma = 0.2126 * r + 0.7152 * g + 0.0722 * b; 170 | 171 | sum += luma; 172 | } 173 | 174 | lumas.push(sum / PUZZLE_GAP); 175 | } 176 | 177 | const n = 2; // minium macroscopic image width (px) 178 | const margin = naturalWidth - PUZZLE_PAD; 179 | const diff = 20; // macroscopic brightness difference 180 | const radius = PUZZLE_PAD; 181 | for (let i = 0, len = lumas.length - 2 * 4; i < len; i++) { 182 | const left = (lumas[i] + lumas[i + 1]) / n; 183 | const right = (lumas[i + 2] + lumas[i + 3]) / n; 184 | const mi = margin + i; 185 | const mLeft = (lumas[mi] + lumas[mi + 1]) / n; 186 | const mRigth = (lumas[mi + 2] + lumas[mi + 3]) / n; 187 | 188 | if (left - right > diff && mLeft - mRigth < -diff) { 189 | const pieces = lumas.slice(i + 2, margin + i + 2); 190 | const median = pieces.sort((x1, x2) => x1 - x2)[20]; 191 | const avg = Math.avg(pieces); 192 | 193 | // noise reducation 194 | if (median > left || median > mRigth) return; 195 | if (avg > 100) return; 196 | // console.table({left,right,mLeft,mRigth,median}); 197 | // ctx.fillRect(i+n-radius, 0, 1, 360); 198 | // console.log(i+n-radius); 199 | return i + n - radius; 200 | } 201 | } 202 | 203 | // not found 204 | return -1; 205 | } 206 | } 207 | 208 | const DATA = { 209 | "appId": "17839d5db83", 210 | "product": "embed", 211 | "lang": "zh_CN", 212 | }; 213 | const SERVER = 'iv.jd.com'; 214 | 215 | class JDJRValidator { 216 | constructor() { 217 | this.data = {}; 218 | this.x = 0; 219 | this.t = Date.now(); 220 | this.count = 0; 221 | } 222 | 223 | async run(scene = 'cww', eid='') { 224 | const tryRecognize = async () => { 225 | const x = await this.recognize(scene, eid); 226 | 227 | if (x > 0) { 228 | return x; 229 | } 230 | // retry 231 | return await tryRecognize(); 232 | }; 233 | const puzzleX = await tryRecognize(); 234 | // console.log(puzzleX); 235 | const pos = new MousePosFaker(puzzleX).run(); 236 | const d = getCoordinate(pos); 237 | 238 | // console.log(pos[pos.length-1][2] -Date.now()); 239 | // await sleep(4500); 240 | await sleep(pos[pos.length - 1][2] - Date.now()); 241 | this.count++; 242 | const result = await JDJRValidator.jsonp('/slide/s.html', {d, ...this.data}, scene); 243 | 244 | if (result.message === 'success') { 245 | // console.log(result); 246 | console.log('JDJR验证用时: %fs', (Date.now() - this.t) / 1000); 247 | return result; 248 | } else { 249 | console.log(`验证失败: ${this.count}/${validatorCount}`); 250 | // console.log(JSON.stringify(result)); 251 | if(this.count >= validatorCount){ 252 | console.log("JDJR验证次数已达上限,退出验证"); 253 | return result; 254 | }else{ 255 | await sleep(300); 256 | return await this.run(scene, eid); 257 | } 258 | } 259 | } 260 | 261 | async recognize(scene, eid) { 262 | const data = await JDJRValidator.jsonp('/slide/g.html', {e: eid}, scene); 263 | const {bg, patch, y} = data; 264 | // const uri = 'data:image/png;base64,'; 265 | // const re = new PuzzleRecognizer(uri+bg, uri+patch, y); 266 | const re = new PuzzleRecognizer(bg, patch, y); 267 | // console.log(JSON.stringify(re)) 268 | const puzzleX = await re.run(); 269 | 270 | if (puzzleX > 0) { 271 | this.data = { 272 | c: data.challenge, 273 | w: re.w, 274 | e: eid, 275 | s: '', 276 | o: '', 277 | }; 278 | this.x = puzzleX; 279 | } 280 | return puzzleX; 281 | } 282 | 283 | async report(n) { 284 | console.time('PuzzleRecognizer'); 285 | let count = 0; 286 | 287 | for (let i = 0; i < n; i++) { 288 | const x = await this.recognize(); 289 | 290 | if (x > 0) count++; 291 | if (i % 50 === 0) { 292 | // console.log('%f\%', (i / n) * 100); 293 | } 294 | } 295 | 296 | console.log('验证成功: %f\%', (count / n) * 100); 297 | console.clear() 298 | console.timeEnd('PuzzleRecognizer'); 299 | } 300 | 301 | static jsonp(api, data = {}, scene) { 302 | return new Promise((resolve, reject) => { 303 | const fnId = `jsonp_${String(Math.random()).replace('.', '')}`; 304 | const extraData = {callback: fnId}; 305 | const query = new URLSearchParams({...DATA,...{"scene": scene}, ...extraData, ...data}).toString(); 306 | const url = `https://${SERVER}${api}?${query}`; 307 | const headers = { 308 | 'Accept': '*/*', 309 | 'Accept-Encoding': 'gzip,deflate,br', 310 | 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', 311 | 'Connection': 'keep-alive', 312 | 'Host': "iv.jd.com", 313 | 'Proxy-Connection': 'keep-alive', 314 | 'Referer': 'https://h5.m.jd.com/', 315 | 'User-Agent': UA, 316 | }; 317 | 318 | const req = https.get(url, {headers}, (response) => { 319 | let res = response; 320 | if (res.headers['content-encoding'] === 'gzip') { 321 | const unzipStream = new stream.PassThrough(); 322 | stream.pipeline( 323 | response, 324 | zlib.createGunzip(), 325 | unzipStream, 326 | reject, 327 | ); 328 | res = unzipStream; 329 | } 330 | res.setEncoding('utf8'); 331 | 332 | let rawData = ''; 333 | 334 | res.on('data', (chunk) => rawData += chunk); 335 | res.on('end', () => { 336 | try { 337 | const ctx = { 338 | [fnId]: (data) => ctx.data = data, 339 | data: {}, 340 | }; 341 | 342 | vm.createContext(ctx); 343 | vm.runInContext(rawData, ctx); 344 | 345 | // console.log(ctx.data); 346 | res.resume(); 347 | resolve(ctx.data); 348 | } catch (e) { 349 | reject(e); 350 | } 351 | }); 352 | }); 353 | 354 | req.on('error', reject); 355 | req.end(); 356 | }); 357 | } 358 | } 359 | 360 | function getCoordinate(c) { 361 | function string10to64(d) { 362 | var c = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-~".split("") 363 | , b = c.length 364 | , e = +d 365 | , a = []; 366 | do { 367 | mod = e % b; 368 | e = (e - mod) / b; 369 | a.unshift(c[mod]) 370 | } while (e); 371 | return a.join("") 372 | } 373 | 374 | function prefixInteger(a, b) { 375 | return (Array(b).join(0) + a).slice(-b) 376 | } 377 | 378 | function pretreatment(d, c, b) { 379 | var e = string10to64(Math.abs(d)); 380 | var a = ""; 381 | if (!b) { 382 | a += (d > 0 ? "1" : "0") 383 | } 384 | a += prefixInteger(e, c); 385 | return a 386 | } 387 | 388 | var b = new Array(); 389 | for (var e = 0; e < c.length; e++) { 390 | if (e == 0) { 391 | b.push(pretreatment(c[e][0] < 262143 ? c[e][0] : 262143, 3, true)); 392 | b.push(pretreatment(c[e][1] < 16777215 ? c[e][1] : 16777215, 4, true)); 393 | b.push(pretreatment(c[e][2] < 4398046511103 ? c[e][2] : 4398046511103, 7, true)) 394 | } else { 395 | var a = c[e][0] - c[e - 1][0]; 396 | var f = c[e][1] - c[e - 1][1]; 397 | var d = c[e][2] - c[e - 1][2]; 398 | b.push(pretreatment(a < 4095 ? a : 4095, 2, false)); 399 | b.push(pretreatment(f < 4095 ? f : 4095, 2, false)); 400 | b.push(pretreatment(d < 16777215 ? d : 16777215, 4, true)) 401 | } 402 | } 403 | return b.join("") 404 | } 405 | 406 | const HZ = 20; 407 | 408 | class MousePosFaker { 409 | constructor(puzzleX) { 410 | this.x = parseInt(Math.random() * 20 + 20, 10); 411 | this.y = parseInt(Math.random() * 80 + 80, 10); 412 | this.t = Date.now(); 413 | this.pos = [[this.x, this.y, this.t]]; 414 | this.minDuration = parseInt(1000 / HZ, 10); 415 | // this.puzzleX = puzzleX; 416 | this.puzzleX = puzzleX + parseInt(Math.random() * 2 - 1, 10); 417 | 418 | this.STEP = parseInt(Math.random() * 6 + 5, 10); 419 | this.DURATION = parseInt(Math.random() * 7 + 14, 10) * 100; 420 | // [9,1600] [10,1400] 421 | this.STEP = 9; 422 | // this.DURATION = 2000; 423 | // console.log(this.STEP, this.DURATION); 424 | } 425 | 426 | run() { 427 | const perX = this.puzzleX / this.STEP; 428 | const perDuration = this.DURATION / this.STEP; 429 | const firstPos = [this.x - parseInt(Math.random() * 6, 10), this.y + parseInt(Math.random() * 11, 10), this.t]; 430 | 431 | this.pos.unshift(firstPos); 432 | this.stepPos(perX, perDuration); 433 | this.fixPos(); 434 | 435 | const reactTime = parseInt(60 + Math.random() * 100, 10); 436 | const lastIdx = this.pos.length - 1; 437 | const lastPos = [this.pos[lastIdx][0], this.pos[lastIdx][1], this.pos[lastIdx][2] + reactTime]; 438 | 439 | this.pos.push(lastPos); 440 | return this.pos; 441 | } 442 | 443 | stepPos(x, duration) { 444 | let n = 0; 445 | const sqrt2 = Math.sqrt(2); 446 | for (let i = 1; i <= this.STEP; i++) { 447 | n += 1 / i; 448 | } 449 | for (let i = 0; i < this.STEP; i++) { 450 | x = this.puzzleX / (n * (i + 1)); 451 | const currX = parseInt((Math.random() * 30 - 15) + x, 10); 452 | const currY = parseInt(Math.random() * 7 - 3, 10); 453 | const currDuration = parseInt((Math.random() * 0.4 + 0.8) * duration, 10); 454 | 455 | this.moveToAndCollect({ 456 | x: currX, 457 | y: currY, 458 | duration: currDuration, 459 | }); 460 | } 461 | } 462 | 463 | fixPos() { 464 | const actualX = this.pos[this.pos.length - 1][0] - this.pos[1][0]; 465 | const deviation = this.puzzleX - actualX; 466 | 467 | if (Math.abs(deviation) > 4) { 468 | this.moveToAndCollect({ 469 | x: deviation, 470 | y: parseInt(Math.random() * 8 - 3, 10), 471 | duration: 250, 472 | }); 473 | } 474 | } 475 | 476 | moveToAndCollect({x, y, duration}) { 477 | let movedX = 0; 478 | let movedY = 0; 479 | let movedT = 0; 480 | const times = duration / this.minDuration; 481 | let perX = x / times; 482 | let perY = y / times; 483 | let padDuration = 0; 484 | 485 | if (Math.abs(perX) < 1) { 486 | padDuration = duration / Math.abs(x) - this.minDuration; 487 | perX = 1; 488 | perY = y / Math.abs(x); 489 | } 490 | 491 | while (Math.abs(movedX) < Math.abs(x)) { 492 | const rDuration = parseInt(padDuration + Math.random() * 16 - 4, 10); 493 | 494 | movedX += perX + Math.random() * 2 - 1; 495 | movedY += perY; 496 | movedT += this.minDuration + rDuration; 497 | 498 | const currX = parseInt(this.x + movedX, 10); 499 | const currY = parseInt(this.y + movedY, 10); 500 | const currT = this.t + movedT; 501 | 502 | this.pos.push([currX, currY, currT]); 503 | } 504 | 505 | this.x += x; 506 | this.y += y; 507 | this.t += Math.max(duration, movedT); 508 | } 509 | } 510 | 511 | function injectToRequest(fn,scene = 'cww', ua = '') { 512 | if(ua) UA = ua 513 | return (opts, cb) => { 514 | fn(opts, async (err, resp, data) => { 515 | if (err) { 516 | console.error(JSON.stringify(err)); 517 | return; 518 | } 519 | if (data.search('验证') > -1) { 520 | console.log('JDJR验证中......'); 521 | let arr = opts.url.split("&") 522 | let eid = '' 523 | for(let i of arr){ 524 | if(i.indexOf("eid=")>-1){ 525 | eid = i.split("=") && i.split("=")[1] || '' 526 | } 527 | } 528 | const res = await new JDJRValidator().run(scene, eid); 529 | 530 | opts.url += `&validate=${res.validate}`; 531 | fn(opts, cb); 532 | } else { 533 | cb(err, resp, data); 534 | } 535 | }); 536 | }; 537 | } 538 | 539 | exports.injectToRequest = injectToRequest; 540 | -------------------------------------------------------------------------------- /USER_AGENTS.js: -------------------------------------------------------------------------------- 1 | const USER_AGENTS = [ 2 | "jdapp;android;10.0.2;10;network/wifi;Mozilla/5.0 (Linux; Android 10; ONEPLUS A5010 Build/QKQ1.191014.012; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/6.2 TBS/045230 Mobile Safari/537.36", 3 | "jdapp;iPhone;10.0.2;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1", 4 | "jdapp;android;10.0.2;9;network/4g;Mozilla/5.0 (Linux; Android 9; Mi Note 3 Build/PKQ1.181007.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/6.2 TBS/045131 Mobile Safari/537.36", 5 | "jdapp;android;10.0.2;10;network/wifi;Mozilla/5.0 (Linux; Android 10; GM1910 Build/QKQ1.190716.003; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/6.2 TBS/045230 Mobile Safari/537.36", 6 | "jdapp;android;10.0.2;9;network/wifi;Mozilla/5.0 (Linux; Android 9; 16T Build/PKQ1.190616.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/6.2 TBS/044942 Mobile Safari/537.36", 7 | "jdapp;iPhone;10.0.2;13.6;network/wifi;Mozilla/5.0 (iPhone; CPU iPhone OS 13_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1", 8 | "jdapp;iPhone;10.0.2;13.6;network/wifi;Mozilla/5.0 (iPhone; CPU iPhone OS 13_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1", 9 | "jdapp;iPhone;10.0.2;13.5;network/wifi;Mozilla/5.0 (iPhone; CPU iPhone OS 13_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1", 10 | "jdapp;iPhone;10.0.2;14.1;network/wifi;Mozilla/5.0 (iPhone; CPU iPhone OS 14_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1", 11 | "jdapp;iPhone;10.0.2;13.3;network/wifi;Mozilla/5.0 (iPhone; CPU iPhone OS 13_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1", 12 | "jdapp;iPhone;10.0.2;13.7;network/wifi;Mozilla/5.0 (iPhone; CPU iPhone OS 13_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1", 13 | "jdapp;iPhone;10.0.2;14.1;network/wifi;Mozilla/5.0 (iPhone; CPU iPhone OS 14_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1", 14 | "jdapp;iPhone;10.0.2;13.3;network/wifi;Mozilla/5.0 (iPhone; CPU iPhone OS 13_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1", 15 | "jdapp;iPhone;10.0.2;13.4;network/wifi;Mozilla/5.0 (iPhone; CPU iPhone OS 13_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1", 16 | "jdapp;iPhone;10.0.2;14.3;network/wifi;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1", 17 | "jdapp;android;10.0.2;9;network/wifi;Mozilla/5.0 (Linux; Android 9; MI 6 Build/PKQ1.190118.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/6.2 TBS/044942 Mobile Safari/537.36", 18 | "jdapp;android;10.0.2;11;network/wifi;Mozilla/5.0 (Linux; Android 11; Redmi K30 5G Build/RKQ1.200826.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/6.2 TBS/045511 Mobile Safari/537.36", 19 | "jdapp;iPhone;10.0.2;11.4;network/wifi;Mozilla/5.0 (iPhone; CPU iPhone OS 11_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15F79", 20 | "jdapp;android;10.0.2;10;;network/wifi;Mozilla/5.0 (Linux; Android 10; M2006J10C Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/6.2 TBS/045230 Mobile Safari/537.36", 21 | "jdapp;android;10.0.2;10;network/wifi;Mozilla/5.0 (Linux; Android 10; M2006J10C Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/6.2 TBS/045230 Mobile Safari/537.36", 22 | "jdapp;android;10.0.2;10;network/wifi;Mozilla/5.0 (Linux; Android 10; ONEPLUS A6000 Build/QKQ1.190716.003; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/6.2 TBS/045224 Mobile Safari/537.36", 23 | "jdapp;android;10.0.2;9;network/wifi;Mozilla/5.0 (Linux; Android 9; MHA-AL00 Build/HUAWEIMHA-AL00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/6.2 TBS/044942 Mobile Safari/537.36", 24 | "jdapp;android;10.0.2;8.1.0;network/wifi;Mozilla/5.0 (Linux; Android 8.1.0; 16 X Build/OPM1.171019.026; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/6.2 TBS/044942 Mobile Safari/537.36", 25 | "jdapp;android;10.0.2;8.0.0;network/wifi;Mozilla/5.0 (Linux; Android 8.0.0; HTC U-3w Build/OPR6.170623.013; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/6.2 TBS/044942 Mobile Safari/537.36", 26 | "jdapp;iPhone;10.0.2;14.0.1;network/wifi;Mozilla/5.0 (iPhone; CPU iPhone OS 14_0_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1", 27 | "jdapp;android;10.0.2;10;network/wifi;Mozilla/5.0 (Linux; Android 10; LYA-AL00 Build/HUAWEILYA-AL00L; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/6.2 TBS/045230 Mobile Safari/537.36", 28 | "jdapp;iPhone;10.0.2;14.2;network/wifi;Mozilla/5.0 (iPhone; CPU iPhone OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1", 29 | "jdapp;iPhone;10.0.2;14.3;network/wifi;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1", 30 | "jdapp;iPhone;10.0.2;14.2;network/wifi;Mozilla/5.0 (iPhone; CPU iPhone OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1", 31 | "jdapp;android;10.0.2;8.1.0;network/wifi;Mozilla/5.0 (Linux; Android 8.1.0; MI 8 Build/OPM1.171019.026; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/6.2 TBS/045131 Mobile Safari/537.36", 32 | "jdapp;android;10.0.2;10;network/wifi;Mozilla/5.0 (Linux; Android 10; Redmi K20 Pro Premium Edition Build/QKQ1.190825.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/6.2 TBS/045227 Mobile Safari/537.36", 33 | "jdapp;iPhone;10.0.2;14.3;network/wifi;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1", 34 | "jdapp;iPhone;10.0.2;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1", 35 | "jdapp;android;10.0.2;11;network/wifi;Mozilla/5.0 (Linux; Android 11; Redmi K20 Pro Premium Edition Build/RKQ1.200826.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/6.2 TBS/045513 Mobile Safari/537.36", 36 | "jdapp;android;10.0.2;10;network/wifi;Mozilla/5.0 (Linux; Android 10; MI 8 Build/QKQ1.190828.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/6.2 TBS/045227 Mobile Safari/537.36", 37 | "jdapp;iPhone;10.0.2;14.1;network/wifi;Mozilla/5.0 (iPhone; CPU iPhone OS 14_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1", 38 | ] 39 | /** 40 | * 生成随机数字 41 | * @param {number} min 最小值(包含) 42 | * @param {number} max 最大值(不包含) 43 | */ 44 | function randomNumber(min = 0, max = 100) { 45 | return Math.min(Math.floor(min + Math.random() * (max - min)), max); 46 | } 47 | const USER_AGENT = USER_AGENTS[randomNumber(0, USER_AGENTS.length)]; 48 | 49 | module.exports = { 50 | USER_AGENT 51 | } 52 | -------------------------------------------------------------------------------- /ZooFaker_Necklace.js: -------------------------------------------------------------------------------- 1 | function safeAdd(x, y) { 2 | var lsw = (x & 0xffff) + (y & 0xffff) 3 | var msw = (x >> 16) + (y >> 16) + (lsw >> 16) 4 | return (msw << 16) | (lsw & 0xffff) 5 | } 6 | 7 | /* 8 | * Bitwise rotate a 32-bit number to the left. 9 | */ 10 | function bitRotateLeft(num, cnt) { 11 | return (num << cnt) | (num >>> (32 - cnt)) 12 | } 13 | 14 | function md5(string, key, raw) { 15 | if (!key) { 16 | if (!raw) { 17 | return hexMD5(string) 18 | } 19 | return rawMD5(string) 20 | } 21 | if (!raw) { 22 | return hexHMACMD5(key, string) 23 | } 24 | return rawHMACMD5(key, string) 25 | } 26 | 27 | /* 28 | * Convert a raw string to a hex string 29 | */ 30 | function rstr2hex(input) { 31 | var hexTab = '0123456789abcdef' 32 | var output = '' 33 | var x 34 | var i 35 | for (i = 0; i < input.length; i += 1) { 36 | x = input.charCodeAt(i) 37 | output += hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f) 38 | } 39 | return output 40 | } 41 | /* 42 | * Encode a string as utf-8 43 | */ 44 | function str2rstrUTF8(input) { 45 | return unescape(encodeURIComponent(input)) 46 | } 47 | /* 48 | * Calculate the MD5 of a raw string 49 | */ 50 | function rstrMD5(s) { 51 | return binl2rstr(binlMD5(rstr2binl(s), s.length * 8)) 52 | } 53 | 54 | function hexMD5(s) { 55 | return rstr2hex(rawMD5(s)) 56 | } 57 | function rawMD5(s) { 58 | return rstrMD5(str2rstrUTF8(s)) 59 | } 60 | 61 | /* 62 | * These functions implement the four basic operations the algorithm uses. 63 | */ 64 | function md5cmn(q, a, b, x, s, t) { 65 | return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b) 66 | } 67 | 68 | function md5ff(a, b, c, d, x, s, t) { 69 | return md5cmn((b & c) | (~b & d), a, b, x, s, t) 70 | } 71 | 72 | function md5gg(a, b, c, d, x, s, t) { 73 | return md5cmn((b & d) | (c & ~d), a, b, x, s, t) 74 | } 75 | 76 | function md5hh(a, b, c, d, x, s, t) { 77 | return md5cmn(b ^ c ^ d, a, b, x, s, t) 78 | } 79 | 80 | function md5ii(a, b, c, d, x, s, t) { 81 | return md5cmn(c ^ (b | ~d), a, b, x, s, t) 82 | } 83 | 84 | /* 85 | * Calculate the MD5 of an array of little-endian words, and a bit length. 86 | */ 87 | function binlMD5(x, len) { 88 | /* append padding */ 89 | x[len >> 5] |= 0x80 << (len % 32) 90 | x[((len + 64) >>> 9 << 4) + 14] = len 91 | 92 | var i 93 | var olda 94 | var oldb 95 | var oldc 96 | var oldd 97 | var a = 1732584193 98 | var b = -271733879 99 | var c = -1732584194 100 | var d = 271733878 101 | 102 | for (i = 0; i < x.length; i += 16) { 103 | olda = a 104 | oldb = b 105 | oldc = c 106 | oldd = d 107 | 108 | a = md5ff(a, b, c, d, x[i], 7, -680876936) 109 | d = md5ff(d, a, b, c, x[i + 1], 12, -389564586) 110 | c = md5ff(c, d, a, b, x[i + 2], 17, 606105819) 111 | b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330) 112 | a = md5ff(a, b, c, d, x[i + 4], 7, -176418897) 113 | d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426) 114 | c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341) 115 | b = md5ff(b, c, d, a, x[i + 7], 22, -45705983) 116 | a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416) 117 | d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417) 118 | c = md5ff(c, d, a, b, x[i + 10], 17, -42063) 119 | b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162) 120 | a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682) 121 | d = md5ff(d, a, b, c, x[i + 13], 12, -40341101) 122 | c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290) 123 | b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329) 124 | 125 | a = md5gg(a, b, c, d, x[i + 1], 5, -165796510) 126 | d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632) 127 | c = md5gg(c, d, a, b, x[i + 11], 14, 643717713) 128 | b = md5gg(b, c, d, a, x[i], 20, -373897302) 129 | a = md5gg(a, b, c, d, x[i + 5], 5, -701558691) 130 | d = md5gg(d, a, b, c, x[i + 10], 9, 38016083) 131 | c = md5gg(c, d, a, b, x[i + 15], 14, -660478335) 132 | b = md5gg(b, c, d, a, x[i + 4], 20, -405537848) 133 | a = md5gg(a, b, c, d, x[i + 9], 5, 568446438) 134 | d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690) 135 | c = md5gg(c, d, a, b, x[i + 3], 14, -187363961) 136 | b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501) 137 | a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467) 138 | d = md5gg(d, a, b, c, x[i + 2], 9, -51403784) 139 | c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473) 140 | b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734) 141 | 142 | a = md5hh(a, b, c, d, x[i + 5], 4, -378558) 143 | d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463) 144 | c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562) 145 | b = md5hh(b, c, d, a, x[i + 14], 23, -35309556) 146 | a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060) 147 | d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353) 148 | c = md5hh(c, d, a, b, x[i + 7], 16, -155497632) 149 | b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640) 150 | a = md5hh(a, b, c, d, x[i + 13], 4, 681279174) 151 | d = md5hh(d, a, b, c, x[i], 11, -358537222) 152 | c = md5hh(c, d, a, b, x[i + 3], 16, -722521979) 153 | b = md5hh(b, c, d, a, x[i + 6], 23, 76029189) 154 | a = md5hh(a, b, c, d, x[i + 9], 4, -640364487) 155 | d = md5hh(d, a, b, c, x[i + 12], 11, -421815835) 156 | c = md5hh(c, d, a, b, x[i + 15], 16, 530742520) 157 | b = md5hh(b, c, d, a, x[i + 2], 23, -995338651) 158 | 159 | a = md5ii(a, b, c, d, x[i], 6, -198630844) 160 | d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415) 161 | c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905) 162 | b = md5ii(b, c, d, a, x[i + 5], 21, -57434055) 163 | a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571) 164 | d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606) 165 | c = md5ii(c, d, a, b, x[i + 10], 15, -1051523) 166 | b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799) 167 | a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359) 168 | d = md5ii(d, a, b, c, x[i + 15], 10, -30611744) 169 | c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380) 170 | b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649) 171 | a = md5ii(a, b, c, d, x[i + 4], 6, -145523070) 172 | d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379) 173 | c = md5ii(c, d, a, b, x[i + 2], 15, 718787259) 174 | b = md5ii(b, c, d, a, x[i + 9], 21, -343485551) 175 | 176 | a = safeAdd(a, olda) 177 | b = safeAdd(b, oldb) 178 | c = safeAdd(c, oldc) 179 | d = safeAdd(d, oldd) 180 | } 181 | return [a, b, c, d] 182 | } 183 | /* 184 | * Convert an array of little-endian words to a string 185 | */ 186 | function binl2rstr(input) { 187 | var i 188 | var output = '' 189 | var length32 = input.length * 32 190 | for (i = 0; i < length32; i += 8) { 191 | output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xff) 192 | } 193 | return output 194 | } 195 | 196 | 197 | /* 198 | * Convert a raw string to an array of little-endian words 199 | * Characters >255 have their high-byte silently ignored. 200 | */ 201 | function rstr2binl(input) { 202 | var i 203 | var output = [] 204 | output[(input.length >> 2) - 1] = undefined 205 | for (i = 0; i < output.length; i += 1) { 206 | output[i] = 0 207 | } 208 | var length8 = input.length * 8 209 | for (i = 0; i < length8; i += 8) { 210 | output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << (i % 32) 211 | } 212 | return output 213 | } 214 | 215 | 216 | function encrypt_3(e) { 217 | return function (e) { 218 | if (Array.isArray(e)) return encrypt_3_3(e) 219 | }(e) || function (e) { 220 | if ("undefined" != typeof Symbol && Symbol.iterator in Object(e)) return Array.from(e) 221 | }(e) || function (e, t) { 222 | if (e) { 223 | if ("string" == typeof e) return encrypt_3_3(e, t); 224 | var n = Object.prototype.toString.call(e).slice(8, -1); 225 | return "Object" === n && e.constructor && (n = e.constructor.name), "Map" === n || "Set" === n ? Array.from(e) : "Arguments" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n) ? encrypt_3_3(e, t) : void 0 226 | } 227 | }(e) || function () { 228 | throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.") 229 | }() 230 | } 231 | 232 | function encrypt_3_3(e, t) { 233 | (null == t || t > e.length) && (t = e.length); 234 | for (var n = 0, r = new Array(t); n < t; n++) r[n] = e[n]; 235 | return r 236 | } 237 | 238 | function rotateRight(n, x) { 239 | return ((x >>> n) | (x << (32 - n))); 240 | } 241 | 242 | function choice(x, y, z) { 243 | return ((x & y) ^ (~x & z)); 244 | } 245 | 246 | function majority(x, y, z) { 247 | return ((x & y) ^ (x & z) ^ (y & z)); 248 | } 249 | 250 | function sha256_Sigma0(x) { 251 | return (rotateRight(2, x) ^ rotateRight(13, x) ^ rotateRight(22, x)); 252 | } 253 | 254 | function sha256_Sigma1(x) { 255 | return (rotateRight(6, x) ^ rotateRight(11, x) ^ rotateRight(25, x)); 256 | } 257 | 258 | function sha256_sigma0(x) { 259 | return (rotateRight(7, x) ^ rotateRight(18, x) ^ (x >>> 3)); 260 | } 261 | 262 | function sha256_sigma1(x) { 263 | return (rotateRight(17, x) ^ rotateRight(19, x) ^ (x >>> 10)); 264 | } 265 | 266 | function sha256_expand(W, j) { 267 | return (W[j & 0x0f] += sha256_sigma1(W[(j + 14) & 0x0f]) + W[(j + 9) & 0x0f] + 268 | sha256_sigma0(W[(j + 1) & 0x0f])); 269 | } 270 | 271 | /* Hash constant words K: */ 272 | var K256 = new Array( 273 | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 274 | 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 275 | 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 276 | 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 277 | 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 278 | 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 279 | 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 280 | 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 281 | 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 282 | 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 283 | 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 284 | 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 285 | 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 286 | 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 287 | 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 288 | 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 289 | ); 290 | 291 | /* global arrays */ 292 | var ihash, count, buffer; 293 | var sha256_hex_digits = "0123456789abcdef"; 294 | 295 | /* Add 32-bit integers with 16-bit operations (bug in some JS-interpreters: 296 | overflow) */ 297 | function safe_add(x, y) { 298 | var lsw = (x & 0xffff) + (y & 0xffff); 299 | var msw = (x >> 16) + (y >> 16) + (lsw >> 16); 300 | return (msw << 16) | (lsw & 0xffff); 301 | } 302 | 303 | /* Initialise the SHA256 computation */ 304 | function sha256_init() { 305 | ihash = new Array(8); 306 | count = new Array(2); 307 | buffer = new Array(64); 308 | count[0] = count[1] = 0; 309 | ihash[0] = 0x6a09e667; 310 | ihash[1] = 0xbb67ae85; 311 | ihash[2] = 0x3c6ef372; 312 | ihash[3] = 0xa54ff53a; 313 | ihash[4] = 0x510e527f; 314 | ihash[5] = 0x9b05688c; 315 | ihash[6] = 0x1f83d9ab; 316 | ihash[7] = 0x5be0cd19; 317 | } 318 | 319 | /* Transform a 512-bit message block */ 320 | function sha256_transform() { 321 | var a, b, c, d, e, f, g, h, T1, T2; 322 | var W = new Array(16); 323 | 324 | /* Initialize registers with the previous intermediate value */ 325 | a = ihash[0]; 326 | b = ihash[1]; 327 | c = ihash[2]; 328 | d = ihash[3]; 329 | e = ihash[4]; 330 | f = ihash[5]; 331 | g = ihash[6]; 332 | h = ihash[7]; 333 | 334 | /* make 32-bit words */ 335 | for (var i = 0; i < 16; i++) 336 | W[i] = ((buffer[(i << 2) + 3]) | (buffer[(i << 2) + 2] << 8) | (buffer[(i << 2) + 1] << 337 | 16) | (buffer[i << 2] << 24)); 338 | 339 | for (var j = 0; j < 64; j++) { 340 | T1 = h + sha256_Sigma1(e) + choice(e, f, g) + K256[j]; 341 | if (j < 16) T1 += W[j]; 342 | else T1 += sha256_expand(W, j); 343 | T2 = sha256_Sigma0(a) + majority(a, b, c); 344 | h = g; 345 | g = f; 346 | f = e; 347 | e = safe_add(d, T1); 348 | d = c; 349 | c = b; 350 | b = a; 351 | a = safe_add(T1, T2); 352 | } 353 | 354 | /* Compute the current intermediate hash value */ 355 | ihash[0] += a; 356 | ihash[1] += b; 357 | ihash[2] += c; 358 | ihash[3] += d; 359 | ihash[4] += e; 360 | ihash[5] += f; 361 | ihash[6] += g; 362 | ihash[7] += h; 363 | } 364 | 365 | /* Read the next chunk of data and update the SHA256 computation */ 366 | function sha256_update(data, inputLen) { 367 | var i, index, curpos = 0; 368 | /* Compute number of bytes mod 64 */ 369 | index = ((count[0] >> 3) & 0x3f); 370 | var remainder = (inputLen & 0x3f); 371 | 372 | /* Update number of bits */ 373 | if ((count[0] += (inputLen << 3)) < (inputLen << 3)) count[1]++; 374 | count[1] += (inputLen >> 29); 375 | 376 | /* Transform as many times as possible */ 377 | for (i = 0; i + 63 < inputLen; i += 64) { 378 | for (var j = index; j < 64; j++) 379 | buffer[j] = data.charCodeAt(curpos++); 380 | sha256_transform(); 381 | index = 0; 382 | } 383 | 384 | /* Buffer remaining input */ 385 | for (var j = 0; j < remainder; j++) 386 | buffer[j] = data.charCodeAt(curpos++); 387 | } 388 | 389 | /* Finish the computation by operations such as padding */ 390 | function sha256_final() { 391 | var index = ((count[0] >> 3) & 0x3f); 392 | buffer[index++] = 0x80; 393 | if (index <= 56) { 394 | for (var i = index; i < 56; i++) 395 | buffer[i] = 0; 396 | } else { 397 | for (var i = index; i < 64; i++) 398 | buffer[i] = 0; 399 | sha256_transform(); 400 | for (var i = 0; i < 56; i++) 401 | buffer[i] = 0; 402 | } 403 | buffer[56] = (count[1] >>> 24) & 0xff; 404 | buffer[57] = (count[1] >>> 16) & 0xff; 405 | buffer[58] = (count[1] >>> 8) & 0xff; 406 | buffer[59] = count[1] & 0xff; 407 | buffer[60] = (count[0] >>> 24) & 0xff; 408 | buffer[61] = (count[0] >>> 16) & 0xff; 409 | buffer[62] = (count[0] >>> 8) & 0xff; 410 | buffer[63] = count[0] & 0xff; 411 | sha256_transform(); 412 | } 413 | 414 | /* Split the internal hash values into an array of bytes */ 415 | function sha256_encode_bytes() { 416 | var j = 0; 417 | var output = new Array(32); 418 | for (var i = 0; i < 8; i++) { 419 | output[j++] = ((ihash[i] >>> 24) & 0xff); 420 | output[j++] = ((ihash[i] >>> 16) & 0xff); 421 | output[j++] = ((ihash[i] >>> 8) & 0xff); 422 | output[j++] = (ihash[i] & 0xff); 423 | } 424 | return output; 425 | } 426 | 427 | /* Get the internal hash as a hex string */ 428 | function sha256_encode_hex() { 429 | var output = new String(); 430 | for (var i = 0; i < 8; i++) { 431 | for (var j = 28; j >= 0; j -= 4) 432 | output += sha256_hex_digits.charAt((ihash[i] >>> j) & 0x0f); 433 | } 434 | return output; 435 | } 436 | let utils = { 437 | getDefaultVal: function (e) { 438 | try { 439 | return { 440 | undefined: "u", 441 | false: "f", 442 | true: "t" 443 | } [e] || e 444 | } catch (t) { 445 | return e 446 | } 447 | }, 448 | requestUrl: { 449 | gettoken: "".concat("https://", "bh.m.jd.com/gettoken"), 450 | bypass: "".concat("https://blackhole", ".m.jd.com/bypass") 451 | }, 452 | getTouchSession: function () { 453 | var e = (new Date).getTime(), 454 | t = this.getRandomInt(1e3, 9999); 455 | return String(e) + String(t) 456 | }, 457 | sha256: function (data) { 458 | sha256_init(); 459 | sha256_update(data, data.length); 460 | sha256_final(); 461 | return sha256_encode_hex().toUpperCase(); 462 | }, 463 | atobPolyfill: function (e) { 464 | return function (e) { 465 | var t = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; 466 | if (e = String(e).replace(/[\t\n\f\r ]+/g, ""), !/^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/.test(e)) throw new TypeError("解密错误"); 467 | e += "==".slice(2 - (3 & e.length)); 468 | for (var n, r, i, o = "", a = 0; a < e.length;) n = t.indexOf(e.charAt(a++)) << 18 | t.indexOf(e.charAt(a++)) << 12 | (r = t.indexOf(e.charAt(a++))) << 6 | (i = t.indexOf(e.charAt(a++))), o += 64 === r ? String.fromCharCode(n >> 16 & 255) : 64 === i ? String.fromCharCode(n >> 16 & 255, n >> 8 & 255) : String.fromCharCode(n >> 16 & 255, n >> 8 & 255, 255 & n); 469 | return o 470 | }(e) 471 | }, 472 | btoaPolyfill: function (e) { 473 | var t = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; 474 | return function (e) { 475 | for (var n, r, i, o, a = "", s = 0, u = (e = String(e)).length % 3; s < e.length;) { 476 | if ((r = e.charCodeAt(s++)) > 255 || (i = e.charCodeAt(s++)) > 255 || (o = e.charCodeAt(s++)) > 255) throw new TypeError("Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range."); 477 | a += t.charAt((n = r << 16 | i << 8 | o) >> 18 & 63) + t.charAt(n >> 12 & 63) + t.charAt(n >> 6 & 63) + t.charAt(63 & n) 478 | } 479 | return u ? a.slice(0, u - 3) + "===".substring(u) : a 480 | }(unescape(encodeURIComponent(e))) 481 | }, 482 | xorEncrypt: function (e, t) { 483 | for (var n = t.length, r = "", i = 0; i < e.length; i++) r += String.fromCharCode(e[i].charCodeAt() ^ t[i % n].charCodeAt()); 484 | return r 485 | }, 486 | encrypt1: function (e, t) { 487 | for (var n = e.length, r = t.toString(), i = [], o = "", a = 0, s = 0; s < r.length; s++) a >= n && (a %= n), o = (r.charCodeAt(s) ^ e.charCodeAt(a)) % 10, i.push(o), a += 1; 488 | return i.join().replace(/,/g, "") 489 | }, 490 | len_Fun: function (e, t) { 491 | return "".concat(e.substring(t, e.length)) + "".concat(e.substring(0, t)) 492 | }, 493 | encrypt2: function (e, t) { 494 | var n = t.toString(), 495 | r = t.toString().length, 496 | i = parseInt((r + e.length) / 3), 497 | o = "", 498 | a = ""; 499 | return r > e.length ? (o = this.len_Fun(n, i), a = this.encrypt1(e, o)) : (o = this.len_Fun(e, i), a = this.encrypt1(n, o)), a 500 | }, 501 | addZeroFront: function (e) { 502 | return e && e.length >= 5 ? e : ("00000" + String(e)).substr(-5) 503 | }, 504 | addZeroBack: function (e) { 505 | return e && e.length >= 5 ? e : (String(e) + "00000").substr(0, 5) 506 | }, 507 | encrypt3: function (e, t) { 508 | var n = this.addZeroBack(t).toString().substring(0, 5), 509 | r = this.addZeroFront(e).substring(e.length - 5), 510 | i = n.length, 511 | o = encrypt_3(Array(i).keys()), 512 | a = []; 513 | return o.forEach(function (e) { 514 | a.push(Math.abs(n.charCodeAt(e) - r.charCodeAt(e))) 515 | }), a.join().replace(/,/g, "") 516 | }, 517 | getCurrentDate: function () { 518 | return new Date 519 | }, 520 | getCurrentTime: function () { 521 | return this.getCurrentDate().getTime() 522 | }, 523 | getRandomInt: function () { 524 | var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : 0, 525 | t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 9; 526 | return e = Math.ceil(e), t = Math.floor(t), Math.floor(Math.random() * (t - e + 1)) + e 527 | }, 528 | getRandomWord: function (e) { 529 | for (var t = "", n = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", r = 0; r < e; r++) { 530 | var i = Math.round(Math.random() * (n.length - 1)); 531 | t += n.substring(i, i + 1) 532 | } 533 | return t 534 | }, 535 | getNumberInString: function (e) { 536 | return Number(e.replace(/[^0-9]/gi, "")) 537 | }, 538 | getSpecialPosition: function (e) { 539 | for (var t = !(arguments.length > 1 && void 0 !== arguments[1]) || arguments[1], n = ((e = String(e)).length, t ? 1 : 0), r = "", i = 0; i < e.length; i++) i % 2 === n && (r += e[i]); 540 | return r 541 | }, 542 | getLastAscii: function (e) { 543 | var t = e.charCodeAt(0).toString(); 544 | return t[t.length - 1] 545 | }, 546 | toAscii: function (e) { 547 | var t = ""; 548 | for (var n in e) { 549 | var r = e[n], 550 | i = /[a-zA-Z]/.test(r); 551 | e.hasOwnProperty(n) && (t += i ? this.getLastAscii(r) : r) 552 | } 553 | return t 554 | }, 555 | add0: function (e, t) { 556 | return (Array(t).join("0") + e).slice(-t) 557 | }, 558 | minusByByte: function (e, t) { 559 | var n = e.length, 560 | r = t.length, 561 | i = Math.max(n, r), 562 | o = this.toAscii(e), 563 | a = this.toAscii(t), 564 | s = "", 565 | u = 0; 566 | for (n !== r && (o = this.add0(o, i), a = this.add0(a, i)); u < i;) s += Math.abs(o[u] - a[u]), u++; 567 | return s 568 | }, 569 | Crc32: function (str) { 570 | var table = "00000000 77073096 EE0E612C 990951BA 076DC419 706AF48F E963A535 9E6495A3 0EDB8832 79DCB8A4 E0D5E91E 97D2D988 09B64C2B 7EB17CBD E7B82D07 90BF1D91 1DB71064 6AB020F2 F3B97148 84BE41DE 1ADAD47D 6DDDE4EB F4D4B551 83D385C7 136C9856 646BA8C0 FD62F97A 8A65C9EC 14015C4F 63066CD9 FA0F3D63 8D080DF5 3B6E20C8 4C69105E D56041E4 A2677172 3C03E4D1 4B04D447 D20D85FD A50AB56B 35B5A8FA 42B2986C DBBBC9D6 ACBCF940 32D86CE3 45DF5C75 DCD60DCF ABD13D59 26D930AC 51DE003A C8D75180 BFD06116 21B4F4B5 56B3C423 CFBA9599 B8BDA50F 2802B89E 5F058808 C60CD9B2 B10BE924 2F6F7C87 58684C11 C1611DAB B6662D3D 76DC4190 01DB7106 98D220BC EFD5102A 71B18589 06B6B51F 9FBFE4A5 E8B8D433 7807C9A2 0F00F934 9609A88E E10E9818 7F6A0DBB 086D3D2D 91646C97 E6635C01 6B6B51F4 1C6C6162 856530D8 F262004E 6C0695ED 1B01A57B 8208F4C1 F50FC457 65B0D9C6 12B7E950 8BBEB8EA FCB9887C 62DD1DDF 15DA2D49 8CD37CF3 FBD44C65 4DB26158 3AB551CE A3BC0074 D4BB30E2 4ADFA541 3DD895D7 A4D1C46D D3D6F4FB 4369E96A 346ED9FC AD678846 DA60B8D0 44042D73 33031DE5 AA0A4C5F DD0D7CC9 5005713C 270241AA BE0B1010 C90C2086 5768B525 206F85B3 B966D409 CE61E49F 5EDEF90E 29D9C998 B0D09822 C7D7A8B4 59B33D17 2EB40D81 B7BD5C3B C0BA6CAD EDB88320 9ABFB3B6 03B6E20C 74B1D29A EAD54739 9DD277AF 04DB2615 73DC1683 E3630B12 94643B84 0D6D6A3E 7A6A5AA8 E40ECF0B 9309FF9D 0A00AE27 7D079EB1 F00F9344 8708A3D2 1E01F268 6906C2FE F762575D 806567CB 196C3671 6E6B06E7 FED41B76 89D32BE0 10DA7A5A 67DD4ACC F9B9DF6F 8EBEEFF9 17B7BE43 60B08ED5 D6D6A3E8 A1D1937E 38D8C2C4 4FDFF252 D1BB67F1 A6BC5767 3FB506DD 48B2364B D80D2BDA AF0A1B4C 36034AF6 41047A60 DF60EFC3 A867DF55 316E8EEF 4669BE79 CB61B38C BC66831A 256FD2A0 5268E236 CC0C7795 BB0B4703 220216B9 5505262F C5BA3BBE B2BD0B28 2BB45A92 5CB36A04 C2D7FFA7 B5D0CF31 2CD99E8B 5BDEAE1D 9B64C2B0 EC63F226 756AA39C 026D930A 9C0906A9 EB0E363F 72076785 05005713 95BF4A82 E2B87A14 7BB12BAE 0CB61B38 92D28E9B E5D5BE0D 7CDCEFB7 0BDBDF21 86D3D2D4 F1D4E242 68DDB3F8 1FDA836E 81BE16CD F6B9265B 6FB077E1 18B74777 88085AE6 FF0F6A70 66063BCA 11010B5C 8F659EFF F862AE69 616BFFD3 166CCF45 A00AE278 D70DD2EE 4E048354 3903B3C2 A7672661 D06016F7 4969474D 3E6E77DB AED16A4A D9D65ADC 40DF0B66 37D83BF0 A9BCAE53 DEBB9EC5 47B2CF7F 30B5FFE9 BDBDF21C CABAC28A 53B39330 24B4A3A6 BAD03605 CDD70693 54DE5729 23D967BF B3667A2E C4614AB8 5D681B02 2A6F2B94 B40BBE37 C30C8EA1 5A05DF1B 2D02EF8D"; 571 | crc = 0 ^ (-1); 572 | var n = 0; //a number between 0 and 255 573 | var x = 0; //an hex number 574 | 575 | for (var i = 0, iTop = str.length; i < iTop; i++) { 576 | n = (crc ^ str.charCodeAt(i)) & 0xFF; 577 | x = "0x" + table.substr(n * 9, 8); 578 | crc = (crc >>> 8) ^ x; 579 | } 580 | return (crc ^ (-1)) >>> 0; 581 | }, 582 | getCrcCode: function (e) { 583 | var t = "0000000", 584 | n = ""; 585 | try { 586 | n = this.Crc32(e).toString(36), t = this.addZeroToSeven(n) 587 | } catch (e) {} 588 | return t 589 | }, 590 | addZeroToSeven: function (e) { 591 | return e && e.length >= 7 ? e : ("0000000" + String(e)).substr(-7) 592 | }, 593 | getInRange: function (e, t, n) { 594 | var r = []; 595 | return e.map(function (e, i) { 596 | e >= t && e <= n && r.push(e) 597 | }), r 598 | }, 599 | RecursiveSorting: function () { 600 | var e = this, 601 | t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}, 602 | n = {}, 603 | r = t; 604 | if ("[object Object]" == Object.prototype.toString.call(r)) { 605 | var i = Object.keys(r).sort(function (e, t) { 606 | return e < t ? -1 : e > t ? 1 : 0 607 | }); 608 | i.forEach(function (t) { 609 | var i = r[t]; 610 | if ("[object Object]" === Object.prototype.toString.call(i)) { 611 | var o = e.RecursiveSorting(i); 612 | n[t] = o 613 | } else if ("[object Array]" === Object.prototype.toString.call(i)) { 614 | for (var a = [], s = 0; s < i.length; s++) { 615 | var u = i[s]; 616 | if ("[object Object]" === Object.prototype.toString.call(u)) { 617 | var c = e.RecursiveSorting(u); 618 | a[s] = c 619 | } else a[s] = u 620 | } 621 | n[t] = a 622 | } else n[t] = i 623 | }) 624 | } else n = t; 625 | return n 626 | }, 627 | objToString2: function () { 628 | var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}, 629 | t = ""; 630 | return Object.keys(e).forEach(function (n) { 631 | var r = e[n]; 632 | null != r && (t += r instanceof Object || r instanceof Array ? "".concat("" === t ? "" : "&").concat(n, "=").concat(JSON.stringify(r)) : "".concat("" === t ? "" : "&").concat(n, "=").concat(r)) 633 | }), t 634 | }, 635 | getKey: function (e, t, n) { 636 | let r = this; 637 | return { 638 | 1: function () { 639 | var e = r.getNumberInString(t), 640 | i = r.getSpecialPosition(n); 641 | return Math.abs(e - i) 642 | }, 643 | 2: function () { 644 | var e = r.getSpecialPosition(t, !1), 645 | i = r.getSpecialPosition(n); 646 | return r.minusByByte(e, i) 647 | }, 648 | 3: function () { 649 | var e = t.slice(0, 5), 650 | i = String(n).slice(-5); 651 | return r.minusByByte(e, i) 652 | }, 653 | 4: function () { 654 | return r.encrypt1(t, n) 655 | }, 656 | 5: function () { 657 | return r.encrypt2(t, n) 658 | }, 659 | 6: function () { 660 | return r.encrypt3(t, n) 661 | } 662 | } [e]() 663 | }, 664 | decipherJoyToken: function (e, t) { 665 | let m = this; 666 | var n = { 667 | jjt: "a", 668 | expire: m.getCurrentTime(), 669 | outtime: 3, 670 | time_correction: !1 671 | }; 672 | var r = "", 673 | i = e.indexOf(t) + t.length, 674 | o = e.length; 675 | if ((r = (r = e.slice(i, o).split(".")).map(function (e) { 676 | return m.atobPolyfill(e) 677 | }))[1] && r[0] && r[2]) { 678 | var a = r[0].slice(2, 7), 679 | s = r[0].slice(7, 9), 680 | u = m.xorEncrypt(r[1] || "", a).split("~"); 681 | n.outtime = u[3] - 0, n.encrypt_id = u[2], n.jjt = "t"; 682 | var c = u[0] - 0 || 0; 683 | c && "number" == typeof c && (n.time_correction = !0, n.expire = c); 684 | var l = c - m.getCurrentTime() || 0; 685 | return n.q = l, n.cf_v = s, n 686 | } 687 | return n 688 | }, 689 | sha1: function (s) { 690 | var data = new Uint8Array(this.encodeUTF8(s)) 691 | var i, j, t; 692 | var l = ((data.length + 8) >>> 6 << 4) + 16, 693 | s = new Uint8Array(l << 2); 694 | s.set(new Uint8Array(data.buffer)), s = new Uint32Array(s.buffer); 695 | for (t = new DataView(s.buffer), i = 0; i < l; i++) s[i] = t.getUint32(i << 2); 696 | s[data.length >> 2] |= 0x80 << (24 - (data.length & 3) * 8); 697 | s[l - 1] = data.length << 3; 698 | var w = [], 699 | f = [ 700 | function () { 701 | return m[1] & m[2] | ~m[1] & m[3]; 702 | }, 703 | function () { 704 | return m[1] ^ m[2] ^ m[3]; 705 | }, 706 | function () { 707 | return m[1] & m[2] | m[1] & m[3] | m[2] & m[3]; 708 | }, 709 | function () { 710 | return m[1] ^ m[2] ^ m[3]; 711 | } 712 | ], 713 | rol = function (n, c) { 714 | return n << c | n >>> (32 - c); 715 | }, 716 | k = [1518500249, 1859775393, -1894007588, -899497514], 717 | m = [1732584193, -271733879, null, null, -1009589776]; 718 | m[2] = ~m[0], m[3] = ~m[1]; 719 | for (var i = 0; i < s.length; i += 16) { 720 | var o = m.slice(0); 721 | for (j = 0; j < 80; j++) 722 | w[j] = j < 16 ? s[i + j] : rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1), 723 | t = rol(m[0], 5) + f[j / 20 | 0]() + m[4] + w[j] + k[j / 20 | 0] | 0, 724 | m[1] = rol(m[1], 30), m.pop(), m.unshift(t); 725 | for (j = 0; j < 5; j++) m[j] = m[j] + o[j] | 0; 726 | }; 727 | t = new DataView(new Uint32Array(m).buffer); 728 | for (var i = 0; i < 5; i++) m[i] = t.getUint32(i << 2); 729 | 730 | var hex = Array.prototype.map.call(new Uint8Array(new Uint32Array(m).buffer), function (e) { 731 | return (e < 16 ? "0" : "") + e.toString(16); 732 | }).join(""); 733 | return hex.toString().toUpperCase(); 734 | }, 735 | encodeUTF8: function (s) { 736 | var i, r = [], 737 | c, x; 738 | for (i = 0; i < s.length; i++) 739 | if ((c = s.charCodeAt(i)) < 0x80) r.push(c); 740 | else if (c < 0x800) r.push(0xC0 + (c >> 6 & 0x1F), 0x80 + (c & 0x3F)); 741 | else { 742 | if ((x = c ^ 0xD800) >> 10 == 0) //对四字节UTF-16转换为Unicode 743 | c = (x << 10) + (s.charCodeAt(++i) ^ 0xDC00) + 0x10000, 744 | r.push(0xF0 + (c >> 18 & 0x7), 0x80 + (c >> 12 & 0x3F)); 745 | else r.push(0xE0 + (c >> 12 & 0xF)); 746 | r.push(0x80 + (c >> 6 & 0x3F), 0x80 + (c & 0x3F)); 747 | }; 748 | return r; 749 | }, 750 | gettoken: function (UA) { 751 | const https = require('https'); 752 | var body = `content={"appname":"50082","whwswswws":"","jdkey":"","body":{"platform":"1"}}`; 753 | return new Promise((resolve, reject) => { 754 | let options = { 755 | hostname: "bh.m.jd.com", 756 | port: 443, 757 | path: "/gettoken", 758 | method: "POST", 759 | rejectUnauthorized: false, 760 | headers: { 761 | "Content-Type": "text/plain;charset=UTF-8", 762 | "Host": "bh.m.jd.com", 763 | "Origin": "https://h5.m.jd.com", 764 | "X-Requested-With": "com.jingdong.app.mall", 765 | "Referer": "https://h5.m.jd.com/babelDiy/Zeus/41Lkp7DumXYCFmPYtU3LTcnTTXTX/index.html", 766 | "User-Agent": UA, 767 | } 768 | } 769 | const req = https.request(options, (res) => { 770 | res.setEncoding('utf-8'); 771 | let rawData = ''; 772 | res.on('error', reject); 773 | res.on('data', chunk => rawData += chunk); 774 | res.on('end', () => resolve(rawData)); 775 | }); 776 | req.write(body); 777 | req.on('error', reject); 778 | req.end(); 779 | }); 780 | }, 781 | get_blog: function (pin) { 782 | let encrypefun = { 783 | "z": function (p1, p2) { 784 | var str = ""; 785 | for (var vi = 0; vi < p1.length; vi++) { 786 | str += (p1.charCodeAt(vi) ^ p2.charCodeAt(vi % p2.length)).toString("16"); 787 | } 788 | return str; 789 | }, 790 | "y": function (p1, p2) { 791 | var str = ""; 792 | for (var vi = 0; vi < p1.length; vi++) { 793 | str += (p1.charCodeAt(vi) & p2.charCodeAt(vi % p2.length)).toString("16"); 794 | } 795 | return str; 796 | }, 797 | "x": function (p1, p2) { 798 | p1 = p1.substring(1) + p1.substring(0, 1); 799 | p2 = p2.substring((p2.length - 1)) + p2.substring(0, (p2.length - 1)); 800 | var str = ""; 801 | for (var vi = 0; vi < p1.length; vi++) { 802 | str += (p1.charCodeAt(vi) ^ p2.charCodeAt(vi % p2.length)).toString("16"); 803 | } 804 | return str; 805 | }, 806 | "jiami": function (po, p1) { 807 | var str = ""; 808 | for (vi = 0; vi < po.length; vi++) { 809 | str += String.fromCharCode(po.charCodeAt(vi) ^ p1.charCodeAt(vi % p1.length)); 810 | } 811 | return new Buffer.from(str).toString('base64'); 812 | } 813 | } 814 | const ids = ["x", "y", "z"]; 815 | var encrypeid = ids[Math.floor(Math.random() * 1e8) % ids.length]; 816 | var timestamp = this.getCurrentTime(); 817 | var nonce_str = this.getRandomWord(10); 818 | var isDefaultKey = "B"; 819 | refer = "com.miui.home"; 820 | encrypeid = "x"; 821 | var json = { 822 | r: refer, 823 | a: "", 824 | c: "a", 825 | v: "2.5.8", 826 | t: timestamp.toString().substring(timestamp.toString().length - 4) 827 | } 828 | var token = md5(pin); 829 | var key = encrypefun[encrypeid](timestamp.toString(), nonce_str); 830 | //console.log(key); 831 | var cipher = encrypefun["jiami"](JSON.stringify(json), key); 832 | return `${timestamp}~1${nonce_str+token}~${encrypeid}~~~${isDefaultKey}~${cipher}~${this.getCrcCode(cipher)}`; 833 | }, 834 | get_risk_result: async function ($) { 835 | var appid = "50082"; 836 | var TouchSession = this.getTouchSession(); 837 | if (!$.joyytoken || $.joyytoken_count > 18) { 838 | $.joyytoken = JSON.parse(await this.gettoken($.UA))["joyytoken"]; 839 | $.joyytoken_count = 0; 840 | } 841 | $.joyytoken_count++; 842 | let riskData; 843 | switch ($.action) { 844 | case 'startTask': 845 | riskData = { 846 | taskId: $.id 847 | }; 848 | break; 849 | case 'chargeScores': 850 | riskData = { 851 | bubleId: $.id 852 | }; 853 | break; 854 | case 'sign': 855 | riskData = {}; 856 | default: 857 | break; 858 | } 859 | 860 | var random = Math.floor(1e+6 * Math.random()).toString().padEnd(6, '8'); 861 | var senddata = this.objToString2(this.RecursiveSorting({ 862 | pin: $.UserName, 863 | random, 864 | ...riskData 865 | })); 866 | var time = this.getCurrentTime(); 867 | var encrypt_id = this.decipherJoyToken(appid + $.joyytoken, appid)["encrypt_id"].split(","); 868 | var nonce_str = this.getRandomWord(10); 869 | var key = this.getKey(encrypt_id[2], nonce_str, time.toString()); 870 | 871 | var str1 = `${senddata}&token=${$.joyytoken}&time=${time}&nonce_str=${nonce_str}&key=${key}&is_trust=1`; 872 | str1 = this.sha1(str1); 873 | var outstr = [time, "1" + nonce_str + $.joyytoken, encrypt_id[2] + "," + encrypt_id[3]]; 874 | outstr.push(str1); 875 | outstr.push(this.getCrcCode(str1)); 876 | outstr.push("C"); 877 | var data = {} 878 | data = { 879 | tm: [], 880 | tnm: [ 'd5-9L,JU,8DB,a,t', 'd7-9L,JU,8HF,a,t', 'd1-9M,JV,8JH,u,t' ], 881 | grn: $.joyytoken_count, 882 | ss: TouchSession, 883 | wed: 'ttttt', 884 | wea: 'ffttttua', 885 | pdn: [ 7, (Math.floor(Math.random() * 1e8) % 180) + 1, 6, 11, 1, 5 ], 886 | jj: 1, 887 | cs: hexMD5("Object.P.=&HTMLDocument.Ut.=https://storage.360buyimg.com/babel/00750963/1942873/production/dev/main.e5d1c436.js"), 888 | np: 'iPhone', 889 | t: time, 890 | jk: `${$.UUID}`, 891 | fpb: '', 892 | nv: 'Apple Computer, Inc.', 893 | nav: '167741', 894 | scr: [ 896, 414 ], 895 | ro: [ 896 | 'iPhone12,1', 897 | 'iOS', 898 | '14.3', 899 | '10.0.10', 900 | '167741', 901 | `${$.UUID}`, 902 | 'a' 903 | ], 904 | ioa: 'fffffftt', 905 | aj: 'u', 906 | ci: 'w3.1.0', 907 | cf_v: '01', 908 | bd: senddata, 909 | mj: [1, 0, 0], 910 | blog: "a", 911 | msg: '' 912 | } 913 | data = new Buffer.from(this.xorEncrypt(JSON.stringify(data), key)).toString('base64'); 914 | outstr.push(data); 915 | outstr.push(this.getCrcCode(data)); 916 | return { 917 | extraData: { 918 | log: outstr.join("~"), 919 | sceneid: "DDhomePageh5" 920 | }, 921 | ...riskData, 922 | random, 923 | }; 924 | } 925 | }; 926 | module.exports = { 927 | utils 928 | } -------------------------------------------------------------------------------- /cleancart_activity.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | */ 4 | let jdSignUrl = '' // 算法url 5 | let Authorization = '' // 算法url token 有则填 6 | let got = ''; 7 | try{ 8 | got = require('got'); 9 | }catch(e){ 10 | console.log('请添加依赖模块"got"') 11 | } 12 | 13 | 14 | jdSignUrl = process.env.gua_cleancart_SignUrl ? process.env.gua_cleancart_SignUrl : `${jdSignUrl}` 15 | Authorization = process.env.gua_cleancart_Authorization ? process.env.gua_cleancart_Authorization : `${Authorization}` 16 | if(Authorization && Authorization.indexOf("Bearer ") === -1) Authorization = `Bearer ${Authorization}` 17 | let cookie = '' 18 | let out = false 19 | 20 | async function clean(ck,url,goodsArr){ 21 | if(!got) return false 22 | return new Promise(async resolve => { 23 | let msg = false 24 | try{ 25 | if(!ck) return '' 26 | if(!jdSignUrl) jdSignUrl = url 27 | cookie = ck 28 | if(jdSignUrl.indexOf("://jd.smiek.tk/") > -1) { 29 | resolve(msg) 30 | return false 31 | } 32 | let signBody = `{"homeWishListUserFlag":"1","userType":"0","updateTag":true,"showPlusEntry":"2","hitNewUIStatus":"1","cvhv":"049591","cartuuid":"hjudwgohxzVu96krv/T6Hg==","adid":""}` 33 | let body = await jdSign('cartClearQuery', signBody) 34 | if(out) return 35 | if(!body){ 36 | console.log('获取不到算法') 37 | return 38 | } 39 | let data = await jdApi('cartClearQuery',body) 40 | let res = jsonParse(data) 41 | if(typeof res == 'object' && res){ 42 | if(res.resultCode == 0){ 43 | if(res.mainTitle.indexOf('购物车是空的') > -1){ 44 | msg = [] 45 | }else if(!res.clearCartInfo || !res.subTitle){ 46 | console.log(res.mainTitle) 47 | }else{ 48 | let num = 0 49 | if(res.subTitle){ 50 | num = res.subTitle.match(/共(\d+)件商品/).length > 0 && res.subTitle.match(/共(\d+)件商品/)[1] || 0 51 | console.log(res.subTitle) 52 | } 53 | // console.log(`共${num}件商品`) 54 | if(num != 0){ 55 | let operations = [] 56 | let operNum = 0 57 | let goodsArrs = [] 58 | let goodsArrsFlag = false 59 | for(let a of res.clearCartInfo || {}){ 60 | // console.log(a.groupName) 61 | // if(a.groupName.indexOf('7天内加入购物车') > -1){ 62 | if(typeof goodsArr !== 'object'){ 63 | goodsArrs = [...goodsArrs,...a.groupDetails] 64 | goodsArrsFlag = true 65 | }else{ 66 | for(let s of a.groupDetails || []){ 67 | if(typeof goodsArr === 'object'){ 68 | let XBDetail = goodsArr.filter((x) => x.skuId === s.skuId) 69 | if(XBDetail.length == 0){ 70 | // console.log(s.unusable,s.skuUuid,s.name) 71 | operNum += s.clearSkus && s.clearSkus.length || 1; 72 | operations.push({ 73 | "itemType": s.itemType+"", 74 | "suitType": s.suitType, 75 | "skuUuid": s.skuUuid+"", 76 | "itemId": s.itemId || s.skuId, 77 | "useUuid": typeof s.useUuid !== 'undefined' && s.useUuid || false 78 | }) 79 | } 80 | } 81 | } 82 | } 83 | // } 84 | } 85 | if(goodsArrsFlag){ 86 | msg = goodsArrs || [] 87 | return 88 | } 89 | console.log(`准备清空${operNum}件商品`) 90 | if(operations.length == 0){ 91 | console.log(`清空${operNum}件商品|没有找到要清空的商品`) 92 | }else{ 93 | let clearBody = `{"homeWishListUserFlag":"1","userType":"0","updateTag":false,"showPlusEntry":"2","hitNewUIStatus":"1","cvhv":"049591","cartuuid":"hjudwgohxzVu96krv/T6Hg==","operations":${jsonStringify(operations)},"adid":"","coord_type":"0"}` 94 | clearBody = await jdSign('cartClearRemove', clearBody) 95 | if(out) return 96 | if(!clearBody){ 97 | console.log('获取不到算法') 98 | }else{ 99 | let clearData = await jdApi('cartClearRemove',clearBody) 100 | let clearRes = jsonParse(clearData) 101 | if(typeof clearRes == 'object'){ 102 | if(clearRes.resultCode == 0) { 103 | console.log(`清空${operNum}件商品|✅\n`) 104 | }else if(clearRes.mainTitle){ 105 | console.log(`清空${operNum}件商品|${clearRes.mainTitle}\n`) 106 | }else{ 107 | console.log(`清空${operNum}件商品|❌\n`) 108 | console.log(clearData) 109 | } 110 | }else{ 111 | console.log(`清空${operNum}件商品|❌\n`) 112 | console.log(clearData) 113 | } 114 | } 115 | } 116 | }else if(res.mainTitle){ 117 | if(res.mainTitle.indexOf('购物车是空的') > -1){ 118 | msg = [] 119 | } 120 | console.log(res.mainTitle) 121 | }else{ 122 | console.log(data) 123 | } 124 | } 125 | }else{ 126 | console.log(data) 127 | } 128 | }else{ 129 | console.log(data) 130 | } 131 | }catch(e){ 132 | console.log(e) 133 | } finally { 134 | resolve(msg); 135 | } 136 | }) 137 | } 138 | 139 | function jdApi(functionId,body) { 140 | if(!functionId || !body) return 141 | return new Promise(resolve => { 142 | let opts = taskPostUrl(`/client.action?functionId=${functionId}`, body) 143 | got.post(opts).then( 144 | (resp) => { 145 | const {body:data } = resp 146 | try { 147 | let res = jsonParse(data); 148 | if(typeof res == 'object'){ 149 | if(res.mainTitle) console.log(res.mainTitle) 150 | if(res.resultCode == 0){ 151 | resolve(res); 152 | }else if (res.tips && res.tips.includes("正在努力加载")){ 153 | console.log("请求太快,ip被限制了") 154 | out = true 155 | } 156 | } 157 | } catch (e) { 158 | console.log(e) 159 | } finally { 160 | resolve(''); 161 | } 162 | }, 163 | (err) => { 164 | try { 165 | const { message: error, response: resp } = err 166 | console.log(`${jsonStringify(error)}`) 167 | console.log(`${functionId} API请求失败,请检查网路重试`) 168 | } catch (e) { 169 | console.log(e) 170 | } finally { 171 | resolve('') 172 | } 173 | } 174 | ) 175 | }) 176 | } 177 | 178 | function jdSign(fn,body) { 179 | let sign = '' 180 | let flag = false 181 | try{ 182 | const fs = require('fs'); 183 | if (fs.existsSync('./gua_encryption_sign.js')) { 184 | const encryptionSign = require('./gua_encryption_sign'); 185 | sign = encryptionSign.getSign(fn, body) 186 | }else{ 187 | flag = true 188 | } 189 | sign = sign.data && sign.data.sign && sign.data.sign || '' 190 | }catch(e){ 191 | flag = true 192 | } 193 | if(!flag) return sign 194 | if(!jdSignUrl.match(/^https?:\/\//)){ 195 | console.log('请填写算法url') 196 | out = true 197 | return '' 198 | } 199 | return new Promise((resolve) => { 200 | let options = { 201 | url: jdSignUrl, 202 | body:`{"fn":"${fn}","body":${body}}`, 203 | headers: { 204 | 'Accept':'*/*', 205 | "accept-encoding": "gzip, deflate, br", 206 | 'Content-Type': 'application/json', 207 | }, 208 | timeout:30000 209 | } 210 | if(Authorization) options["headers"]["Authorization"] = Authorization 211 | got.post(options).then( 212 | (resp) => { 213 | const {body:data } = resp 214 | try { 215 | let res = jsonParse(data) 216 | if(typeof res === 'object' && res){ 217 | if(res.code && res.code == 200 && res.data){ 218 | if(res.data.sign) sign = res.data.sign || '' 219 | if(sign != '') resolve(sign) 220 | }else{ 221 | console.log(data) 222 | } 223 | }else{ 224 | console.log(data) 225 | } 226 | } catch (e) { 227 | console.log(e) 228 | } finally { 229 | resolve('') 230 | } 231 | }, 232 | (err) => { 233 | try { 234 | const { message: error, response: resp } = err 235 | console.log(`${jsonStringify(error)}`) 236 | console.log(`算法url API请求失败,请检查网路重试`) 237 | } catch (e) { 238 | console.log(e) 239 | } finally { 240 | resolve('') 241 | } 242 | } 243 | 244 | ) 245 | }) 246 | } 247 | 248 | function jsonParse(str) { 249 | try { 250 | return JSON.parse(str); 251 | } catch (e) { 252 | return str; 253 | } 254 | } 255 | 256 | function jsonStringify(arr) { 257 | try { 258 | return JSON.stringify(arr); 259 | } catch (e) { 260 | return arr; 261 | } 262 | } 263 | 264 | function taskPostUrl(url, body) { 265 | return { 266 | url: `https://api.m.jd.com${url}`, 267 | body: body, 268 | headers: { 269 | "Accept": "*/*", 270 | "Accept-Language": "zh-cn", 271 | "Accept-Encoding": "gzip, deflate, br", 272 | "Connection": "keep-alive", 273 | "Content-Type": "application/x-www-form-urlencoded", 274 | 'Cookie': `${cookie}`, 275 | "User-Agent": "JD4iPhone/167853 (iPhone; iOS; Scale/2.00)" , 276 | } 277 | } 278 | } 279 | 280 | module.exports = { 281 | clean 282 | } -------------------------------------------------------------------------------- /gua_MMdou.js: -------------------------------------------------------------------------------- 1 | /* 2 | // https://h5.m.jd.com/rn/42yjy8na6pFsq1cx9MJQ5aTgu3kX/index.html 3 | 4 | 入口:APP首页-领京豆-升级赚京豆 5 | cron:21 9 * * * 6 | 21 9 * * * https://raw.githubusercontent.com/smiek2121/scripts/master/gua_MMdou.js, tag=MM领京豆, enabled=true 7 | 8 | */ 9 | 10 | const $ = new Env('MM领京豆'); 11 | const jdCookieNode = $.isNode() ? require('./jdCookie.js') : ''; 12 | const notify = $.isNode() ? require('./sendNotify') : ''; 13 | 14 | const jdVersion = '10.1.2' 15 | const iphoneVersion = [Math.ceil(Math.random()*2+12),Math.ceil(Math.random()*4)] 16 | const UA = `jdapp;iPhone;${jdVersion};${Math.ceil(Math.random()*2+12)}.${Math.ceil(Math.random()*4)};${randomString(40)};network/wifi;model/iPhone12,1;addressid/0;appBuild/167802;jdSupportDarkMode/0;Mozilla/5.0 (iPhone; CPU iPhone OS ${iphoneVersion[0]}_${iphoneVersion[1]} like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1` 17 | const UUID = UA.split(';') && UA.split(';')[4] || '' 18 | function randomString(e) { 19 | e = e || 32; 20 | let t = "abcdef0123456789", a = t.length, n = ""; 21 | for (i = 0; i < e; i++) 22 | n += t.charAt(Math.floor(Math.random() * a)); 23 | return n 24 | } 25 | 26 | let cookiesArr = []; 27 | let message = '' 28 | if ($.isNode()) { 29 | Object.keys(jdCookieNode).forEach((item) => { 30 | cookiesArr.push(jdCookieNode[item]) 31 | }) 32 | if (process.env.JD_DEBUG && process.env.JD_DEBUG === 'false') console.log = () => { }; 33 | } else { 34 | cookiesArr = [$.getdata('CookieJD'), $.getdata('CookieJD2'), ...jsonParse($.getdata('CookiesJD') || "[]").map(item => item.cookie)].filter(item => !!item); 35 | } 36 | 37 | !(async () => { 38 | if (!cookiesArr[0]) { 39 | $.msg('【京东账号一】宠汪汪积分兑换奖品失败', '【提示】请先获取京东账号一cookie\n直接使用NobyDa的京东签到获取', 'https://bean.m.jd.com/bean/signIndex.action', { "open-url": "https://bean.m.jd.com/bean/signIndex.action" }); 40 | return 41 | } 42 | for (let i = 0; i < cookiesArr.length; i++) { 43 | if (cookiesArr[i]) { 44 | $.cookie = cookiesArr[i] + ''; 45 | $.UserName = decodeURIComponent($.cookie.match(/pt_pin=([^; ]+)(?=;?)/) && $.cookie.match(/pt_pin=([^; ]+)(?=;?)/)[1]) 46 | $.index = i + 1; 47 | $.bean = 0 48 | console.log(`\n*****开始【京东账号${$.index}】${$.UserName}****\n`); 49 | await run(); 50 | if($.bean > 0) message += `【京东账号${$.index}】获得${$.bean}京豆\n` 51 | } 52 | } 53 | if(message){ 54 | $.msg($.name, ``, `${message}\n入口:APP首页-领京豆-升级赚京豆`); 55 | if ($.isNode()){ 56 | await notify.sendNotify(`${$.name}`, `${message}\n入口:APP首页-领京豆-升级赚京豆`); 57 | } 58 | } 59 | })() 60 | .catch((e) => { 61 | $.log('', `❌ ${$.name}, 失败! 原因: ${e}!`, '') 62 | }).finally(() => { 63 | $.done(); 64 | }) 65 | 66 | async function run() { 67 | try{ 68 | $.taskList = []; 69 | await takePostRequest('beanTaskList') 70 | // await takePostRequest('morningGetBean') 71 | console.log(`做任务\n`); 72 | if($.viewAppHome && $.viewAppHome.takenTask == false){ 73 | $.IconDoTaskFlag = 0 74 | console.log(`做任务:${$.viewAppHome.mainTitle};等待完成`); 75 | await takePostRequest('beanHomeIconDoTask') 76 | await $.wait(getRndInteger(2500, 3500)) 77 | } 78 | if($.viewAppHome && $.viewAppHome.doneTask == false){ 79 | $.IconDoTaskFlag = 1 80 | console.log(`做任务:${$.viewAppHome.mainTitle}`); 81 | await takePostRequest('beanHomeIconDoTask') 82 | await $.wait(getRndInteger(1000, 1500)) 83 | } 84 | let s = 0 85 | do{ 86 | s++; 87 | await task() 88 | await $.wait(getRndInteger(1000, 1500)) 89 | await takePostRequest('beanTaskList1') 90 | }while ($.taskFlag && s < 4) 91 | 92 | await $.wait(getRndInteger(1000, 1500)) 93 | }catch (e) { 94 | console.log(e); 95 | } 96 | } 97 | 98 | async function task() { 99 | await $.wait(getRndInteger(1000, 1500)) 100 | //做任务 101 | $.taskFlag = false 102 | for (let i = 0; i < $.taskList.length; i++) { 103 | $.oneTask = $.taskList[i]; 104 | if ($.oneTask.status === 1) { 105 | $.activityInfoList = $.oneTask.subTaskVOS; 106 | for (let j = 0; j < $.activityInfoList.length; j++) { 107 | $.taskFlag = true 108 | $.oneActivityInfo = $.activityInfoList[j]; 109 | console.log(`做任务:${$.oneActivityInfo.title || $.oneTask.taskName};等待完成`); 110 | $.actionType = 0 111 | if($.oneTask.taskType == 9 || $.oneTask.taskType == 8){ 112 | $.actionType = 1 113 | await takePostRequest('beanDoTask'); 114 | await $.wait(getRndInteger($.oneTask.waitDuration && $.oneTask.waitDuration*1000 + 1000 || 6500, $.oneTask.waitDuration && $.oneTask.waitDuration*1000 + 2000 || 7000 )) 115 | $.actionType = 0 116 | } 117 | await takePostRequest('beanDoTask'); 118 | await $.wait(getRndInteger(4000, 5500)) 119 | } 120 | }else if ($.oneTask.status === 2){ 121 | console.log(`任务:${$.oneTask.taskName};已完成`); 122 | }else{ 123 | console.log(`任务:${$.oneTask.taskName};未能完成\n${JSON.stringify($.oneTask)}`); 124 | } 125 | } 126 | } 127 | 128 | async function takePostRequest(type) { 129 | let body = ``; 130 | let myRequest = ``; 131 | switch (type) { 132 | case 'beanTaskList': 133 | case 'beanTaskList1': 134 | body = `{"viewChannel":"AppHome"}`; 135 | myRequest = await getGetRequest(`beanTaskList`, escape(body)); 136 | break; 137 | case 'beanHomeIconDoTask': 138 | body = `{"flag":"${$.IconDoTaskFlag}","viewChannel":"AppHome"}`; 139 | myRequest = await getGetRequest(`beanHomeIconDoTask`, escape(body)); 140 | break; 141 | case 'beanDoTask': 142 | body = `{"actionType":${$.actionType},"taskToken":"${$.oneActivityInfo.taskToken}"}`; 143 | myRequest = await getGetRequest(`beanDoTask`, escape(body)); 144 | break; 145 | case 'morningGetBean': 146 | body = `{"fp":"-1","shshshfp":"-1","shshshfpa":"-1","referUrl":"-1","userAgent":"-1","jda":"-1","rnVersion":"3.9"}`; 147 | myRequest = await getGetRequest(`morningGetBean`, escape(body)); 148 | break; 149 | default: 150 | console.log(`错误${type}`); 151 | } 152 | if (myRequest) { 153 | return new Promise(async resolve => { 154 | $.get(myRequest, (err, resp, data) => { 155 | try { 156 | // console.log(data); 157 | dealReturn(type, data); 158 | } catch (e) { 159 | $.logErr(e, resp) 160 | } finally { 161 | resolve(); 162 | } 163 | }) 164 | }) 165 | } 166 | } 167 | 168 | async function dealReturn(type, res) { 169 | try { 170 | data = JSON.parse(res); 171 | } catch (e) { 172 | console.log(`返回异常:${res}`); 173 | return; 174 | } 175 | switch (type) { 176 | case 'beanTaskList': 177 | if (data.code == 0 && data.data) { 178 | console.log(`当前等级:${data.data.curLevel || 0} 下一级可领取:${data.data.nextLevelBeanNum || 0}京豆`) 179 | $.taskList = data.data.taskInfos && data.data.taskInfos || []; 180 | $.viewAppHome = data.data.viewAppHome && data.data.viewAppHome || {}; 181 | } else if (data.data && data.data.bizMsg) { 182 | console.log(data.data.bizMsg); 183 | } else { 184 | console.log(res); 185 | } 186 | break; 187 | case 'beanTaskList1': 188 | if (data.code == 0 && data.data) { 189 | $.taskList = data.data.taskInfos && data.data.taskInfos || []; 190 | } else if (data.data && data.data.bizMsg) { 191 | console.log(data.data.bizMsg); 192 | } else { 193 | console.log(res); 194 | } 195 | break; 196 | case 'beanDoTask': 197 | case 'beanHomeIconDoTask': 198 | if (data.data && (data.data.bizMsg || data.data.remindMsg)) { 199 | console.log((data.data.bizMsg || data.data.remindMsg)); 200 | if(data.data.growthResult && data.data.growthResult.sceneLevelConfig){ 201 | console.log(`获得:${data.data.growthResult.sceneLevelConfig.beanNum || 0}京豆`) 202 | $.bean += Number(data.data.growthResult.sceneLevelConfig.beanNum) || 0 203 | if(!data.data.growthResult.sceneLevelConfig.beanNum){ 204 | console.log(JSON.stringify(data.data.growthResult.sceneLevelConfig)) 205 | } 206 | } 207 | } else { 208 | console.log(res); 209 | } 210 | break; 211 | case 'morningGetBean': 212 | if (data.code == 0 && data.data && data.data.awardResultFlag+"" == "1") { 213 | console.log(`获得:${data.data.beanNum || 0}京豆`) 214 | $.bean += Number(data.data.beanNum) || 0 215 | } else if (data.data && data.data.bizMsg) { 216 | console.log(data.data.bizMsg); 217 | } else { 218 | console.log(res); 219 | } 220 | break; 221 | default: 222 | console.log(`未判断的异常${type}`); 223 | } 224 | } 225 | async function getGetRequest(type, body) { 226 | let url = `https://api.m.jd.com/client.action?functionId=${type}&body=${body}&appid=ld&client=apple&clientVersion=${jdVersion}&networkType=wifi&osVersion=${iphoneVersion[0]}.${iphoneVersion[1]}&uuid=${UUID}&openudid=${UUID}`; 227 | const method = `GET`; 228 | const headers = { 229 | "Accept": "*/*", 230 | "Accept-Encoding": "gzip, deflate, br", 231 | "Accept-Language": "zh-cn", 232 | 'Cookie': $.cookie, 233 | "Referer": "https://h5.m.jd.com/", 234 | "User-Agent": UA, 235 | }; 236 | return {url: url, method: method, headers: headers}; 237 | } 238 | // 随机数 239 | function getRndInteger(min, max) { 240 | return Math.floor(Math.random() * (max - min) ) + min; 241 | } 242 | function jsonParse(str) { 243 | if (typeof str == "string") { 244 | try { 245 | return JSON.parse(str); 246 | } catch (e) { 247 | console.log(e); 248 | $.msg($.name, '', '请勿随意在BoxJs输入框修改内容\n建议通过脚本去获取cookie') 249 | return []; 250 | } 251 | } 252 | } 253 | 254 | 255 | 256 | function Env(t,e){"undefined"!=typeof process&&JSON.stringify(process.env).indexOf("GITHUB")>-1&&process.exit(0);class s{constructor(t){this.env=t}send(t,e="GET"){t="string"==typeof t?{url:t}:t;let s=this.get;return"POST"===e&&(s=this.post),new Promise((e,i)=>{s.call(this,t,(t,s,r)=>{t?i(t):e(s)})})}get(t){return this.send.call(this.env,t)}post(t){return this.send.call(this.env,t,"POST")}}return new class{constructor(t,e){this.name=t,this.http=new s(this),this.data=null,this.dataFile="box.dat",this.logs=[],this.isMute=!1,this.isNeedRewrite=!1,this.logSeparator="\n",this.startTime=(new Date).getTime(),Object.assign(this,e),this.log("",`\ud83d\udd14${this.name}, \u5f00\u59cb!`)}isNode(){return"undefined"!=typeof module&&!!module.exports}isQuanX(){return"undefined"!=typeof $task}isSurge(){return"undefined"!=typeof $httpClient&&"undefined"==typeof $loon}isLoon(){return"undefined"!=typeof $loon}isShadowrocket(){return"undefined"!=typeof $rocket}toObj(t,e=null){try{return JSON.parse(t)}catch{return e}}toStr(t,e=null){try{return JSON.stringify(t)}catch{return e}}getjson(t,e){let s=e;const i=this.getdata(t);if(i)try{s=JSON.parse(this.getdata(t))}catch{}return s}setjson(t,e){try{return this.setdata(JSON.stringify(t),e)}catch{return!1}}getScript(t){return new Promise(e=>{this.get({url:t},(t,s,i)=>e(i))})}runScript(t,e){return new Promise(s=>{let i=this.getdata("@chavy_boxjs_userCfgs.httpapi");i=i?i.replace(/\n/g,"").trim():i;let r=this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout");r=r?1*r:20,r=e&&e.timeout?e.timeout:r;const[o,h]=i.split("@"),a={url:`http://${h}/v1/scripting/evaluate`,body:{script_text:t,mock_type:"cron",timeout:r},headers:{"X-Key":o,Accept:"*/*"}};this.post(a,(t,e,i)=>s(i))}).catch(t=>this.logErr(t))}loaddata(){if(!this.isNode())return{};{this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e);if(!s&&!i)return{};{const i=s?t:e;try{return JSON.parse(this.fs.readFileSync(i))}catch(t){return{}}}}}writedata(){if(this.isNode()){this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e),r=JSON.stringify(this.data);s?this.fs.writeFileSync(t,r):i?this.fs.writeFileSync(e,r):this.fs.writeFileSync(t,r)}}lodash_get(t,e,s){const i=e.replace(/\[(\d+)\]/g,".$1").split(".");let r=t;for(const t of i)if(r=Object(r)[t],void 0===r)return s;return r}lodash_set(t,e,s){return Object(t)!==t?t:(Array.isArray(e)||(e=e.toString().match(/[^.[\]]+/g)||[]),e.slice(0,-1).reduce((t,s,i)=>Object(t[s])===t[s]?t[s]:t[s]=Math.abs(e[i+1])>>0==+e[i+1]?[]:{},t)[e[e.length-1]]=s,t)}getdata(t){let e=this.getval(t);if(/^@/.test(t)){const[,s,i]=/^@(.*?)\.(.*?)$/.exec(t),r=s?this.getval(s):"";if(r)try{const t=JSON.parse(r);e=t?this.lodash_get(t,i,""):e}catch(t){e=""}}return e}setdata(t,e){let s=!1;if(/^@/.test(e)){const[,i,r]=/^@(.*?)\.(.*?)$/.exec(e),o=this.getval(i),h=i?"null"===o?null:o||"{}":"{}";try{const e=JSON.parse(h);this.lodash_set(e,r,t),s=this.setval(JSON.stringify(e),i)}catch(e){const o={};this.lodash_set(o,r,t),s=this.setval(JSON.stringify(o),i)}}else s=this.setval(t,e);return s}getval(t){return this.isSurge()||this.isLoon()?$persistentStore.read(t):this.isQuanX()?$prefs.valueForKey(t):this.isNode()?(this.data=this.loaddata(),this.data[t]):this.data&&this.data[t]||null}setval(t,e){return this.isSurge()||this.isLoon()?$persistentStore.write(t,e):this.isQuanX()?$prefs.setValueForKey(t,e):this.isNode()?(this.data=this.loaddata(),this.data[e]=t,this.writedata(),!0):this.data&&this.data[e]||null}initGotEnv(t){this.got=this.got?this.got:require("got"),this.cktough=this.cktough?this.cktough:require("tough-cookie"),this.ckjar=this.ckjar?this.ckjar:new this.cktough.CookieJar,t&&(t.headers=t.headers?t.headers:{},void 0===t.headers.Cookie&&void 0===t.cookieJar&&(t.cookieJar=this.ckjar))}get(t,e=(()=>{})){t.headers&&(delete t.headers["Content-Type"],delete t.headers["Content-Length"]),this.isSurge()||this.isLoon()?(this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.get(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)})):this.isQuanX()?(this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t))):this.isNode()&&(this.initGotEnv(t),this.got(t).on("redirect",(t,e)=>{try{if(t.headers["set-cookie"]){const s=t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString();s&&this.ckjar.setCookieSync(s,null),e.cookieJar=this.ckjar}}catch(t){this.logErr(t)}}).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)}))}post(t,e=(()=>{})){const s=t.method?t.method.toLocaleLowerCase():"post";if(t.body&&t.headers&&!t.headers["Content-Type"]&&(t.headers["Content-Type"]="application/x-www-form-urlencoded"),t.headers&&delete t.headers["Content-Length"],this.isSurge()||this.isLoon())this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient[s](t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)});else if(this.isQuanX())t.method=s,this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t));else if(this.isNode()){this.initGotEnv(t);const{url:i,...r}=t;this.got[s](i,r).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)})}}put(t,e=(()=>{})){const s=t.method?t.method.toLocaleLowerCase():"put";if(t.body&&t.headers&&!t.headers["Content-Type"]&&(t.headers["Content-Type"]="application/x-www-form-urlencoded"),t.headers&&delete t.headers["Content-Length"],this.isSurge()||this.isLoon())this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient[s](t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)});else if(this.isQuanX())t.method=s,this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t));else if(this.isNode()){this.initGotEnv(t);const{url:i,...r}=t;this.got[s](i,r).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)})}}time(t,e=null){const s=e?new Date(e):new Date;let i={"M+":s.getMonth()+1,"d+":s.getDate(),"H+":s.getHours(),"m+":s.getMinutes(),"s+":s.getSeconds(),"q+":Math.floor((s.getMonth()+3)/3),S:s.getMilliseconds()};/(y+)/.test(t)&&(t=t.replace(RegExp.$1,(s.getFullYear()+"").substr(4-RegExp.$1.length)));for(let e in i)new RegExp("("+e+")").test(t)&&(t=t.replace(RegExp.$1,1==RegExp.$1.length?i[e]:("00"+i[e]).substr((""+i[e]).length)));return t}msg(e=t,s="",i="",r){const o=t=>{if(!t)return t;if("string"==typeof t)return this.isLoon()?t:this.isQuanX()?{"open-url":t}:this.isSurge()?{url:t}:void 0;if("object"==typeof t){if(this.isLoon()){let e=t.openUrl||t.url||t["open-url"],s=t.mediaUrl||t["media-url"];return{openUrl:e,mediaUrl:s}}if(this.isQuanX()){let e=t["open-url"]||t.url||t.openUrl,s=t["media-url"]||t.mediaUrl;return{"open-url":e,"media-url":s}}if(this.isSurge()){let e=t.url||t.openUrl||t["open-url"];return{url:e}}}};if(this.isMute||(this.isSurge()||this.isLoon()?$notification.post(e,s,i,o(r)):this.isQuanX()&&$notify(e,s,i,o(r))),!this.isMuteLog){let t=["","==============\ud83d\udce3\u7cfb\u7edf\u901a\u77e5\ud83d\udce3=============="];t.push(e),s&&t.push(s),i&&t.push(i),console.log(t.join("\n")),this.logs=this.logs.concat(t)}}log(...t){t.length>0&&(this.logs=[...this.logs,...t]),console.log(t.join(this.logSeparator))}logErr(t,e){const s=!this.isSurge()&&!this.isQuanX()&&!this.isLoon();s?this.log("",`\u2757\ufe0f${this.name}, \u9519\u8bef!`,t.stack):this.log("",`\u2757\ufe0f${this.name}, \u9519\u8bef!`,t)}wait(t){return new Promise(e=>setTimeout(e,t))}done(t={}){const e=(new Date).getTime(),s=(e-this.startTime)/1e3;this.log("",`\ud83d\udd14${this.name}, \u7ed3\u675f! \ud83d\udd5b ${s} \u79d2`),this.log(),(this.isSurge()||this.isQuanX()||this.isLoon())&&$done(t)}}(t,e)} 257 | -------------------------------------------------------------------------------- /gua_cleancart.js: -------------------------------------------------------------------------------- 1 | /* 2 | 清空购物车 3 | 更新时间:2022-05-26 4 | 因其他脚本会加入商品到购物车,故此脚本用来清空购物车 5 | 包括预售 6 | 需要算法支持 7 | 默认:不执行 如需要请添加环境变量 8 | gua_cleancart_Run="true" 9 | gua_cleancart_SignUrl="" # 算法url 10 | gua_cleancart_Authorization="" # 算法url token 有则填 11 | 12 | —————————————— 13 | 1.@&@ 前面加数字 指定账号pin 14 | 如果有中文请填写中文 15 | 2.|-| 账号之间隔开 16 | 3.英文大小写请填清楚 17 | 4.优先匹配账号再匹配* 18 | 5.定义不清空的[商品]名称支持模糊匹配 19 | 6.pin@&@ 👉 指定账号(后面添加商品 前面账号[pin] *表示所有账号 20 | 7.|-| 👉 账号之间隔开 21 | —————————————— 22 | 23 | 商品名称规则 24 | ——————gua_cleancart_products———————— 25 | pin2@&@商品1,商品2👉该pin这几个商品名不清空 26 | pin5@&@👉该pin全清 27 | pin3@&@不清空👉该pin不清空 28 | *@&@不清空👉所有账号不请空 29 | *@&@👉所有账号清空 30 | 31 | 优先匹配账号再匹配* 32 | |-| 👉 账号之间隔开 33 | 有填帐号pin则*不适配 34 | —————————————— 35 | 如果有不清空的一定要加上"*@&@不清空" 36 | 防止没指定的账号购物车全清空 37 | 38 | */ 39 | let jdSignUrl = '' // 算法url 40 | let Authorization = '' // 算法url token 有则填 41 | let cleancartRun = 'false' 42 | let cleancartProducts = '' 43 | 44 | const $ = new Env('清空购物车'); 45 | const jdCookieNode = $.isNode() ? require('./jdCookie.js') : ''; 46 | const notify = $.isNode() ? require('./sendNotify') : ''; 47 | //IOS等用户直接用NobyDa的jd cookie 48 | let cookiesArr = [], 49 | cookie = ''; 50 | if ($.isNode()) { 51 | Object.keys(jdCookieNode).forEach((item) => { 52 | cookiesArr.push(jdCookieNode[item]) 53 | }) 54 | if (process.env.JD_DEBUG && process.env.JD_DEBUG === 'false') console.log = () => {}; 55 | } else { 56 | cookiesArr = [$.getdata('CookieJD'), $.getdata('CookieJD2'), ...jsonParse($.getdata('CookiesJD') || "[]").map(item => item.cookie)].filter(item => !!item); 57 | } 58 | 59 | message = '' 60 | 61 | jdSignUrl = $.isNode() ? (process.env.gua_cleancart_SignUrl ? process.env.gua_cleancart_SignUrl : `${jdSignUrl}`) : ($.getdata('gua_cleancart_SignUrl') ? $.getdata('gua_cleancart_SignUrl') : `${jdSignUrl}`); 62 | 63 | Authorization = process.env.gua_cleancart_Authorization ? process.env.gua_cleancart_Authorization : `${Authorization}` 64 | if(Authorization && Authorization.indexOf("Bearer ") === -1) Authorization = `Bearer ${Authorization}` 65 | 66 | cleancartRun = $.isNode() ? (process.env.gua_cleancart_Run ? process.env.gua_cleancart_Run : `${cleancartRun}`) : ($.getdata('gua_cleancart_Run') ? $.getdata('gua_cleancart_Run') : `${cleancartRun}`); 67 | 68 | cleancartProducts = $.isNode() ? (process.env.gua_cleancart_products ? process.env.gua_cleancart_products : `${cleancartProducts}`) : ($.getdata('gua_cleancart_products') ? $.getdata('gua_cleancart_products') : `${cleancartProducts}`); 69 | 70 | let productsArr = [] 71 | let cleancartProductsAll = [] 72 | for (let i of cleancartProducts && cleancartProducts.split('|-|')) { 73 | productsArr.push(i) 74 | } 75 | for (let i of cleancartProducts && cleancartProducts.split('|-|')) { 76 | productsArr.push(i) 77 | } 78 | for (let i in productsArr) { 79 | if(productsArr[i].indexOf('@&@') > -1){ 80 | let arr = productsArr[i].split('@&@') 81 | cleancartProductsAll[arr[0]] = arr[1].split(',') 82 | } 83 | } 84 | !(async () => { 85 | if (!cookiesArr[0]) { 86 | $.msg($.name, '【提示】请先获取cookie\n直接使用NobyDa的京东签到获取', 'https://bean.m.jd.com/', { 87 | "open-url": "https://bean.m.jd.com/" 88 | }); 89 | return; 90 | } 91 | if(cleancartRun !== 'true'){ 92 | console.log('脚本停止\n请添加环境变量[gua_cleancart_Run]为"true"') 93 | return 94 | } 95 | if(!cleancartProducts){ 96 | console.log('脚本停止\n请添加环境变量[gua_cleancart_products]\n清空商品\n内容规则看脚本文件') 97 | return 98 | } 99 | if(jdSignUrl.indexOf("://jd.smiek.tk/") > -1) { 100 | return 101 | } 102 | $.out = false 103 | for (let i = 0; i < cookiesArr.length; i++) { 104 | cookie = cookiesArr[i]; 105 | if (cookie) { 106 | $.UserName = decodeURIComponent(cookie.match(/pt_pin=([^; ]+)(?=;?)/) && cookie.match(/pt_pin=([^; ]+)(?=;?)/)[1]) 107 | $.index = i + 1; 108 | console.log(`\n\n******开始【京东账号${$.index}】${$.nickName || $.UserName}*********\n`); 109 | if(cleancartProductsAll[$.UserName]){ 110 | $.cleancartProductsArr = cleancartProductsAll[$.UserName] 111 | }else if(cleancartProductsAll["*"]){ 112 | $.cleancartProductsArr = cleancartProductsAll["*"] 113 | }else $.cleancartProductsArr = false 114 | if($.cleancartProductsArr) console.log($.cleancartProductsArr) 115 | await run(); 116 | if($.out) break 117 | } 118 | } 119 | if(message){ 120 | $.msg($.name, ``, `${message}`); 121 | if ($.isNode()){ 122 | await notify.sendNotify(`${$.name}`, `${message}`); 123 | } 124 | } 125 | })() 126 | .catch((e) => $.logErr(e)) 127 | .finally(() => $.done()) 128 | 129 | async function run(){ 130 | try{ 131 | let msg = '' 132 | let signBody = `{"homeWishListUserFlag":"1","userType":"0","updateTag":true,"showPlusEntry":"2","hitNewUIStatus":"1","cvhv":"049591","cartuuid":"hjudwgohxzVu96krv/T6Hg==","adid":""}` 133 | let body = await jdSign('cartClearQuery', signBody) 134 | if($.out) return 135 | if(!body){ 136 | console.log('获取不到算法') 137 | return 138 | } 139 | let data = await jdApi('cartClearQuery',body) 140 | let res = $.toObj(data,data); 141 | if(typeof res == 'object' && res){ 142 | if(res.resultCode == 0){ 143 | if(!res.clearCartInfo || !res.subTitle){ 144 | msg += `${res.mainTitle}\n` 145 | console.log(res.mainTitle) 146 | }else{ 147 | let num = 0 148 | if(res.subTitle){ 149 | num = res.subTitle.match(/共(\d+)件商品/).length > 0 && res.subTitle.match(/共(\d+)件商品/)[1] || 0 150 | msg += res.subTitle + "\n" 151 | console.log(res.subTitle) 152 | } 153 | // console.log(`共${num}件商品`) 154 | if(num != 0){ 155 | let operations = [] 156 | let operNum = 0 157 | for(let a of res.clearCartInfo || {}){ 158 | // console.log(a.groupName) 159 | // if(a.groupName.indexOf('7天前加入购物车') > -1){ 160 | for(let s of a.groupDetails || []){ 161 | if(toSDS(s.name)){ 162 | // console.log(s.unusable,s.skuUuid,s.name) 163 | operNum += s.clearSkus && s.clearSkus.length || 1; 164 | operations.push({ 165 | "itemType": s.itemType+"", 166 | "suitType": s.suitType, 167 | "skuUuid": s.skuUuid+"", 168 | "itemId": s.itemId || s.skuId, 169 | "useUuid": typeof s.useUuid !== 'undefined' && s.useUuid || false 170 | }) 171 | } 172 | } 173 | // } 174 | } 175 | console.log(`准备清空${operNum}件商品`) 176 | if(operations.length == 0){ 177 | console.log(`清空${operNum}件商品|没有找到要清空的商品`) 178 | msg += `清空${operNum}件商品|没有找到要清空的商品\n` 179 | }else{ 180 | let clearBody = `{"homeWishListUserFlag":"1","userType":"0","updateTag":false,"showPlusEntry":"2","hitNewUIStatus":"1","cvhv":"049591","cartuuid":"hjudwgohxzVu96krv/T6Hg==","operations":${$.toStr(operations,operations)},"adid":"","coord_type":"0"}` 181 | clearBody = await jdSign('cartClearRemove', clearBody) 182 | if($.out) return 183 | if(!clearBody){ 184 | console.log('获取不到算法') 185 | }else{ 186 | let clearData = await jdApi('cartClearRemove',clearBody) 187 | let clearRes = $.toObj(clearData,clearData); 188 | if(typeof clearRes == 'object'){ 189 | if(clearRes.resultCode == 0) { 190 | msg += `清空${operNum}件商品|✅\n` 191 | console.log(`清空${operNum}件商品|✅\n`) 192 | }else if(clearRes.mainTitle){ 193 | msg += `清空${operNum}件商品|${clearRes.mainTitle}\n` 194 | console.log(`清空${operNum}件商品|${clearRes.mainTitle}\n`) 195 | }else{ 196 | msg += `清空${operNum}件商品|❌\n` 197 | console.log(`清空${operNum}件商品|❌\n`) 198 | console.log(clearData) 199 | } 200 | }else{ 201 | msg += `清空${operNum}件商品|❌\n` 202 | console.log(`清空${operNum}件商品|❌\n`) 203 | console.log(clearData) 204 | } 205 | } 206 | } 207 | }else if(res.mainTitle){ 208 | msg += `${res.mainTitle}\n` 209 | console.log(res.mainTitle) 210 | }else{ 211 | msg += `未识别到购物车有商品\n` 212 | console.log(data) 213 | } 214 | } 215 | }else{ 216 | console.log(data) 217 | } 218 | }else{ 219 | console.log(data) 220 | } 221 | if(msg){ 222 | message += `【京东账号${$.index}】${$.nickName || $.UserName}\n${msg}\n` 223 | } 224 | if(!$.out){ 225 | console.log('等待45秒') 226 | await $.wait(parseInt(Math.random() * 2000 + 40000, 10)) 227 | } 228 | }catch(e){ 229 | console.log(e) 230 | } 231 | } 232 | function toSDS(name){ 233 | let res = true 234 | if($.cleancartProductsArr === false) return false 235 | for(let t of $.cleancartProductsArr || []){ 236 | if(t && name.indexOf(t) > -1 || t == '不清空'){ 237 | res = false 238 | break 239 | } 240 | } 241 | return res 242 | } 243 | function jdApi(functionId,body) { 244 | if(!functionId || !body) return 245 | return new Promise(resolve => { 246 | $.post(taskPostUrl(`/client.action?functionId=${functionId}`, body), async (err, resp, data) => { 247 | try { 248 | if (err) { 249 | console.log(`${$.toStr(err)}`) 250 | console.log(`${$.name} API请求失败,请检查网路重试`) 251 | } else { 252 | // console.log(data) 253 | let res = $.toObj(data,data); 254 | if(typeof res == 'object'){ 255 | if(res.mainTitle) console.log(res.mainTitle) 256 | if(res.resultCode == 0){ 257 | resolve(res); 258 | }else if (res.tips && res.tips.includes("正在努力加载")){ 259 | console.log("请求太快,ip被限制了") 260 | $.out = true 261 | } 262 | } 263 | } 264 | } catch (e) { 265 | $.logErr(e, resp) 266 | } finally { 267 | resolve(''); 268 | } 269 | }) 270 | }) 271 | } 272 | 273 | function jdSign(fn,body) { 274 | let sign = '' 275 | let flag = false 276 | try{ 277 | const fs = require('fs'); 278 | if (fs.existsSync('./gua_encryption_sign.js')) { 279 | const encryptionSign = require('./gua_encryption_sign'); 280 | sign = encryptionSign.getSign(fn, body) 281 | }else{ 282 | flag = true 283 | } 284 | sign = sign.data && sign.data.sign && sign.data.sign || '' 285 | }catch(e){ 286 | flag = true 287 | } 288 | if(!flag) return sign 289 | if(!jdSignUrl.match(/^https?:\/\//)){ 290 | console.log('请填写算法url') 291 | $.out = true 292 | return '' 293 | } 294 | return new Promise((resolve) => { 295 | let options = { 296 | url: jdSignUrl, 297 | body:`{"fn":"${fn}","body":${body}}`, 298 | followRedirect:false, 299 | headers: { 300 | 'Accept':'*/*', 301 | "accept-encoding": "gzip, deflate, br", 302 | 'Content-Type': 'application/json', 303 | }, 304 | timeout:30000 305 | } 306 | if(Authorization) options["headers"]["Authorization"] = Authorization 307 | $.post(options, async (err, resp, data) => { 308 | try { 309 | // console.log(data) 310 | let res = $.toObj(data,data) 311 | if(typeof res === 'object' && res){ 312 | if(res.code && res.code == 200 && res.data){ 313 | if(res.data.sign) sign = res.data.sign || '' 314 | if(sign != '') resolve(sign) 315 | }else{ 316 | console.log(data) 317 | } 318 | }else{ 319 | console.log(data) 320 | } 321 | } catch (e) { 322 | $.logErr(e, resp); 323 | } finally { 324 | resolve('') 325 | } 326 | }) 327 | }) 328 | } 329 | 330 | 331 | function taskPostUrl(url, body) { 332 | return { 333 | url: `https://api.m.jd.com${url}`, 334 | body: body, 335 | headers: { 336 | "Accept": "*/*", 337 | "Accept-Language": "zh-cn", 338 | "Accept-Encoding": "gzip, deflate, br", 339 | "Connection": "keep-alive", 340 | "Content-Type": "application/x-www-form-urlencoded", 341 | 'Cookie': `${cookie}`, 342 | "Host": "api.m.jd.com", 343 | "User-Agent": "JD4iPhone/167853 (iPhone; iOS; Scale/2.00)" , 344 | } 345 | } 346 | } 347 | 348 | function randomString(e) { 349 | e = e || 32; 350 | let t = "abcdef0123456789", a = t.length, n = ""; 351 | for (i = 0; i < e; i++) 352 | n += t.charAt(Math.floor(Math.random() * a)); 353 | return n 354 | } 355 | 356 | function jsonParse(str) { 357 | if (typeof str == "string") { 358 | try { 359 | return JSON.parse(str); 360 | } catch (e) { 361 | console.log(e); 362 | $.msg($.name, '', '请勿随意在BoxJs输入框修改内容\n建议通过脚本去获取cookie') 363 | return []; 364 | } 365 | } 366 | } 367 | 368 | // prettier-ignore 369 | function Env(t,e){"undefined"!=typeof process&&JSON.stringify(process.env).indexOf("GITHUB")>-1&&process.exit(0);class s{constructor(t){this.env=t}send(t,e="GET"){t="string"==typeof t?{url:t}:t;let s=this.get;return"POST"===e&&(s=this.post),new Promise((e,i)=>{s.call(this,t,(t,s,r)=>{t?i(t):e(s)})})}get(t){return this.send.call(this.env,t)}post(t){return this.send.call(this.env,t,"POST")}}return new class{constructor(t,e){this.name=t,this.http=new s(this),this.data=null,this.dataFile="box.dat",this.logs=[],this.isMute=!1,this.isNeedRewrite=!1,this.logSeparator="\n",this.startTime=(new Date).getTime(),Object.assign(this,e),this.log("",`🔔${this.name}, 开始!`)}isNode(){return"undefined"!=typeof module&&!!module.exports}isQuanX(){return"undefined"!=typeof $task}isSurge(){return"undefined"!=typeof $httpClient&&"undefined"==typeof $loon}isLoon(){return"undefined"!=typeof $loon}toObj(t,e=null){try{return JSON.parse(t)}catch{return e}}toStr(t,e=null){try{return JSON.stringify(t)}catch{return e}}getjson(t,e){let s=e;const i=this.getdata(t);if(i)try{s=JSON.parse(this.getdata(t))}catch{}return s}setjson(t,e){try{return this.setdata(JSON.stringify(t),e)}catch{return!1}}getScript(t){return new Promise(e=>{this.get({url:t},(t,s,i)=>e(i))})}runScript(t,e){return new Promise(s=>{let i=this.getdata("@chavy_boxjs_userCfgs.httpapi");i=i?i.replace(/\n/g,"").trim():i;let r=this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout");r=r?1*r:20,r=e&&e.timeout?e.timeout:r;const[o,h]=i.split("@"),n={url:`http://${h}/v1/scripting/evaluate`,body:{script_text:t,mock_type:"cron",timeout:r},headers:{"X-Key":o,Accept:"*/*"}};this.post(n,(t,e,i)=>s(i))}).catch(t=>this.logErr(t))}loaddata(){if(!this.isNode())return{};{this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e);if(!s&&!i)return{};{const i=s?t:e;try{return JSON.parse(this.fs.readFileSync(i))}catch(t){return{}}}}}writedata(){if(this.isNode()){this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e),r=JSON.stringify(this.data);s?this.fs.writeFileSync(t,r):i?this.fs.writeFileSync(e,r):this.fs.writeFileSync(t,r)}}lodash_get(t,e,s){const i=e.replace(/\[(\d+)\]/g,".$1").split(".");let r=t;for(const t of i)if(r=Object(r)[t],void 0===r)return s;return r}lodash_set(t,e,s){return Object(t)!==t?t:(Array.isArray(e)||(e=e.toString().match(/[^.[\]]+/g)||[]),e.slice(0,-1).reduce((t,s,i)=>Object(t[s])===t[s]?t[s]:t[s]=Math.abs(e[i+1])>>0==+e[i+1]?[]:{},t)[e[e.length-1]]=s,t)}getdata(t){let e=this.getval(t);if(/^@/.test(t)){const[,s,i]=/^@(.*?)\.(.*?)$/.exec(t),r=s?this.getval(s):"";if(r)try{const t=JSON.parse(r);e=t?this.lodash_get(t,i,""):e}catch(t){e=""}}return e}setdata(t,e){let s=!1;if(/^@/.test(e)){const[,i,r]=/^@(.*?)\.(.*?)$/.exec(e),o=this.getval(i),h=i?"null"===o?null:o||"{}":"{}";try{const e=JSON.parse(h);this.lodash_set(e,r,t),s=this.setval(JSON.stringify(e),i)}catch(e){const o={};this.lodash_set(o,r,t),s=this.setval(JSON.stringify(o),i)}}else s=this.setval(t,e);return s}getval(t){return this.isSurge()||this.isLoon()?$persistentStore.read(t):this.isQuanX()?$prefs.valueForKey(t):this.isNode()?(this.data=this.loaddata(),this.data[t]):this.data&&this.data[t]||null}setval(t,e){return this.isSurge()||this.isLoon()?$persistentStore.write(t,e):this.isQuanX()?$prefs.setValueForKey(t,e):this.isNode()?(this.data=this.loaddata(),this.data[e]=t,this.writedata(),!0):this.data&&this.data[e]||null}initGotEnv(t){this.got=this.got?this.got:require("got"),this.cktough=this.cktough?this.cktough:require("tough-cookie"),this.ckjar=this.ckjar?this.ckjar:new this.cktough.CookieJar,t&&(t.headers=t.headers?t.headers:{},void 0===t.headers.Cookie&&void 0===t.cookieJar&&(t.cookieJar=this.ckjar))}get(t,e=(()=>{})){t.headers&&(delete t.headers["Content-Type"],delete t.headers["Content-Length"]),this.isSurge()||this.isLoon()?(this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.get(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)})):this.isQuanX()?(this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t))):this.isNode()&&(this.initGotEnv(t),this.got(t).on("redirect",(t,e)=>{try{if(t.headers["set-cookie"]){const s=t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString();s&&this.ckjar.setCookieSync(s,null),e.cookieJar=this.ckjar}}catch(t){this.logErr(t)}}).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)}))}post(t,e=(()=>{})){if(t.body&&t.headers&&!t.headers["Content-Type"]&&(t.headers["Content-Type"]="application/x-www-form-urlencoded"),t.headers&&delete t.headers["Content-Length"],this.isSurge()||this.isLoon())this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.post(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)});else if(this.isQuanX())t.method="POST",this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t));else if(this.isNode()){this.initGotEnv(t);const{url:s,...i}=t;this.got.post(s,i).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)})}}time(t,e=null){const s=e?new Date(e):new Date;let i={"M+":s.getMonth()+1,"d+":s.getDate(),"H+":s.getHours(),"m+":s.getMinutes(),"s+":s.getSeconds(),"q+":Math.floor((s.getMonth()+3)/3),S:s.getMilliseconds()};/(y+)/.test(t)&&(t=t.replace(RegExp.$1,(s.getFullYear()+"").substr(4-RegExp.$1.length)));for(let e in i)new RegExp("("+e+")").test(t)&&(t=t.replace(RegExp.$1,1==RegExp.$1.length?i[e]:("00"+i[e]).substr((""+i[e]).length)));return t}msg(e=t,s="",i="",r){const o=t=>{if(!t)return t;if("string"==typeof t)return this.isLoon()?t:this.isQuanX()?{"open-url":t}:this.isSurge()?{url:t}:void 0;if("object"==typeof t){if(this.isLoon()){let e=t.openUrl||t.url||t["open-url"],s=t.mediaUrl||t["media-url"];return{openUrl:e,mediaUrl:s}}if(this.isQuanX()){let e=t["open-url"]||t.url||t.openUrl,s=t["media-url"]||t.mediaUrl;return{"open-url":e,"media-url":s}}if(this.isSurge()){let e=t.url||t.openUrl||t["open-url"];return{url:e}}}};if(this.isMute||(this.isSurge()||this.isLoon()?$notification.post(e,s,i,o(r)):this.isQuanX()&&$notify(e,s,i,o(r))),!this.isMuteLog){let t=["","==============📣系统通知📣=============="];t.push(e),s&&t.push(s),i&&t.push(i),console.log(t.join("\n")),this.logs=this.logs.concat(t)}}log(...t){t.length>0&&(this.logs=[...this.logs,...t]),console.log(t.join(this.logSeparator))}logErr(t,e){const s=!this.isSurge()&&!this.isQuanX()&&!this.isLoon();s?this.log("",`❗️${this.name}, 错误!`,t.stack):this.log("",`❗️${this.name}, 错误!`,t)}wait(t){return new Promise(e=>setTimeout(e,t))}done(t={}){const e=(new Date).getTime(),s=(e-this.startTime)/1e3;this.log("",`🔔${this.name}, 结束! 🕛 ${s} 秒`),this.log(),(this.isSurge()||this.isQuanX()||this.isLoon())&&$done(t)}}(t,e)} 370 | 371 | 372 | -------------------------------------------------------------------------------- /jdCookie.js: -------------------------------------------------------------------------------- 1 | /* 2 | 此文件为Node.js专用。其他用户请忽略 3 | */ 4 | //此处填写京东账号cookie。 5 | let CookieJDs = [ 6 | ] 7 | // 判断环境变量里面是否有京东ck 8 | if (process.env.JD_COOKIE) { 9 | if (process.env.JD_COOKIE.indexOf('&') > -1) { 10 | CookieJDs = process.env.JD_COOKIE.split('&'); 11 | } else if (process.env.JD_COOKIE.indexOf('\n') > -1) { 12 | CookieJDs = process.env.JD_COOKIE.split('\n'); 13 | } else { 14 | CookieJDs = [process.env.JD_COOKIE]; 15 | } 16 | } 17 | if (JSON.stringify(process.env).indexOf('GITHUB')>-1) { 18 | console.log(`请勿使用github action运行此脚本,无论你是从你自己的私库还是其他哪里拉取的源代码,都会导致我被封号\n`); 19 | !(async () => { 20 | await require('./sendNotify').sendNotify('提醒', `请勿使用github action、滥用github资源会封我仓库以及账号`) 21 | await process.exit(0); 22 | })() 23 | } 24 | CookieJDs = [...new Set(CookieJDs.filter(item => !!item))] 25 | console.log(`\n====================共${CookieJDs.length}个京东账号Cookie=========\n`); 26 | console.log(`==================脚本执行- 北京时间(UTC+8):${new Date(new Date().getTime() + new Date().getTimezoneOffset()*60*1000 + 8*60*60*1000).toLocaleString('zh', {hour12: false}).replace(' 24:',' 00:')}=====================\n`) 27 | if (process.env.JD_DEBUG && process.env.JD_DEBUG === 'false') console.log = () => {}; 28 | for (let i = 0; i < CookieJDs.length; i++) { 29 | if (!CookieJDs[i].match(/pt_pin=(.+?);/) || !CookieJDs[i].match(/pt_key=(.+?);/)) console.log(`\n提示:京东cookie 【${CookieJDs[i]}】填写不规范,可能会影响部分脚本正常使用。正确格式为: pt_key=xxx;pt_pin=xxx;(分号;不可少)\n`); 30 | const index = (i + 1 === 1) ? '' : (i + 1); 31 | exports['CookieJD' + index] = CookieJDs[i].trim(); 32 | } 33 | -------------------------------------------------------------------------------- /jd_sendBeans.js: -------------------------------------------------------------------------------- 1 | /* 2 | * 来客有礼小程序 3 | * 搬运不知名人士 4 | * cron 23 10 * * * 5 | * */ 6 | const $ = new Env('送豆得豆'); 7 | const notify = $.isNode() ? require('./sendNotify') : ''; 8 | const jdCookieNode = $.isNode() ? require('./jdCookie.js') : ''; 9 | let cookiesArr = []; 10 | if ($.isNode()) { 11 | Object.keys(jdCookieNode).forEach((item) => { 12 | cookiesArr.push(jdCookieNode[item]) 13 | }); 14 | if (process.env.JD_DEBUG && process.env.JD_DEBUG === 'false') console.log = () => {}; 15 | } else { 16 | cookiesArr = [ 17 | $.getdata("CookieJD"), 18 | $.getdata("CookieJD2"), 19 | ...$.toObj($.getdata("CookiesJD") || "[]").map((item) => item.cookie)].filter((item) => !!item); 20 | } 21 | let lkt = 0 22 | !(async () => { 23 | $.isLoginInfo = {}; 24 | if (!cookiesArr[0]) { 25 | $.msg($.name, '【提示】请先获取京东账号一cookie\n直接使用NobyDa的京东签到获取', 'https://bean.m.jd.com/bean/signIndex.action', {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); 26 | return; 27 | } 28 | $.activityId = ''; 29 | $.completeNumbers = ''; 30 | $.invokeKey = 'q8DNJdpcfRQ69gIx' 31 | $.invokeKey = $.isNode() ? (process.env.JD_invokeKey ? process.env.JD_invokeKey : `${$.invokeKey}`) : ($.getdata('JD_invokeKey') ? $.getdata('JD_invokeKey') : `${$.invokeKey}`); 32 | MD5() 33 | console.log(`开始获取活动信息`); 34 | for (let i = 0; i < cookiesArr.length && $.activityId === '' && i < 3; i++) { 35 | $.cookie = cookiesArr[i]; 36 | $.UserName = decodeURIComponent($.cookie.match(/pt_pin=(.+?);/) && $.cookie.match(/pt_pin=(.+?);/)[1]); 37 | $.isLogin = true; 38 | $.nickName = $.UserName; 39 | lkt = new Date().getTime() 40 | getUA() 41 | await getActivityInfo(); 42 | } 43 | if($.activityId === ''){ 44 | console.log(`获取活动ID失败`); 45 | return ; 46 | } 47 | let openCount = Math.floor((Number(cookiesArr.length)-1)/Number($.completeNumbers)); 48 | // openCount = 1; 49 | console.log(`\n共有${cookiesArr.length}个账号,前${openCount}个账号可以开团\n`); 50 | $.openTuanList = []; 51 | console.log(`前${openCount}个账号开始开团\n`); 52 | for (let i = 0; i < cookiesArr.length && i < openCount; i++) { 53 | $.cookie = cookiesArr[i]; 54 | $.UserName = decodeURIComponent($.cookie.match(/pt_pin=(.+?);/) && $.cookie.match(/pt_pin=(.+?);/)[1]); 55 | $.index = i + 1; 56 | $.isLogin = true; 57 | $.nickName = $.UserName; 58 | if(!$.isLoginInfo[$.UserName]){ 59 | await TotalBean(); 60 | console.log(`\n*****开始【京东账号${$.index}】${$.nickName || $.UserName}*****\n`); 61 | $.isLoginInfo[$.UserName] = $.isLogin; 62 | if (!$.isLogin) { 63 | $.msg($.name, `【提示】cookie已失效`, `京东账号${$.index} ${$.nickName || $.UserName}\n请重新登录获取\nhttps://bean.m.jd.com/bean/signIndex.action`, {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); 64 | if ($.isNode()) { 65 | await notify.sendNotify(`${$.name}cookie已失效 - ${$.UserName}`, `京东账号${$.index} ${$.UserName}\n请重新登录获取cookie`); 66 | } 67 | continue; 68 | } 69 | }else { 70 | console.log(`\n*****开始【京东账号${$.index}】${$.nickName || $.UserName}*****\n`); 71 | } 72 | await openTuan(); 73 | } 74 | console.log('\n开团信息\n'+JSON.stringify($.openTuanList)); 75 | console.log(`\n开始互助\n`); 76 | let ckList = getRandomArrayElements(cookiesArr,cookiesArr.length); 77 | for (let i = 0; i < ckList.length && $.openTuanList.length > 0; i++) { 78 | $.cookie = ckList[i]; 79 | $.UserName = decodeURIComponent($.cookie.match(/pt_pin=(.+?);/) && $.cookie.match(/pt_pin=(.+?);/)[1]) 80 | $.index = i + 1; 81 | $.isLogin = true; 82 | if(!$.isLoginInfo[$.UserName]){ 83 | await TotalBean(); 84 | $.isLoginInfo[$.UserName] = $.isLogin; 85 | if (!$.isLogin) { 86 | $.msg($.name, `【提示】cookie已失效`, `京东账号${$.index} ${$.UserName}\n请重新登录获取\nhttps://bean.m.jd.com/bean/signIndex.action`, {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); 87 | if ($.isNode()) { 88 | await notify.sendNotify(`${$.name}cookie已失效 - ${$.UserName}`, `京东账号${$.index} ${$.UserName}\n请重新登录获取cookie`); 89 | } 90 | continue; 91 | } 92 | } 93 | await helpMain(); 94 | } 95 | console.log(`\n开始领取奖励\n`); 96 | for (let i = 0; i < cookiesArr.length && i < openCount && $.openTuanList.length > 0; i++) { 97 | $.cookie = cookiesArr[i]; 98 | $.UserName = decodeURIComponent($.cookie.match(/pt_pin=(.+?);/) && $.cookie.match(/pt_pin=(.+?);/)[1]) 99 | $.index = i + 1; 100 | $.isLogin = true; 101 | if(!$.isLoginInfo[$.UserName]){ 102 | await TotalBean(); 103 | $.isLoginInfo[$.UserName] = $.isLogin; 104 | if (!$.isLogin) { 105 | $.msg($.name, `【提示】cookie已失效`, `京东账号${$.index} ${$.nickName || $.UserName}\n请重新登录获取\nhttps://bean.m.jd.com/bean/signIndex.action`, {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); 106 | if ($.isNode()) { 107 | await notify.sendNotify(`${$.name}cookie已失效 - ${$.UserName}`, `京东账号${$.index} ${$.UserName}\n请重新登录获取cookie`); 108 | } 109 | continue; 110 | } 111 | } 112 | console.log(`\n*****开始【京东账号${$.index}】${$.UserName}*****\n`); 113 | await rewardMain(); 114 | } 115 | })().catch((e) => {$.log('', `❌ ${$.name}, 失败! 原因: ${e}!`, '')}).finally(() => {$.done();}); 116 | 117 | async function getActivityInfo(){ 118 | $.activityList = []; 119 | await getActivityList(); 120 | if($.activityList.length === 0){ 121 | return ; 122 | } 123 | for (let i = 0; i < $.activityList.length; i++) { 124 | if($.activityList[i].status !== 'NOT_BEGIN'){ 125 | $.activityCode = $.activityList[i].activityCode; 126 | $.activityId = $.activityList[i].activeId; 127 | break; 128 | } 129 | } 130 | await $.wait(3000); 131 | $.detail = {}; 132 | await getActivityDetail(); 133 | if(JSON.stringify($.detail) === '{}'){ 134 | console.log(`获取活动详情失败`); 135 | return; 136 | }else{ 137 | console.log(`获取活动详情成功`); 138 | } 139 | $.completeNumbers = $.detail.activityInfo.completeNumbers; 140 | console.log(`获取到的活动ID:${$.activityId},需要邀请${$.completeNumbers}人瓜分`); 141 | } 142 | 143 | async function getActivityList(){ 144 | return new Promise((resolve) => { 145 | let options = { 146 | "url": `https://sendbeans.jd.com/common/api/bean/activity/get/entry/list/by/channel?channelId=14&channelType=H5&sendType=0&singleActivity=false&invokeKey=${$.invokeKey}`, 147 | "headers": { 148 | "Origin": "https://sendbeans.jd.com", 149 | "Cookie": $.cookie, 150 | "Connection": "keep-alive", 151 | "Accept": "application/json, text/plain, */*", 152 | "User-Agent":$.UA, 153 | "Accept-Language": "zh-cn", 154 | "Referer": "https://sendbeans.jd.com/dist/index.html", 155 | "Accept-Encoding": "gzip, deflate, br", 156 | "lks": $.md5(""+$.invokeKey+lkt), 157 | "lkt": lkt 158 | } 159 | }; 160 | $.get(options, (err, resp, data) => { 161 | try { 162 | data = JSON.parse(data); 163 | if(data.success){ 164 | $.activityList = data.data.items; 165 | }else{ 166 | console.log(JSON.stringify(data)); 167 | } 168 | } catch (e) { 169 | console.log(e); 170 | } finally { 171 | resolve(data); 172 | } 173 | }) 174 | }); 175 | } 176 | 177 | 178 | async function openTuan(){ 179 | $.detail = {}; 180 | $.rewardRecordId = ''; 181 | await getActivityDetail(); 182 | if(JSON.stringify($.detail) === '{}'){ 183 | console.log(`获取活动详情失败`); 184 | return; 185 | }else{ 186 | $.rewardRecordId = $.detail.rewardRecordId; 187 | console.log(`获取活动详情成功`); 188 | } 189 | await $.wait(3000); 190 | if(!$.rewardRecordId){ 191 | if(!$.detail.invited){ 192 | await invite(); 193 | await $.wait(1000); 194 | await getActivityDetail(); 195 | await $.wait(3000); 196 | $.rewardRecordId = $.detail.rewardRecordId; 197 | console.log(`【京东账号${$.index}】${$.UserName} 瓜分ID:${$.rewardRecordId}`); 198 | } 199 | }else{ 200 | console.log(`【京东账号${$.index}】${$.UserName} 瓜分ID:${$.rewardRecordId}`); 201 | } 202 | $.openTuanList.push({ 203 | 'user':$.UserName, 204 | 'rewardRecordId':$.rewardRecordId, 205 | 'completed':$.detail.completed, 206 | 'rewardOk':$.detail.rewardOk 207 | }); 208 | } 209 | 210 | async function helpMain(){ 211 | $.canHelp = true; 212 | for (let j = 0; j < $.openTuanList.length && $.canHelp; j++) { 213 | $.oneTuanInfo = $.openTuanList[j]; 214 | if( $.UserName === $.oneTuanInfo['user']){ 215 | continue; 216 | } 217 | if( $.oneTuanInfo['completed']){ 218 | continue; 219 | } 220 | console.log(`${$.UserName}去助力${$.oneTuanInfo['user']}`); 221 | $.detail = {}; 222 | $.rewardRecordId = ''; 223 | await getActivityDetail(); 224 | if(JSON.stringify($.detail) === '{}'){ 225 | console.log(`获取活动详情失败`); 226 | return; 227 | }else{ 228 | $.rewardRecordId = $.detail.rewardRecordId; 229 | console.log(`获取活动详情成功`); 230 | } 231 | await $.wait(3000); 232 | await help(); 233 | await $.wait(2000); 234 | } 235 | } 236 | 237 | async function rewardMain(){ 238 | $.detail = {}; 239 | $.rewardRecordId = ''; 240 | await getActivityDetail(); 241 | if(JSON.stringify($.detail) === '{}'){ 242 | console.log(`获取活动详情失败`); 243 | return; 244 | }else{ 245 | $.rewardRecordId = $.detail.rewardRecordId; 246 | console.log(`获取活动详情成功`); 247 | } 248 | await $.wait(3000); 249 | if($.rewardRecordId && $.detail.completed && !$.detail.rewardOk){ 250 | await rewardBean(); 251 | await $.wait(2000); 252 | }else if($.rewardRecordId && $.detail.completed && $.detail.rewardOk){ 253 | console.log(`奖励已领取`); 254 | }else{ 255 | console.log(`未满足条件,不可领取奖励`); 256 | } 257 | } 258 | async function rewardBean(){ 259 | return new Promise((resolve) => { 260 | let options = { 261 | "url": `https://draw.jdfcloud.com/common/api/bean/activity/sendBean?rewardRecordId=${$.rewardRecordId}&jdChannelId=&userSource=mp&appId=wxccb5c536b0ecd1bf&invokeKey=${$.invokeKey}`, 262 | "headers": { 263 | 'content-type' : `application/json`, 264 | 'Connection' : `keep-alive`, 265 | 'Accept-Encoding' : `gzip,compress,br,deflate`, 266 | "User-Agent": $.UA, 267 | 'Host' : `draw.jdfcloud.com`, 268 | 'Referer' : `https://servicewechat.com/wxccb5c536b0ecd1bf/733/page-frame.html`, 269 | 'cookie' : $.cookie, 270 | "lks": $.md5(""+$.invokeKey+lkt), 271 | "lkt": lkt 272 | } 273 | }; 274 | $.get(options, (err, resp, data) => { 275 | try { 276 | data = JSON.parse(data); 277 | if(data.success){ 278 | console.log(`领取豆子奖励成功`); 279 | }else{ 280 | console.log(JSON.stringify(data)); 281 | } 282 | } catch (e) { 283 | console.log(e); 284 | } finally { 285 | resolve(data); 286 | } 287 | }) 288 | }); 289 | } 290 | 291 | function getRandomArrayElements(arr, count) { 292 | var shuffled = arr.slice(0), i = arr.length, min = i - count, temp, index; 293 | while (i-- > min) { 294 | index = Math.floor((i + 1) * Math.random()); 295 | temp = shuffled[index]; 296 | shuffled[index] = shuffled[i]; 297 | shuffled[i] = temp; 298 | } 299 | return shuffled.slice(min); 300 | } 301 | 302 | async function help() { 303 | await new Promise((resolve) => { 304 | let options = { 305 | "url": `https://draw.jdfcloud.com/common/api/bean/activity/participate?activityCode=${$.activityCode}&activityId=${$.activityId}&inviteUserPin=${encodeURIComponent($.oneTuanInfo['user'])}&invokeKey=${$.invokeKey}×tap=${Date.now()}`, 306 | "headers": { 307 | 'content-type' : `application/json`, 308 | 'Connection' : `keep-alive`, 309 | 'Accept-Encoding' : `gzip,compress,br,deflate`, 310 | "User-Agent": $.UA, 311 | 'Host' : `draw.jdfcloud.com`, 312 | 'Referer' : `https://servicewechat.com/wxccb5c536b0ecd1bf/733/page-frame.html`, 313 | 'cookie' : $.cookie, 314 | "lks": $.md5(""+$.invokeKey+lkt+$.activityCode), 315 | "lkt": lkt 316 | } 317 | }; 318 | $.post(options, (err, resp, res) => { 319 | try { 320 | if (res) { 321 | res = JSON.parse(res); 322 | if([2,5,7].includes(res.data.result)){ 323 | $.oneTuanInfo['completed'] = true; 324 | }else if(res.data.result === 0 || res.data.result === 1){ 325 | $.canHelp = false; 326 | } 327 | console.log(JSON.stringify(res)); 328 | } 329 | } catch (e) { 330 | console.log(e); 331 | } finally { 332 | resolve(res); 333 | } 334 | }) 335 | }); 336 | } 337 | 338 | async function invite() { 339 | const url = `https://draw.jdfcloud.com/common/api/bean/activity/invite?activityCode=${$.activityCode}&activityId=${$.activityId}&userSource=mp&formId=123&jdChannelId=&fp=&appId=wxccb5c536b0ecd1bf&invokeKey=${$.invokeKey}`; 340 | const method = `POST`; 341 | const headers = { 342 | 'content-type' : `application/json`, 343 | 'Connection' : `keep-alive`, 344 | 'Accept-Encoding' : `gzip,compress,br,deflate`, 345 | "User-Agent": $.UA, 346 | 'Host' : `draw.jdfcloud.com`, 347 | 'Referer' : `https://servicewechat.com/wxccb5c536b0ecd1bf/733/page-frame.html`, 348 | 'cookie' : $.cookie, 349 | "lks": $.md5(""+$.invokeKey+lkt+$.activityCode), 350 | "lkt": lkt 351 | }; 352 | const body = `{}`; 353 | const myRequest = { 354 | url: url, 355 | method: method, 356 | headers: headers, 357 | body: body 358 | }; 359 | return new Promise(async resolve => { 360 | $.post(myRequest, (err, resp, data) => { 361 | try { 362 | data = JSON.parse(data); 363 | if(data.success){ 364 | console.log(`发起瓜分成功`); 365 | }else{ 366 | console.log(JSON.stringify(data)); 367 | } 368 | } catch (e) { 369 | console.log(data); 370 | $.logErr(e, resp) 371 | } finally { 372 | resolve(); 373 | } 374 | }) 375 | }) 376 | } 377 | 378 | 379 | async function getActivityDetail() { 380 | const url = `https://draw.jdfcloud.com/common/api/bean/activity/detail?activityCode=${$.activityCode}&activityId=${$.activityId}×tap=${Date.now()}&userSource=mp&jdChannelId=&appId=wxccb5c536b0ecd1bf&invokeKey=${$.invokeKey}`; 381 | const method = `GET`; 382 | const headers = { 383 | 'cookie' : $.cookie, 384 | 'Connection' : `keep-alive`, 385 | 'content-type' : `application/json`, 386 | 'Host' : `draw.jdfcloud.com`, 387 | 'Accept-Encoding' : `gzip,compress,br,deflate`, 388 | "User-Agent": $.UA, 389 | 'Referer' : `https://servicewechat.com/wxccb5c536b0ecd1bf/733/page-frame.html`, 390 | "lks": $.md5(""+$.invokeKey+lkt+$.activityCode), 391 | "lkt": lkt 392 | }; 393 | const myRequest = {url: url, method: method, headers: headers}; 394 | return new Promise(async resolve => { 395 | $.get(myRequest, (err, resp, data) => { 396 | try { 397 | //console.log(data); 398 | data = JSON.parse(data); 399 | if(data.success){ 400 | $.detail = data.data; 401 | } 402 | } catch (e) { 403 | //console.log(data); 404 | $.logErr(e, resp) 405 | } finally { 406 | resolve(); 407 | } 408 | }) 409 | }) 410 | } 411 | function TotalBean() { 412 | return new Promise(async resolve => { 413 | const options = { 414 | url: "https://me-api.jd.com/user_new/info/GetJDUserInfoUnion", 415 | headers: { 416 | Host: "me-api.jd.com", 417 | Accept: "*/*", 418 | Connection: "keep-alive", 419 | Cookie: $.cookie, 420 | "User-Agent": $.UA, 421 | "Accept-Language": "zh-cn", 422 | "Referer": "https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&", 423 | "Accept-Encoding": "gzip, deflate, br" 424 | } 425 | } 426 | $.get(options, (err, resp, data) => { 427 | try { 428 | if (err) { 429 | $.logErr(err) 430 | } else { 431 | if (data) { 432 | data = JSON.parse(data); 433 | if (data['retcode'] === "1001") { 434 | $.isLogin = false; //cookie过期 435 | return; 436 | } 437 | if (data['retcode'] === "0" && data.data && data.data.hasOwnProperty("userInfo")) { 438 | $.nickName = data.data.userInfo.baseInfo.nickname; 439 | } 440 | } else { 441 | $.log('京东服务器返回空数据'); 442 | } 443 | } 444 | } catch (e) { 445 | $.logErr(e) 446 | } finally { 447 | resolve(); 448 | } 449 | }) 450 | }) 451 | } 452 | 453 | function getUA(){ 454 | $.UA = `jdapp;iPhone;10.1.2;14.3;${randomString(40)};network/wifi;model/iPhone12,1;addressid/4199175193;appBuild/167802;jdSupportDarkMode/0;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1` 455 | } 456 | function randomString(e) { 457 | e = e || 32; 458 | let t = "abcdef0123456789", a = t.length, n = ""; 459 | for (i = 0; i < e; i++) 460 | n += t.charAt(Math.floor(Math.random() * a)); 461 | return n 462 | } 463 | 464 | 465 | function MD5(){ 466 | // MD5 467 | !function (n) { "use strict"; function t(n, t) { var r = (65535 & n) + (65535 & t); return (n >> 16) + (t >> 16) + (r >> 16) << 16 | 65535 & r } function r(n, t) { return n << t | n >>> 32 - t } function e(n, e, o, u, c, f) { return t(r(t(t(e, n), t(u, f)), c), o) } function o(n, t, r, o, u, c, f) { return e(t & r | ~t & o, n, t, u, c, f) } function u(n, t, r, o, u, c, f) { return e(t & o | r & ~o, n, t, u, c, f) } function c(n, t, r, o, u, c, f) { return e(t ^ r ^ o, n, t, u, c, f) } function f(n, t, r, o, u, c, f) { return e(r ^ (t | ~o), n, t, u, c, f) } function i(n, r) { n[r >> 5] |= 128 << r % 32, n[14 + (r + 64 >>> 9 << 4)] = r; var e, i, a, d, h, l = 1732584193, g = -271733879, v = -1732584194, m = 271733878; for (e = 0; e < n.length; e += 16)i = l, a = g, d = v, h = m, g = f(g = f(g = f(g = f(g = c(g = c(g = c(g = c(g = u(g = u(g = u(g = u(g = o(g = o(g = o(g = o(g, v = o(v, m = o(m, l = o(l, g, v, m, n[e], 7, -680876936), g, v, n[e + 1], 12, -389564586), l, g, n[e + 2], 17, 606105819), m, l, n[e + 3], 22, -1044525330), v = o(v, m = o(m, l = o(l, g, v, m, n[e + 4], 7, -176418897), g, v, n[e + 5], 12, 1200080426), l, g, n[e + 6], 17, -1473231341), m, l, n[e + 7], 22, -45705983), v = o(v, m = o(m, l = o(l, g, v, m, n[e + 8], 7, 1770035416), g, v, n[e + 9], 12, -1958414417), l, g, n[e + 10], 17, -42063), m, l, n[e + 11], 22, -1990404162), v = o(v, m = o(m, l = o(l, g, v, m, n[e + 12], 7, 1804603682), g, v, n[e + 13], 12, -40341101), l, g, n[e + 14], 17, -1502002290), m, l, n[e + 15], 22, 1236535329), v = u(v, m = u(m, l = u(l, g, v, m, n[e + 1], 5, -165796510), g, v, n[e + 6], 9, -1069501632), l, g, n[e + 11], 14, 643717713), m, l, n[e], 20, -373897302), v = u(v, m = u(m, l = u(l, g, v, m, n[e + 5], 5, -701558691), g, v, n[e + 10], 9, 38016083), l, g, n[e + 15], 14, -660478335), m, l, n[e + 4], 20, -405537848), v = u(v, m = u(m, l = u(l, g, v, m, n[e + 9], 5, 568446438), g, v, n[e + 14], 9, -1019803690), l, g, n[e + 3], 14, -187363961), m, l, n[e + 8], 20, 1163531501), v = u(v, m = u(m, l = u(l, g, v, m, n[e + 13], 5, -1444681467), g, v, n[e + 2], 9, -51403784), l, g, n[e + 7], 14, 1735328473), m, l, n[e + 12], 20, -1926607734), v = c(v, m = c(m, l = c(l, g, v, m, n[e + 5], 4, -378558), g, v, n[e + 8], 11, -2022574463), l, g, n[e + 11], 16, 1839030562), m, l, n[e + 14], 23, -35309556), v = c(v, m = c(m, l = c(l, g, v, m, n[e + 1], 4, -1530992060), g, v, n[e + 4], 11, 1272893353), l, g, n[e + 7], 16, -155497632), m, l, n[e + 10], 23, -1094730640), v = c(v, m = c(m, l = c(l, g, v, m, n[e + 13], 4, 681279174), g, v, n[e], 11, -358537222), l, g, n[e + 3], 16, -722521979), m, l, n[e + 6], 23, 76029189), v = c(v, m = c(m, l = c(l, g, v, m, n[e + 9], 4, -640364487), g, v, n[e + 12], 11, -421815835), l, g, n[e + 15], 16, 530742520), m, l, n[e + 2], 23, -995338651), v = f(v, m = f(m, l = f(l, g, v, m, n[e], 6, -198630844), g, v, n[e + 7], 10, 1126891415), l, g, n[e + 14], 15, -1416354905), m, l, n[e + 5], 21, -57434055), v = f(v, m = f(m, l = f(l, g, v, m, n[e + 12], 6, 1700485571), g, v, n[e + 3], 10, -1894986606), l, g, n[e + 10], 15, -1051523), m, l, n[e + 1], 21, -2054922799), v = f(v, m = f(m, l = f(l, g, v, m, n[e + 8], 6, 1873313359), g, v, n[e + 15], 10, -30611744), l, g, n[e + 6], 15, -1560198380), m, l, n[e + 13], 21, 1309151649), v = f(v, m = f(m, l = f(l, g, v, m, n[e + 4], 6, -145523070), g, v, n[e + 11], 10, -1120210379), l, g, n[e + 2], 15, 718787259), m, l, n[e + 9], 21, -343485551), l = t(l, i), g = t(g, a), v = t(v, d), m = t(m, h); return [l, g, v, m] } function a(n) { var t, r = "", e = 32 * n.length; for (t = 0; t < e; t += 8)r += String.fromCharCode(n[t >> 5] >>> t % 32 & 255); return r } function d(n) { var t, r = []; for (r[(n.length >> 2) - 1] = void 0, t = 0; t < r.length; t += 1)r[t] = 0; var e = 8 * n.length; for (t = 0; t < e; t += 8)r[t >> 5] |= (255 & n.charCodeAt(t / 8)) << t % 32; return r } function h(n) { return a(i(d(n), 8 * n.length)) } function l(n, t) { var r, e, o = d(n), u = [], c = []; for (u[15] = c[15] = void 0, o.length > 16 && (o = i(o, 8 * n.length)), r = 0; r < 16; r += 1)u[r] = 909522486 ^ o[r], c[r] = 1549556828 ^ o[r]; return e = i(u.concat(d(t)), 512 + 8 * t.length), a(i(c.concat(e), 640)) } function g(n) { var t, r, e = ""; for (r = 0; r < n.length; r += 1)t = n.charCodeAt(r), e += "0123456789abcdef".charAt(t >>> 4 & 15) + "0123456789abcdef".charAt(15 & t); return e } function v(n) { return unescape(encodeURIComponent(n)) } function m(n) { return h(v(n)) } function p(n) { return g(m(n)) } function s(n, t) { return l(v(n), v(t)) } function C(n, t) { return g(s(n, t)) } function A(n, t, r) { return t ? r ? s(t, n) : C(t, n) : r ? m(n) : p(n) } $.md5 = A }(this); 468 | } 469 | 470 | 471 | // prettier-ignore 472 | function Env(t,e){"undefined"!=typeof process&&JSON.stringify(process.env).indexOf("GITHUB")>-1&&process.exit(0);class s{constructor(t){this.env=t}send(t,e="GET"){t="string"==typeof t?{url:t}:t;let s=this.get;return"POST"===e&&(s=this.post),new Promise((e,i)=>{s.call(this,t,(t,s,r)=>{t?i(t):e(s)})})}get(t){return this.send.call(this.env,t)}post(t){return this.send.call(this.env,t,"POST")}}return new class{constructor(t,e){this.name=t,this.http=new s(this),this.data=null,this.dataFile="box.dat",this.logs=[],this.isMute=!1,this.isNeedRewrite=!1,this.logSeparator="\n",this.startTime=(new Date).getTime(),Object.assign(this,e),this.log("",`🔔${this.name}, 开始!`)}isNode(){return"undefined"!=typeof module&&!!module.exports}isQuanX(){return"undefined"!=typeof $task}isSurge(){return"undefined"!=typeof $httpClient&&"undefined"==typeof $loon}isLoon(){return"undefined"!=typeof $loon}toObj(t,e=null){try{return JSON.parse(t)}catch{return e}}toStr(t,e=null){try{return JSON.stringify(t)}catch{return e}}getjson(t,e){let s=e;const i=this.getdata(t);if(i)try{s=JSON.parse(this.getdata(t))}catch{}return s}setjson(t,e){try{return this.setdata(JSON.stringify(t),e)}catch{return!1}}getScript(t){return new Promise(e=>{this.get({url:t},(t,s,i)=>e(i))})}runScript(t,e){return new Promise(s=>{let i=this.getdata("@chavy_boxjs_userCfgs.httpapi");i=i?i.replace(/\n/g,"").trim():i;let r=this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout");r=r?1*r:20,r=e&&e.timeout?e.timeout:r;const[o,h]=i.split("@"),n={url:`http://${h}/v1/scripting/evaluate`,body:{script_text:t,mock_type:"cron",timeout:r},headers:{"X-Key":o,Accept:"*/*"}};this.post(n,(t,e,i)=>s(i))}).catch(t=>this.logErr(t))}loaddata(){if(!this.isNode())return{};{this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e);if(!s&&!i)return{};{const i=s?t:e;try{return JSON.parse(this.fs.readFileSync(i))}catch(t){return{}}}}}writedata(){if(this.isNode()){this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e),r=JSON.stringify(this.data);s?this.fs.writeFileSync(t,r):i?this.fs.writeFileSync(e,r):this.fs.writeFileSync(t,r)}}lodash_get(t,e,s){const i=e.replace(/\[(\d+)\]/g,".$1").split(".");let r=t;for(const t of i)if(r=Object(r)[t],void 0===r)return s;return r}lodash_set(t,e,s){return Object(t)!==t?t:(Array.isArray(e)||(e=e.toString().match(/[^.[\]]+/g)||[]),e.slice(0,-1).reduce((t,s,i)=>Object(t[s])===t[s]?t[s]:t[s]=Math.abs(e[i+1])>>0==+e[i+1]?[]:{},t)[e[e.length-1]]=s,t)}getdata(t){let e=this.getval(t);if(/^@/.test(t)){const[,s,i]=/^@(.*?)\.(.*?)$/.exec(t),r=s?this.getval(s):"";if(r)try{const t=JSON.parse(r);e=t?this.lodash_get(t,i,""):e}catch(t){e=""}}return e}setdata(t,e){let s=!1;if(/^@/.test(e)){const[,i,r]=/^@(.*?)\.(.*?)$/.exec(e),o=this.getval(i),h=i?"null"===o?null:o||"{}":"{}";try{const e=JSON.parse(h);this.lodash_set(e,r,t),s=this.setval(JSON.stringify(e),i)}catch(e){const o={};this.lodash_set(o,r,t),s=this.setval(JSON.stringify(o),i)}}else s=this.setval(t,e);return s}getval(t){return this.isSurge()||this.isLoon()?$persistentStore.read(t):this.isQuanX()?$prefs.valueForKey(t):this.isNode()?(this.data=this.loaddata(),this.data[t]):this.data&&this.data[t]||null}setval(t,e){return this.isSurge()||this.isLoon()?$persistentStore.write(t,e):this.isQuanX()?$prefs.setValueForKey(t,e):this.isNode()?(this.data=this.loaddata(),this.data[e]=t,this.writedata(),!0):this.data&&this.data[e]||null}initGotEnv(t){this.got=this.got?this.got:require("got"),this.cktough=this.cktough?this.cktough:require("tough-cookie"),this.ckjar=this.ckjar?this.ckjar:new this.cktough.CookieJar,t&&(t.headers=t.headers?t.headers:{},void 0===t.headers.Cookie&&void 0===t.cookieJar&&(t.cookieJar=this.ckjar))}get(t,e=(()=>{})){t.headers&&(delete t.headers["Content-Type"],delete t.headers["Content-Length"]),this.isSurge()||this.isLoon()?(this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.get(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)})):this.isQuanX()?(this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t))):this.isNode()&&(this.initGotEnv(t),this.got(t).on("redirect",(t,e)=>{try{if(t.headers["set-cookie"]){const s=t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString();s&&this.ckjar.setCookieSync(s,null),e.cookieJar=this.ckjar}}catch(t){this.logErr(t)}}).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)}))}post(t,e=(()=>{})){if(t.body&&t.headers&&!t.headers["Content-Type"]&&(t.headers["Content-Type"]="application/x-www-form-urlencoded"),t.headers&&delete t.headers["Content-Length"],this.isSurge()||this.isLoon())this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.post(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)});else if(this.isQuanX())t.method="POST",this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t));else if(this.isNode()){this.initGotEnv(t);const{url:s,...i}=t;this.got.post(s,i).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)})}}time(t,e=null){const s=e?new Date(e):new Date;let i={"M+":s.getMonth()+1,"d+":s.getDate(),"H+":s.getHours(),"m+":s.getMinutes(),"s+":s.getSeconds(),"q+":Math.floor((s.getMonth()+3)/3),S:s.getMilliseconds()};/(y+)/.test(t)&&(t=t.replace(RegExp.$1,(s.getFullYear()+"").substr(4-RegExp.$1.length)));for(let e in i)new RegExp("("+e+")").test(t)&&(t=t.replace(RegExp.$1,1==RegExp.$1.length?i[e]:("00"+i[e]).substr((""+i[e]).length)));return t}msg(e=t,s="",i="",r){const o=t=>{if(!t)return t;if("string"==typeof t)return this.isLoon()?t:this.isQuanX()?{"open-url":t}:this.isSurge()?{url:t}:void 0;if("object"==typeof t){if(this.isLoon()){let e=t.openUrl||t.url||t["open-url"],s=t.mediaUrl||t["media-url"];return{openUrl:e,mediaUrl:s}}if(this.isQuanX()){let e=t["open-url"]||t.url||t.openUrl,s=t["media-url"]||t.mediaUrl;return{"open-url":e,"media-url":s}}if(this.isSurge()){let e=t.url||t.openUrl||t["open-url"];return{url:e}}}};if(this.isMute||(this.isSurge()||this.isLoon()?$notification.post(e,s,i,o(r)):this.isQuanX()&&$notify(e,s,i,o(r))),!this.isMuteLog){let t=["","==============📣系统通知📣=============="];t.push(e),s&&t.push(s),i&&t.push(i),console.log(t.join("\n")),this.logs=this.logs.concat(t)}}log(...t){t.length>0&&(this.logs=[...this.logs,...t]),console.log(t.join(this.logSeparator))}logErr(t,e){const s=!this.isSurge()&&!this.isQuanX()&&!this.isLoon();s?this.log("",`❗️${this.name}, 错误!`,t.stack):this.log("",`❗️${this.name}, 错误!`,t)}wait(t){return new Promise(e=>setTimeout(e,t))}done(t={}){const e=(new Date).getTime(),s=(e-this.startTime)/1e3;this.log("",`🔔${this.name}, 结束! 🕛 ${s} 秒`),this.log(),(this.isSurge()||this.isQuanX()||this.isLoon())&&$done(t)}}(t,e)} 473 | -------------------------------------------------------------------------------- /sendNotify.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: lxk0301 https://gitee.com/lxk0301 3 | * @Date: 2020-08-19 16:12:40 4 | * @Last Modified by: smiek2121 5 | * @Last Modified time: 2021-11-12 6 | * sendNotify 推送通知功能 7 | * @param text 通知头 8 | * @param desp 通知体 9 | * @param params 某些推送通知方式点击弹窗可跳转, 例:{ url: 'https://abc.com' } 10 | * @param author 作者仓库等信息 例:`本通知 By:https://github.com/smiek2121/scripts` 11 | */ 12 | 13 | const querystring = require('querystring'); 14 | const $ = new Env(); 15 | const timeout = 15000; //超时时间(单位毫秒) 16 | // =======================================go-cqhttp通知设置区域=========================================== 17 | //gobot_url 填写请求地址http://127.0.0.1/send_private_msg 18 | //gobot_token 填写在go-cqhttp文件设置的访问密钥 19 | //gobot_qq 填写推送到个人QQ或者QQ群号 20 | //go-cqhttp相关API https://docs.go-cqhttp.org/api 21 | let GOBOT_URL = ''; // 推送到个人QQ: http://127.0.0.1/send_private_msg 群:http://127.0.0.1/send_group_msg 22 | let GOBOT_TOKEN = ''; //访问密钥 23 | let GOBOT_QQ = ''; // 如果GOBOT_URL设置 /send_private_msg 则需要填入 user_id=个人QQ 相反如果是 /send_group_msg 则需要填入 group_id=QQ群 24 | 25 | // =======================================微信server酱通知设置区域=========================================== 26 | //此处填你申请的SCKEY. 27 | //(环境变量名 PUSH_KEY) 28 | let SCKEY = ''; 29 | 30 | // =======================================Bark App通知设置区域=========================================== 31 | //此处填你BarkAPP的信息(IP/设备码,例如:https://api.day.app/XXXXXXXX) 32 | let BARK_PUSH = ''; 33 | //BARK app推送铃声,铃声列表去APP查看复制填写 34 | let BARK_SOUND = ''; 35 | 36 | // =======================================telegram机器人通知设置区域=========================================== 37 | //此处填你telegram bot 的Token,telegram机器人通知推送必填项.例如:1077xxx4424:AAFjv0FcqxxxxxxgEMGfi22B4yh15R5uw 38 | //(环境变量名 TG_BOT_TOKEN) 39 | let TG_BOT_TOKEN = ''; 40 | //此处填你接收通知消息的telegram用户的id,telegram机器人通知推送必填项.例如:129xxx206 41 | //(环境变量名 TG_USER_ID) 42 | let TG_USER_ID = ''; 43 | //tg推送HTTP代理设置(不懂可忽略,telegram机器人通知推送功能中非必填) 44 | let TG_PROXY_HOST = ''; //例如:127.0.0.1(环境变量名:TG_PROXY_HOST) 45 | let TG_PROXY_PORT = ''; //例如:1080(环境变量名:TG_PROXY_PORT) 46 | let TG_PROXY_AUTH = ''; //tg代理配置认证参数 47 | //Telegram api自建的反向代理地址(不懂可忽略,telegram机器人通知推送功能中非必填),默认tg官方api(环境变量名:TG_API_HOST) 48 | let TG_API_HOST = 'api.telegram.org'; 49 | // =======================================钉钉机器人通知设置区域=========================================== 50 | //此处填你钉钉 bot 的webhook,例如:5a544165465465645d0f31dca676e7bd07415asdasd 51 | //(环境变量名 DD_BOT_TOKEN) 52 | let DD_BOT_TOKEN = ''; 53 | //密钥,机器人安全设置页面,加签一栏下面显示的SEC开头的字符串 54 | let DD_BOT_SECRET = ''; 55 | 56 | // =======================================企业微信机器人通知设置区域=========================================== 57 | //此处填你企业微信机器人的 webhook(详见文档 https://work.weixin.qq.com/api/doc/90000/90136/91770),例如:693a91f6-7xxx-4bc4-97a0-0ec2sifa5aaa 58 | //(环境变量名 QYWX_KEY) 59 | let QYWX_KEY = ''; 60 | 61 | // =======================================企业微信应用消息通知设置区域=========================================== 62 | /* 63 | 此处填你企业微信应用消息的值(详见文档 https://work.weixin.qq.com/api/doc/90000/90135/90236) 64 | 环境变量名 QYWX_AM依次填入 corpid,corpsecret,touser(注:多个成员ID使用|隔开),agentid,消息类型(选填,不填默认文本消息类型) 65 | 注意用,号隔开(英文输入法的逗号),例如:wwcff56746d9adwers,B-791548lnzXBE6_BWfxdf3kSTMJr9vFEPKAbh6WERQ,mingcheng,1000001,2COXgjH2UIfERF2zxrtUOKgQ9XklUqMdGSWLBoW_lSDAdafat 66 | 可选推送消息类型(推荐使用图文消息(mpnews)): 67 | - 文本卡片消息: 0 (数字零) 68 | - 文本消息: 1 (数字一) 69 | - 图文消息(mpnews): 素材库图片id, 可查看此教程(http://note.youdao.com/s/HMiudGkb)或者(https://note.youdao.com/ynoteshare1/index.html?id=1a0c8aff284ad28cbd011b29b3ad0191&type=note) 70 | */ 71 | let QYWX_AM = ''; 72 | 73 | // =======================================iGot聚合推送通知设置区域=========================================== 74 | //此处填您iGot的信息(推送key,例如:https://push.hellyw.com/XXXXXXXX) 75 | let IGOT_PUSH_KEY = ''; 76 | 77 | // =======================================push+设置区域======================================= 78 | //官方文档:http://www.pushplus.plus/ 79 | //PUSH_PLUS_TOKEN:微信扫码登录后一对一推送或一对多推送下面的token(您的Token),不提供PUSH_PLUS_USER则默认为一对一推送 80 | //PUSH_PLUS_USER: 一对多推送的“群组编码”(一对多推送下面->您的群组(如无则新建)->群组编码,如果您是创建群组人。也需点击“查看二维码”扫描绑定,否则不能接受群组消息推送) 81 | let PUSH_PLUS_TOKEN = ''; 82 | let PUSH_PLUS_USER = ''; 83 | 84 | //==========================云端环境变量的判断与接收========================= 85 | if (process.env.GOBOT_URL) { 86 | GOBOT_URL = process.env.GOBOT_URL; 87 | } 88 | if (process.env.GOBOT_TOKEN) { 89 | GOBOT_TOKEN = process.env.GOBOT_TOKEN; 90 | } 91 | if (process.env.GOBOT_QQ) { 92 | GOBOT_QQ = process.env.GOBOT_QQ; 93 | } 94 | 95 | if (process.env.PUSH_KEY) { 96 | SCKEY = process.env.PUSH_KEY; 97 | } 98 | 99 | if (process.env.QQ_SKEY) { 100 | QQ_SKEY = process.env.QQ_SKEY; 101 | } 102 | 103 | if (process.env.QQ_MODE) { 104 | QQ_MODE = process.env.QQ_MODE; 105 | } 106 | 107 | if (process.env.BARK_PUSH) { 108 | if ( 109 | process.env.BARK_PUSH.indexOf('https') > -1 || 110 | process.env.BARK_PUSH.indexOf('http') > -1 111 | ) { 112 | //兼容BARK自建用户 113 | BARK_PUSH = process.env.BARK_PUSH; 114 | } else { 115 | BARK_PUSH = `https://api.day.app/${process.env.BARK_PUSH}`; 116 | } 117 | if (process.env.BARK_SOUND) { 118 | BARK_SOUND = process.env.BARK_SOUND; 119 | } 120 | } else { 121 | if ( 122 | BARK_PUSH && 123 | BARK_PUSH.indexOf('https') === -1 && 124 | BARK_PUSH.indexOf('http') === -1 125 | ) { 126 | //兼容BARK本地用户只填写设备码的情况 127 | BARK_PUSH = `https://api.day.app/${BARK_PUSH}`; 128 | } 129 | } 130 | if (process.env.TG_BOT_TOKEN) { 131 | TG_BOT_TOKEN = process.env.TG_BOT_TOKEN; 132 | } 133 | if (process.env.TG_USER_ID) { 134 | TG_USER_ID = process.env.TG_USER_ID; 135 | } 136 | if (process.env.TG_PROXY_AUTH) TG_PROXY_AUTH = process.env.TG_PROXY_AUTH; 137 | if (process.env.TG_PROXY_HOST) TG_PROXY_HOST = process.env.TG_PROXY_HOST; 138 | if (process.env.TG_PROXY_PORT) TG_PROXY_PORT = process.env.TG_PROXY_PORT; 139 | if (process.env.TG_API_HOST) TG_API_HOST = process.env.TG_API_HOST; 140 | 141 | if (process.env.DD_BOT_TOKEN) { 142 | DD_BOT_TOKEN = process.env.DD_BOT_TOKEN; 143 | if (process.env.DD_BOT_SECRET) { 144 | DD_BOT_SECRET = process.env.DD_BOT_SECRET; 145 | } 146 | } 147 | 148 | if (process.env.QYWX_KEY) { 149 | QYWX_KEY = process.env.QYWX_KEY; 150 | } 151 | 152 | if (process.env.QYWX_AM) { 153 | QYWX_AM = process.env.QYWX_AM; 154 | } 155 | 156 | if (process.env.IGOT_PUSH_KEY) { 157 | IGOT_PUSH_KEY = process.env.IGOT_PUSH_KEY; 158 | } 159 | 160 | if (process.env.PUSH_PLUS_TOKEN) { 161 | PUSH_PLUS_TOKEN = process.env.PUSH_PLUS_TOKEN; 162 | } 163 | if (process.env.PUSH_PLUS_USER) { 164 | PUSH_PLUS_USER = process.env.PUSH_PLUS_USER; 165 | } 166 | //==========================云端环境变量的判断与接收========================= 167 | 168 | /** 169 | * sendNotify 推送通知功能 170 | * @param text 通知头 171 | * @param desp 通知体 172 | * @param params 某些推送通知方式点击弹窗可跳转, 例:{ url: 'https://abc.com' } 173 | * @param author 作者仓库等信息 例:`本通知 By:https://github.com/smiek2121/scripts` 174 | * @returns {Promise} 175 | */ 176 | async function sendNotify( 177 | text, 178 | desp, 179 | params = {}, 180 | author = '', 181 | ) { 182 | //提供6种通知 183 | desp += "\n"+author; //增加作者信息,防止被贩卖等 184 | text = text.replace(/&/g,'%26') 185 | desp = desp.replace(/&/g,'%26') 186 | await Promise.all([ 187 | serverNotify(text, desp), //微信server酱 188 | pushPlusNotify(text, desp), //pushplus(推送加) 189 | ]) 190 | //由于上述两种微信通知需点击进去才能查看到详情,故text(标题内容)携带了账号序号以及昵称信息,方便不点击也可知道是哪个京东哪个活动 191 | text = text.match(/.*?(?=\s?-)/g) ? text.match(/.*?(?=\s?-)/g)[0] : text; 192 | await Promise.all([ 193 | BarkNotify(text, desp, params), //iOS Bark APP 194 | tgBotNotify(text, desp), //telegram 机器人 195 | ddBotNotify(text, desp), //钉钉机器人 196 | qywxBotNotify(text, desp), //企业微信机器人 197 | qywxamNotify(text, desp), //企业微信应用消息推送 198 | iGotNotify(text, desp, params), //iGot 199 | gobotNotify(text, desp),//go-cqhttp 200 | ]); 201 | } 202 | 203 | function gobotNotify(text, desp, time = 2100) { 204 | return new Promise((resolve) => { 205 | if (GOBOT_URL) { 206 | const options = { 207 | url: `${GOBOT_URL}?access_token=${GOBOT_TOKEN}&${GOBOT_QQ}`, 208 | body: `message=${text}\n${desp}`, 209 | headers: { 210 | 'Content-Type': 'application/x-www-form-urlencoded', 211 | }, 212 | timeout, 213 | }; 214 | setTimeout(() => { 215 | $.post(options, (err, resp, data) => { 216 | try { 217 | if (err) { 218 | console.log('发送go-cqhttp通知调用API失败!!\n'); 219 | console.log(err); 220 | } else { 221 | data = JSON.parse(data); 222 | if (data.retcode === 0) { 223 | console.log('go-cqhttp发送通知消息成功🎉\n'); 224 | } else if (data.retcode === 100) { 225 | console.log(`go-cqhttp发送通知消息异常: ${data.errmsg}\n`); 226 | } else { 227 | console.log( 228 | `go-cqhttp发送通知消息异常\n${JSON.stringify(data)}`, 229 | ); 230 | } 231 | } 232 | } catch (e) { 233 | $.logErr(e, resp); 234 | } finally { 235 | resolve(data); 236 | } 237 | }); 238 | }, time); 239 | } else { 240 | resolve(); 241 | } 242 | }); 243 | } 244 | 245 | function serverNotify(text, desp, time = 2100) { 246 | return new Promise(resolve => { 247 | if (SCKEY) { 248 | //微信server酱推送通知一个\n不会换行,需要两个\n才能换行,故做此替换 249 | desp = desp.replace(/[\n\r]/g, '\n\n'); 250 | const options = { 251 | url: SCKEY.includes('SCT') 252 | ? `https://sctapi.ftqq.com/${SCKEY}.send` 253 | : `https://sc.ftqq.com/${SCKEY}.send`, 254 | body: `text=${text}&desp=${desp}`, 255 | headers: { 256 | 'Content-Type': 'application/x-www-form-urlencoded', 257 | }, 258 | timeout, 259 | } 260 | setTimeout(() => { 261 | $.post(options, (err, resp, data) => { 262 | try { 263 | if (err) { 264 | console.log('发送通知调用API失败!!\n') 265 | console.log(err); 266 | } else { 267 | data = JSON.parse(data); 268 | //server酱和Server酱·Turbo版的返回json格式不太一样 269 | if (data.errno === 0 || data.data.errno === 0 ) { 270 | console.log('server酱发送通知消息成功🎉\n') 271 | } else if (data.errno === 1024) { 272 | // 一分钟内发送相同的内容会触发 273 | console.log(`server酱发送通知消息异常: ${data.errmsg}\n`) 274 | } else { 275 | console.log(`server酱发送通知消息异常\n${JSON.stringify(data)}`) 276 | } 277 | } 278 | } catch (e) { 279 | $.logErr(e, resp); 280 | } finally { 281 | resolve(data); 282 | } 283 | }) 284 | }, time) 285 | } else { 286 | resolve() 287 | } 288 | }) 289 | } 290 | 291 | function CoolPush(text, desp) { 292 | return new Promise(resolve => { 293 | if (QQ_SKEY) { 294 | let options = { 295 | url: `https://push.xuthus.cc/${QQ_MODE}/${QQ_SKEY}`, 296 | headers: { 297 | 'Content-Type': 'application/json', 298 | }, 299 | }; 300 | 301 | // 已知敏感词 302 | text = text.replace(/京豆/g, '豆豆'); 303 | desp = desp.replace(/京豆/g, ''); 304 | desp = desp.replace(/🐶/g, ''); 305 | desp = desp.replace(/红包/g, 'H包'); 306 | 307 | switch (QQ_MODE) { 308 | case 'email': 309 | options.json = { 310 | t: text, 311 | c: desp, 312 | }; 313 | break; 314 | default: 315 | options.body = `${text}\n\n${desp}`; 316 | } 317 | 318 | let pushMode = function (t) { 319 | switch (t) { 320 | case 'send': 321 | return '个人'; 322 | case 'group': 323 | return 'QQ群'; 324 | case 'wx': 325 | return '微信'; 326 | case 'ww': 327 | return '企业微信'; 328 | case 'email': 329 | return '邮件'; 330 | default: 331 | return '未知方式'; 332 | } 333 | }; 334 | 335 | $.post(options, (err, resp, data) => { 336 | try { 337 | if (err) { 338 | console.log(`发送${pushMode(QQ_MODE)}通知调用API失败!!\n`) 339 | console.log(err); 340 | } else { 341 | data = JSON.parse(data); 342 | if (data.code === 200) { 343 | console.log(`酷推发送${pushMode(QQ_MODE)}通知消息成功🎉\n`) 344 | } else if (data.code === 400) { 345 | console.log(`QQ酷推(Cool Push)发送${pushMode(QQ_MODE)}推送失败:${data.msg}\n`) 346 | } else if (data.code === 503) { 347 | console.log(`QQ酷推出错,${data.message}:${data.data}\n`) 348 | }else{ 349 | console.log(`酷推推送异常: ${JSON.stringify(data)}`); 350 | } 351 | } 352 | } catch (e) { 353 | $.logErr(e, resp); 354 | } finally { 355 | resolve(data); 356 | } 357 | }) 358 | } else { 359 | resolve() 360 | } 361 | }) 362 | } 363 | 364 | function BarkNotify(text, desp, params = {}) { 365 | return new Promise((resolve) => { 366 | if (BARK_PUSH) { 367 | const options = { 368 | url: `${BARK_PUSH}/${encodeURIComponent(text)}/${encodeURIComponent( 369 | desp, 370 | )}?sound=${BARK_SOUND}&${querystring.stringify(params)}`, 371 | headers: { 372 | 'Content-Type': 'application/x-www-form-urlencoded', 373 | }, 374 | timeout, 375 | } 376 | $.get(options, (err, resp, data) => { 377 | try { 378 | if (err) { 379 | console.log('Bark APP发送通知调用API失败!!\n') 380 | console.log(err); 381 | } else { 382 | data = JSON.parse(data); 383 | if (data.code === 200) { 384 | console.log('Bark APP发送通知消息成功🎉\n') 385 | } else { 386 | console.log(`${data.message}\n`); 387 | } 388 | } 389 | } catch (e) { 390 | $.logErr(e, resp); 391 | } finally { 392 | resolve() 393 | } 394 | }) 395 | } else { 396 | resolve() 397 | } 398 | }) 399 | } 400 | 401 | function tgBotNotify(text, desp) { 402 | return new Promise((resolve) => { 403 | if (TG_BOT_TOKEN && TG_USER_ID) { 404 | const options = { 405 | url: `https://${TG_API_HOST}/bot${TG_BOT_TOKEN}/sendMessage`, 406 | body: `chat_id=${TG_USER_ID}&text=${text}\n\n${desp}&disable_web_page_preview=true`, 407 | headers: { 408 | 'Content-Type': 'application/x-www-form-urlencoded', 409 | }, 410 | timeout, 411 | } 412 | if (TG_PROXY_HOST && TG_PROXY_PORT) { 413 | const tunnel = require('tunnel'); 414 | const agent = { 415 | https: tunnel.httpsOverHttp({ 416 | proxy: { 417 | host: TG_PROXY_HOST, 418 | port: TG_PROXY_PORT * 1, 419 | proxyAuth: TG_PROXY_AUTH, 420 | }, 421 | }), 422 | } 423 | Object.assign(options, { agent }) 424 | } 425 | $.post(options, (err, resp, data) => { 426 | try { 427 | if (err) { 428 | console.log('telegram发送通知消息失败!!\n') 429 | console.log(err); 430 | } else { 431 | data = JSON.parse(data); 432 | if (data.ok) { 433 | console.log('Telegram发送通知消息成功🎉。\n') 434 | } else if (data.error_code === 400) { 435 | console.log('请主动给bot发送一条消息并检查接收用户ID是否正确。\n') 436 | } else if (data.error_code === 401) { 437 | console.log('Telegram bot token 填写错误。\n') 438 | } 439 | } 440 | } catch (e) { 441 | $.logErr(e, resp); 442 | } finally { 443 | resolve(data); 444 | } 445 | }) 446 | } else { 447 | resolve() 448 | } 449 | }) 450 | } 451 | function ddBotNotify(text, desp) { 452 | return new Promise((resolve) => { 453 | const options = { 454 | url: `https://oapi.dingtalk.com/robot/send?access_token=${DD_BOT_TOKEN}`, 455 | json: { 456 | msgtype: 'text', 457 | text: { 458 | content: ` ${text}\n\n${desp}`, 459 | }, 460 | }, 461 | headers: { 462 | 'Content-Type': 'application/json', 463 | }, 464 | timeout, 465 | } 466 | if (DD_BOT_TOKEN && DD_BOT_SECRET) { 467 | const crypto = require('crypto'); 468 | const dateNow = Date.now(); 469 | const hmac = crypto.createHmac('sha256', DD_BOT_SECRET); 470 | hmac.update(`${dateNow}\n${DD_BOT_SECRET}`); 471 | const result = encodeURIComponent(hmac.digest('base64')); 472 | options.url = `${options.url}×tamp=${dateNow}&sign=${result}`; 473 | $.post(options, (err, resp, data) => { 474 | try { 475 | if (err) { 476 | console.log('钉钉发送通知消息失败!!\n') 477 | console.log(err); 478 | } else { 479 | data = JSON.parse(data); 480 | if (data.errcode === 0) { 481 | console.log('钉钉发送通知消息成功🎉。\n') 482 | } else { 483 | console.log(`${data.errmsg}\n`) 484 | } 485 | } 486 | } catch (e) { 487 | $.logErr(e, resp); 488 | } finally { 489 | resolve(data); 490 | } 491 | }) 492 | } else if (DD_BOT_TOKEN) { 493 | $.post(options, (err, resp, data) => { 494 | try { 495 | if (err) { 496 | console.log('钉钉发送通知消息失败!!\n') 497 | console.log(err); 498 | } else { 499 | data = JSON.parse(data); 500 | if (data.errcode === 0) { 501 | console.log('钉钉发送通知消息完成。\n') 502 | } else { 503 | console.log(`${data.errmsg}\n`) 504 | } 505 | } 506 | } catch (e) { 507 | $.logErr(e, resp); 508 | } finally { 509 | resolve(data); 510 | } 511 | }) 512 | } else { 513 | resolve() 514 | } 515 | }) 516 | } 517 | 518 | function qywxBotNotify(text, desp) { 519 | return new Promise((resolve) => { 520 | const options = { 521 | url: `https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=${QYWX_KEY}`, 522 | json: { 523 | msgtype: 'text', 524 | text: { 525 | content: ` ${text}\n\n${desp}`, 526 | }, 527 | }, 528 | headers: { 529 | 'Content-Type': 'application/json', 530 | }, 531 | timeout, 532 | }; 533 | if (QYWX_KEY) { 534 | $.post(options, (err, resp, data) => { 535 | try { 536 | if (err) { 537 | console.log('企业微信发送通知消息失败!!\n') 538 | console.log(err) 539 | } else { 540 | data = JSON.parse(data) 541 | if (data.errcode === 0) { 542 | console.log('企业微信发送通知消息成功🎉。\n') 543 | } else { 544 | console.log(`${data.errmsg}\n`) 545 | } 546 | } 547 | } catch (e) { 548 | $.logErr(e, resp) 549 | } finally { 550 | resolve(data) 551 | } 552 | }); 553 | } else { 554 | resolve() 555 | } 556 | }); 557 | } 558 | 559 | function ChangeUserId(desp) { 560 | const QYWX_AM_AY = QYWX_AM.split(',') 561 | if (QYWX_AM_AY[2]) { 562 | const userIdTmp = QYWX_AM_AY[2].split('|') 563 | let userId = ''; 564 | for (let i = 0; i < userIdTmp.length; i++) { 565 | const count = '账号' + (i + 1) 566 | const count2 = '签到号 ' + (i + 1) 567 | if (desp.match(count2)) { 568 | userId = userIdTmp[i] 569 | } 570 | } 571 | if (!userId) userId = QYWX_AM_AY[2] 572 | return userId; 573 | } else { 574 | return '@all' 575 | } 576 | } 577 | 578 | function qywxamNotify(text, desp) { 579 | return new Promise((resolve) => { 580 | if (QYWX_AM) { 581 | const QYWX_AM_AY = QYWX_AM.split(',') 582 | const options_accesstoken = { 583 | url: `https://qyapi.weixin.qq.com/cgi-bin/gettoken`, 584 | json: { 585 | corpid: `${QYWX_AM_AY[0]}`, 586 | corpsecret: `${QYWX_AM_AY[1]}`, 587 | }, 588 | headers: { 589 | 'Content-Type': 'application/json', 590 | }, 591 | timeout, 592 | } 593 | $.post(options_accesstoken, (err, resp, data) => { 594 | html = desp.replace(/\n/g, '
'); 595 | var json = JSON.parse(data); 596 | accesstoken = json.access_token; 597 | let options; 598 | 599 | switch (QYWX_AM_AY[4]) { 600 | case '0': 601 | options = { 602 | msgtype: 'textcard', 603 | textcard: { 604 | title: `${text}`, 605 | description: `${desp}`, 606 | url: 'https://github.com/smiek2121/scripts', 607 | btntxt: '更多', 608 | }, 609 | } 610 | break; 611 | 612 | case '1': 613 | options = { 614 | msgtype: 'text', 615 | text: { 616 | content: `${text}\n\n${desp}`, 617 | }, 618 | } 619 | break; 620 | 621 | default: 622 | options = { 623 | msgtype: 'mpnews', 624 | mpnews: { 625 | articles: [ 626 | { 627 | title: `${text}`, 628 | thumb_media_id: `${QYWX_AM_AY[4]}`, 629 | author: `智能助手`, 630 | content_source_url: ``, 631 | content: `${html}`, 632 | digest: `${desp}`, 633 | }, 634 | ], 635 | }, 636 | } 637 | } 638 | if (!QYWX_AM_AY[4]) { 639 | //如不提供第四个参数,则默认进行文本消息类型推送 640 | options = { 641 | msgtype: 'text', 642 | text: { 643 | content: `${text}\n\n${desp}`, 644 | }, 645 | } 646 | } 647 | options = { 648 | url: `https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=${accesstoken}`, 649 | json: { 650 | touser: `${ChangeUserId(desp)}`, 651 | agentid: `${QYWX_AM_AY[3]}`, 652 | safe: '0', 653 | ...options, 654 | }, 655 | headers: { 656 | 'Content-Type': 'application/json', 657 | }, 658 | } 659 | 660 | $.post(options, (err, resp, data) => { 661 | try { 662 | if (err) { 663 | console.log( 664 | '成员ID:' + 665 | ChangeUserId(desp) + 666 | '企业微信应用消息发送通知消息失败!!\n', 667 | ); 668 | console.log(err); 669 | } else { 670 | data = JSON.parse(data); 671 | if (data.errcode === 0) { 672 | console.log('成员ID:' + ChangeUserId(desp) + '企业微信应用消息发送通知消息成功🎉。\n') 673 | } else { 674 | console.log(`${data.errmsg}\n`); 675 | } 676 | } 677 | } catch (e) { 678 | $.logErr(e, resp); 679 | } finally { 680 | resolve(data); 681 | } 682 | }); 683 | }); 684 | } else { 685 | resolve() 686 | } 687 | }) 688 | } 689 | 690 | function iGotNotify(text, desp, params = {}) { 691 | return new Promise((resolve) => { 692 | if (IGOT_PUSH_KEY) { 693 | // 校验传入的IGOT_PUSH_KEY是否有效 694 | const IGOT_PUSH_KEY_REGX = new RegExp('^[a-zA-Z0-9]{24}$') 695 | if (!IGOT_PUSH_KEY_REGX.test(IGOT_PUSH_KEY)) { 696 | console.log('您所提供的IGOT_PUSH_KEY无效\n') 697 | resolve() 698 | return 699 | } 700 | const options = { 701 | url: `https://push.hellyw.com/${IGOT_PUSH_KEY.toLowerCase()}`, 702 | body: `title=${text}&content=${desp}&${querystring.stringify(params)}`, 703 | headers: { 704 | 'Content-Type': 'application/x-www-form-urlencoded', 705 | }, 706 | timeout, 707 | } 708 | $.post(options, (err, resp, data) => { 709 | try { 710 | if (err) { 711 | console.log('发送通知调用API失败!!\n') 712 | console.log(err); 713 | } else { 714 | if (typeof data === 'string') data = JSON.parse(data) 715 | if (data.ret === 0) { 716 | console.log('iGot发送通知消息成功🎉\n') 717 | } else { 718 | console.log(`iGot发送通知消息失败:${data.errMsg}\n`) 719 | } 720 | } 721 | } catch (e) { 722 | $.logErr(e, resp); 723 | } finally { 724 | resolve(data); 725 | } 726 | }) 727 | } else { 728 | resolve() 729 | } 730 | }) 731 | } 732 | 733 | function pushPlusNotify(text, desp) { 734 | return new Promise((resolve) => { 735 | if (PUSH_PLUS_TOKEN) { 736 | desp = desp.replace(/[\n\r]/g, '
'); // 默认为html, 不支持plaintext 737 | const body = { 738 | token: `${PUSH_PLUS_TOKEN}`, 739 | title: `${text}`, 740 | content: `${desp}`, 741 | topic: `${PUSH_PLUS_USER}`, 742 | } 743 | const options = { 744 | url: `https://www.pushplus.plus/send`, 745 | body: JSON.stringify(body), 746 | headers: { 747 | 'Content-Type': ' application/json', 748 | }, 749 | timeout, 750 | } 751 | $.post(options, (err, resp, data) => { 752 | try { 753 | if (err) { 754 | console.log(`push+发送${PUSH_PLUS_USER ? '一对多' : '一对一'}通知消息失败!!\n`) 755 | console.log(err); 756 | } else { 757 | data = JSON.parse(data); 758 | if (data.code === 200) { 759 | console.log(`push+发送${PUSH_PLUS_USER ? '一对多' : '一对一'}通知消息完成。\n`) 760 | } else { 761 | console.log(`push+发送${PUSH_PLUS_USER ? '一对多' : '一对一'}通知消息失败:${data.msg}\n`) 762 | } 763 | } 764 | } catch (e) { 765 | $.logErr(e, resp); 766 | } finally { 767 | resolve(data); 768 | } 769 | }) 770 | } else { 771 | resolve() 772 | } 773 | }) 774 | } 775 | 776 | module.exports = { 777 | sendNotify, 778 | BARK_PUSH 779 | } 780 | // prettier-ignore 781 | function Env(t,s){return new class{constructor(t,s){this.name=t,this.data=null,this.dataFile="box.dat",this.logs=[],this.logSeparator="\n",this.startTime=(new Date).getTime(),Object.assign(this,s),this.log("",`\ud83d\udd14${this.name}, \u5f00\u59cb!`)}isNode(){return"undefined"!=typeof module&&!!module.exports}isQuanX(){return"undefined"!=typeof $task}isSurge(){return"undefined"!=typeof $httpClient&&"undefined"==typeof $loon}isLoon(){return"undefined"!=typeof $loon}getScript(t){return new Promise(s=>{$.get({url:t},(t,e,i)=>s(i))})}runScript(t,s){return new Promise(e=>{let i=this.getdata("@chavy_boxjs_userCfgs.httpapi");i=i?i.replace(/\n/g,"").trim():i;let o=this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout");o=o?1*o:20,o=s&&s.timeout?s.timeout:o;const[h,a]=i.split("@"),r={url:`http://${a}/v1/scripting/evaluate`,body:{script_text:t,mock_type:"cron",timeout:o},headers:{"X-Key":h,Accept:"*/*"}};$.post(r,(t,s,i)=>e(i))}).catch(t=>this.logErr(t))}loaddata(){if(!this.isNode())return{};{this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),s=this.path.resolve(process.cwd(),this.dataFile),e=this.fs.existsSync(t),i=!e&&this.fs.existsSync(s);if(!e&&!i)return{};{const i=e?t:s;try{return JSON.parse(this.fs.readFileSync(i))}catch(t){return{}}}}}writedata(){if(this.isNode()){this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),s=this.path.resolve(process.cwd(),this.dataFile),e=this.fs.existsSync(t),i=!e&&this.fs.existsSync(s),o=JSON.stringify(this.data);e?this.fs.writeFileSync(t,o):i?this.fs.writeFileSync(s,o):this.fs.writeFileSync(t,o)}}lodash_get(t,s,e){const i=s.replace(/\[(\d+)\]/g,".$1").split(".");let o=t;for(const t of i)if(o=Object(o)[t],void 0===o)return e;return o}lodash_set(t,s,e){return Object(t)!==t?t:(Array.isArray(s)||(s=s.toString().match(/[^.[\]]+/g)||[]),s.slice(0,-1).reduce((t,e,i)=>Object(t[e])===t[e]?t[e]:t[e]=Math.abs(s[i+1])>>0==+s[i+1]?[]:{},t)[s[s.length-1]]=e,t)}getdata(t){let s=this.getval(t);if(/^@/.test(t)){const[,e,i]=/^@(.*?)\.(.*?)$/.exec(t),o=e?this.getval(e):"";if(o)try{const t=JSON.parse(o);s=t?this.lodash_get(t,i,""):s}catch(t){s=""}}return s}setdata(t,s){let e=!1;if(/^@/.test(s)){const[,i,o]=/^@(.*?)\.(.*?)$/.exec(s),h=this.getval(i),a=i?"null"===h?null:h||"{}":"{}";try{const s=JSON.parse(a);this.lodash_set(s,o,t),e=this.setval(JSON.stringify(s),i)}catch(s){const h={};this.lodash_set(h,o,t),e=this.setval(JSON.stringify(h),i)}}else e=$.setval(t,s);return e}getval(t){return this.isSurge()||this.isLoon()?$persistentStore.read(t):this.isQuanX()?$prefs.valueForKey(t):this.isNode()?(this.data=this.loaddata(),this.data[t]):this.data&&this.data[t]||null}setval(t,s){return this.isSurge()||this.isLoon()?$persistentStore.write(t,s):this.isQuanX()?$prefs.setValueForKey(t,s):this.isNode()?(this.data=this.loaddata(),this.data[s]=t,this.writedata(),!0):this.data&&this.data[s]||null}initGotEnv(t){this.got=this.got?this.got:require("got"),this.cktough=this.cktough?this.cktough:require("tough-cookie"),this.ckjar=this.ckjar?this.ckjar:new this.cktough.CookieJar,t&&(t.headers=t.headers?t.headers:{},void 0===t.headers.Cookie&&void 0===t.cookieJar&&(t.cookieJar=this.ckjar))}get(t,s=(()=>{})){t.headers&&(delete t.headers["Content-Type"],delete t.headers["Content-Length"]),this.isSurge()||this.isLoon()?$httpClient.get(t,(t,e,i)=>{!t&&e&&(e.body=i,e.statusCode=e.status),s(t,e,i)}):this.isQuanX()?$task.fetch(t).then(t=>{const{statusCode:e,statusCode:i,headers:o,body:h}=t;s(null,{status:e,statusCode:i,headers:o,body:h},h)},t=>s(t)):this.isNode()&&(this.initGotEnv(t),this.got(t).on("redirect",(t,s)=>{try{const e=t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString();this.ckjar.setCookieSync(e,null),s.cookieJar=this.ckjar}catch(t){this.logErr(t)}}).then(t=>{const{statusCode:e,statusCode:i,headers:o,body:h}=t;s(null,{status:e,statusCode:i,headers:o,body:h},h)},t=>s(t)))}post(t,s=(()=>{})){if(t.body&&t.headers&&!t.headers["Content-Type"]&&(t.headers["Content-Type"]="application/x-www-form-urlencoded"),delete t.headers["Content-Length"],this.isSurge()||this.isLoon())$httpClient.post(t,(t,e,i)=>{!t&&e&&(e.body=i,e.statusCode=e.status),s(t,e,i)});else if(this.isQuanX())t.method="POST",$task.fetch(t).then(t=>{const{statusCode:e,statusCode:i,headers:o,body:h}=t;s(null,{status:e,statusCode:i,headers:o,body:h},h)},t=>s(t));else if(this.isNode()){this.initGotEnv(t);const{url:e,...i}=t;this.got.post(e,i).then(t=>{const{statusCode:e,statusCode:i,headers:o,body:h}=t;s(null,{status:e,statusCode:i,headers:o,body:h},h)},t=>s(t))}}time(t){let s={"M+":(new Date).getMonth()+1,"d+":(new Date).getDate(),"H+":(new Date).getHours(),"m+":(new Date).getMinutes(),"s+":(new Date).getSeconds(),"q+":Math.floor(((new Date).getMonth()+3)/3),S:(new Date).getMilliseconds()};/(y+)/.test(t)&&(t=t.replace(RegExp.$1,((new Date).getFullYear()+"").substr(4-RegExp.$1.length)));for(let e in s)new RegExp("("+e+")").test(t)&&(t=t.replace(RegExp.$1,1==RegExp.$1.length?s[e]:("00"+s[e]).substr((""+s[e]).length)));return t}msg(s=t,e="",i="",o){const h=t=>!t||!this.isLoon()&&this.isSurge()?t:"string"==typeof t?this.isLoon()?t:this.isQuanX()?{"open-url":t}:void 0:"object"==typeof t&&(t["open-url"]||t["media-url"])?this.isLoon()?t["open-url"]:this.isQuanX()?t:void 0:void 0;$.isMute||(this.isSurge()||this.isLoon()?$notification.post(s,e,i,h(o)):this.isQuanX()&&$notify(s,e,i,h(o))),this.logs.push("","==============\ud83d\udce3\u7cfb\u7edf\u901a\u77e5\ud83d\udce3=============="),this.logs.push(s),e&&this.logs.push(e),i&&this.logs.push(i)}log(...t){t.length>0?this.logs=[...this.logs,...t]:console.log(this.logs.join(this.logSeparator))}logErr(t,s){const e=!this.isSurge()&&!this.isQuanX()&&!this.isLoon();e?$.log("",`\u2757\ufe0f${this.name}, \u9519\u8bef!`,t.stack):$.log("",`\u2757\ufe0f${this.name}, \u9519\u8bef!`,t)}wait(t){return new Promise(s=>setTimeout(s,t))}done(t={}){const s=(new Date).getTime(),e=(s-this.startTime)/1e3;this.log("",`\ud83d\udd14${this.name}, \u7ed3\u675f! \ud83d\udd5b ${e} \u79d2`),this.log(),(this.isSurge()||this.isQuanX()||this.isLoon())&&$done(t)}}(t,s)} 782 | --------------------------------------------------------------------------------