Files
clone_scripts_clone/jd_sign.js
2021-08-06 11:01:17 -04:00

282 lines
17 KiB
JavaScript
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// @grant require
/*
cron 14 10 * * * https://raw.githubusercontent.com/smiek2221/scripts/master/jd_sign_graphics.js
只支持nodejs环境
需要安装依赖
npm i png-js 或者 npm i png-js -S
如果 read ECONNRESET 错误 可以试试
环境变量 JOY_HOST
修改域名 https://jdjoy.jd.com 可以改成ip https://49.7.27.236
*/
const validator = require('./JDJRValidator_Smiek.js');
const Faker=require('./sign_graphics_validate.js')
const $ = new Env('京东签到图形验证');
const notify = $.isNode() ? require('./sendNotify') : '';
//Node.js用户请在jdCookie.js处填写京东ck;
const jdCookieNode = $.isNode() ? require('./jdCookie.js') : '';
let cookiesArr = [], cookie = '';
if ($.isNode()) {
Object.keys(jdCookieNode).forEach((item) => {
cookiesArr.push(jdCookieNode[item])
})
if (process.env.JD_DEBUG && process.env.JD_DEBUG === 'false') console.log = () => { };
} else {
cookiesArr = [$.getdata('CookieJD'), $.getdata('CookieJD2'), ...jsonParse($.getdata('CookiesJD') || "[]").map(item => item.cookie)].filter(item => !!item);
}
let message = '', subTitle = '', beanNum = 0;
let fp = ''
let eid = ''
let UA = ""
let signFlag = false
let successNum = 0
let errorNum = 0
let JD_API_HOST = 'https://jdjoy.jd.com'
if(process.env.JOY_HOST){
JD_API_HOST = process.env.JOY_HOST
}
const turnTableId = [
{ "name": "京东商城-内衣", "id": 1071, "url": "https://prodev.m.jd.com/mall/active/4PgpL1xqPSW1sVXCJ3xopDbB1f69/index.html" },
{ "name": "京东商城-健康", "id": 527, "url": "https://prodev.m.jd.com/mall/active/w2oeK5yLdHqHvwef7SMMy4PL8LF/index.html" },
{ "name": "京东商城-清洁", "id": 446, "url": "https://prodev.m.jd.com/mall/active/2Tjm6ay1ZbZ3v7UbriTj6kHy9dn6/index.html" },
{ "name": "京东商城-个护", "id": 336, "url": "https://prodev.m.jd.com/mall/active/2tZssTgnQsiUqhmg5ooLSHY9XSeN/index.html" },
{ "name": "京东商城-童装", "id": 511, "url": "https://prodev.m.jd.com/mall/active/3Af6mZNcf5m795T8dtDVfDwWVNhJ/index.html" },
{ "name": "京东商城-母婴", "id": 458, "url": "https://prodev.m.jd.com/mall/active/3BbAVGQPDd6vTyHYjmAutXrKAos6/index.html" },
{ "name": "京东商城-数码", "id": 347, "url": "https://prodev.m.jd.com/mall/active/4SWjnZSCTHPYjE5T7j35rxxuMTb6/index.html" },
{ "name": "京东超市", "id": 1204, "url": "https://pro.m.jd.com/mall/active/QPwDgLSops2bcsYqQ57hENGrjgj/index.html" },
]
$.UA = $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1")
$.get = validator.injectToRequest($.get.bind($), 'channelSign', $.UA)
$.post = validator.injectToRequest($.post.bind($), 'channelSign', $.UA)
!(async () => {
if (!cookiesArr[0]) {
$.msg($.name, '【提示】请先获取京东账号一cookie\n直接使用NobyDa的京东签到获取', 'https://bean.m.jd.com/bean/signIndex.action', { "open-url": "https://bean.m.jd.com/bean/signIndex.action" });
return;
}
for (let i = 0; i < cookiesArr.length; i++) {
if (cookiesArr[i]) {
cookie = cookiesArr[i];
$.UserName = decodeURIComponent(cookie.match(/pt_pin=(.+?);/) && cookie.match(/pt_pin=(.+?);/)[1])
$.index = i + 1;
$.nickName = '';
console.log(`\n开始【京东账号${$.index}${$.nickName || $.UserName}\n`);
beanNum = 0
successNum = 0
errorNum = 0
subTitle = '';
await signRun()
const UTC8 = new Date().getTime() + new Date().getTimezoneOffset()*60000 + 28800000;
$.beanSignTime = new Date(UTC8).toLocaleString('zh', {hour12: false});
let msg = `【京东账号${$.index}${$.nickName || $.UserName}\n【签到时间】: ${$.beanSignTime}\n【签到概览】: 成功${successNum}个, 失败${errorNum}\n【签到奖励】: ${beanNum}京豆\n`
message += msg + '\n'
$.msg($.name, msg);
// break
}
}
await showMsg();
})()
.catch((e) => {
$.log('', `${$.name}, 失败! 原因: ${e}!`, '')
})
.finally(() => {
$.done();
})
async function showMsg() {
$.msg($.name, `【签到数量】: ${turnTableId.length}\n` + subTitle + message);
if ($.isNode() && message) await notify.sendNotify(`${$.name}`, `【签到数量】: ${turnTableId.length}\n` + subTitle + message);
}
async function signRun() {
for (let i in turnTableId) {
signFlag = false
await Login(i)
if(signFlag){
successNum++;
}else{
errorNum++;
}
}
}
function Sign(i) {
return new Promise(resolve => {
$.post(tasPostkUrl(turnTableId[i].id), (err, resp, data) => {
try {
if (err) {
console.log(`\n${turnTableId[i].name} 签到: API查询请求失败 ‼️‼️`)
throw new Error(err);
} else {
if (data) {
// console.log(data)
data = JSON.parse(data);
if (data.success && data.data) {
data = data.data
if (Number(data.jdBeanQuantity) > 0) beanNum += Number(data.jdBeanQuantity)
signFlag = true;
console.log(`${turnTableId[i].name} 签到成功:获得 ${Number(data.jdBeanQuantity)}京豆`)
} else {
if (data.errorMessage) {
if(data.errorMessage.indexOf('已签到') > -1 || data.errorMessage.indexOf('今天已经签到') > -1){
signFlag = true;
}
console.log(`${turnTableId[i].name} ${data.errorMessage}`)
} else {
console.log(`${turnTableId[i].name} ${JSON.stringify(data)}`)
}
}
} else {
console.log(`京豆api返回数据为空请检查自身原因`)
}
}
} catch (e) {
$.logErr(e, resp);
} finally {
resolve(data);
}
})
})
}
function Login(i) {
return new Promise(resolve => {
$.get(taskUrl(turnTableId[i].id), async (err, resp, data) => {
try {
if (err) {
console.log(`\n${turnTableId[i].name} 登录: API查询请求失败 ‼️‼️`)
console.log(`${JSON.stringify(err)}`)
} else {
if (data) {
// console.log(data)
data = JSON.parse(data);
if (data.success && data.data) {
data = data.data
if (!data.hasSign) {
let arr = await Faker.getBody(UA,turnTableId[i].url)
fp = arr.fp
await getEid(arr)
await Sign(i)
} else {
if(data.records && data.records[0]){
for(let i in data.records){
let item = data.records[i]
if((item.hasSign == false && item.index != 1) || i == data.records.length-1){
if(item.hasSign == false) i = i-1
beanNum += Number(data.records[i].beanQuantity)
break;
}
}
}
signFlag = true;
console.log(`${turnTableId[i].name} 已签到`)
}
} else {
if (data.errorMessage) {
if(data.errorMessage.indexOf('已签到') > -1 || data.errorMessage.indexOf('今天已经签到') > -1){
signFlag = true;
}
console.log(`${turnTableId[i].name} ${data.errorMessage}`)
} else {
console.log(`${turnTableId[i].name} ${JSON.stringify(data)}`)
}
}
} else {
console.log(`京豆api返回数据为空请检查自身原因`)
}
}
} catch (e) {
$.logErr(e, resp);
} finally {
resolve(data);
}
})
})
}
function getEid(arr) {
return new Promise(resolve => {
const options = {
url: `https://gia.jd.com/fcf.html?a=${arr.a}`,
body: `d=${arr.d}`,
headers: {
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
"User-Agent": $.UA
}
}
$.post(options, async (err, resp, data) => {
try {
if (err) {
console.log(`\n${turnTableId[i].name} 登录: API查询请求失败 ‼️‼️`)
throw new Error(err);
} else {
if (data.indexOf("*_*") > 0) {
data = data.split("*_*", 2);
data = JSON.parse(data[1]);
eid = data.eid
} else {
console.log(`京豆api返回数据为空请检查自身原因`)
}
}
} catch (e) {
$.logErr(e, resp);
} finally {
resolve(data);
}
})
})
}
function taskUrl(turnTableId) {
const url = `${JD_API_HOST}/api/turncard/channel/detail?turnTableId=${turnTableId}&invokeKey=qRKHmL4sna8ZOP9F`
return {
url,
headers: {
"Accept": "application/json, text/plain, */*",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-cn",
"Connection": "keep-alive",
'Cookie': cookie,
'Host': `jdjoy.jd.com`,
"Origin": "https://prodev.m.jd.com",
"Referer": "https://prodev.m.jd.com/",
"User-Agent": $.UA,
}
}
}
function tasPostkUrl(turnTableId) {
const url = `${JD_API_HOST}/api/turncard/channel/sign?turnTableId=${turnTableId}&fp=${fp}&eid=${eid}&invokeKey=qRKHmL4sna8ZOP9F`
return {
url,
headers: {
"Accept": "application/json, text/plain, */*",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Connection": "keep-alive",
"Content-Type": "application/x-www-form-urlencoded",
'Cookie': cookie,
'Host': `jdjoy.jd.com`,
"Origin": "https://prodev.m.jd.com",
"Referer": "https://prodev.m.jd.com/",
"User-Agent": $.UA,
}
}
}
function jsonParse(str) {
if (typeof str == "string") {
try {
return JSON.parse(str);
} catch (e) {
console.log(e);
$.msg($.name, '', '请勿随意在BoxJs输入框修改内容\n建议通过脚本去获取cookie')
return [];
}
}
}
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)}