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&param=${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&param=${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&param=${pd.skuId}`)
+                await $.wait(200, 500)
+                count--
+            }
+        }
+        if (ele.taskId === 'followshop') {
+            $.log('followshop')
+            await $.api('drawCenter/doTask',
+                `activityId=${$.activityId}&pin=${
+                    $.Pin}&taskId=followshop&param=`)
+        }
+        if (ele.taskId === 'joinvip') {
+            $.log('joinvip')
+            await $.api('drawCenter/doTask',
+                `activityId=${$.activityId}&pin=${
+                    $.Pin}&taskId=joinvip&param=`)
+        }
+    }
+    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()