From 29d8ebf50778568404a370a5810b063a9099ef65 Mon Sep 17 00:00:00 2001 From: Faker <Faker@apple.com> Date: Mon, 8 Aug 2022 11:45:34 +0800 Subject: [PATCH] update --- m_jd_wx_centerDraw.js | 209 ++++++++++++++++++++ magic.js | 62 +++--- magic.py | 429 ++++++++++++++++++++++++++---------------- 3 files changed, 509 insertions(+), 191 deletions(-) create mode 100644 m_jd_wx_centerDraw.js diff --git a/m_jd_wx_centerDraw.js b/m_jd_wx_centerDraw.js new file mode 100644 index 0000000..08df7fa --- /dev/null +++ b/m_jd_wx_centerDraw.js @@ -0,0 +1,209 @@ +let mode = __dirname.includes('magic') +const {Env} = mode ? require('./magic') : require('./magic') +const $ = new Env('M老虎机抽奖'); +$.lz = 'LZ_TOKEN_KEY=lztokef1eb8494b0af868bd18bdaf8;LZ_TOKEN_VALUE=Aa5RE8RuY4X3zA==;'; +$.activityUrl = process.env.M_WX_CENTER_DRAW_URL + ? process.env.M_WX_CENTER_DRAW_URL + : ''; +if (mode) { + $.activityUrl = 'https://lzkj-isv.isvjcloud.com/lzclient/8e5f3ebaf6e545959aa6311d14be5dfa/cjwx/common/entry.html?activityId=8e5f3ebaf6e545959aa6311d14be5dfa&gameType=wxTurnTable' + // $.activityUrl = 'https://lzkj-isv.isvjcloud.com/wxDrawActivity/activity?activityId=37c4c35255a84522bc944974edeef960' + // $.activityUrl = 'https://lzkj-isv.isvjcloud.com/wxDrawActivity/activity?activityId=1155ac7d4ec74a8ba31238d846866599' + $.activityUrl = 'https://lzkj-isv.isvjcloud.com/wxDrawActivity/activity?activityId=a5b7b7b8196e4dc192c4ffd3221a7866' + $.activityUrl = 'https://lzkj-isv.isvjcloud.com/drawCenter/activity/75f5617c3c844163b8ccb1b410eb23e8?activityId=75f5617c3c844163b8ccb1b410eb23e8' + $.activityUrl = 'https://lzkj-isv.isvjcloud.com/drawCenter/activity?activityId=7113c86ee0b94fbbb803a76c8bda6065' +} +$.activityUrl = $.match( + /(https?:\/\/[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|])/, + $.activityUrl) +$.domain = $.match(/https?:\/\/([^/]+)/, $.activityUrl) +$.activityId = $.getQueryString($.activityUrl, 'activityId') +let shopInfo = '' +$.uid = ''//全都助力1号 +$.logic = async function () { + if (!$.activityId || !$.activityUrl) { + $.expire = true; + $.putMsg(`activityId|activityUrl不存在`); + return + } + $.log(`活动id: ${$.activityId}`, `活动url: ${$.activityUrl}`) + $.UA = $.ua(); + let token = await $.isvObfuscator(); + if (token.code !== '0') { + $.putMsg(`获取Token失败`); + return + } + $.Token = token?.token + + let actInfo = await $.api('customer/getSimpleActInfoVo', + `activityId=${$.activityId}`); + if (!actInfo.result || !actInfo.data) { + $.log(`获取活动信息失败`); + return + } + $.venderId = actInfo.data.venderId; + $.shopId = actInfo.data.shopId; + $.activityType = actInfo.data.activityType; + + let myPing = await $.api('customer/getMyPing', + `userId=${$.venderId}&token=${$.Token}&fromType=APP`) + if (!myPing.result) { + $.putMsg(`获取pin失败`); + return + } + $.Pin = $.domain.includes('cjhy') ? encodeURIComponent( + encodeURIComponent(myPing.data.secretPin)) : encodeURIComponent( + myPing.data.secretPin); + + await $.api( + `common/${$.domain.includes('cjhy') ? 'accessLog' : 'accessLogWithAD'}`, + `venderId=${$.venderId}&code=${$.activityType}&pin=${ + $.Pin}&activityId=${$.activityId}&pageUrl=${encodeURIComponent($.activityUrl)}&subType=app&adSource=`); + + let userInfo = await $.api('wxActionCommon/getUserInfo', + `pin=${$.Pin}`); + if (!userInfo.result) { + $.putMsg('获取用户信息,结束运行') + return + } + $.nickname = userInfo.data.nickname; + + //助力暂且不弄 + let activityContent = await $.api( + 'drawCenter/activityContent', + `activityId=${$.activityId}&pin=${ + $.Pin}&nick=${$.nickname}&pinImg=${encodeURIComponent( + 'https://img10.360buyimg.com/imgzone/jfs/t1/21383/2/6633/3879/5c5138d8E0967ccf2/91da57c5e2166005.jpg')}&shareUuid=${$.uid}`, + true); + if (!activityContent.result || !activityContent.data) { + $.putMsg(activityContent.errorMessage || '活动可能已结束') + return + } + if (!$.uid) { + $.uid = activityContent.data.uid//大概率助力码 + } + let prizeList = await $.api('drawCenter/getPrizeList', + `activityId=${$.activityId}&activityType=${$.activityType}&venderId=${$.venderId}`); + if (prizeList.result) { + $.content = prizeList.data; + } + let myInfo = await $.api('drawCenter/myInfo', + `activityId=${$.activityId}&pin=${$.Pin}`); + + if (!myInfo.result) { + $.putMsg('获取任务列表失败') + return + } + for (let ele of myInfo?.data?.taskList || []) { + if (ele.curNum >= ele.maxNeed) { + //完成了 + continue; + } + let count = ele.maxNeed - ele.curNum; + if (ele.taskId === 'followsku') { + $.log('followsku') + let products = await $.api('drawCenter/getProduct', + `activityId=${$.activityId}&pin=${ + $.Pin}&type=3`); + for (let pd of products?.data.filter(o => !o.taskDone)) { + if (count <= 0) { + break; + } + await $.api('drawCenter/doTask', + `activityId=${$.activityId}&pin=${ + $.Pin}&taskId=followsku¶m=${pd.skuId}`) + await $.wait(200, 500) + count-- + } + } + if (ele.taskId === 'add2cart') { + $.log('add2cart') + let products = await $.api('drawCenter/getProduct', + `activityId=${$.activityId}&pin=${ + $.Pin}&type=1`); + for (let pd of products?.data.filter(o => !o.taskDone)) { + if (count <= 0) { + break; + } + await $.api('drawCenter/doTask', + `activityId=${$.activityId}&pin=${ + $.Pin}&taskId=add2cart¶m=${pd.skuId}`) + await $.wait(200, 500) + count-- + } + } + if (ele.taskId === 'scansku') { + $.log('scansku') + let products = await $.api('drawCenter/getProduct', + `activityId=${$.activityId}&pin=${ + $.Pin}&type=2`); + for (let pd of products?.data.filter(o => !o.taskDone)) { + if (count <= 0) { + break; + } + await $.api('drawCenter/doTask', + `activityId=${$.activityId}&pin=${ + $.Pin}&taskId=scansku¶m=${pd.skuId}`) + await $.wait(200, 500) + count-- + } + } + if (ele.taskId === 'followshop') { + $.log('followshop') + await $.api('drawCenter/doTask', + `activityId=${$.activityId}&pin=${ + $.Pin}&taskId=followshop¶m=`) + } + if (ele.taskId === 'joinvip') { + $.log('joinvip') + await $.api('drawCenter/doTask', + `activityId=${$.activityId}&pin=${ + $.Pin}&taskId=joinvip¶m=`) + } + } + activityContent = await $.api( + 'drawCenter/activityContent', + `activityId=${$.activityId}&pin=${ + $.Pin}&nick=${$.nickname}&pinImg=${encodeURIComponent( + 'https://img10.360buyimg.com/imgzone/jfs/t1/21383/2/6633/3879/5c5138d8E0967ccf2/91da57c5e2166005.jpg')}&shareUuid=${$.uid}`, + true); + if (!activityContent.result) { + $.putMsg('获取不到活动信息,结束运行') + return + } + $.canDrawTimes = activityContent.data.chance || 0 + if ($.canDrawTimes === 0) { + $.putMsg(`抽奖次数 ${$.canDrawTimes}`) + return + } + for (let i = 0; i < $.canDrawTimes; i++) { + let prize = await $.api('/drawCenter/draw/luckyDraw', + `activityId=${$.activityId}&pin=${$.Pin}`); + if (prize.result) { + let msg = prize.data.drawOk ? prize.data.name + : prize.data.errorMessage || '空气'; + $.putMsg(msg) + } else { + if (prize.errorMessage) { + await $.wxStop(prize.errorMessage) ? $.expire = true : '' + $.putMsg(`${prize.errorMessage}`); + + } + break + } + } +} +$.after = async function () { + if ($.msg.length > 0) { + let message = `\n${(await $.getShopInfo()).shopName || ''}\n`; + for (let ele of $.content || []) { + if (ele.name.includes('谢谢') || ele.name.includes('再来')) { + continue; + } + message += ` ${ele.name}${ele?.type === 8 ? '专享价' : ''}\n` + } + $.msg.push(message) + $.msg.push($.activityUrl); + } +} +$.run({whitelist: ['1-5'], wait: [1000, 3000]}).catch(reason => $.log(reason)); diff --git a/magic.js b/magic.js index 858af35..ab15960 100644 --- a/magic.js +++ b/magic.js @@ -675,7 +675,7 @@ class Env { return; } let LZ_TOKEN_KEY = '', LZ_TOKEN_VALUE = '', JSESSIONID = '', - jcloud_alb_route = '', ci_session = '' + jcloud_alb_route = '', ci_session = '', LZ_AES_PIN= '' let sc = typeof scs != 'object' ? scs.split(',') : scs for (let ck of sc) { let name = ck.split(";")[0].trim() @@ -690,19 +690,16 @@ class Env { ? jcloud_alb_route = name.replace(/ /g, '') + ';' : '' name.includes('ci_session=') ? ci_session = name.replace(/ /g, '') + ';' : '' + name.includes('LZ_AES_PIN=') ? this.LZ_AES_PIN = name.replace(/ /g, '') + + ';' : '' + } } + if (JSESSIONID && LZ_TOKEN_KEY && LZ_TOKEN_VALUE) { - this.lz = `${JSESSIONID}${LZ_TOKEN_KEY}${LZ_TOKEN_VALUE}` + this.lz = `${JSESSIONID}${LZ_TOKEN_KEY}${LZ_TOKEN_VALUE}${this.LZ_AES_PIN||''}` } else if (LZ_TOKEN_KEY && LZ_TOKEN_VALUE) { - this.lz = `${LZ_TOKEN_KEY}${LZ_TOKEN_VALUE}` - } else if (JSESSIONID && jcloud_alb_route) { - this.lz = `${JSESSIONID}${jcloud_alb_route}` - } else if (JSESSIONID) { - this.lz = `${JSESSIONID}` - } - if (ci_session) { - this.lz = `${ci_session}` + this.lz = `${LZ_TOKEN_KEY}${LZ_TOKEN_VALUE}${this.LZ_AES_PIN||''}` } // testMode ? this.log('lz', this.lz) : '' } @@ -853,16 +850,27 @@ class Env { } async sign(fn, body = {}) { - let b = {"fn": fn, "body": body}; - let h = {"token": apiToken} - try { - let {data} = await this.request(apiSignUrl, h, b); - console.log(data) - return {fn: data.fn, sign: data.body}; - } catch (e) { - console.log("sign接口异常") + if ('isvObfuscator'===fn){ + let b = {"functionId": fn, "body": JSON.stringify(body)}; + let h= {"Content-Type": "application/json","Cookie":"HELLO WORLD"} + try { + let {data} = await this.request('https://api.lfyouse.org/jdsign', h, b); + console.log(data) + return {fn: fn, sign: data}; + } catch (e) { + console.log("isvObfuscator sign接口异常") + } + }else { + let b = {"fn": fn, "body": body}; + let h = {"token": apiToken} + try { + let {data} = await this.request(apiSignUrl, h, b); + return {fn: data.fn, sign: data.body}; + } catch (e) { + console.log("sign接口异常") + } + return {fn: "", sign: ""}; } - return {fn: "", sign: ""}; } async _algo() { @@ -914,19 +922,12 @@ class Env { } async isvObfuscator() { - let url = `https://api.m.jd.com/client.action?functionId=isvObfuscator` let body = '' - switch (this.domain) { - case 'cjhy-isv.isvjcloud.com': - case 'lzkj-isv.isvjcloud.com': - case 'txzj-isv.isvjcloud.com': - case 'lzdz-isv.isvjcloud.com': - case 'cjhydz-isv.isvjcloud.com': - body = this.randomArray(ISV_OBFUSCATOR[this.domain], 1)[0] - break - default: - body = 'adid=7B411CD9-D62C-425B-B083-9AFC49B94228&area=16_1332_42932_43102&body=%7B%22url%22%3A%22https%3A%5C/%5C/cjhydz-isv.isvjcloud.com%22%2C%22id%22%3A%22%22%7D&build=167541&client=apple&clientVersion=9.4.0&d_brand=apple&d_model=iPhone8%2C1&eid=eidId10b812191seBCFGmtbeTX2vXF3lbgDAVwQhSA8wKqj6OA9J4foPQm3UzRwrrLdO23B3E2wCUY/bODH01VnxiEnAUvoM6SiEnmP3IPqRuO%2By/%2BZo&isBackground=N&joycious=48&lang=zh_CN&networkType=wifi&networklibtype=JDNetworkBaseAF&openudid=2f7578cb634065f9beae94d013f172e197d62283&osVersion=13.1.2&partner=apple&rfs=0000&scope=11&screen=750%2A1334&sign=60bde51b4b7f7ff6e1bc1f473ecf3d41&st=1613720203903&sv=110&uts=0f31TVRjBStG9NoZJdXLGd939Wv4AlsWNAeL1nxafUsZqiV4NLsVElz6AjC4L7tsnZ1loeT2A8Z5/KfI/YoJAUfJzTd8kCedfnLG522ydI0p40oi8hT2p2sNZiIIRYCfjIr7IAL%2BFkLsrWdSiPZP5QLptc8Cy4Od6/cdYidClR0NwPMd58K5J9narz78y9ocGe8uTfyBIoA9aCd/X3Muxw%3D%3D&uuid=hjudwgohxzVu96krv/T6Hg%3D%3D&wifiBssid=9cf90c586c4468e00678545b16176ed2' + let newVar = await this.sign('isvObfuscator', {'id': '', 'url': `https://${this.domain}`}); + if (newVar.sign) { + body = newVar.sign; } + let url = `https://api.m.jd.com/client.action?functionId=isvObfuscator` let headers = { "Accept": "*/*", "Accept-Encoding": "gzip, deflate, br", @@ -959,6 +960,7 @@ class Env { "User-Agent": this.UA } let {data} = await this.request(url, headers, body); + console.log(JSON.stringify(data)) return data; } diff --git a/magic.py b/magic.py index 078d782..3e860bf 100644 --- a/magic.py +++ b/magic.py @@ -1,191 +1,298 @@ import asyncio import datetime import json +import logging import os import re -import urllib.parse +from urllib import parse from cacheout import FIFOCache -from pyrogram import Client, filters +from telethon import TelegramClient, events -cache = FIFOCache(maxsize=512) +# 0. 进入容器 +# 1. pip3 install -U cacheout +# 2. 复制magic.py,magic.json到/ql/config/目录 并配置 +# 3. python3 /ql/config/magic.py 登录 +# 4. 给bot发送在吗 有反应即可 +# 5. pm2 start /ql/config/magic.py -x --interpreter python3 +# 6. 挂起bot到后台 查看状态 pm2 l +# 7. 如果修改了magic.json,执行pm2 restart magic 即可重启 +# pm2 start /jd/config/magic.py -x --interpreter python3 -platform = "v4" +logging.basicConfig(format='[%(levelname) 5s/%(asctime)s] %(name)s: %(message)s', level=logging.INFO) +# 创建 +logger = logging.getLogger("magic") +logger.setLevel(logging.INFO) + +_ConfigCar = "" +_ConfigSh = "" if os.path.exists("/jd/config/magic.json"): - with open("/jd/config/magic.json", 'r', encoding='utf-8') as f: - BOT = json.load(f) - -if os.path.exists("/ql/config/magic.json"): - platform = "ql" - with open("/ql/config/magic.json", 'r', encoding='utf-8') as f: - BOT = json.load(f) - -if os.path.exists("/ql/data/config/magic.json"): - platform = "ql2" - with open("/ql/data/config/magic.json", 'r', encoding='utf-8') as f: - BOT = json.load(f) - -api_id = int(BOT['api_id']) -api_hash = BOT['api_hash'] -my_id = int(BOT['user_id']) -my_bot_id = int(BOT['bot_token'].split(":")[0]) -base_path = BOT['base_path'] - -if platform == "v4": - _ConfigSH = '/jd/config/config.sh' -elif platform == 'ql': - _ConfigSH = '/ql/config/config.sh' + _ConfigCar = "/jd/config/magic.json" + _ConfigSh = "/jd/config/config.sh" +elif os.path.exists("/ql/config/magic.json"): + _ConfigCar = "/ql/config/magic.json" + _ConfigSh = "/ql/config/config.sh" +elif os.path.exists("/ql/data/config/magic.json"): + _ConfigCar = "/ql/data/config/magic.json" + _ConfigSh = "/ql/data/config/config.sh" else: - _ConfigSH = '/ql/data/config/config.sh' + logger.info("未找到magic.json config.sh") -if BOT['proxy']: +with open(_ConfigCar, 'r', encoding='utf-8') as f: + magic_json = f.read() + properties = json.loads(magic_json) + +# 缓存 +cache = FIFOCache(maxsize=properties.get("monitor_cache_size")) + +# Telegram相关 +api_id = properties.get("api_id") +api_hash = properties.get("api_hash") +bot_id = properties.get("bot_id") +bot_token = properties.get("bot_token") +user_id = properties.get("user_id") +# 监控相关 +monitor_cars = properties.get("monitor_cars") +command = properties.get("command") +log_path = properties.get("log_path") +log_send = properties.get("log_send") +logger.info(f"监控的频道或群组-->{monitor_cars}") +monitor_scripts_path = properties.get("monitor_scripts_path") +logger.info(f"监控的文件目录-->{monitor_scripts_path}") +monitor_scripts = properties.get("monitor_scripts") +monitor_auto_stops = properties.get("monitor_auto_stops") +logger.info(f"监控的自动停车-->{monitor_auto_stops}") + +if properties.get("proxy"): proxy = { - 'hostname': BOT['proxy_add'], # 改成自己的 - 'port': int(BOT['proxy_port']), - 'username': BOT['proxy_username'], - 'password': BOT['proxy_password'] + 'proxy_type': properties.get("proxy_type"), + 'addr': properties.get("proxy_addr"), + 'port': properties.get("proxy_port") } - app = Client('magic', api_id, api_hash, proxy=proxy) + client = TelegramClient("magic", api_id, api_hash, proxy=proxy, auto_reconnect=True, retry_delay=1, connection_retries=99999).start() else: - app = Client('magic', api_id, api_hash) - -# 监控的自动车 -car_group_id = int(BOT['car_group_id']) - -monitor_flag = 'https://i.walle.com/api?data=' - -# 你的脚本配置 -car_config = [ - {'name': 'M加购有礼', 'env': 'M_WX_ADD_CART_URL', 'js': 'm_jd_wx_addCart.js', 'cmd': 'now'}, - {'name': 'M幸运抽奖', 'env': 'M_WX_LUCK_DRAW_URL', 'js': 'm_jd_wx_luckDraw.js', 'cmd': 'now'}, - {'name': 'M集卡抽奖', 'env': 'M_WX_COLLECT_CARD_URL', 'js': 'm_jd_wx_collectCard.js', 'cmd': 'now'}, - {'name': 'M关注有礼', 'env': 'M_FOLLOW_SHOP_ARGV', 'js': 'm_jd_follow_shop.js', 'cmd': 'now'} -] + client = TelegramClient("magic", api_id, api_hash, auto_reconnect=True, retry_delay=1, connection_retries=99999).start() -@app.on_message(filters.chat(my_bot_id) & filters.regex("在吗")) -async def handler(client, message): - await message.reply("老板啥事!") - - -@app.on_message(filters.chat(car_group_id) & filters.text) -async def handler(client, message): - try: - if message.entities is None: - return - text = message.entities[0]['url'] - if text is None: - return - if 'i.walle.com' not in text: - return - text = urllib.parse.unquote(text.replace(monitor_flag, '')) - zd = 1 - if 'jd_zdjr_activityId' in text: - zd = re.search(f'jd_zdjr_activityId="(.*)"', text)[1] - if zd != 1: - if cache.get(zd) is not None: - await client.send_message(my_bot_id, f'跑过 {text}') - return - cache.set(zd, zd) - else: - if cache.get(text) is not None: - await client.send_message(my_bot_id, f'跑过 {text}') - return - cache.set(text, text) - name = '' - js = '' - command = '' - for v in car_config: - if v['env'] in text: - name = v['name'] - js = v['js'] - command = v['cmd'] - break - if len(name) == 0: - await client.send_message(my_bot_id, f'未知变量`{text}`') - return - messages = text.split("\n") - change = "" - for message in messages: - if "export " not in message: - continue - kv = message.replace("export ", "") - key = kv.split("=")[0] - value = re.findall(r'"([^"]*)"', kv)[0] - configs = rwcon("str") - if kv in configs: - continue - if key in configs: - configs = re.sub(f'{key}=("|\').*("|\')', kv, configs) - change += f"【替换】 `{name}` 环境变量成功\n`{kv}\n`" - else: - if platform == 'v4': - end_line = 0 - configs = rwcon("list") - for config in configs: - if "第五区域" in config and "↑" in config: - end_line = configs.index(config) - 1 - break - configs.insert(end_line, f'export {key}="{value}"\n') - else: - configs = rwcon("str") - configs += f'export {key}="{value}"\n' - change += f"【新增】 `{name}` 环境变量成功\n`{kv}\n`" - await client.send_message(my_bot_id, change) - rwcon(configs) - if len(change) == 0: - await client.send_message(my_bot_id, f'【取消】{name}环境变量无需改动') - return - if len(js) > 0: - await client.send_message(my_bot_id, f'开始运行 {js}') - if platform == 'v4': - await cmd(client, f'jtask {base_path}/{js} {command}') - else: - await cmd(client, f'task {base_path}/{js} {command}') - else: - await client.send_message(my_bot_id, f'无需执行') - except Exception as e: - await client.send_message(my_bot_id, f'{str(e)}') - - -async def cmd(client, cmd_text): - '''定义执行cmd命令''' - try: - p = await asyncio.create_subprocess_shell( - cmd_text, stdout=asyncio.subprocess.PIPE, - stderr=asyncio.subprocess.PIPE) - res_bytes, res_err = await p.communicate() - res = res_bytes.decode('utf-8') - if len(res) > 0: - if platform == "v4": - base = "/jd" - elif platform == "ql": - base = "/ql" - else: - base = "/ql/data" - tmp_log = f'{base}/log/bot/{cmd_text.split("/")[-1].split(".js")[0]}-{datetime.datetime.now().strftime("%H-%M-%S.%f")}.log' - with open(tmp_log, 'w+', encoding='utf-8') as f: - f.write(res) - except Exception as e: - await client.send_message(my_bot_id, f'日志目录有误,{str(e)}') - - -# 读写config.sh def rwcon(arg): if arg == "str": - with open(_ConfigSH, 'r', encoding='utf-8') as f1: + with open(_ConfigSh, 'r', encoding='utf-8') as f1: configs = f1.read() return configs elif arg == "list": - with open(_ConfigSH, 'r', encoding='utf-8') as f1: + with open(_ConfigSh, 'r', encoding='utf-8') as f1: configs = f1.readlines() return configs elif isinstance(arg, str): - with open(_ConfigSH, 'w', encoding='utf-8') as f1: + with open(_ConfigSh, 'w', encoding='utf-8') as f1: f1.write(arg) elif isinstance(arg, list): - with open(_ConfigSH, 'w', encoding='utf-8') as f1: + with open(_ConfigSh, 'w', encoding='utf-8') as f1: f1.write("".join(arg)) -app.run() +async def export(text): + messages = text.split("\n") + change = "" + key = "" + for message in messages: + if "export " not in message: + continue + kv = message.replace("export ", "") + key = kv.split("=")[0] + value = re.findall(r'"([^"]*)"', kv)[0] + configs = rwcon("str") + if kv in configs: + continue + if key in configs: + configs = re.sub(f'{key}=("|\').*("|\')', kv, configs) + change += f"【替换】环境变量成功\nexport {kv}" + await client.send_message(bot_id, change) + else: + end_line = 0 + configs = rwcon("list") + for config in configs: + if "第二区域" in config and "↑" in config: + end_line = configs.index(config) - 1 + break + configs.insert(end_line, f'export {key}="{value}"\n') + change += f"【新增】环境变量成功\nexport {kv}" + await client.send_message(bot_id, change) + rwcon(configs) + if len(change) == 0: + await client.send_message(bot_id, f'【取消】{key}环境变量无需改动') + + +# 设置变量 +@client.on(events.NewMessage(chats=monitor_cars, pattern='^没水了$')) +async def handler(event): + for auto_stop_file in monitor_auto_stops: + os.popen(f"ps -ef | grep {auto_stop_file}" + " | grep -v grep | awk '{print $1}' | xargs kill -9") + await client.send_message(bot_id, f'没水停车') + + +# 设置变量 +@client.on(events.NewMessage(chats=monitor_cars, pattern='^在吗$')) +async def handler(event): + await client.send_message(bot_id, f'老板啥事?') + + +# 设置变量 +@client.on(events.NewMessage(chats=monitor_cars, pattern='^清理缓存$')) +async def handler(event): + b_size = cache.size() + logger.info(f"清理前缓存数量,{b_size}") + cache.clear() + a_size = cache.size() + logger.info(f"清理后缓存数量,{a_size}") + await client.send_message(bot_id, f'清理缓存结束 {b_size}-->{a_size}') + + +# 监听事件 +@client.on(events.NewMessage(chats=monitor_cars)) +async def handler(event): + origin = event.message.text + text = re.findall(r'https://i.walle.com/api\?data=(.+)?\)', origin) + if len(text) > 0: + text = parse.unquote_plus(text[0]) + elif origin.startswith("export "): + text = origin + else: + return + try: + logger.info(f"原始数据 {text}") + # 微定制 + if "WDZactivityId" in text: + activity_id = re.search(f'WDZactivityId="(.+?)"', text)[1] + if cache.get(activity_id) is not None: + await client.send_message(bot_id, f'跑过 {text}') + return + cache.set(activity_id, activity_id) + text = f'export jd_wdz_custom="{activity_id}"' + else: + urls = re.search('((http|https)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|])', text) + if urls is not None: + url = urls[0] + domain = re.findall('https?://([^/]+)', url)[0] + params = parse.parse_qs(parse.urlparse(url).query) + activity_id = '' + if 'cjhy' in domain or 'lzkj' in domain or 'lzdz1' in domain: + if 'pageDecorateView/previewPage' in url: + activity_id = params["tplId"][0] + elif 'wxPointShopView' in url: + activity_id = params["giftId"][0] + elif 'activityId' in url: + activity_id = params["activityId"][0] + if len(activity_id) == 0: + if cache.get(text) is not None: + await client.send_message(bot_id, f'跑过 {text}') + return + cache.set(text, text) + elif cache.get(activity_id) is not None: + await client.send_message(bot_id, f'跑过 {text}') + return + cache.set(activity_id, activity_id) + else: + if cache.get(text) is not None: + await client.send_message(bot_id, f'跑过 {text}') + return + cache.set(text, text) + logger.info(f"最终变量 {text}") + kv = text.replace("export ", "") + key = kv.split("=")[0] + value = re.findall(r'"([^"]*)"', kv)[0] + action = monitor_scripts.get(key) + logger.info(f'ACTION {action}') + if action is None: # 没有自动车 + await client.send_message(bot_id, f'没有自动车 #{text}') + return + file = action.get("file", "") + # 没有匹配的动作 或没开启 + name = action.get("name") + enable = action.get("enable") + logger.info(f'name {name} enable {enable}') + if not enable: + await client.send_message(bot_id, f'未开启任务 #{name}') + return + queue = action.get("queue") + logger.info(f'queue {queue} name {name}') + if queue: + await queues[action.get("queue_name")].put({"text": text, "action": action}) + await client.send_message(bot_id, f'入队执行 #{name}') + return + logger.info(f'设置环境变量export {action}') + await export(text) + await client.send_message(bot_id, f'开始执行 #{name}') + await cmd(f'cd {monitor_scripts_path} && {command} {file}') + except Exception as e: + logger.error(e) + await client.send_message(bot_id, f'{str(e)}') + + +queues = {} + + +async def task(task_name, task_key): + logger.info(f"队列监听--> {task_name} {task_key} 已启动,等待任务") + curr_queue = queues[task_key] + while True: + try: + param = await curr_queue.get() + logger.info(f"出队执行开始 {param}") + text = param.get("text") + kv = text.replace("export ", "") + key = kv.split("=")[0] + value = re.findall(r'"([^"]*)"', kv)[0] + logger.info(f'出队执行变量与值 {key},{value}') + action = param.get("action") + logger.info(f'ACTION {action}') + file = action.get("file", "") + logger.info(f'JTASK命令 {file},{parse.quote_plus(value)}') + logger.info(f'出队执行-->设置环境变量export {action}') + await export(text) + await cmd(f'cd {monitor_scripts_path} && {command} {file}') + if curr_queue.qsize() > 1: + await client.send_message(bot_id, f'{action["name"]},队列长度{curr_queue.qsize()},将等待{action["wait"]}秒...') + await asyncio.sleep(action['wait']) + except Exception as e: + logger.error(e) + + +async def cmd(text): + try: + logger.info(f"执行命令{text}") + if 'node' in text: + name = re.findall(r'node (.*).js', text)[0] + else: + name = re.findall(r'task (.*).js', text)[0] + tmp_log = f'{log_path}/{name}.{datetime.datetime.now().strftime("%H%M%S%f")}.log' + proc = await asyncio.create_subprocess_shell( + f"{text} >> {tmp_log} 2>&1", + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE + ) + await proc.communicate() + if log_send: + await client.send_file(bot_id, tmp_log) + # os.remove(tmp_log) + except Exception as e: + logger.error(e) + await client.send_message(bot_id, f'something wrong,I\'m sorry\n{str(e)}') + + +if __name__ == "__main__": + try: + logger.info("开始运行") + for key in monitor_scripts: + action = monitor_scripts[key] + name = action.get('name') + queue = action.get("queue") + if queue: + queues[action.get("queue_name")] = asyncio.Queue() + client.loop.create_task(task(name, key)) + else: + logger.info(f"无需队列--> {name} {key}") + client.run_until_disconnected() + except Exception as e: + logger.error(e) + client.disconnect()