This commit is contained in:
可达鸭 2025-03-19 20:42:46 +08:00
parent 9a1cbdf6f0
commit cb0574a8e6
5 changed files with 155 additions and 288 deletions

123
bot.js Executable file
View File

@ -0,0 +1,123 @@
import TelegramBot from "node-telegram-bot-api"
import ini from "ini"
import qs from "qs"
import fs from "fs"
import path from 'path';
import SocksProxyAgent from 'socks-proxy-agent'
import {
fileURLToPath,
pathToFileURL
} from 'url';
import {
spawnSync,
spawn
} from "child_process"
let dirpath = fileURLToPath(
import.meta.url);
let abspath = path.dirname(dirpath);
let scripts = []
let iniPath = `${abspath}/config/config.ini`
let iniText = fs.readFileSync(iniPath, 'UTF-8')
iniPath = pathToFileURL(iniPath).href
const psyduck = ini.parse(iniText)
const bot = psyduck.bot
let request = {}
let nodePath = '/usr/bin/node'
let nodeList = ['/usr/bin/node', '/usr/local/bin/node']
for (nodePath of nodeList) {
let d = spawnSync(nodePath, ['-v'], {
encoding: 'utf-8',
})
if (d.output) {
break
}
}
if (bot.BOT_PROXY) {
if (env.BOT_PROXY.toLowerCase().includes("socks")) {
var agent = new SocksProxyAgent(bot.BOT_PROXY.toLowerCase());
request.agent = agent
}
else {
request.proxy = bot.BOT_PROXY
}
}
let dir = fs.readdirSync(`${abspath}/parse`);
dir.forEach(async function(item, index) {
let stat = fs.lstatSync(`${abspath}/parse/` + item)
if (stat.isDirectory() === true) {
for (let script of fs.readdirSync(`${abspath}/parse/${item}`)) {
let ff = script.match(/jd_task_(\w+)/)
if (ff) {
scripts.push(ff[1])
}
}
}
});
//
!(async () => {
const bots = new TelegramBot(bot.BOT_TOKEN, {
polling: true,
request,
});
const wait = function(t) {
return new Promise(e => setTimeout(e, t))
}
const sendMessage = async function(id, echo, params = {}, timeout = 0) {
bots.sendMessage(id, echo, params || {}).then(async (res) => {
if (timeout) {
await wait(parseInt(timeout))
console.log(`删除消息: ${echo}`)
bots.deleteMessage(res.chat.id, res.message_id)
}
});
}
bots.on('text', async (msg) => {
let sm = sendMessage
let chat = msg.chat
let from = msg.from
let id = from.id
let messageId = msg.message_id
let chatId = chat.id
let text = msg.text
let admin = bot.BOT_ROOT.includes(id.toString())
if (text.match(/^task\s+\w+_\w+/) && admin) {
let filename = text.match(/task\s*(\w+)\s*/)[1]
let argv = text.split(filename)
let params = []
if (argv.length>1 && argv[1]) {
params = argv[1].split(" ")
}
let command = spawn(nodePath, [...['main', filename], ...params], {
encoding: 'utf-8',
})
command.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
if (data.includes("即将运行")) {
console.log(`正在运行: ${filename}`)
sm(chatId, `正在运行: ${filename}`, '', 3456)
}
});
}
else if (text.match(/^\w+\s+\w+/)) {
let tt = text.match(/^(\w+)\s+(\w+)/)
if (scripts.includes(tt[1]) && admin) {
let filename = `jd_task_${tt[1]}`;
let params = tt[2] == 'start' ? [] : ['-custom', tt[2]];
let command = spawn(nodePath, [...['main', filename], ...params], {
encoding: 'utf-8',
})
command.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
if (data.includes("即将运行")) {
console.log(`正在运行: ${filename} -custom ${tt[2]}`)
sm(chatId, `正在运行: ${filename} -custom ${tt[2]}`, '', 3456)
}
});
}
}
})
})().catch((e) => {
console.log(e)
}).finally(() => {
});

View File

@ -12,6 +12,7 @@
"lodash": "^4.17.21",
"node-jsencrypt": "^1.0.0",
"node-schedule": "^2.1.1",
"node-telegram-bot-api": "^0.66.0",
"os": "^0.1.2",
"qs": "^6.14.0",
"readline-sync": "^1.4.10",

View File

@ -40,7 +40,6 @@ export class Main extends Template {
t.push(`🦊 还未生效: ${data.disable}`)
t.push(`🦊 通用红包: ${data.current[0]}元, 过期: ${data.current[1]}`)
t.push(`🦊 商城红包: ${data.app[0]}元, 过期: ${data.app[1]}`)
// t.push(`🦊 京喜红包: ${data.pingou[0]}元, 过期: ${data.pingou[1]}元`)
t.push(`🦊 特价红包: ${data.lite[0]}元, 过期: ${data.lite[1]}`)
t.push(`🦊 微信红包: ${data.wechat[0]}元, 过期: ${data.wechat[1]}`)
t.push(`🦊 健康红包: ${data.healthy[0]}元, 过期: ${data.healthy[1]}`)
@ -55,33 +54,6 @@ export class Main extends Template {
}
}
break
case 'xibean':
t.push(`🐻 当前喜豆: ${data || 0}喜豆`)
break
case'cash':
t.push(`🐰 换领现金: 可兑换${data || 0}`)
break
case 'ms':
t.push(`🦁 换秒秒币: 可兑换${(data / 1000).toFixed(2)}`)
break
case 'earn':
t.push(`🐹 京东赚赚: 可兑换${(data / 10000).toFixed(2)}`)
break
case 'coin':
t.push(`🐯 极速金币: 可兑换${(data / 10000).toFixed(2)}`)
break
case 'cattle':
t.push(`🐮 牛牛福利: 可兑换${(data / 1000).toFixed(2)}`)
break
case 'egg':
t.push(`🐥 京喜牧场: 可兑换鸡蛋${data || 0}`)
break
case 'pet':
t.push(`🐙 东东萌宠: ${data.goods}, 完成: ${data.complete}-${data.percent}%/${data.exchange}`)
break
case 'farm':
t.push(`🐨 东东农场: ${data.goods}, 完成: ${data.complete}/${data.exchange}, 还需浇水: ${(data.exchange - data.complete) / 10}次, 进度: ${data.percent}%`)
break
default:
// console.log(i)
break
@ -93,11 +65,17 @@ export class Main extends Template {
async _bean(p) {
let user = p.data.user;
let context = p.context;
let b = await this.curl({
url: 'https://api.m.jd.com/client.action',
form: 'functionId=jingBeanDetail&body=%7B%7D&uuid=bbf7dd32710a04388eec3dd&client=apple&clientVersion=10.0.10&st=1640919377235&sv=112&sign=8ddd454db0ddfa76947dab4c35cc07fb',
user
})
let c = await this.curl({
'form': `functionId=myBeanHome&body={}&t=1742384177284&appid=jd-home-mybean&client=ios&clientVersion=15.0.65`,
user,
algo: {
appId: '502bc',
expire: {
code: 2
}
}
}
)
try {
let x = this.getDate(this.timestamp, 0, '-')
let y = this.getDate(this.timestamp, -1, '-')
@ -130,8 +108,24 @@ export class Main extends Template {
let bean = {}
bean.today = [this.sum(xsa) || 0, this.sum(xsb) || 0]
bean.yesterday = [this.sum(ysa) || 0, this.sum(ysb) || 0]
bean.expire = this.haskey(b, 'others.jingBeanExpiringInfo.detailList')
bean.all = this.haskey(b, 'others.jingBeanBalance.jingBeanCount')
if (this.haskey(c, 'data.beanAmount')) {
bean.expire = c.data.expireSoonNum
bean.all = c.data.beanAmount
}
else {
let b = await this.curl({
url: 'https://api.m.jd.com/client.action',
form: 'functionId=jingBeanDetail&body=%7B%7D&uuid=bbf7dd32710a04388eec3dd&client=android&clientVersion=15.2.8&st=1640919377235&sv=112&sign=8ddd454db0ddfa76947dab4c35cc07fb',
user,
algo: {
sign: true
}
})
if (this.haskey(b, 'others')) {
bean.expire = this.haskey(b, 'others.jingBeanExpiringInfo.detailList')
bean.all = this.haskey(b, 'others.jingBeanBalance.jingBeanCount')
}
}
context.dict.bean = bean
} catch (e) {
}

View File

@ -1,211 +0,0 @@
import {Template} from '../../template.js'
import jsdom from "jsdom";
import {Window} from 'happy-dom' ;
import fs from 'fs'
export class Main extends Template {
constructor() {
super()
this.profile = {
title: '京东保险天天领权益',
crontab: 3
}
}
async prepare() {
let ua = this.userAgents().jd
let resourceLoader = new jsdom.ResourceLoader({
userAgent: ua,
"referer": "https://iu.jr.jd.com/",
});
let virtualConsole = new jsdom.VirtualConsole();
this.jsConfig = {
"url": "https://iu.jr.jd.com/",
"referer": "https://iu.jr.jd.com/",
"userAgent": ua,
runScripts: "dangerously",
resources: resourceLoader,
includeNodeLocations: true,
storageQuota: 10000000,
pretendToBeVisual: true,
virtualConsole,
};
let JSDOM = jsdom.JSDOM
let a = new JSDOM(`<body><script src="https://jrsecstatic.jdpay.com/jr-sec-dev-static/aar2.min.js"></script> <script src="https://m.jr.jd.com/common/jssdk/jrbridge/2.0.0/jrbridge.js"></script> <script src="https://jrsecstatic.jdpay.com/jr-sec-dev-static/cryptico.min.js"></script> </body>`, this.jsConfig)
await this.wait(1000)
if (a.window.AAR2) {
a.window.AAR2.init();
this.crypto = {
aar: new a.window.AAR2(),
cry: a.window.cryptico
}
}
else {
this.log("jsdom没有获取到aar2")
this.jump = 1
}
// let jsFiles = [
// 'aar2.min.js',
// 'cryptico.min.js',
// 'jrbridge.js',
// ];
// const window = new Window();
// const document = window.document;
// for (let i of jsFiles) {
// const jsCode = fs.readFileSync(`${this.abspath}/static/${i}`, 'utf-8');
// const scriptElement = document.createElement('script');
// scriptElement.textContent = jsCode;
// document.body.appendChild(scriptElement);
// }
// document.body.innerHTML = '<body><script src="https://jrsecstatic.jdpay.com/jr-sec-dev-static/aar2.min.js"></script> <script src="https://m.jr.jd.com/common/jssdk/jrbridge/2.0.0/jrbridge.js"></script> <script src="https://jrsecstatic.jdpay.com/jr-sec-dev-static/cryptico.min.js"></script> </body>';
// window.AAR2.init();
// this.crypto = {
// aar: new window.AAR2(),
// cry: window.cryptico
// }
// console.log(this.crypto.aar.nonce())
// console.log(this.crypto.aar.sign(234,this.crypto.aar.nonce()))
// this.jump=234
}
async main(p) {
let user = p.data.user;
let context = p.context;
let a = new jsdom.JSDOM(`<body><script src="//gia.jd.com/m.html"></script> <script src="//gias.jd.com/js/m.js"></body>`, this.jsConfig)
await this.wait(2000)
let riskJd = a.window.getJdEid();
let bean = 0
const aar = this.crypto.aar
var nonce = aar.nonce()
let getAAR = function() {
var s = "qypd" + (new Date).getTime();
return {
nonce,
signData: s,
signature: aar.sign(s, nonce)
}
}
let rsa = await this.curl({
'url': `https://ms.jr.jd.com/gw/generic/getRSAPublicKey`,
'form': `reqData=%7B%22channel%22%3A%22sy%22%2C%22channelLv%22%3A%22sy%22%7D`,
user
})
let resBusiData = this.loads(rsa.resultData.publicKey)
this.crypto.cry.setPublicKeyString(resBusiData)
let bodyEnc = await this.crypto.cry.encryptData(this.dumps({
"marketId": "bxqypd",
"pageUrl": "https://iu.jr.jd.com/insurance/channel/interest?showTab=1",
"qdPageId": "3MB9G",
eid: riskJd.eid,
fp: riskJd.fp,
token: riskJd.token,
profitChannelCode: "qypd",
rush: getAAR()
}))
let jdr = await this.curl({
'url': `https://ms.jr.jd.com/gw2/generic/bxpd/newh5/m/jingDouInterestChannel`,
json: {
reqData: {
"channelEncrypt": 1,
"bodyEncrypt": bodyEnc.cipher
}
},
user
}
)
let res = (await this.crypto.cry.decryptData(jdr.resultData))
if (res.status) {
let plaintext = this.loads(res.plaintext)
p.log("签到中...")
let signData = {
"relationId": "ej94ec6d",
"relationType": 3,
"ruleAliasCode": "signUpAndTake",
"contextParams": {
"request": {
"riskMap": {
"pageUrl": "https://iu.jr.jd.com/insurance/channel/interest?showTab=1",
"qdPageId": "M2Wq",
"mdClickId": `M2Wq|*ej94ec6d****${this.md5(p.user)}`
},
"deviceInfo": riskJd
}
}
}
let signature = aar.sign(this.dumps(signData), nonce)
let sign = await this.curl({
'url': `https://ms.jr.jd.com/gw2/generic/jractivity/h5/m/rule/execute`,
'json': {
reqData: {
"preview": 0,
"antiRushFlag": "1",
"domain": "iu.jr.jd.com",
"uri": "/insurance/channel/interest?showTab=1",
"nonce": nonce,
"signature": signature,
"signData": this.dumps(signData)
}
},
algo: {
valid: {
'resultData.data.code': ['0006']
}
},
user
}
)
if (this.haskey(sign, 'resultData.data.data.signAwardInfoList')) {
p.info.work = true
for (let i of sign.resultData.data.data.signAwardInfoList) {
p.log(`获得${i.awardName}:${i.awardNum}`)
bean += i.awardNum
}
}
else {
p.log(this.haskey(sign, 'resultData.data.msg') || sign)
if (this.haskey(sign, 'resultData.data.code', '0002')) {
p.log("风控账户")
return
}
else if (this.haskey(sign, 'resultData.data.code', '0006')) {
p.log("未登录")
return
}
else if (this.haskey(sign, 'resultData.data.code', '0009')) {
p.info.work = true
}
}
// p.log(plaintext)
// for (let i of this.haskey(plaintext, 'task.taskList')) {
// if (i.taskStatus) {
// p.log("任务已完成:", i.taskName)
// }
// else {
// p.log("正在运行:", i.taskName)
// let juid = this.match(/juid=(\w+)/, i.taskLink)
// if (juid) {
// let juidSign = aar.sign(juid, nonce)
// let jump = await this.curl({
// 'url': `https://ms.jr.jd.com/gw2/generic/mission/h5/m/getJumpInfo?juid=${juid}&signature=${juidSign}&nonce=${nonce}`,
// user
// }
// )
// if (this.haskey(jump, 'resultData.code') == '0000') {
// p.log(`获得京豆:${i.awardNum}`)
// bean += i.awardNum
// }
// else {
// p.log('失败了:', jump)
// }
// }
// }
// }
}
else {
p.log("没有获取到游戏数据...")
}
if (bean>0) {
p.msg(`获得京豆: ${bean}`)
}
}
}

View File

@ -18,38 +18,6 @@ export class Main extends Template {
await this.field('actId')
}
async batch1(p) {
let a = await this.curl({
'url': `https://jinggengjcq-isv.isvjcloud.com/dm/front/jdJoinCardtf/shop/shopProduct?open_id=&mix_nick=BZwJHR&push_way=1&user_id=10299171`,
json: {
"jsonRpc": "2.0",
"params": {
"commonParameter": {
"m": "POST",
"oba": "6e5e793ff0ce0ac6293e2ee26f88dac6",
"timestamp": 1713947376182,
"userId": 10299171
},
"admJson": {
"actId": p.actId,
"method": "/jdJoinCardtf/shop/shopProduct",
"userId": 10299171,
"pushWay": 1
}
}
}
}
)
let skuList = []
if (this.haskey(a, 'data.data.0.numId')) {
skuList = this.column(a.data.data, 'numId')
}
if (skuList) {
p.skuList = skuList
return p
}
}
async main(p) {
let user = p.data.user;
let context = p.context;
@ -154,10 +122,6 @@ export class Main extends Template {
if (remark.includes("京豆")) {
p.award(remark, 'bean')
}
if (this.haskey(s, 'data.data.sendStatus')) {
let num = this.match(/(\d+)个京豆/, remark)
bean += parseInt(num)
}
else {
if (this.dumps(s).includes("上限")) {
break
@ -197,15 +161,11 @@ export class Main extends Template {
)
let remark = this.haskey(collectShop, 'data.data.remark') || ''
p.log(remark)
if (this.haskey(collectShop, 'data.data.sendStatus')) {
let num = this.match(/(\d+)个京豆/, remark)
bean += parseInt(num)
if (remark.includes("京豆")) {
p.award(remark, 'bean')
}
await this.wait(1000)
}
if (bean>0) {
p.msg(`获得京豆: ${bean}`)
}
p.info.work = true
}
else {