mirror of
https://github.com/qitoqito/psyduck.git
synced 2026-01-12 04:30:42 +08:00
.
This commit is contained in:
parent
9a1cbdf6f0
commit
cb0574a8e6
123
bot.js
Executable file
123
bot.js
Executable 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(() => {
|
||||
});
|
||||
@ -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",
|
||||
|
||||
@ -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) {
|
||||
}
|
||||
|
||||
@ -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}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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 {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user