├── 315sm.py ├── README.md ├── SendNotify.py ├── dfjs.py ├── dfyc.js ├── htmwg.py ├── ikuuu.js ├── itzj.py ├── jdd.py ├── jlzx.py ├── kghw.py ├── lccd.py ├── lhcm.py ├── ljgy.py ├── nbb.js ├── notify.py ├── qbd.py ├── ql.js ├── sendNotify.js ├── tls.js ├── utils.js └── xmyd.py /315sm.py: -------------------------------------------------------------------------------- 1 | ''' 2 | new Env('315监控'); 3 | 没啥卵用就是发一些零撸的东西 4 | ''' 5 | import requests 6 | import re 7 | import sys 8 | from os import path 9 | def load_send(): 10 | global send 11 | cur_path = path.abspath(path.dirname(__file__)) 12 | send_module_path = cur_path + "/SendNotify.py" 13 | if path.exists(send_module_path): 14 | from SendNotify import send 15 | print("加载通知服务成功!") 16 | else: 17 | print("未找SendNotify.py文件即将推出运行") 18 | sys.exit() 19 | def ac(): 20 | url = "https://www.315som.com/category/ll" 21 | headers = { 22 | "User-Agent": "Mozilla/5.0 (Linux; U; Android 14; zh-cn; RMX3562 Build/UKQ1.230924.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/90.0.4430.61 Mobile Safari/537.36 HeyTapBrowser/40.8.30.3", 23 | "Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7" 24 | } 25 | response = requests.get(url, headers=headers) 26 | html_content = response.text 27 | 28 | pattern = re.compile(r'

(.*?)

') 29 | matches = pattern.findall(html_content) 30 | content = "" 31 | for match in matches: 32 | link, title = match 33 | content += f"项目名称: {title}\n项目地址: {link}\n\n" 34 | return content 35 | if __name__ == "__main__": 36 | load_send() 37 | content = ac() 38 | send("大人请查收今日零撸项目", content) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 本仓库仅用于学习交流有问题联系双向bot@YourAhTzubot 2 | -------------------------------------------------------------------------------- /SendNotify.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # _*_ coding:utf-8 _*_ 3 | import base64 4 | import hashlib 5 | import hmac 6 | import json 7 | import os 8 | import re 9 | import threading 10 | import time 11 | import urllib.parse 12 | 13 | import requests 14 | 15 | from requests.packages.urllib3.exceptions import InsecureRequestWarning 16 | # 禁用安全请求警告 17 | requests.packages.urllib3.disable_warnings(InsecureRequestWarning) 18 | # 创建 session 对象,全局设置 verify=False 19 | session = requests.Session() 20 | session.verify = False 21 | 22 | # 原先的 print 函数和主线程的锁 23 | _print = print 24 | mutex = threading.Lock() 25 | 26 | 27 | # 定义新的 print 函数 28 | def print(text, *args, **kw): 29 | """ 30 | 使输出有序进行,不出现多线程同一时间输出导致错乱的问题。 31 | """ 32 | with mutex: 33 | _print(text, *args, **kw) 34 | 35 | # 通知服务 36 | # fmt: off 37 | push_config = { 38 | 'HITOKOTO': False, # 启用一言(随机句子) 39 | 40 | 'BARK_PUSH': '', # bark IP 或设备码,例:https://api.day.app/DxHcxxxxxRxxxxxxcm/ 41 | 'BARK_ARCHIVE': '', # bark 推送是否存档 42 | 'BARK_GROUP': '', # bark 推送分组 43 | 'BARK_SOUND': '', # bark 推送声音 44 | 45 | 'CONSOLE': True, # 控制台输出 46 | 47 | 'DD_BOT_SECRET': '', # 钉钉机器人的 DD_BOT_SECRET 48 | 'DD_BOT_TOKEN': '', # 钉钉机器人的 DD_BOT_TOKEN 49 | 50 | 'FSKEY': '', # 飞书机器人的 FSKEY 51 | 52 | 'GOBOT_URL': '', # go-cqhttp 53 | # 推送到个人QQ:http://127.0.0.1/send_private_msg 54 | # 群:http://127.0.0.1/send_group_msg 55 | 'GOBOT_QQ': '', # go-cqhttp 的推送群或用户 56 | # GOBOT_URL 设置 /send_private_msg 时填入 user_id=个人QQ 57 | # /send_group_msg 时填入 group_id=QQ群 58 | 'GOBOT_TOKEN': '', # go-cqhttp 的 access_token 59 | 60 | 'GOTIFY_URL': '', # gotify地址,如https://push.example.de:8080 61 | 'GOTIFY_TOKEN': '', # gotify的消息应用token 62 | 'GOTIFY_PRIORITY': 0, # 推送消息优先级,默认为0 63 | 64 | 'IGOT_PUSH_KEY': '', # iGot 聚合推送的 IGOT_PUSH_KEY 65 | 66 | 'PUSH_KEY': '', # server 酱的 PUSH_KEY,兼容旧版与 Turbo 版 67 | 68 | 'PUSH_PLUS_TOKEN': '', # push+ 微信推送的用户令牌 69 | 'PUSH_PLUS_USER': '', # push+ 微信推送的群组编码 70 | 71 | 'QMSG_KEY': '', # qmsg 酱的 QMSG_KEY 72 | 'QMSG_TYPE': '', # qmsg 酱的 QMSG_TYPE 73 | 74 | 'QYWX_AM': '', # 企业微信应用 75 | 76 | 'QYWX_KEY': '', # 企业微信机器人 77 | 78 | 'TG_BOT_TOKEN': '', # tg 机器人的 TG_BOT_TOKEN,例: 79 | 'TG_USER_ID': '', # tg 机器人的 TG_USER_ID,例:1434078534 80 | 'TG_API_HOST': '', # tg 代理 api 81 | 'TG_PROXY_AUTH': '', # tg 代理认证参数 82 | 'TG_PROXY_HOST': '', # tg 机器人的 TG_PROXY_HOST 83 | 'TG_PROXY_PORT': '', # tg 机器人的 TG_PROXY_PORT 84 | } 85 | notify_function = [] 86 | # fmt: on 87 | 88 | # 首先读取 面板变量 或者 github action 运行变量 89 | for k in push_config: 90 | if os.getenv(k): 91 | v = os.getenv(k) 92 | push_config[k] = v 93 | 94 | def bark(title: str, content: str) -> None: 95 | """ 96 | 使用 bark 推送消息。 97 | """ 98 | if not push_config.get("BARK_PUSH"): 99 | print("bark 服务的 BARK_PUSH 未设置!!\n取消推送") 100 | return 101 | print("bark 服务启动") 102 | 103 | if push_config.get("BARK_PUSH").startswith("http"): 104 | url = f'{push_config.get("BARK_PUSH")}/{urllib.parse.quote_plus(title)}/{urllib.parse.quote_plus(content)}' 105 | else: 106 | url = f'https://api.day.app/{push_config.get("BARK_PUSH")}/{urllib.parse.quote_plus(title)}/{urllib.parse.quote_plus(content)}' 107 | 108 | bark_params = { 109 | "BARK_ARCHIVE": "isArchive", 110 | "BARK_GROUP": "group", 111 | "BARK_SOUND": "sound", 112 | } 113 | params = "" 114 | for pair in filter( 115 | lambda pairs: pairs[0].startswith("BARK_") 116 | and pairs[0] != "BARK_PUSH" 117 | and pairs[1] 118 | and bark_params.get(pairs[0]), 119 | push_config.items(), 120 | ): 121 | params += f"{bark_params.get(pair[0])}={pair[1]}&" 122 | if params: 123 | url = url + "?" + params.rstrip("&") 124 | response = session.get(url).json() 125 | 126 | if response["code"] == 200: 127 | print("bark 推送成功!") 128 | else: 129 | print("bark 推送失败!") 130 | 131 | 132 | def console(title: str, content: str) -> None: 133 | """ 134 | 使用 控制台 推送消息。 135 | """ 136 | print(f"{title}\n\n{content}") 137 | 138 | 139 | def dingding_bot(title: str, content: str) -> None: 140 | """ 141 | 使用 钉钉机器人 推送消息。 142 | """ 143 | if not push_config.get("DD_BOT_SECRET") or not push_config.get("DD_BOT_TOKEN"): 144 | print("钉钉机器人 服务的 DD_BOT_SECRET 或者 DD_BOT_TOKEN 未设置!!\n取消推送") 145 | return 146 | print("钉钉机器人 服务启动") 147 | 148 | timestamp = str(round(time.time() * 1000)) 149 | secret_enc = push_config.get("DD_BOT_SECRET").encode("utf-8") 150 | string_to_sign = "{}\n{}".format(timestamp, push_config.get("DD_BOT_SECRET")) 151 | string_to_sign_enc = string_to_sign.encode("utf-8") 152 | hmac_code = hmac.new( 153 | secret_enc, string_to_sign_enc, digestmod=hashlib.sha256 154 | ).digest() 155 | sign = urllib.parse.quote_plus(base64.b64encode(hmac_code)) 156 | url = f'https://oapi.dingtalk.com/robot/send?access_token={push_config.get("DD_BOT_TOKEN")}×tamp={timestamp}&sign={sign}' 157 | headers = {"Content-Type": "application/json;charset=utf-8"} 158 | data = {"msgtype": "text", "text": {"content": f"{title}\n\n{content}"}} 159 | response = session.post( 160 | url=url, data=json.dumps(data), headers=headers, timeout=15 161 | ).json() 162 | 163 | if not response["errcode"]: 164 | print("钉钉机器人 推送成功!") 165 | else: 166 | print("钉钉机器人 推送失败!") 167 | 168 | 169 | def feishu_bot(title: str, content: str) -> None: 170 | """ 171 | 使用 飞书机器人 推送消息。 172 | """ 173 | if not push_config.get("FSKEY"): 174 | print("飞书 服务的 FSKEY 未设置!!\n取消推送") 175 | return 176 | print("飞书 服务启动") 177 | 178 | url = f'https://open.feishu.cn/open-apis/bot/v2/hook/{push_config.get("FSKEY")}' 179 | data = {"msg_type": "text", "content": {"text": f"{title}\n\n{content}"}} 180 | response = session.post(url, data=json.dumps(data)).json() 181 | 182 | if response.get("StatusCode") == 0: 183 | print("飞书 推送成功!") 184 | else: 185 | print("飞书 推送失败!错误信息如下:\n", response) 186 | 187 | 188 | def go_cqhttp(title: str, content: str) -> None: 189 | """ 190 | 使用 go_cqhttp 推送消息。 191 | """ 192 | if not push_config.get("GOBOT_URL") or not push_config.get("GOBOT_QQ"): 193 | print("go-cqhttp 服务的 GOBOT_URL 或 GOBOT_QQ 未设置!!\n取消推送") 194 | return 195 | print("go-cqhttp 服务启动") 196 | 197 | url = f'{push_config.get("GOBOT_URL")}?access_token={push_config.get("GOBOT_TOKEN")}&{push_config.get("GOBOT_QQ")}&message=标题:{title}\n内容:{content}' 198 | response = session.get(url).json() 199 | 200 | if response["status"] == "ok": 201 | print("go-cqhttp 推送成功!") 202 | else: 203 | print("go-cqhttp 推送失败!") 204 | 205 | 206 | def gotify(title:str,content:str) -> None: 207 | """ 208 | 使用 gotify 推送消息。 209 | """ 210 | if not push_config.get("GOTIFY_URL") or not push_config.get("GOTIFY_TOKEN"): 211 | print("gotify 服务的 GOTIFY_URL 或 GOTIFY_TOKEN 未设置!!\n取消推送") 212 | return 213 | print("gotify 服务启动") 214 | 215 | url = f'{push_config.get("GOTIFY_URL")}/message?token={push_config.get("GOTIFY_TOKEN")}' 216 | data = {"title": title,"message": content,"priority": push_config.get("GOTIFY_PRIORITY")} 217 | response = session.post(url,data=data).json() 218 | 219 | if response.get("id"): 220 | print("gotify 推送成功!") 221 | else: 222 | print("gotify 推送失败!") 223 | 224 | 225 | def iGot(title: str, content: str) -> None: 226 | """ 227 | 使用 iGot 推送消息。 228 | """ 229 | if not push_config.get("IGOT_PUSH_KEY"): 230 | print("iGot 服务的 IGOT_PUSH_KEY 未设置!!\n取消推送") 231 | return 232 | print("iGot 服务启动") 233 | 234 | url = f'https://push.hellyw.com/{push_config.get("IGOT_PUSH_KEY")}' 235 | data = {"title": title, "content": content} 236 | headers = {"Content-Type": "application/x-www-form-urlencoded"} 237 | response = session.post(url, data=data, headers=headers).json() 238 | 239 | if response["ret"] == 0: 240 | print("iGot 推送成功!") 241 | else: 242 | print(f'iGot 推送失败!{response["errMsg"]}') 243 | 244 | 245 | def serverJ(title: str, content: str) -> None: 246 | """ 247 | 通过 serverJ 推送消息。 248 | """ 249 | if not push_config.get("PUSH_KEY"): 250 | print("serverJ 服务的 PUSH_KEY 未设置!!\n取消推送") 251 | return 252 | print("serverJ 服务启动") 253 | 254 | data = {"text": title, "desp": content.replace("\n", "\n\n")} 255 | if push_config.get("PUSH_KEY").index("SCT") != -1: 256 | url = f'https://sctapi.ftqq.com/{push_config.get("PUSH_KEY")}.send' 257 | else: 258 | url = f'https://sc.ftqq.com/${push_config.get("PUSH_KEY")}.send' 259 | response = session.post(url, data=data).json() 260 | 261 | if response.get("errno") == 0 or response.get("code") == 0: 262 | print("serverJ 推送成功!") 263 | else: 264 | print(f'serverJ 推送失败!错误码:{response["message"]}') 265 | 266 | 267 | def pushplus_bot(title: str, content: str) -> None: 268 | """ 269 | 通过 push+ 推送消息。 270 | """ 271 | if not push_config.get("PUSH_PLUS_TOKEN"): 272 | print("PUSHPLUS 服务的 PUSH_PLUS_TOKEN 未设置!!\n取消推送") 273 | return 274 | print("PUSHPLUS 服务启动") 275 | 276 | url = "http://www.pushplus.plus/send" 277 | data = { 278 | "token": push_config.get("PUSH_PLUS_TOKEN"), 279 | "title": title, 280 | "content": content, 281 | "topic": push_config.get("PUSH_PLUS_USER"), 282 | } 283 | body = json.dumps(data).encode(encoding="utf-8") 284 | headers = {"Content-Type": "application/json"} 285 | response = session.post(url=url, data=body, headers=headers).json() 286 | 287 | if response["code"] == 200: 288 | print("PUSHPLUS 推送成功!") 289 | 290 | else: 291 | 292 | url_old = "http://pushplus.hxtrip.com/send" 293 | headers["Accept"] = "application/json" 294 | response = session.post(url=url_old, data=body, headers=headers).json() 295 | 296 | if response["code"] == 200: 297 | print("PUSHPLUS(hxtrip) 推送成功!") 298 | 299 | else: 300 | print("PUSHPLUS 推送失败!") 301 | 302 | 303 | def qmsg_bot(title: str, content: str) -> None: 304 | """ 305 | 使用 qmsg 推送消息。 306 | """ 307 | if not push_config.get("QMSG_KEY") or not push_config.get("QMSG_TYPE"): 308 | print("qmsg 的 QMSG_KEY 或者 QMSG_TYPE 未设置!!\n取消推送") 309 | return 310 | print("qmsg 服务启动") 311 | 312 | url = f'https://qmsg.zendee.cn/{push_config.get("QMSG_TYPE")}/{push_config.get("QMSG_KEY")}' 313 | payload = {"msg": f'{title}\n\n{content.replace("----", "-")}'.encode("utf-8")} 314 | response = session.post(url=url, params=payload).json() 315 | 316 | if response["code"] == 0: 317 | print("qmsg 推送成功!") 318 | else: 319 | print(f'qmsg 推送失败!{response["reason"]}') 320 | 321 | 322 | def wecom_app(title: str, content: str) -> None: 323 | """ 324 | 通过 企业微信 APP 推送消息。 325 | """ 326 | if not push_config.get("QYWX_AM"): 327 | print("QYWX_AM 未设置!!\n取消推送") 328 | return 329 | QYWX_AM_AY = re.split(",", push_config.get("QYWX_AM")) 330 | if title == "WsKey转换脚本" : 331 | print("包含屏蔽词 取消推送") 332 | return 333 | if title == "WSKEY转换" : 334 | print("包含屏蔽词 取消推送") 335 | return 336 | if 4 < len(QYWX_AM_AY) > 5: 337 | print("QYWX_AM 设置错误!!\n取消推送") 338 | return 339 | print("企业微信 APP 服务启动") 340 | corpid = QYWX_AM_AY[0] 341 | corpsecret = QYWX_AM_AY[1] 342 | touser = QYWX_AM_AY[2] 343 | agentid = QYWX_AM_AY[3] 344 | try: 345 | media_id = QYWX_AM_AY[4] 346 | except IndexError: 347 | media_id = "" 348 | wx = WeCom(corpid, corpsecret, agentid) 349 | # 如果没有配置 media_id 默认就以 text 方式发送 350 | if not media_id: 351 | message = title + "\n\n" + content 352 | response = wx.send_text(message, touser) 353 | else: 354 | response = wx.send_mpnews(title, content, media_id, touser) 355 | 356 | if response == "ok": 357 | print("企业微信推送成功!") 358 | else: 359 | print("企业微信推送失败!错误信息如下:\n", response) 360 | 361 | 362 | class WeCom: 363 | def __init__(self, corpid, corpsecret, agentid): 364 | self.CORPID = corpid 365 | self.CORPSECRET = corpsecret 366 | self.AGENTID = agentid 367 | 368 | def get_access_token(self): 369 | url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken" 370 | values = { 371 | "corpid": self.CORPID, 372 | "corpsecret": self.CORPSECRET, 373 | } 374 | req = session.post(url, params=values) 375 | data = json.loads(req.text) 376 | return data["access_token"] 377 | 378 | def send_text(self, message, touser="@all"): 379 | send_url = ( 380 | "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" 381 | + self.get_access_token() 382 | ) 383 | send_values = { 384 | "touser": touser, 385 | "msgtype": "text", 386 | "agentid": self.AGENTID, 387 | "text": {"content": message}, 388 | "safe": "0", 389 | } 390 | send_msges = bytes(json.dumps(send_values), "utf-8") 391 | respone = session.post(send_url, send_msges) 392 | respone = respone.json() 393 | return respone["errmsg"] 394 | 395 | def send_mpnews(self, title, message, media_id, touser="@all"): 396 | send_url = ( 397 | "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" 398 | + self.get_access_token() 399 | ) 400 | send_values = { 401 | "touser": touser, 402 | "msgtype": "mpnews", 403 | "agentid": self.AGENTID, 404 | "mpnews": { 405 | "articles": [ 406 | { 407 | "title": title, 408 | "thumb_media_id": media_id, 409 | "author": "Author", 410 | "content_source_url": "", 411 | "content": message.replace("\n", "
"), 412 | "digest": message, 413 | } 414 | ] 415 | }, 416 | } 417 | send_msges = bytes(json.dumps(send_values), "utf-8") 418 | respone = session.post(send_url, send_msges) 419 | respone = respone.json() 420 | return respone["errmsg"] 421 | 422 | 423 | def wecom_bot(title: str, content: str) -> None: 424 | """ 425 | 通过 企业微信机器人 推送消息。 426 | """ 427 | if not push_config.get("QYWX_KEY"): 428 | print("企业微信机器人 服务的 QYWX_KEY 未设置!!\n取消推送") 429 | return 430 | print("企业微信机器人服务启动") 431 | 432 | url = f"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={push_config.get('QYWX_KEY')}" 433 | headers = {"Content-Type": "application/json;charset=utf-8"} 434 | data = {"msgtype": "text", "text": {"content": f"{title}\n\n{content}"}} 435 | response = session.post( 436 | url=url, data=json.dumps(data), headers=headers, timeout=15 437 | ).json() 438 | 439 | if response["errcode"] == 0: 440 | print("企业微信机器人推送成功!") 441 | else: 442 | print("企业微信机器人推送失败!") 443 | 444 | 445 | def telegram_bot(title: str, content: str) -> None: 446 | """ 447 | 使用 telegram 机器人 推送消息。 448 | """ 449 | if not push_config.get("TG_BOT_TOKEN") or not push_config.get("TG_USER_ID"): 450 | print("tg 服务的 bot_token 或者 user_id 未设置!!\n取消推送") 451 | return 452 | print("tg 服务启动") 453 | 454 | if push_config.get("TG_API_HOST"): 455 | url = f"https://{push_config.get('TG_API_HOST')}/bot{push_config.get('TG_BOT_TOKEN')}/sendMessage" 456 | else: 457 | url = ( 458 | f"https://api.telegram.org/bot{push_config.get('TG_BOT_TOKEN')}/sendMessage" 459 | ) 460 | headers = {"Content-Type": "application/x-www-form-urlencoded"} 461 | payload = { 462 | "chat_id": str(push_config.get("TG_USER_ID")), 463 | "text": f"{title}\n\n{content}", 464 | "disable_web_page_preview": "true", 465 | } 466 | proxies = None 467 | if push_config.get("TG_PROXY_HOST") and push_config.get("TG_PROXY_PORT"): 468 | if push_config.get("TG_PROXY_AUTH") is not None and "@" not in push_config.get( 469 | "TG_PROXY_HOST" 470 | ): 471 | push_config["TG_PROXY_HOST"] = ( 472 | push_config.get("TG_PROXY_AUTH") 473 | + "@" 474 | + push_config.get("TG_PROXY_HOST") 475 | ) 476 | proxyStr = "http://{}:{}".format( 477 | push_config.get("TG_PROXY_HOST"), push_config.get("TG_PROXY_PORT") 478 | ) 479 | proxies = {"http": proxyStr, "https": proxyStr} 480 | response = session.post( 481 | url=url, headers=headers, params=payload, proxies=proxies 482 | ).json() 483 | 484 | if response["ok"]: 485 | print("tg 推送成功!") 486 | else: 487 | print("tg 推送失败!") 488 | 489 | 490 | def one() -> str: 491 | """ 492 | 获取一条一言。 493 | :return: 494 | """ 495 | url = "https://v1.hitokoto.cn/" 496 | res = session.get(url).json() 497 | return res["hitokoto"] + " ----" + res["from"] 498 | 499 | 500 | if push_config.get("BARK_PUSH"): 501 | notify_function.append(bark) 502 | if push_config.get("CONSOLE"): 503 | notify_function.append(console) 504 | if push_config.get("DD_BOT_TOKEN") and push_config.get("DD_BOT_SECRET"): 505 | notify_function.append(dingding_bot) 506 | if push_config.get("FSKEY"): 507 | notify_function.append(feishu_bot) 508 | if push_config.get("GOBOT_URL") and push_config.get("GOBOT_QQ"): 509 | notify_function.append(go_cqhttp) 510 | if push_config.get("GOTIFY_URL") and push_config.get("GOTIFY_TOKEN"): 511 | notify_function.append(gotify) 512 | if push_config.get("IGOT_PUSH_KEY"): 513 | notify_function.append(iGot) 514 | if push_config.get("PUSH_KEY"): 515 | notify_function.append(serverJ) 516 | if push_config.get("PUSH_PLUS_TOKEN"): 517 | notify_function.append(pushplus_bot) 518 | if push_config.get("QMSG_KEY") and push_config.get("QMSG_TYPE"): 519 | notify_function.append(qmsg_bot) 520 | if push_config.get("QYWX_AM"): 521 | notify_function.append(wecom_app) 522 | if push_config.get("QYWX_KEY"): 523 | notify_function.append(wecom_bot) 524 | if push_config.get("TG_BOT_TOKEN") and push_config.get("TG_USER_ID"): 525 | notify_function.append(telegram_bot) 526 | 527 | 528 | def send(title: str, content: str) -> None: 529 | if not content: 530 | print(f"{title} 推送内容为空!") 531 | return 532 | 533 | hitokoto = push_config.get("HITOKOTO") 534 | 535 | text = one() if hitokoto else "" 536 | now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) 537 | content += "\n" + text + f"推送时间:{now}" 538 | 539 | ts = [ 540 | threading.Thread(target=mode, args=(title, content), name=mode.__name__) 541 | for mode in notify_function 542 | ] 543 | [t.start() for t in ts] 544 | [t.join() for t in ts] 545 | 546 | 547 | def main(): 548 | send("title", "content") 549 | 550 | 551 | if __name__ == "__main__": 552 | main() 553 | -------------------------------------------------------------------------------- /dfjs.py: -------------------------------------------------------------------------------- 1 | ''' 2 | new Env('东方棘市'); 3 | 东方棘市每日签到,分享提现后续完成可关注github 4 | 变量格式 token#备注,多账号换行或者用@连接 5 | 7.1号19:38更新自动提现(PS余额不满足1则不进行提现) 6 | 7.1号22:40更新用户判断和余额错误来自@pijiu10456_S修改 7 | ''' 8 | def sign(token, remark): 9 | url = "https://ys.shajixueyuan.com/api/user_sign/sign" 10 | headers = { 11 | 'User-Agent': "Mozilla/5.0 (Linux; Android 12; RMX3562 Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/122.0.6261.120 Mobile Safari/537.36 XWEB/1220099 MMWEBSDK/20240404 MMWEBID/2307 MicroMessenger/8.0.49.2600(0x28003133) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android", 12 | 'token': token 13 | } 14 | response = requests.post(url, headers=headers) 15 | data = response.json() 16 | if data['code'] == 1: 17 | msg = data['data']['msg'] 18 | energy_release = data["data"]["rewards_info"]["energy_release"] 19 | print(f"[{remark}] 签到结果: {msg}, 释放 {energy_release} 能量果子") 20 | else: 21 | msg = data["msg"] 22 | print(f"[{remark}] 签到失败原因: {msg}") 23 | 24 | def issueRewards(token, remark): 25 | url = "https://ys.shajixueyuan.com/api/quest.quest/issueRewards" 26 | headers = { 27 | 'User-Agent': "Mozilla/5.0 (Linux; Android 12; RMX3562 Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/122.0.6261.120 Mobile Safari/537.36 XWEB/1220099 MMWEBSDK/20240404 MMWEBID/2307 MicroMessenger/8.0.49.2600(0x28003133) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android", 28 | 'token': token 29 | } 30 | data = { 31 | "quest_id": 4 32 | } 33 | response = requests.post(url, json=data, headers=headers) 34 | data = response.json() 35 | msg = data['msg'] 36 | print(f"[{remark}] 分享结果: {msg}") 37 | 38 | def info(token, remark): 39 | url = "https://ys.shajixueyuan.com/api/user/info" 40 | headers = { 41 | 'User-Agent': "Mozilla/5.0 (Linux; Android 12; RMX3562 Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/122.0.6261.120 Mobile Safari/537.36 XWEB/1220099 MMWEBSDK/20240404 MMWEBID/2307 MicroMessenger/8.0.49.2600(0x28003133) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android", 42 | 'token': token 43 | } 44 | response = requests.get(url, headers=headers) 45 | data = response.json() 46 | if data['code'] == 1: 47 | remaining_fruits = float(data["data"]["remaining_fruits"]) 48 | nickname = data["data"]["nickname"] 49 | print(f"[{remark}]:当前余额: {remaining_fruits}") 50 | if remaining_fruits >= 0.3: 51 | apply(token, remark) 52 | else: 53 | print(f"[{remark}] 余额不足,无法进行提现") 54 | else: 55 | msg = data["msg"] 56 | print(f"[{remark}] 查询失败: {msg}") 57 | 58 | def apply(token, remark): 59 | url = "https://ys.shajixueyuan.com/api/user.user_withdraw/apply" 60 | headers = { 61 | 'User-Agent': "Mozilla/5.0 (Linux; Android 12; RMX3562 Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/122.0.6261.120 Mobile Safari/537.36 XWEB/1220099 MMWEBSDK/20240404 MMWEBID/2307 MicroMessenger/8.0.49.2600(0x28003133) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android", 62 | 'token': token 63 | } 64 | data = { 65 | "fruit_withdraw_amount": "0.3", 66 | "pay_gateway": "wechat" 67 | } 68 | response = requests.post(url, json=data, headers=headers) 69 | data = response.json() 70 | msg = data['msg'] 71 | print(f"[{remark}] 提现结果: {msg}") 72 | 73 | if __name__ == "__main__": 74 | tokens = os.environ.get('dfjsck') 75 | if not tokens: 76 | print("获取账号失败,请检查配置是否正确") 77 | else: 78 | tokens_list = [token.strip() for token in tokens.replace('@', '\n').split('\n') if token.strip()] 79 | for index, item in enumerate(tokens_list, start=1): 80 | parts = item.split('#') 81 | token = parts[0].strip() 82 | remark = parts[1].strip() if len(parts) > 1 else f"账号{index}" 83 | print(f"===== 开始执行第 {index} 个账号任务 =====") 84 | print(f"账号: {remark}") 85 | print(f"===== 开始执行签到任务 =====") 86 | sign(token, remark) 87 | print(f"===== 开始执行分享任务 =====") 88 | issueRewards(token, remark) 89 | print(f"===== 开始执行查询和提现任务 =====") 90 | info(token, remark) 91 | print("==============================") -------------------------------------------------------------------------------- /dfyc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 转载 3 | * cron 5 15 * * * 4 | * Show:东方烟草报App 积分换实物 5 | * 变量名:dfycToken 6 | * 变量值:POST请求任意链接包含https://eapp.eastobacco.com/index.php body中的token 多账号&分割 不是@ 和换行 7 | * scriptVersionNow = "0.0.1"; 8 | */ 9 | 10 | //Quantumult X 可以在cookies里面写变量 11 | const cookies = [] 12 | 13 | 14 | const $ = new Env("东方烟草报"); 15 | const notify = $.isNode() ? require('./sendNotify') : ''; 16 | let ckName = "dfycToken"; 17 | let envSplitor = ["&"]; //多账号分隔符 18 | let strSplitor = "#"; //多变量分隔符 19 | let userIdx = 0; 20 | let userList = []; 21 | let msg = "" 22 | class UserInfo { 23 | constructor(str) { 24 | this.index = ++userIdx; 25 | this.ck = str.split(strSplitor)[0]; //单账号多变量分隔符 26 | this.ckStatus = true; 27 | this.artList = [] 28 | } 29 | async main() { 30 | await this.user_info(); 31 | if (this.ckStatus) { 32 | await this.art_list() 33 | if (this.artList.length !== 0) { 34 | for (let i = 0; i < 3; i++) { 35 | await this.task_read(this.artList[i].id, this.artList[i].catid) 36 | await this.task_share(this.artList[i].id, this.artList[i].catid) 37 | await this.task_like(this.artList[i].id, this.artList[i].catid) 38 | } 39 | } 40 | } 41 | } 42 | async user_info() { 43 | try { 44 | let options = { 45 | fn: "信息", 46 | method: "post", 47 | url: `https://eapp.eastobacco.com/index.php?m=api&c=user&a=userinfo`, 48 | headers: { 49 | "Content-Type": "application/x-www-form-urlencoded" 50 | }, 51 | body: `platform=android&token=${this.ck}×tamp=${Date.now()}&api_version=4` 52 | } 53 | let { body: result } = await $.httpRequest(options); 54 | //console.log(options); 55 | //console.log(result); 56 | if (result.code == 200) { 57 | $.log(`✅账号[${this.index}] 积分[${result.data.point}]🎉`) 58 | this.ckStatus = true; 59 | } else { 60 | console.log(`❌账号[${this.index}] 用户查询: 失败`); 61 | this.ckStatus = false; 62 | console.log(result); 63 | } 64 | } catch (e) { 65 | console.log(e); 66 | } 67 | } 68 | 69 | async task_daka() { 70 | try { 71 | let options = { 72 | fn: "打卡", 73 | method: "post", 74 | url: `https://eapp.eastobacco.com/index.php?m=api&c=user&a=daka`, 75 | headers: { 76 | "Content-Type": "application/x-www-form-urlencoded" 77 | }, 78 | body: `platform=android&token=${this.ck}×tamp=${Date.now()}&api_version=4` 79 | } 80 | let { body: result } = await $.httpRequest(options); 81 | //console.log(options); 82 | //console.log(result); 83 | $.log(`✅账号[${this.index}] 打卡[${result.message}]🎉`) 84 | } catch (e) { 85 | console.log(e); 86 | } 87 | } 88 | 89 | async art_list() { 90 | try { 91 | let options = { 92 | fn: "文章列表", 93 | method: "post", 94 | url: `https://eapp.eastobacco.com/index.php?m=api&c=content&a=newsList_pub`, 95 | headers: { 96 | "Content-Type": "application/x-www-form-urlencoded" 97 | }, 98 | body: `catid=1&num=20&page=1&api_version=4&platform=android&token=${this.ck}×tamp=${Date.now()}` 99 | } 100 | let { body: result } = await $.httpRequest(options); 101 | //console.log(options); 102 | //console.log(result); 103 | if (result.data.news) { 104 | for (let news of result.data.news) { 105 | this.artList.push( 106 | { 107 | id: news.id, 108 | catid: news.catid, 109 | title: news.title 110 | } 111 | ) 112 | } 113 | console.log(`获取文章成功`); 114 | } else { 115 | console.log(`获取文章失败`); 116 | } 117 | } catch (e) { 118 | console.log(e); 119 | } 120 | } 121 | 122 | async task_read(id, catid) { 123 | try { 124 | let options = { 125 | fn: "阅读", 126 | method: "post", 127 | url: `https://eapp.eastobacco.com/index.php?m=api&c=content&a=addvisite`, 128 | headers: { 129 | "Content-Type": "application/x-www-form-urlencoded" 130 | }, 131 | body: `platform=android&token=${this.ck}×tamp=${Date.now()}&api_version=4&newsid=${id}&catid=${catid}` 132 | } 133 | let { body: result } = await $.httpRequest(options); 134 | //console.log(options); 135 | //console.log(result); 136 | if (result.code == 200) { 137 | $.log(`✅账号[${this.index}] 阅读[${id}]成功🎉`) 138 | 139 | } else { 140 | $.log(`❌账号[${this.index}] 阅读[${id}]失败`) 141 | } 142 | } catch (e) { 143 | console.log(e); 144 | } 145 | } 146 | 147 | async task_share(id, catid) { 148 | try { 149 | let options = { 150 | fn: "分享", 151 | method: "post", 152 | url: `https://eapp.eastobacco.com/index.php?m=api&c=user&a=addScoreZf`, 153 | headers: { 154 | "Content-Type": "application/x-www-form-urlencoded" 155 | }, 156 | body: `platform=android&token=${this.ck}×tamp=${Date.now()}&api_version=4&id=${id}&catid=${catid}` 157 | } 158 | let { body: result } = await $.httpRequest(options); 159 | //console.log(options); 160 | //console.log(result); 161 | if (result.code == 200) { 162 | $.log(`✅账号[${this.index}] 分享[${id}]成功🎉`) 163 | 164 | } else { 165 | $.log(`❌账号[${this.index}] 分享[${id}]失败`) 166 | } 167 | } catch (e) { 168 | console.log(e); 169 | } 170 | } 171 | 172 | async task_like(id, catid) { 173 | try { 174 | let options = { 175 | fn: "点赞", 176 | method: "post", 177 | url: `https://eapp.eastobacco.com/index.php?m=api&c=content&a=dingcai`, 178 | headers: { 179 | "Content-Type": "application/x-www-form-urlencoded" 180 | }, 181 | body: `platform=android&token=${this.ck}×tamp=${Date.now()}&api_version=4&newsid=${id}&catid=${catid}` 182 | } 183 | let { body: result } = await $.httpRequest(options); 184 | //console.log(options); 185 | //console.log(result); 186 | if (result.code == 200) { 187 | $.log(`✅账号[${this.index}] 点赞[${id}]成功🎉`) 188 | 189 | } else { 190 | $.log(`❌账号[${this.index}] 点赞[${id}]失败`) 191 | } 192 | } catch (e) { 193 | console.log(e); 194 | } 195 | } 196 | } 197 | 198 | async function start() { 199 | let taskall = []; 200 | for (let user of userList) { 201 | if (user.ckStatus) { 202 | taskall.push(await user.main()); 203 | } 204 | } 205 | await Promise.all(taskall); 206 | } 207 | 208 | !(async () => { 209 | if (!(await checkEnv())) return; 210 | if (userList.length > 0) { 211 | await start(); 212 | } 213 | await $.sendMsg($.logs.join("\n")) 214 | })() 215 | .catch((e) => console.log(e)) 216 | .finally(() => $.done()); 217 | 218 | //******************************************************** 219 | /** 220 | * 变量检查与处理 221 | * @returns 222 | */ 223 | async function checkEnv() { 224 | let userCookie = ($.isNode() ? process.env[ckName] : cookies) || ""; 225 | if (userCookie) { 226 | let e = envSplitor[0]; 227 | for (let o of envSplitor) 228 | if (userCookie.indexOf(o) > -1) { 229 | e = o; 230 | break; 231 | } 232 | for (let n of userCookie.split(e)) n && userList.push(new UserInfo(n)); 233 | } else { 234 | console.log("未找到CK"); 235 | return; 236 | } 237 | return console.log(`共找到${userList.length}个账号`), true; //true == !0 238 | } 239 | 240 | ///////////////////////////////////////////////////////////////////////////////////// 241 | // prettier-ignore 242 | function Env(t, s) { 243 | return new (class { 244 | constructor(t, s) { 245 | this.name = t; 246 | this.data = null; 247 | this.dataFile = "box.dat"; 248 | this.logs = []; 249 | this.logSeparator = "\n"; 250 | this.startTime = new Date().getTime(); 251 | Object.assign(this, s); 252 | this.log("", `\ud83d\udd14${this.name}, \u5f00\u59cb!`); 253 | } 254 | isNode() { 255 | return "undefined" != typeof module && !!module.exports; 256 | } 257 | isQuanX() { 258 | return "undefined" != typeof $task; 259 | } 260 | isSurge() { 261 | return "undefined" != typeof $httpClient && "undefined" == typeof $loon; 262 | } 263 | isLoon() { 264 | return "undefined" != typeof $loon; 265 | } 266 | loaddata() { 267 | if (!this.isNode()) return {}; 268 | { 269 | this.fs = this.fs ? this.fs : require("fs"); 270 | this.path = this.path ? this.path : require("path"); 271 | const t = this.path.resolve(this.dataFile), 272 | s = this.path.resolve(process.cwd(), this.dataFile), 273 | e = this.fs.existsSync(t), 274 | i = !e && this.fs.existsSync(s); 275 | if (!e && !i) return {}; 276 | { 277 | const i = e ? t : s; 278 | try { 279 | return JSON.parse(this.fs.readFileSync(i)); 280 | } catch (t) { 281 | return {}; 282 | } 283 | } 284 | } 285 | } 286 | writedata() { 287 | if (this.isNode()) { 288 | this.fs = this.fs ? this.fs : require("fs"); 289 | this.path = this.path ? this.path : require("path"); 290 | const t = this.path.resolve(this.dataFile), 291 | s = this.path.resolve(process.cwd(), this.dataFile), 292 | e = this.fs.existsSync(t), 293 | i = !e && this.fs.existsSync(s), 294 | o = JSON.stringify(this.data); 295 | e ? this.writeFileSync(t, o) : i ? this.fs.writeFileSync(s, o) : this.fs.writeFileSync(t, o); 296 | } 297 | } 298 | lodash_get(t, s, e) { 299 | const i = s.replace(/\[(\d+)\]/g, ".$1").split("."); 300 | let o = t; 301 | for (const t of i) if (((o = Object(o)[t]), void 0 === o)) return e; 302 | return o; 303 | } 304 | lodash_set(t, s, e) { 305 | return Object(t) !== t 306 | ? t 307 | : (Array.isArray(s) || (s = s.toString().match(/[^.[\]]+/g) || []), 308 | (s 309 | .slice(0, -1) 310 | .reduce( 311 | (t, e, i) => 312 | Object(t[e]) === t[e] 313 | ? t[e] 314 | : (t[e] = Math.abs(s[i + 1]) >> 0 == +s[i + 1] ? [] : {}), 315 | t 316 | )[s[s.length - 1]] = e), 317 | t); 318 | } 319 | getdata(t) { 320 | let s = this.getval(t); 321 | if (/^@/.test(t)) { 322 | const [, e, i] = /^@(.*?)\.(.*?)$/.exec(t), 323 | o = e ? this.getval(e) : ""; 324 | if (o) 325 | try { 326 | const t = JSON.parse(o); 327 | s = t ? this.lodash_get(t, i, "") : s; 328 | } catch (t) { 329 | s = ""; 330 | } 331 | } 332 | return s; 333 | } 334 | setdata(t, s) { 335 | let e = !1; 336 | if (/^@/.test(s)) { 337 | const [, i, o] = /^@(.*?)\.(.*?)$/.exec(s), 338 | h = this.getval(i), 339 | a = i ? ("null" === h ? null : h || "{}") : "{}"; 340 | try { 341 | const s = JSON.parse(a); 342 | this.lodash_set(s, o, t), (e = this.setval(JSON.stringify(s), i)); 343 | } catch (s) { 344 | const h = {}; 345 | this.lodash_set(h, o, t), (e = this.setval(JSON.stringify(h), i)); 346 | } 347 | } else e = this.setval(t, s); 348 | return e; 349 | } 350 | getval(t) { 351 | if (this.isSurge() || this.isLoon()) { 352 | return $persistentStore.read(t); 353 | } else if (this.isQuanX()) { 354 | return $prefs.valueForKey(t); 355 | } else if (this.isNode()) { 356 | this.data = this.loaddata(); 357 | return this.data[t]; 358 | } else { 359 | return this.data && this.data[t] || null; 360 | } 361 | } 362 | setval(t, s) { 363 | if (this.isSurge() || this.isLoon()) { 364 | return $persistentStore.write(t, s); 365 | } else if (this.isQuanX()) { 366 | return $prefs.setValueForKey(t, s); 367 | } else if (this.isNode()) { 368 | this.data = this.loaddata(); 369 | this.data[s] = t; 370 | this.writedata(); 371 | return true; 372 | } else { 373 | return this.data && this.data[s] || null; 374 | } 375 | } 376 | initGotEnv(t) { 377 | this.got = this.got ? this.got : require("got"); 378 | this.cktough = this.cktough ? this.cktough : require("tough-cookie"); 379 | this.ckjar = this.ckjar ? this.ckjar : new this.cktough.CookieJar(); 380 | if (t) { 381 | t.headers = t.headers ? t.headers : {}; 382 | if (typeof t.headers.Cookie === "undefined" && typeof t.cookieJar === "undefined") { 383 | t.cookieJar = this.ckjar; 384 | } 385 | } 386 | } 387 | /** 388 | * @param {Object} options 389 | * @returns {String} 将 Object 对象 转换成 queryStr: key=val&name=senku 390 | */ 391 | queryStr(options) { 392 | return Object.entries(options) 393 | .map(([key, value]) => `${key}=${typeof value === 'object' ? JSON.stringify(value) : value}`) 394 | .join('&'); 395 | } 396 | isJSONString(str) { 397 | try { 398 | var obj = JSON.parse(str); 399 | if (typeof obj == 'object' && obj) { 400 | return true; 401 | } else { 402 | return false; 403 | } 404 | } catch (e) { 405 | return false; 406 | } 407 | } 408 | isJson(obj) { 409 | var isjson = typeof (obj) == "object" && Object.prototype.toString.call(obj).toLowerCase() == "[object object]" && !obj.length; 410 | return isjson; 411 | } 412 | async sendMsg(message) { 413 | if (!message) return; 414 | if ($.isNode()) { 415 | await notify.sendNotify($.name, message) 416 | } else { 417 | $.msg($.name, '', message) 418 | } 419 | } 420 | async httpRequest(options) { 421 | let t = { 422 | ...options 423 | }; 424 | if (!t.headers) { 425 | t.headers = {} 426 | } 427 | if (t.params) { 428 | t.url += '?' + this.queryStr(t.params); 429 | } 430 | t.method = t.method.toLowerCase(); 431 | if (t.method === 'get') { 432 | delete t.headers['Content-Type']; 433 | delete t.headers['Content-Length']; 434 | delete t["body"] 435 | } 436 | if (t.method === 'post') { 437 | let contentType; 438 | 439 | if (!t.body) { 440 | t.body = "" 441 | } else { 442 | if (typeof t.body == "string") { 443 | if (this.isJSONString(t.body)) { 444 | contentType = 'application/json' 445 | } else { 446 | contentType = 'application/x-www-form-urlencoded' 447 | } 448 | } else if (this.isJson(t.body)) { 449 | t.body = JSON.stringify(t.body); 450 | contentType = 'application/json'; 451 | } 452 | } 453 | if (!t.headers['Content-Type']) { 454 | t.headers['Content-Type'] = contentType; 455 | } 456 | delete t.headers['Content-Length']; 457 | } 458 | if (this.isNode()) { 459 | this.initGotEnv(t); 460 | let httpResult = await this.got(t); 461 | if (this.isJSONString(httpResult.body)) { 462 | httpResult.body = JSON.parse(httpResult.body) 463 | } 464 | return httpResult; 465 | } 466 | if (this.isQuanX()) { 467 | t.method = t.method.toUpperCase() 468 | return new Promise((resolve, reject) => { 469 | $task.fetch(t).then(response => { 470 | if (this.isJSONString(response.body)) { 471 | response.body = JSON.parse(response.body) 472 | } 473 | resolve(response) 474 | }) 475 | }) 476 | } 477 | } 478 | randomNumber(length) { 479 | const characters = '0123456789'; 480 | return Array.from({ length }, () => characters[Math.floor(Math.random() * characters.length)]).join(''); 481 | } 482 | randomString(length) { 483 | const characters = 'abcdefghijklmnopqrstuvwxyz0123456789'; 484 | return Array.from({ length }, () => characters[Math.floor(Math.random() * characters.length)]).join(''); 485 | } 486 | timeStamp() { 487 | return new Date().getTime() 488 | } 489 | uuid() { 490 | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { 491 | var r = Math.random() * 16 | 0, 492 | v = c == 'x' ? r : (r & 0x3 | 0x8); 493 | return v.toString(16); 494 | }); 495 | } 496 | time(t) { 497 | let s = { 498 | "M+": new Date().getMonth() + 1, 499 | "d+": new Date().getDate(), 500 | "H+": new Date().getHours(), 501 | "m+": new Date().getMinutes(), 502 | "s+": new Date().getSeconds(), 503 | "q+": Math.floor((new Date().getMonth() + 3) / 3), 504 | S: new Date().getMilliseconds(), 505 | }; 506 | /(y+)/.test(t) && 507 | (t = t.replace( 508 | RegExp.$1, 509 | (new Date().getFullYear() + "").substr(4 - RegExp.$1.length) 510 | )); 511 | for (let e in s) 512 | new RegExp("(" + e + ")").test(t) && 513 | (t = t.replace( 514 | RegExp.$1, 515 | 1 == RegExp.$1.length 516 | ? s[e] 517 | : ("00" + s[e]).substr(("" + s[e]).length) 518 | )); 519 | return t; 520 | } 521 | msg(s = t, e = "", i = "", o) { 522 | const h = (t) => 523 | !t || (!this.isLoon() && this.isSurge()) 524 | ? t 525 | : "string" == typeof t 526 | ? this.isLoon() 527 | ? t 528 | : this.isQuanX() 529 | ? { "open-url": t } 530 | : void 0 531 | : "object" == typeof t && (t["open-url"] || t["media-url"]) 532 | ? this.isLoon() 533 | ? t["open-url"] 534 | : this.isQuanX() 535 | ? t 536 | : void 0 537 | : void 0; 538 | this.isMute || 539 | (this.isSurge() || this.isLoon() 540 | ? $notification.post(s, e, i, h(o)) 541 | : this.isQuanX() && $notify(s, e, i, h(o))); 542 | let logs = ['', '==============📣系统通知📣==============']; 543 | logs.push(t); 544 | e ? logs.push(e) : ''; 545 | i ? logs.push(i) : ''; 546 | console.log(logs.join('\n')); 547 | this.logs = this.logs.concat(logs); 548 | } 549 | log(...t) { 550 | t.length > 0 && (this.logs = [...this.logs, ...t]), 551 | console.log(t.join(this.logSeparator)); 552 | } 553 | logErr(t, s) { 554 | const e = !this.isSurge() && !this.isQuanX() && !this.isLoon(); 555 | e 556 | ? this.log("", `\u2757\ufe0f${this.name}, \u9519\u8bef!`, t.stack) 557 | : this.log("", `\u2757\ufe0f${this.name}, \u9519\u8bef!`, t); 558 | } 559 | wait(t) { 560 | return new Promise((s) => setTimeout(s, t)); 561 | } 562 | done(t = {}) { 563 | const s = new Date().getTime(), 564 | e = (s - this.startTime) / 1e3; 565 | this.log( 566 | "", 567 | `\ud83d\udd14${this.name}, \u7ed3\u675f! \ud83d\udd5b ${e} \u79d2` 568 | ) 569 | this.log() 570 | if (this.isNode()) { 571 | process.exit(1) 572 | } 573 | if (this.isQuanX()) { 574 | $done(t) 575 | } 576 | } 577 | })(t, s); 578 | } -------------------------------------------------------------------------------- /htmwg.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import datetime 3 | import os 4 | 5 | def Refresh(refreshToken): 6 | url = "https://cmallapi.haday.cn/buyer-api/passport/token" 7 | headers = { 8 | 'User-Agent': "Mozilla/5.0 (Linux; Android 12; RMX3562 Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/126.0.6478.187 Mobile Safari/537.36 XWEB/1260075 MMWEBSDK/20240501 MMWEBID/2307 MicroMessenger/8.0.50.2701(0x28003255) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android", 9 | 'Content-Type': "application/x-www-form-urlencoded", 10 | 'uuid': uuid, 11 | 'charset': "utf-8", 12 | 'Referer': "https://servicewechat.com/wx7a890ea13f50d7b6/612/page-frame.html" 13 | } 14 | data = { 15 | "refresh_token": refreshToken 16 | } 17 | response = requests.post(url, data=data, headers=headers) 18 | data = response.json() 19 | accessToken = data['accessToken'] 20 | return accessToken 21 | def sign(accessToken): 22 | url = "https://cmallapi.haday.cn/buyer-api/sign/activity/sign" 23 | headers = { 24 | 'User-Agent': "Mozilla/5.0 (Linux; Android 12; RMX3562 Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/126.0.6478.187 Mobile Safari/537.36 XWEB/1260075 MMWEBSDK/20240501 MMWEBID/2307 MicroMessenger/8.0.50.2701(0x28003255) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android", 25 | 'Content-Type': "application/json", 26 | 'uuid': uuid, 27 | 'envVersion': "release", 28 | 'Authorization': accessToken, 29 | 'charset': "utf-8", 30 | 'Referer': "https://servicewechat.com/wx7a890ea13f50d7b6/612/page-frame.html" 31 | } 32 | data = { 33 | "activity_code": datetime.datetime.now().strftime('%Y%m'), 34 | "fill_date": "" 35 | } 36 | response = requests.post(url, json=data, headers=headers) 37 | if response.status_code == 200: 38 | print("签到成功") 39 | else: 40 | print("已签到过无需再签到") 41 | 42 | if __name__ == "__main__": 43 | htmwg = os.environ.get('htmwg') 44 | if not htmwg: 45 | print("请设置环境变量 'htmwg' 后再运行") 46 | else: 47 | htmwg_list = htmwg.split('@') 48 | for num, htmwg_item in enumerate(htmwg_list, start=1): 49 | uuid, refreshToken = htmwg_item.split('&') 50 | print(f"=====开始执行第{num}个账号任务=====") 51 | accessToken = Refresh(refreshToken) 52 | if accessToken: 53 | print(f"获取刷新后的AccessToken:{accessToken}") 54 | result = sign(accessToken) -------------------------------------------------------------------------------- /ikuuu.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ========= 青龙 ========= 3 | * const $ = new Env("ikuuu机场"); 4 | * 这个机场个人认为挺好的 5 | * 账号#密码多号&隔开 6 | * 变量名ikuuu 7 | */ 8 | const _0x5d47f6=_0xf1fc;(function(_0x4bafaa,_0x38ecad){const _0x2a73a2=_0xf1fc,_0x1246bc=_0x4bafaa();while(!![]){try{const _0xea0eac=parseInt(_0x2a73a2(0x1c0))/0x1*(parseInt(_0x2a73a2(0x1ba))/0x2)+parseInt(_0x2a73a2(0x1d0))/0x3*(-parseInt(_0x2a73a2(0x1b0))/0x4)+-parseInt(_0x2a73a2(0x1bb))/0x5+-parseInt(_0x2a73a2(0x1da))/0x6+-parseInt(_0x2a73a2(0x1ae))/0x7*(parseInt(_0x2a73a2(0x1d8))/0x8)+-parseInt(_0x2a73a2(0x1be))/0x9+parseInt(_0x2a73a2(0x1cd))/0xa;if(_0xea0eac===_0x38ecad)break;else _0x1246bc['push'](_0x1246bc['shift']());}catch(_0x32fc91){_0x1246bc['push'](_0x1246bc['shift']());}}}(_0x2b75,0x67cf0));function _0xf1fc(_0x513d33,_0x2d0f8c){const _0x2b7549=_0x2b75();return _0xf1fc=function(_0xf1fc28,_0x586c61){_0xf1fc28=_0xf1fc28-0x1ae;let _0x1f0c18=_0x2b7549[_0xf1fc28];return _0x1f0c18;},_0xf1fc(_0x513d33,_0x2d0f8c);}const axios=require('axios'),cheerio=require(_0x5d47f6(0x1c5));function load_ikuuu(){const _0x7f3355=_0x5d47f6;console[_0x7f3355(0x1d5)](_0x7f3355(0x1c3));}function get_environment_variable(_0x30f48f,_0x4fc4fa='',_0x2e63ce=!![]){const _0x1b8d59=_0x5d47f6;function _0x728ce9(){const _0x33d50e=_0xf1fc;return _0x2e63ce&&(console[_0x33d50e(0x1d5)](_0x33d50e(0x1d7)+_0x30f48f+_0x33d50e(0x1ce)),process[_0x33d50e(0x1ca)](0x0)),_0x4fc4fa;}return process[_0x1b8d59(0x1b4)][_0x30f48f]?process[_0x1b8d59(0x1b4)][_0x30f48f]:_0x728ce9();}class ikuuu{constructor(_0x3c795d){const _0x4cbf69=_0x5d47f6;this['msg']='',this['ck']=_0x3c795d,this[_0x4cbf69(0x1d1)]='';}async[_0x5d47f6(0x1bd)](){const _0x22eefe=_0x5d47f6;await new Promise(_0x1f9677=>setTimeout(_0x1f9677,0x1f4));const _0x2a44b5=_0x22eefe(0x1cf),_0x433ac2=_0x22eefe(0x1b9),_0x1d64dd=_0x22eefe(0x1d3),_0x3c5974={'User-Agent':_0x22eefe(0x1b1)},_0x43df6a={'email':this['ck'][0x0],'passwd':this['ck'][0x1]},_0xb8ede0=await axios[_0x22eefe(0x1d6)](_0x1d64dd,_0x43df6a,{'headers':_0x3c5974}),_0x2f9d1d=_0xb8ede0[_0x22eefe(0x1d2)][_0x22eefe(0x1d4)];_0x2f9d1d['forEach'](_0x1eb59b=>{const _0x490f6a=_0x22eefe,_0x409f12=_0x1eb59b['split'](';')[0x0]['split']('='),_0x2d0477=_0x409f12[0x0],_0x3aef33=_0x409f12[0x1],_0xc9212a=_0x2d0477+'='+_0x3aef33;this[_0x490f6a(0x1d1)]+=_0xc9212a+';';});const _0x3688d5={'Cookie':this[_0x22eefe(0x1d1)],'sec-ch-ua':_0x22eefe(0x1c6)};await new Promise(_0x2e6dbc=>setTimeout(_0x2e6dbc,0x1f4));const _0x4f0e01=await axios[_0x22eefe(0x1d6)](_0x2a44b5,{},{'headers':_0x3688d5});await new Promise(_0x234753=>setTimeout(_0x234753,0x1f4));const _0x105050=await axios[_0x22eefe(0x1c8)](_0x433ac2,{'headers':_0x3688d5});try{const _0x5e6e90=cheerio[_0x22eefe(0x1c4)](_0x105050[_0x22eefe(0x1b3)]),_0x53197e=_0x5e6e90('.counter')['text'](),_0x19af93=_0x5e6e90(_0x22eefe(0x1bc))[_0x22eefe(0x1b7)](),_0x4f6007=_0x22eefe(0x1c1)+_0x19af93+_0x22eefe(0x1cc)+_0x4f0e01['data']['msg']+_0x22eefe(0x1c9)+_0x53197e+_0x22eefe(0x1bf);return this[_0x22eefe(0x1b6)]+=_0x4f6007,this['msg'];}catch(_0x46cf31){const _0x181311=_0x22eefe(0x1cb)+this['ck']+'\x0a\x0a';return this['msg']+=_0x181311,this[_0x22eefe(0x1b6)];}}[_0x5d47f6(0x1b2)](){return this['sign']();}}async function main(){const _0x5c92d9=_0x5d47f6,_0x1e0d2d=get_environment_variable(_0x5c92d9(0x1af));let _0x299e86='';const _0x54fba=_0x1e0d2d['split']('&');console[_0x5c92d9(0x1d5)](_0x5c92d9(0x1c7)+_0x54fba['length']+_0x5c92d9(0x1c2));const _0x16ff5b=_0x54fba['map'](async _0x46b7c2=>{const _0x23b6e7=_0x5c92d9,_0x10c1a0=_0x46b7c2[_0x23b6e7(0x1b5)]('#'),_0x5a63ea=new ikuuu(_0x10c1a0);return await _0x5a63ea[_0x23b6e7(0x1b2)]();}),_0x576a04=await Promise[_0x5c92d9(0x1d9)](_0x16ff5b);_0x299e86=_0x576a04[_0x5c92d9(0x1b8)](''),console['log'](_0x299e86);}load_ikuuu(),main();function _0x2b75(){const _0x310671=['[登录]:','个ck记录,开始ikuuu签到\x0a','加载ikuuu签到服务成功!','load','cheerio','\x22Microsoft\x20Edge\x22;v=\x22111\x22,\x20\x22Not(A:Brand\x22;v=\x228\x22,\x20\x22Chromium\x22;v=\x22111\x22','检测到','get','\x0a[流量]:','exit','[登录]:解析响应失败,请检查网络或者ck有效性:','\x0a[签到]:','27044230ozwHhh',',请添加','https://ikuuu.me/user/checkin','6kBijrT','cks','headers','https://ikuuu.me/auth/login','set-cookie','log','post','未设置环境变量\x20','923368gTnuWq','all','5066790VkpfjQ','7XntSzx','ikuuu','1615292WdjNCt','Mozilla/5.0\x20(Windows\x20NT\x2010.0;\x20Win64;\x20x64)\x20AppleWebKit/537.36\x20(KHTML,\x20like\x20Gecko)\x20Chrome/58.0.3029.110\x20Safari/537.3','get_sign_msg','data','env','split','msg','text','join','https://ikuuu.me/user','27688FyAzIg','3267305eilUnr','.d-sm-none.d-lg-inline-block','sign','4580082YwQBFj','GB\x0a\x0a','47qFyaqB'];_0x2b75=function(){return _0x310671;};return _0x2b75();} -------------------------------------------------------------------------------- /itzj.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 太久没更新了随机更新一个年终奖吧物品少看情况挂 3 | 抓任意URL的userHash只要Bearer后面的数据即可 4 | new Env('IT之家');''' 5 | import requests 6 | import os 7 | class ITZJ(): 8 | def __init__(self, token): 9 | self.token = token 10 | def sign(self): 11 | url = f"https://napi.ithome.com/api/UserSign/WeChatSign?userHash=Bearer {self.token}&coinHistoryType=157"#此处为请求的URL 12 | headers = { 13 | 'User-Agent': "Mozilla/5.0 (Linux; Android 12; RMX3562 Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/126.0.6478.188 Mobile Safari/537.36 XWEB/1260213 MMWEBSDK/20240802 MMWEBID/2307 MicroMessenger/8.0.53.2740(0x2800353E) WeChat/arm64 Weixin NetType/5G Language/zh_CN ABI/arm64 miniProgram/wx8869812e2ddf7133", 14 | 'sec-ch-ua-platform': "\"Android\"" 15 | } 16 | response = requests.get(url, headers=headers) 17 | print(response.text) 18 | if __name__ == "__main__": 19 | tokens = os.environ.get('itzj') 20 | if not tokens: 21 | print("请设置变量名"itzj") 22 | else: 23 | tokens_list = tokens.split('@') 24 | for index, token in enumerate(tokens_list, start=1): 25 | print(f"=====开始执行第{index}个账号任务=====") 26 | it = ITZJ(token) 27 | it.sign() -------------------------------------------------------------------------------- /jdd.py: -------------------------------------------------------------------------------- 1 | ''' 2 | new Env('金杜丹小程序'); 3 | 变量名字JDD抓tianxin.jmd724.com域名下的access_token多号@ 4 | ''' 5 | 6 | import requests 7 | import os 8 | class AC: 9 | def __init__(self, token): 10 | self.token = token 11 | self.headers = { 12 | 'User-Agent': "Mozilla/5.0 (Linux; Android 12; RMX3562 Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/126.0.6478.122 Mobile Safari/537.36 XWEB/1260059 MMWEBSDK/20240501 MMWEBID/2307 MicroMessenger/8.0.50.2701(0x28003253) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android" 13 | } 14 | self.article_ids = self.fetch_ids() # 初始化时获取文章 IDs 15 | self.video_ids = self.fetch_video_ids() # 初始化视频 ID 16 | def sign(self): 17 | url = f"https://tianxin.jmd724.com/index.php?r=client/v1/task/sign-up&access_token={self.token}" 18 | response = requests.get(url, headers=self.headers) 19 | response_data = response.json() 20 | if response_data['code'] == 0: 21 | gold_num = response_data["data"]["gold_num"] 22 | msg = response_data["msg"] 23 | print(f"{msg} 获得 {gold_num} 金币") 24 | else: 25 | msg = response_data["msg"] 26 | print(msg) 27 | def fetch_ids(self): 28 | url = "https://tianxin.jmd724.com/index.php?r=client/v1/article/list" 29 | response = requests.get(url, headers=self.headers) 30 | response_data = response.json() 31 | ids = [] 32 | for item in response_data.get("data", {}).get("list", [])[:5]: 33 | article_id = item.get("id") 34 | ids.append(article_id) 35 | return ids 36 | 37 | def fetch_video_ids(self): 38 | url = "https://tianxin.jmd724.com/index.php?store_id=1&r=client/v1/article/list&pageSize=10&article_type=2" 39 | response = requests.get(url, headers=self.headers) 40 | response_data = response.json() 41 | ids = [] 42 | for item in response_data.get("data", {}).get("list", [])[:5]: 43 | article_id = item.get("id") 44 | ids.append(article_id) 45 | return ids 46 | def red(self): 47 | for article_id in self.article_ids: 48 | url = f"https://tianxin.jmd724.com/index.php?r=client/v1/article/detail&article_id={article_id}&access_token={self.token}" 49 | response = requests.get(url, headers=self.headers) 50 | response_data = response.json() 51 | if response_data['code'] == 0: 52 | print(f"开始阅读文章编号{article_id}") 53 | else: 54 | msg = response_data["msg"] 55 | print(msg) 56 | def gold(self): 57 | for article_id in self.article_ids: 58 | url = "https://tianxin.jmd724.com/index.php?r=client/v1/article/read-gold" 59 | data = { 60 | 'article_id': article_id, 61 | 'access_token': self.token 62 | } 63 | response = requests.post(url, headers=self.headers, data=data) 64 | response_data = response.json() 65 | if response_data['code'] == 0: 66 | print(f"成功获取文章编号{article_id} 的金币奖励") 67 | else: 68 | msg = response_data["msg"] 69 | print(msg) 70 | def Videoviewing(self): 71 | for video_ids in self.video_ids: 72 | url = f"https://tianxin.jmd724.com/index.php?r=client/v1/article/detail&article_id={video_ids}&access_token={self.token}" 73 | response = requests.get(url, headers=self.headers) 74 | response_data = response.json() 75 | if response_data['code'] == 0: 76 | print(f"开始观看视频编号{video_ids}") 77 | else: 78 | msg = response_data["msg"] 79 | print(msg) 80 | def VideoRewards(self): 81 | for video_ids in self.video_ids: 82 | url = "https://tianxin.jmd724.com/index.php?r=client/v1/article/read-gold" 83 | data = { 84 | 'article_id': video_ids, 85 | 'access_token': self.token 86 | } 87 | response = requests.post(url, headers=self.headers, data=data) 88 | response_data = response.json() 89 | if response_data['code'] == 0: 90 | print(f"成功获取视频编号{video_ids} 的金币奖励") 91 | else: 92 | msg = response_data["msg"] 93 | print(msg) 94 | if __name__ == "__main__": 95 | tokens = os.environ.get('JDD') 96 | if not tokens: 97 | print("获取账号失败,请检查配置是否正确") 98 | else: 99 | tokens_list = tokens.split('@') 100 | for index, token in enumerate(tokens_list, start=1): 101 | print(f"=====开始执行第{index}个账号任务=====") 102 | ac = AC(token) 103 | ac.sign() 104 | ac.red() 105 | ac.gold() 106 | ac.Videoviewing() 107 | ac.VideoRewards() 108 | -------------------------------------------------------------------------------- /jlzx.py: -------------------------------------------------------------------------------- 1 | ''' 2 | new Env('江铃智行'); 3 | ''' 4 | import requests 5 | import os 6 | def signIn(token): 7 | url = "https://superapp.jmc.com.cn/jmc-zx-app-owner/v1/signIn/add" 8 | headers = { 9 | "Host": "superapp.jmc.com.cn", 10 | "Content-Length": "33", 11 | "Access-Token": token, 12 | "Content-Type": "application/json" 13 | } 14 | data = { 15 | "activityCode": "HD202401010007" 16 | } 17 | response = requests.post(url, headers=headers, json=data) 18 | json_data = response.json() 19 | msg = json_data["resultMsg"] 20 | print(f"签到结果:{msg}") 21 | if __name__ == "__main__": 22 | tokens = os.environ.get('jlzx') 23 | if not tokens: 24 | print("获取账号失败,检查是否配置正确") 25 | else: 26 | tokens_list = tokens.split('@') 27 | num = len(tokens_list) 28 | for num, token in enumerate(tokens_list, start=1): 29 | print(f"=====开始执行第{num}个账号任务=====") 30 | signIn(token) 31 | print("==============================") -------------------------------------------------------------------------------- /kghw.py: -------------------------------------------------------------------------------- 1 | import os 2 | import requests 3 | 4 | class AC: 5 | def __init__(self, appid, openid, refresh_token): 6 | self.headers = { 7 | 'User-Agent': "Mozilla/5.0 (Linux; Android 12; RMX3562 Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/126.0.6478.122 Mobile Safari/537.36 XWEB/1260059 MMWEBSDK/20240501 MMWEBID/2307 MicroMessenger/8.0.50.2701(0x28003252) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android", 8 | 'Content-Type': "application/json" 9 | } 10 | self.data = { 11 | "appid": appid, 12 | "openid": openid, 13 | "refresh_token": refresh_token 14 | } 15 | 16 | def login(self): 17 | url = "https://www.kugua.com/wxapp/refreshToken" 18 | response = requests.post(url, headers=self.headers, json=self.data) 19 | data = response.json() 20 | if data['status'] == "0000": 21 | token = data["data"]["token"] 22 | print(f"最新token为:{token}") 23 | return token 24 | else: 25 | codemsg = data["codemsg"] 26 | print(f"{codemsg}") 27 | return None 28 | 29 | def withdrawal(self, token, withdrawal_id): 30 | url = "https://www.kugua.com/wxapp/withdrawal/withdrawal" 31 | data = { 32 | "token": token, 33 | "withdrawalId": withdrawal_id, 34 | "appid": self.data["appid"], 35 | "openid": self.data["openid"] 36 | } 37 | response = requests.post(url, headers=self.headers, json=data) 38 | data = response.json() 39 | if data['status'] == "0000": 40 | codemsg = data["codemsg"] 41 | print(f"提现结果为{codemsg}") 42 | else: 43 | codemsg = data["codemsg"] 44 | print(f"{codemsg}") 45 | 46 | def main(self): 47 | token = self.login() 48 | if token: 49 | withdrawal_id = 8 # 提现ID 50 | self.withdrawal(token, withdrawal_id) 51 | 52 | if __name__ == '__main__': 53 | kghw = os.environ.get('kghw') 54 | if not kghw: 55 | print("请设置环境变量 'kghw' 后再运行") 56 | else: 57 | kghw_list = kghw.split('@') 58 | for num, kghw_item in enumerate(kghw_list, start=1): 59 | appid, openid, refreshToken = kghw_item.split('&') 60 | print(f"=====开始执行第{num}个账号任务=====") 61 | ac = AC(appid, openid, refreshToken) 62 | ac.main() 63 | -------------------------------------------------------------------------------- /lccd.py: -------------------------------------------------------------------------------- 1 | ''' 2 | BY:YourAhTzu 3 | 完成日期:12.31 下午13:21 4 | new Env('莱充充电'); 5 | 一天一次抓authorization的JWT后面数据填入lccd变量 6 | ''' 7 | import os 8 | import requests 9 | def main(): 10 | authorization = os.environ.get('lccd') 11 | numbers = authorization.split('@') 12 | for number in numbers: 13 | print(f">>>>开始执行莱充充电任务<<<<<") 14 | userinfo(number) 15 | signComplete(number) 16 | pointsDouble(number) 17 | taskComplete(number) 18 | def userinfo(number): 19 | print(f">>>>用户查询<<<<<") 20 | url = 'https://shop.laichon.com/api/v1/member/userinfo' 21 | headers = { 22 | 'Host': 'shop.laichon.com', 23 | 'Connection': 'keep-alive', 24 | 'authorization': f'JWT {number}', 25 | 'charset': 'utf-8', 26 | 'service-code': 'WYC-MI-WEIXIN', 27 | 'User-Agent': 'Mozilla/5.0 (Linux; Android 12; RMX3562 Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Mobile Safari/537.36 XWEB/1160027 MMWEBSDK/20231105 MMWEBID/2307 MicroMessenger/8.0.44.2502(0x28002CCA) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android', 28 | 'content-type': 'application/x-www-form-urlencoded', 29 | 'Accept-Encoding': 'gzip,compress,br,deflate', 30 | 'Referer': 'https://servicewechat.com/wxa68db1dabe823e7e/316/page-frame.html' 31 | } 32 | data = {} 33 | response = requests.get(url, headers=headers, data=data) 34 | json_response = response.json() 35 | mobile = json_response['data']['mobile'] 36 | points = json_response['data']['points'] 37 | print(f"用户:{mobile}", f"当前积分:{points}") 38 | def signComplete(number): 39 | print(f">>>>开始执行签到<<<<<") 40 | url = 'https://shop.laichon.com/api/v1/task/signComplete' 41 | headers = { 42 | 'Host': 'shop.laichon.com', 43 | 'Connection': 'keep-alive', 44 | 'authorization': f'JWT {number}', 45 | 'charset': 'utf-8', 46 | 'service-code': 'WYC-MI-WEIXIN', 47 | 'User-Agent': 'Mozilla/5.0 (Linux; Android 12; RMX3562 Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Mobile Safari/537.36 XWEB/1160027 MMWEBSDK/20231105 MMWEBID/2307 MicroMessenger/8.0.44.2502(0x28002CCA) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android', 48 | 'content-type': 'application/x-www-form-urlencoded', 49 | 'Accept-Encoding': 'gzip,compress,br,deflate', 50 | 'Referer': 'https://servicewechat.com/wxa68db1dabe823e7e/316/page-frame.html' 51 | } 52 | data = {} 53 | response = requests.get(url, headers=headers, data=data) 54 | json_response = response.json() 55 | msg = json_response.get('msg') 56 | print(f"签到结果:{msg}") 57 | def pointsDouble(number): 58 | print(f">>>>开始执行签到翻倍<<<<<") 59 | url = 'https://shop.laichon.com/api/v1/task/pointsDouble' 60 | headers = { 61 | 'Host': 'shop.laichon.com', 62 | 'Connection': 'keep-alive', 63 | 'authorization': f'JWT {number}', 64 | 'charset': 'utf-8', 65 | 'service-code': 'WYC-MI-WEIXIN', 66 | 'User-Agent': 'Mozilla/5.0 (Linux; Android 12; RMX3562 Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Mobile Safari/537.36 XWEB/1160027 MMWEBSDK/20231105 MMWEBID/2307 MicroMessenger/8.0.44.2502(0x28002CCA) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android', 67 | 'content-type': 'application/x-www-form-urlencoded', 68 | 'Accept-Encoding': 'gzip,compress,br,deflate', 69 | 'Referer': 'https://servicewechat.com/wxa68db1dabe823e7e/316/page-frame.html' 70 | } 71 | data = {} 72 | response = requests.get(url, headers=headers, data=data) 73 | json_response = response.json() 74 | msg = json_response.get('msg') 75 | print(f"签到翻倍结果:{msg}") 76 | def taskComplete(number): 77 | print(f">>>>开始执行看广告<<<<<") 78 | url = 'https://shop.laichon.com/api/v1/task/taskComplete' 79 | headers = { 80 | 'Host': 'shop.laichon.com', 81 | 'Connection': 'keep-alive', 82 | 'authorization': f'JWT {number}', 83 | 'charset': 'utf-8', 84 | 'service-code': 'WYC-MI-WEIXIN', 85 | 'User-Agent': 'Mozilla/5.0 (Linux; Android 12; RMX3562 Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Mobile Safari/537.36 XWEB/1160027 MMWEBSDK/20231105 MMWEBID/2307 MicroMessenger/8.0.44.2502(0x28002CCA) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android', 86 | 'content-type': 'application/x-www-form-urlencoded', 87 | 'Accept-Encoding': 'gzip,compress,br,deflate', 88 | 'Referer': 'https://servicewechat.com/wxa68db1dabe823e7e/316/page-frame.html' 89 | } 90 | data = { 91 | 'task_id': 4 92 | } 93 | response = requests.post(url, headers=headers, data=data) 94 | json_response = response.json() 95 | msg = json_response.get('msg') 96 | print(f"看广告结果:{msg}") 97 | if __name__ == '__main__': 98 | main() -------------------------------------------------------------------------------- /lhcm.py: -------------------------------------------------------------------------------- 1 | ''' 2 | new Env('灵魂触摸'); 3 | 注册入口:https://www.bai6du.com/shareGameServlet/shareregister/linghunchumo/zouluzhuanqian.html?masterId=175244 4 | 抓account填入变量lhcm多号@隔开 (禁止改邀请不然关闭脚本) 5 | ''' 6 | import bz2, base64 7 | exec(bz2.decompress(base64.b64decode('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'))) -------------------------------------------------------------------------------- /ljgy.py: -------------------------------------------------------------------------------- 1 | ''' 2 | new Env('丽瑾国韵'); 3 | 账号&密码 多账号换行或者@分隔 4 | ''' 5 | import requests 6 | import os 7 | from os import path 8 | import sys 9 | headers = { 10 | 'User-Agent': "Mozilla/5.0 (Linux; Android 12; RMX3562 Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/122.0.6261.120 Mobile Safari/537.36 XWEB/1220099 MMWEBSDK/20240404 MMWEBID/2307 MicroMessenger/8.0.49.2600(0x28003133) WeChat/arm64 Weixin NetType/5G Language/zh_CN ABI/arm64", 11 | 'Accept': "application/json, text/plain, */*", 12 | 'sec-ch-ua': "\"Chromium\";v=\"122\", \"Not(A:Brand\";v=\"24\", \"Android WebView\";v=\"122\"", 13 | } 14 | def login(username, password): 15 | url = "https://wep.qzlcis.com/api/index/login" 16 | data = { 17 | "username": username, 18 | "password": password, 19 | "token": None 20 | } 21 | response = requests.post(url, json=data, headers=headers) 22 | json_data = response.json() 23 | if json_data.get("code") == 1: 24 | token = json_data["data"]["token"] 25 | info = json_data["info"] 26 | print(f"登录成功: {info}") 27 | return token 28 | else: 29 | print(f"登录失败: {json_data.get('info')}") 30 | return None 31 | def sign(token): 32 | url = "https://wep.qzlcis.com/api/user/sign" 33 | data = {"token": token} 34 | response = requests.post(url, json=data, headers=headers) 35 | json_data = response.json() 36 | code = json_data.get("code") 37 | info = json_data.get("info") 38 | if code == 1: 39 | reward_num = json_data["data"].get("reward_num", "未知") 40 | print(f"签到成功: {info}, 奖励数量: {reward_num}") 41 | else: 42 | print(f"签到失败: {info}") 43 | def info(token): 44 | url = "https://wep.qzlcis.com/api/user/info" 45 | data = {"token": token} 46 | response = requests.post(url, json=data, headers=headers) 47 | json_data = response.json() 48 | code = json_data.get("code") 49 | info = json_data.get("info") 50 | if code == 1: 51 | mobile = json_data["data"]["mobile"] 52 | money = json_data["data"]["money"] 53 | print(f"账户{mobile}余额为{money}") 54 | else: 55 | print(f"获取账户信息失败: {info}") 56 | if __name__ == "__main__": 57 | ljgy = os.environ.get('ljgy') 58 | if not ljgy: 59 | print("请设置环境变量在运行") 60 | else: 61 | ljgy_list = ljgy.split('@') 62 | for num, ljgy_item in enumerate(ljgy_list, start=1): 63 | username, password = ljgy_item.split('&') 64 | print(f"=====开始执行第{num}个账号任务=====") 65 | print("---------开始执行账号登录") 66 | token = login(username, password) 67 | if token: 68 | print("---------开始执行签到任务---------") 69 | sign(token) 70 | print("---------开始执行获取账户信息任务---------") 71 | info(token) -------------------------------------------------------------------------------- /nbb.js: -------------------------------------------------------------------------------- 1 | /* 2 | 微信小程序:农耙耙 3 | 更新时间:2023-3-20 4 | 先去小程序注册账号密码,然后把账号密码填到nbb变量 5 | 变量 export nbb='手机号&密码' 多个账号使用@隔开 6 | */ 7 | const $ = new Env('农耙耙'); 8 | const axios = require("axios"); 9 | 10 | let nbb = (($.isNode() ? process.env.nbb : $.getdata('nbb')) || '').split('@'); 11 | let tel = ''; //账号 12 | let pwd= ''; //密码 13 | let ck=''; //cookie 14 | let videoList=""; //视频列表 15 | let videoId=""; //视频id 16 | let score=""; //积分 17 | !(async () => 18 | { 19 | console.log(`\n============ 微信小程序:柠檬玩机 ============`) 20 | console.log(`\n=================== 共找到 ${nbb.length} 个账号 ===================`) 21 | for (let i = 0; i < nbb.length; i++) { 22 | console.log(`\n==== 开始【第 ${[i+1]} 个账号】====\n`); 23 | tel=nbb[i].split('&')[0]; 24 | pwd=nbb[i].split('&')[1]; 25 | await refreshToken(); //获取token 26 | await $.wait(2000); 27 | await sign(); //签到 28 | await getVideoList() 29 | for (let j = 0; j < videoList.length; j++) { 30 | console.log(`\n==== 开始观看【第 ${[j+1]} 个视频】====\n`); 31 | videoId=videoList[j].id; 32 | await watchVideo(); //观看视频 33 | await $.wait(15000); 34 | } 35 | await getVideoList(); 36 | console.log(`\n==== 当前有${score}积分====\n`); 37 | console.log(`\n`); 38 | 39 | } 40 | $.done(); 41 | } 42 | )() 43 | 44 | 45 | // 获取cookie 46 | function refreshToken() { 47 | return new Promise((resolve, reject) => { 48 | axios({ 49 | method: 'post', 50 | url: `https://sc.gdzfxc.com/?s=/ApiIndex/loginsub&aid=1&platform=wx&pid=0`, 51 | headers:{ 52 | 'User-Agent': 'Mozilla/5.0 (Linux; Android 13; PHB110 Build/TP1A.220905.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/111.0.5563.116 Mobile Safari/537.36 XWEB/5089 MMWEBSDK/20230405 MMWEBID/5281 MicroMessenger/8.0.35.2360(0x280023EE) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android' 53 | 54 | }, 55 | data: { 56 | "tel": `${tel}`, 57 | "pwd": `${pwd}`, 58 | "logintype":1, 59 | "pid":0 60 | } 61 | }).then(res => { 62 | if(res.data.status=="1"){ 63 | ck=res.data.session_id; 64 | resolve() 65 | } 66 | }) 67 | }) 68 | } 69 | 70 | // 签到 71 | function sign() { 72 | return new Promise((resolve, reject) => { 73 | axios({ 74 | method: "post", 75 | url: `https://sc.gdzfxc.com/?s=/ApiSign/signin&aid=1&platform=wx&session_id=${ck}&pid=0`, 76 | headers:{ 77 | 'User-Agent': 'Mozilla/5.0 (Linux; Android 13; PHB110 Build/TP1A.220905.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/111.0.5563.116 Mobile Safari/537.36 XWEB/5089 MMWEBSDK/20230405 MMWEBID/5281 MicroMessenger/8.0.35.2360(0x280023EE) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android' 78 | 79 | }, 80 | }).then(res => { 81 | console.log(res.data.msg); 82 | resolve() 83 | }) 84 | }) 85 | } 86 | 87 | // 获取视频列表 88 | function getVideoList() { 89 | return new Promise((resolve, reject) => { 90 | axios({ 91 | method: "post", 92 | url: `https://sc.gdzfxc.com/?s=/ApiSign/index&aid=1&platform=wx&session_id=${ck}&pid=0`, 93 | headers:{ 94 | 'User-Agent': 'Mozilla/5.0 (Linux; Android 13; PHB110 Build/TP1A.220905.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/111.0.5563.116 Mobile Safari/537.36 XWEB/5089 MMWEBSDK/20230405 MMWEBID/5281 MicroMessenger/8.0.35.2360(0x280023EE) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android' 95 | 96 | }, 97 | }).then(res => { 98 | videoList=res.data.video_renwu; 99 | score=res.data.userinfo.score; 100 | resolve() 101 | }) 102 | }) 103 | } 104 | 105 | // 观看视频 106 | function watchVideo() { 107 | return new Promise((resolve, reject) => { 108 | axios({ 109 | method: "post", 110 | url: `https://sc.gdzfxc.com/?s=/ApiSign/videoRenwu&aid=1&platform=wx&session_id=${ck}&pid=0`, 111 | headers:{ 112 | 'User-Agent': 'Mozilla/5.0 (Linux; Android 13; PHB110 Build/TP1A.220905.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/111.0.5563.116 Mobile Safari/537.36 XWEB/5089 MMWEBSDK/20230405 MMWEBID/5281 MicroMessenger/8.0.35.2360(0x280023EE) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android' 113 | 114 | }, 115 | data: { 116 | "renwu_id": `${videoId}`, 117 | } 118 | }).then(res => { 119 | console.log(res.data.msg); 120 | resolve() 121 | }) 122 | }) 123 | } 124 | 125 | 126 | function Env(t, e) { 127 | "undefined" != typeof process && JSON.stringify(process.env).indexOf("GITHUB") > -1 && process.exit(0); 128 | 129 | class s { 130 | constructor(t) { 131 | this.env = t 132 | } 133 | 134 | send(t, e = "GET") { 135 | t = "string" == typeof t ? {url: t} : t; 136 | let s = this.get; 137 | return "POST" === e && (s = this.post), new Promise((e, i) => { 138 | s.call(this, t, (t, s, r) => { 139 | t ? i(t) : e(s) 140 | }) 141 | }) 142 | } 143 | 144 | get(t) { 145 | return this.send.call(this.env, t) 146 | } 147 | 148 | post(t) { 149 | return this.send.call(this.env, t, "POST") 150 | } 151 | } 152 | 153 | return new class { 154 | constructor(t, e) { 155 | 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}, 开始!`) 156 | } 157 | 158 | isNode() { 159 | return "undefined" != typeof module && !!module.exports 160 | } 161 | 162 | isQuanX() { 163 | return "undefined" != typeof $task 164 | } 165 | 166 | isSurge() { 167 | return "undefined" != typeof $httpClient && "undefined" == typeof $loon 168 | } 169 | 170 | isLoon() { 171 | return "undefined" != typeof $loon 172 | } 173 | 174 | toObj(t, e = null) { 175 | try { 176 | return JSON.parse(t) 177 | } catch { 178 | return e 179 | } 180 | } 181 | 182 | toStr(t, e = null) { 183 | try { 184 | return JSON.stringify(t) 185 | } catch { 186 | return e 187 | } 188 | } 189 | 190 | getjson(t, e) { 191 | let s = e; 192 | const i = this.getdata(t); 193 | if (i) try { 194 | s = JSON.parse(this.getdata(t)) 195 | } catch { 196 | } 197 | return s 198 | } 199 | 200 | setjson(t, e) { 201 | try { 202 | return this.setdata(JSON.stringify(t), e) 203 | } catch { 204 | return !1 205 | } 206 | } 207 | 208 | getScript(t) { 209 | return new Promise(e => { 210 | this.get({url: t}, (t, s, i) => e(i)) 211 | }) 212 | } 213 | 214 | runScript(t, e) { 215 | return new Promise(s => { 216 | let i = this.getdata("@chavy_boxjs_userCfgs.httpapi"); 217 | i = i ? i.replace(/\n/g, "").trim() : i; 218 | let r = this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout"); 219 | r = r ? 1 * r : 20, r = e && e.timeout ? e.timeout : r; 220 | const [o, h] = i.split("@"), n = { 221 | url: `http://${h}/v1/scripting/evaluate`, 222 | body: {script_text: t, mock_type: "cron", timeout: r}, 223 | headers: {"X-Key": o, Accept: "*/*"} 224 | }; 225 | this.post(n, (t, e, i) => s(i)) 226 | }).catch(t => this.logErr(t)) 227 | } 228 | 229 | loaddata() { 230 | if (!this.isNode()) return {}; 231 | { 232 | this.fs = this.fs ? this.fs : require("fs"), this.path = this.path ? this.path : require("path"); 233 | const t = this.path.resolve(this.dataFile), e = this.path.resolve(process.cwd(), this.dataFile), 234 | s = this.fs.existsSync(t), i = !s && this.fs.existsSync(e); 235 | if (!s && !i) return {}; 236 | { 237 | const i = s ? t : e; 238 | try { 239 | return JSON.parse(this.fs.readFileSync(i)) 240 | } catch (t) { 241 | return {} 242 | } 243 | } 244 | } 245 | } 246 | 247 | writedata() { 248 | if (this.isNode()) { 249 | this.fs = this.fs ? this.fs : require("fs"), this.path = this.path ? this.path : require("path"); 250 | const t = this.path.resolve(this.dataFile), e = this.path.resolve(process.cwd(), this.dataFile), 251 | s = this.fs.existsSync(t), i = !s && this.fs.existsSync(e), r = JSON.stringify(this.data); 252 | s ? this.fs.writeFileSync(t, r) : i ? this.fs.writeFileSync(e, r) : this.fs.writeFileSync(t, r) 253 | } 254 | } 255 | 256 | lodash_get(t, e, s) { 257 | const i = e.replace(/\[(\d+)\]/g, ".$1").split("."); 258 | let r = t; 259 | for (const t of i) if (r = Object(r)[t], void 0 === r) return s; 260 | return r 261 | } 262 | 263 | lodash_set(t, e, s) { 264 | 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) 265 | } 266 | 267 | getdata(t) { 268 | let e = this.getval(t); 269 | if (/^@/.test(t)) { 270 | const [, s, i] = /^@(.*?)\.(.*?)$/.exec(t), r = s ? this.getval(s) : ""; 271 | if (r) try { 272 | const t = JSON.parse(r); 273 | e = t ? this.lodash_get(t, i, "") : e 274 | } catch (t) { 275 | e = "" 276 | } 277 | } 278 | return e 279 | } 280 | 281 | setdata(t, e) { 282 | let s = !1; 283 | if (/^@/.test(e)) { 284 | const [, i, r] = /^@(.*?)\.(.*?)$/.exec(e), o = this.getval(i), 285 | h = i ? "null" === o ? null : o || "{}" : "{}"; 286 | try { 287 | const e = JSON.parse(h); 288 | this.lodash_set(e, r, t), s = this.setval(JSON.stringify(e), i) 289 | } catch (e) { 290 | const o = {}; 291 | this.lodash_set(o, r, t), s = this.setval(JSON.stringify(o), i) 292 | } 293 | } else s = this.setval(t, e); 294 | return s 295 | } 296 | 297 | getval(t) { 298 | 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 299 | } 300 | 301 | setval(t, e) { 302 | 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 303 | } 304 | 305 | initGotEnv(t) { 306 | 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)) 307 | } 308 | 309 | get(t, e = (() => { 310 | })) { 311 | 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) => { 312 | !t && s && (s.body = i, s.statusCode = s.status), e(t, s, i) 313 | })) : this.isQuanX() ? (this.isNeedRewrite && (t.opts = t.opts || {}, Object.assign(t.opts, {hints: !1})), $task.fetch(t).then(t => { 314 | const {statusCode: s, statusCode: i, headers: r, body: o} = t; 315 | e(null, {status: s, statusCode: i, headers: r, body: o}, o) 316 | }, t => e(t))) : this.isNode() && (this.initGotEnv(t), this.got(t).on("redirect", (t, e) => { 317 | try { 318 | if (t.headers["set-cookie"]) { 319 | const s = t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString(); 320 | s && this.ckjar.setCookieSync(s, null), e.cookieJar = this.ckjar 321 | } 322 | } catch (t) { 323 | this.logErr(t) 324 | } 325 | }).then(t => { 326 | const {statusCode: s, statusCode: i, headers: r, body: o} = t; 327 | e(null, {status: s, statusCode: i, headers: r, body: o}, o) 328 | }, t => { 329 | const {message: s, response: i} = t; 330 | e(s, i, i && i.body) 331 | })) 332 | } 333 | 334 | post(t, e = (() => { 335 | })) { 336 | 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) => { 337 | !t && s && (s.body = i, s.statusCode = s.status), e(t, s, i) 338 | }); else if (this.isQuanX()) t.method = "POST", this.isNeedRewrite && (t.opts = t.opts || {}, Object.assign(t.opts, {hints: !1})), $task.fetch(t).then(t => { 339 | const {statusCode: s, statusCode: i, headers: r, body: o} = t; 340 | e(null, {status: s, statusCode: i, headers: r, body: o}, o) 341 | }, t => e(t)); else if (this.isNode()) { 342 | this.initGotEnv(t); 343 | const {url: s, ...i} = t; 344 | this.got.post(s, i).then(t => { 345 | const {statusCode: s, statusCode: i, headers: r, body: o} = t; 346 | e(null, {status: s, statusCode: i, headers: r, body: o}, o) 347 | }, t => { 348 | const {message: s, response: i} = t; 349 | e(s, i, i && i.body) 350 | }) 351 | } 352 | } 353 | 354 | time(t, e = null) { 355 | const s = e ? new Date(e) : new Date; 356 | let i = { 357 | "M+": s.getMonth() + 1, 358 | "d+": s.getDate(), 359 | "H+": s.getHours(), 360 | "m+": s.getMinutes(), 361 | "s+": s.getSeconds(), 362 | "q+": Math.floor((s.getMonth() + 3) / 3), 363 | S: s.getMilliseconds() 364 | }; 365 | /(y+)/.test(t) && (t = t.replace(RegExp.$1, (s.getFullYear() + "").substr(4 - RegExp.$1.length))); 366 | 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))); 367 | return t 368 | } 369 | 370 | msg(e = t, s = "", i = "", r) { 371 | const o = t => { 372 | if (!t) return t; 373 | if ("string" == typeof t) return this.isLoon() ? t : this.isQuanX() ? {"open-url": t} : this.isSurge() ? {url: t} : void 0; 374 | if ("object" == typeof t) { 375 | if (this.isLoon()) { 376 | let e = t.openUrl || t.url || t["open-url"], s = t.mediaUrl || t["media-url"]; 377 | return {openUrl: e, mediaUrl: s} 378 | } 379 | if (this.isQuanX()) { 380 | let e = t["open-url"] || t.url || t.openUrl, s = t["media-url"] || t.mediaUrl; 381 | return {"open-url": e, "media-url": s} 382 | } 383 | if (this.isSurge()) { 384 | let e = t.url || t.openUrl || t["open-url"]; 385 | return {url: e} 386 | } 387 | } 388 | }; 389 | if (this.isMute || (this.isSurge() || this.isLoon() ? $notification.post(e, s, i, o(r)) : this.isQuanX() && $notify(e, s, i, o(r))), !this.isMuteLog) { 390 | let t = ["", "==============📣系统通知📣=============="]; 391 | t.push(e), s && t.push(s), i && t.push(i), console.log(t.join("\n")), this.logs = this.logs.concat(t) 392 | } 393 | } 394 | 395 | log(...t) { 396 | t.length > 0 && (this.logs = [...this.logs, ...t]), console.log(t.join(this.logSeparator)) 397 | } 398 | 399 | logErr(t, e) { 400 | const s = !this.isSurge() && !this.isQuanX() && !this.isLoon(); 401 | s ? this.log("", `❗️${this.name}, 错误!`, t.stack) : this.log("", `❗️${this.name}, 错误!`, t) 402 | } 403 | 404 | wait(t) { 405 | return new Promise(e => setTimeout(e, t)) 406 | } 407 | 408 | done(t = {}) { 409 | const e = (new Date).getTime(), s = (e - this.startTime) / 1e3; 410 | this.log("", `🔔${this.name}, 结束! 🕛 ${s} 秒`), this.log(), (this.isSurge() || this.isQuanX() || this.isLoon()) && $done(t) 411 | } 412 | }(t, e) 413 | } 414 | -------------------------------------------------------------------------------- /notify.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # _*_ coding:utf-8 _*_ 3 | import base64 4 | import hashlib 5 | import hmac 6 | import json 7 | import os 8 | import re 9 | import threading 10 | import time 11 | import urllib.parse 12 | import smtplib 13 | from email.mime.text import MIMEText 14 | from email.header import Header 15 | from email.utils import formataddr 16 | 17 | import requests 18 | 19 | # 原先的 print 函数和主线程的锁 20 | _print = print 21 | mutex = threading.Lock() 22 | 23 | 24 | # 定义新的 print 函数 25 | def print(text, *args, **kw): 26 | """ 27 | 使输出有序进行,不出现多线程同一时间输出导致错乱的问题。 28 | """ 29 | with mutex: 30 | _print(text, *args, **kw) 31 | 32 | 33 | # 通知服务 34 | # fmt: off 35 | push_config = { 36 | 'HITOKOTO': False, # 启用一言(随机句子) 37 | 38 | 'BARK_PUSH': '', # bark IP 或设备码,例:https://api.day.app/DxHcxxxxxRxxxxxxcm/ 39 | 'BARK_ARCHIVE': '', # bark 推送是否存档 40 | 'BARK_GROUP': '', # bark 推送分组 41 | 'BARK_SOUND': '', # bark 推送声音 42 | 'BARK_ICON': '', # bark 推送图标 43 | 44 | 'CONSOLE': True, # 控制台输出 45 | 46 | 'DD_BOT_SECRET': '', # 钉钉机器人的 DD_BOT_SECRET 47 | 'DD_BOT_TOKEN': '', # 钉钉机器人的 DD_BOT_TOKEN 48 | 49 | 'FSKEY': '', # 飞书机器人的 FSKEY 50 | 51 | 'GOBOT_URL': '', # go-cqhttp 52 | # 推送到个人QQ:http://127.0.0.1/send_private_msg 53 | # 群:http://127.0.0.1/send_group_msg 54 | 'GOBOT_QQ': '', # go-cqhttp 的推送群或用户 55 | # GOBOT_URL 设置 /send_private_msg 时填入 user_id=个人QQ 56 | # /send_group_msg 时填入 group_id=QQ群 57 | 'GOBOT_TOKEN': '', # go-cqhttp 的 access_token 58 | 59 | 'GOTIFY_URL': '', # gotify地址,如https://push.example.de:8080 60 | 'GOTIFY_TOKEN': '', # gotify的消息应用token 61 | 'GOTIFY_PRIORITY': 0, # 推送消息优先级,默认为0 62 | 63 | 'IGOT_PUSH_KEY': '', # iGot 聚合推送的 IGOT_PUSH_KEY 64 | 65 | 'PUSH_KEY': '', # server 酱的 PUSH_KEY,兼容旧版与 Turbo 版 66 | 67 | 'DEER_KEY': '', # PushDeer 的 PUSHDEER_KEY 68 | 'DEER_URL': '', # PushDeer 的 PUSHDEER_URL 69 | 70 | 'CHAT_URL': '', # synology chat url 71 | 'CHAT_TOKEN': '', # synology chat token 72 | 73 | 'PUSH_PLUS_TOKEN': '', # push+ 微信推送的用户令牌 74 | 'PUSH_PLUS_USER': '', # push+ 微信推送的群组编码 75 | 76 | 'QMSG_KEY': '', # qmsg 酱的 QMSG_KEY 77 | 'QMSG_TYPE': '', # qmsg 酱的 QMSG_TYPE 78 | 79 | 'QYWX_ORIGIN': '', # 企业微信代理地址 80 | 81 | 'QYWX_AM': '', # 企业微信应用 82 | 83 | 'QYWX_KEY': '', # 企业微信机器人 84 | 85 | 'TG_BOT_TOKEN': '', # tg 机器人的 TG_BOT_TOKEN,例:1407203283:AAG9rt-6RDaaX0HBLZQq0laNOh898iFYaRQ 86 | 'TG_USER_ID': '', # tg 机器人的 TG_USER_ID,例:1434078534 87 | 'TG_API_HOST': '', # tg 代理 api 88 | 'TG_PROXY_AUTH': '', # tg 代理认证参数 89 | 'TG_PROXY_HOST': '', # tg 机器人的 TG_PROXY_HOST 90 | 'TG_PROXY_PORT': '', # tg 机器人的 TG_PROXY_PORT 91 | 92 | 'AIBOTK_KEY': '', # 智能微秘书 个人中心的apikey 文档地址:http://wechat.aibotk.com/docs/about 93 | 'AIBOTK_TYPE': '', # 智能微秘书 发送目标 room 或 contact 94 | 'AIBOTK_NAME': '', # 智能微秘书 发送群名 或者好友昵称和type要对应好 95 | 96 | 'SMTP_SERVER': '', # SMTP 发送邮件服务器,形如 smtp.exmail.qq.com:465 97 | 'SMTP_SSL': 'false', # SMTP 发送邮件服务器是否使用 SSL,填写 true 或 false 98 | 'SMTP_EMAIL': '', # SMTP 收发件邮箱,通知将会由自己发给自己 99 | 'SMTP_PASSWORD': '', # SMTP 登录密码,也可能为特殊口令,视具体邮件服务商说明而定 100 | 'SMTP_NAME': '', # SMTP 收发件人姓名,可随意填写 101 | 102 | 'PUSHME_KEY': '', # PushMe 酱的 PUSHME_KEY 103 | } 104 | notify_function = [] 105 | # fmt: on 106 | 107 | # 首先读取 面板变量 或者 github action 运行变量 108 | for k in push_config: 109 | if os.getenv(k): 110 | v = os.getenv(k) 111 | push_config[k] = v 112 | 113 | 114 | def bark(title: str, content: str) -> None: 115 | """ 116 | 使用 bark 推送消息。 117 | """ 118 | if not push_config.get("BARK_PUSH"): 119 | print("bark 服务的 BARK_PUSH 未设置!!\n取消推送") 120 | return 121 | print("bark 服务启动") 122 | 123 | if push_config.get("BARK_PUSH").startswith("http"): 124 | url = f'{push_config.get("BARK_PUSH")}/{urllib.parse.quote_plus(title)}/{urllib.parse.quote_plus(content)}' 125 | else: 126 | url = f'https://api.day.app/{push_config.get("BARK_PUSH")}/{urllib.parse.quote_plus(title)}/{urllib.parse.quote_plus(content)}' 127 | 128 | bark_params = { 129 | "BARK_ARCHIVE": "isArchive", 130 | "BARK_GROUP": "group", 131 | "BARK_SOUND": "sound", 132 | "BARK_ICON": "icon", 133 | } 134 | params = "" 135 | for pair in filter( 136 | lambda pairs: pairs[0].startswith("BARK_") 137 | and pairs[0] != "BARK_PUSH" 138 | and pairs[1] 139 | and bark_params.get(pairs[0]), 140 | push_config.items(), 141 | ): 142 | params += f"{bark_params.get(pair[0])}={pair[1]}&" 143 | if params: 144 | url = url + "?" + params.rstrip("&") 145 | response = requests.get(url).json() 146 | 147 | if response["code"] == 200: 148 | print("bark 推送成功!") 149 | else: 150 | print("bark 推送失败!") 151 | 152 | 153 | def console(title: str, content: str) -> None: 154 | """ 155 | 使用 控制台 推送消息。 156 | """ 157 | # print(f"{title}\n\n{content}") 158 | 159 | 160 | def dingding_bot(title: str, content: str) -> None: 161 | """ 162 | 使用 钉钉机器人 推送消息。 163 | """ 164 | if not push_config.get("DD_BOT_SECRET") or not push_config.get("DD_BOT_TOKEN"): 165 | print("钉钉机器人 服务的 DD_BOT_SECRET 或者 DD_BOT_TOKEN 未设置!!\n取消推送") 166 | return 167 | print("钉钉机器人 服务启动") 168 | 169 | timestamp = str(round(time.time() * 1000)) 170 | secret_enc = push_config.get("DD_BOT_SECRET").encode("utf-8") 171 | string_to_sign = "{}\n{}".format(timestamp, push_config.get("DD_BOT_SECRET")) 172 | string_to_sign_enc = string_to_sign.encode("utf-8") 173 | hmac_code = hmac.new( 174 | secret_enc, string_to_sign_enc, digestmod=hashlib.sha256 175 | ).digest() 176 | sign = urllib.parse.quote_plus(base64.b64encode(hmac_code)) 177 | url = f'https://oapi.dingtalk.com/robot/send?access_token={push_config.get("DD_BOT_TOKEN")}×tamp={timestamp}&sign={sign}' 178 | headers = {"Content-Type": "application/json;charset=utf-8"} 179 | data = {"msgtype": "text", "text": {"content": f"{title}\n\n{content}"}} 180 | response = requests.post( 181 | url=url, data=json.dumps(data), headers=headers, timeout=15 182 | ).json() 183 | 184 | if not response["errcode"]: 185 | print("钉钉机器人 推送成功!") 186 | else: 187 | print("钉钉机器人 推送失败!") 188 | 189 | 190 | def feishu_bot(title: str, content: str) -> None: 191 | """ 192 | 使用 飞书机器人 推送消息。 193 | """ 194 | if not push_config.get("FSKEY"): 195 | print("飞书 服务的 FSKEY 未设置!!\n取消推送") 196 | return 197 | print("飞书 服务启动") 198 | 199 | url = f'https://open.feishu.cn/open-apis/bot/v2/hook/{push_config.get("FSKEY")}' 200 | data = {"msg_type": "text", "content": {"text": f"{title}\n\n{content}"}} 201 | response = requests.post(url, data=json.dumps(data)).json() 202 | 203 | if response.get("StatusCode") == 0: 204 | print("飞书 推送成功!") 205 | else: 206 | print("飞书 推送失败!错误信息如下:\n", response) 207 | 208 | 209 | def go_cqhttp(title: str, content: str) -> None: 210 | """ 211 | 使用 go_cqhttp 推送消息。 212 | """ 213 | if not push_config.get("GOBOT_URL") or not push_config.get("GOBOT_QQ"): 214 | print("go-cqhttp 服务的 GOBOT_URL 或 GOBOT_QQ 未设置!!\n取消推送") 215 | return 216 | print("go-cqhttp 服务启动") 217 | 218 | url = f'{push_config.get("GOBOT_URL")}?access_token={push_config.get("GOBOT_TOKEN")}&{push_config.get("GOBOT_QQ")}&message={title}\n{content}' 219 | response = requests.get(url).json() 220 | 221 | if response["status"] == "ok": 222 | print("go-cqhttp 推送成功!") 223 | else: 224 | print("go-cqhttp 推送失败!") 225 | 226 | 227 | def gotify(title: str, content: str) -> None: 228 | """ 229 | 使用 gotify 推送消息。 230 | """ 231 | if not push_config.get("GOTIFY_URL") or not push_config.get("GOTIFY_TOKEN"): 232 | print("gotify 服务的 GOTIFY_URL 或 GOTIFY_TOKEN 未设置!!\n取消推送") 233 | return 234 | print("gotify 服务启动") 235 | 236 | url = f'{push_config.get("GOTIFY_URL")}/message?token={push_config.get("GOTIFY_TOKEN")}' 237 | data = { 238 | "title": title, 239 | "message": content, 240 | "priority": push_config.get("GOTIFY_PRIORITY"), 241 | } 242 | response = requests.post(url, data=data).json() 243 | 244 | if response.get("id"): 245 | print("gotify 推送成功!") 246 | else: 247 | print("gotify 推送失败!") 248 | 249 | 250 | def iGot(title: str, content: str) -> None: 251 | """ 252 | 使用 iGot 推送消息。 253 | """ 254 | if not push_config.get("IGOT_PUSH_KEY"): 255 | print("iGot 服务的 IGOT_PUSH_KEY 未设置!!\n取消推送") 256 | return 257 | print("iGot 服务启动") 258 | 259 | url = f'https://push.hellyw.com/{push_config.get("IGOT_PUSH_KEY")}' 260 | data = {"title": title, "content": content} 261 | headers = {"Content-Type": "application/x-www-form-urlencoded"} 262 | response = requests.post(url, data=data, headers=headers).json() 263 | 264 | if response["ret"] == 0: 265 | print("iGot 推送成功!") 266 | else: 267 | print(f'iGot 推送失败!{response["errMsg"]}') 268 | 269 | 270 | def serverJ(title: str, content: str) -> None: 271 | """ 272 | 通过 serverJ 推送消息。 273 | """ 274 | if not push_config.get("PUSH_KEY"): 275 | print("serverJ 服务的 PUSH_KEY 未设置!!\n取消推送") 276 | return 277 | print("serverJ 服务启动") 278 | 279 | data = {"text": title, "desp": content.replace("\n", "\n\n")} 280 | if push_config.get("PUSH_KEY").find("SCT") != -1: 281 | url = f'https://sctapi.ftqq.com/{push_config.get("PUSH_KEY")}.send' 282 | else: 283 | url = f'https://sc.ftqq.com/{push_config.get("PUSH_KEY")}.send' 284 | response = requests.post(url, data=data).json() 285 | 286 | if response.get("errno") == 0 or response.get("code") == 0: 287 | print("serverJ 推送成功!") 288 | else: 289 | print(f'serverJ 推送失败!错误码:{response["message"]}') 290 | 291 | 292 | def pushdeer(title: str, content: str) -> None: 293 | """ 294 | 通过PushDeer 推送消息 295 | """ 296 | if not push_config.get("DEER_KEY"): 297 | print("PushDeer 服务的 DEER_KEY 未设置!!\n取消推送") 298 | return 299 | print("PushDeer 服务启动") 300 | data = { 301 | "text": title, 302 | "desp": content, 303 | "type": "markdown", 304 | "pushkey": push_config.get("DEER_KEY"), 305 | } 306 | url = "https://api2.pushdeer.com/message/push" 307 | if push_config.get("DEER_URL"): 308 | url = push_config.get("DEER_URL") 309 | 310 | response = requests.post(url, data=data).json() 311 | 312 | if len(response.get("content").get("result")) > 0: 313 | print("PushDeer 推送成功!") 314 | else: 315 | print("PushDeer 推送失败!错误信息:", response) 316 | 317 | 318 | def chat(title: str, content: str) -> None: 319 | """ 320 | 通过Chat 推送消息 321 | """ 322 | if not push_config.get("CHAT_URL") or not push_config.get("CHAT_TOKEN"): 323 | print("chat 服务的 CHAT_URL或CHAT_TOKEN 未设置!!\n取消推送") 324 | return 325 | print("chat 服务启动") 326 | data = "payload=" + json.dumps({"text": title + "\n" + content}) 327 | url = push_config.get("CHAT_URL") + push_config.get("CHAT_TOKEN") 328 | response = requests.post(url, data=data) 329 | 330 | if response.status_code == 200: 331 | print("Chat 推送成功!") 332 | else: 333 | print("Chat 推送失败!错误信息:", response) 334 | 335 | 336 | def pushplus_bot(title: str, content: str) -> None: 337 | """ 338 | 通过 push+ 推送消息。 339 | """ 340 | if not push_config.get("PUSH_PLUS_TOKEN"): 341 | print("PUSHPLUS 服务的 PUSH_PLUS_TOKEN 未设置!!\n取消推送") 342 | return 343 | print("PUSHPLUS 服务启动") 344 | 345 | url = "http://www.pushplus.plus/send" 346 | data = { 347 | "token": push_config.get("PUSH_PLUS_TOKEN"), 348 | "title": title, 349 | "content": content, 350 | "topic": push_config.get("PUSH_PLUS_USER"), 351 | } 352 | body = json.dumps(data).encode(encoding="utf-8") 353 | headers = {"Content-Type": "application/json"} 354 | response = requests.post(url=url, data=body, headers=headers).json() 355 | 356 | if response["code"] == 200: 357 | print("PUSHPLUS 推送成功!") 358 | 359 | else: 360 | url_old = "http://pushplus.hxtrip.com/send" 361 | headers["Accept"] = "application/json" 362 | response = requests.post(url=url_old, data=body, headers=headers).json() 363 | 364 | if response["code"] == 200: 365 | print("PUSHPLUS(hxtrip) 推送成功!") 366 | 367 | else: 368 | print("PUSHPLUS 推送失败!") 369 | 370 | 371 | def qmsg_bot(title: str, content: str) -> None: 372 | """ 373 | 使用 qmsg 推送消息。 374 | """ 375 | if not push_config.get("QMSG_KEY") or not push_config.get("QMSG_TYPE"): 376 | print("qmsg 的 QMSG_KEY 或者 QMSG_TYPE 未设置!!\n取消推送") 377 | return 378 | print("qmsg 服务启动") 379 | 380 | url = f'https://qmsg.zendee.cn/{push_config.get("QMSG_TYPE")}/{push_config.get("QMSG_KEY")}' 381 | payload = {"msg": f'{title}\n\n{content.replace("----", "-")}'.encode("utf-8")} 382 | response = requests.post(url=url, params=payload).json() 383 | 384 | if response["code"] == 0: 385 | print("qmsg 推送成功!") 386 | else: 387 | print(f'qmsg 推送失败!{response["reason"]}') 388 | 389 | 390 | def wecom_app(title: str, content: str) -> None: 391 | """ 392 | 通过 企业微信 APP 推送消息。 393 | """ 394 | if not push_config.get("QYWX_AM"): 395 | print("QYWX_AM 未设置!!\n取消推送") 396 | return 397 | QYWX_AM_AY = re.split(",", push_config.get("QYWX_AM")) 398 | if 4 < len(QYWX_AM_AY) > 5: 399 | print("QYWX_AM 设置错误!!\n取消推送") 400 | return 401 | print("企业微信 APP 服务启动") 402 | 403 | corpid = QYWX_AM_AY[0] 404 | corpsecret = QYWX_AM_AY[1] 405 | touser = QYWX_AM_AY[2] 406 | agentid = QYWX_AM_AY[3] 407 | try: 408 | media_id = QYWX_AM_AY[4] 409 | except IndexError: 410 | media_id = "" 411 | wx = WeCom(corpid, corpsecret, agentid) 412 | # 如果没有配置 media_id 默认就以 text 方式发送 413 | if not media_id: 414 | message = title + "\n\n" + content 415 | response = wx.send_text(message, touser) 416 | else: 417 | response = wx.send_mpnews(title, content, media_id, touser) 418 | 419 | if response == "ok": 420 | print("企业微信推送成功!") 421 | else: 422 | print("企业微信推送失败!错误信息如下:\n", response) 423 | 424 | 425 | class WeCom: 426 | def __init__(self, corpid, corpsecret, agentid): 427 | self.CORPID = corpid 428 | self.CORPSECRET = corpsecret 429 | self.AGENTID = agentid 430 | self.ORIGIN = "https://qyapi.weixin.qq.com" 431 | if push_config.get("QYWX_ORIGIN"): 432 | self.ORIGIN = push_config.get("QYWX_ORIGIN") 433 | 434 | def get_access_token(self): 435 | url = f"{self.ORIGIN}/cgi-bin/gettoken" 436 | values = { 437 | "corpid": self.CORPID, 438 | "corpsecret": self.CORPSECRET, 439 | } 440 | req = requests.post(url, params=values) 441 | data = json.loads(req.text) 442 | return data["access_token"] 443 | 444 | def send_text(self, message, touser="@all"): 445 | send_url = f"{self.ORIGIN}/cgi-bin/message/send?access_token={self.get_access_token()}" 446 | send_values = { 447 | "touser": touser, 448 | "msgtype": "text", 449 | "agentid": self.AGENTID, 450 | "text": {"content": message}, 451 | "safe": "0", 452 | } 453 | send_msges = bytes(json.dumps(send_values), "utf-8") 454 | respone = requests.post(send_url, send_msges) 455 | respone = respone.json() 456 | return respone["errmsg"] 457 | 458 | def send_mpnews(self, title, message, media_id, touser="@all"): 459 | send_url = f"https://{self.HOST}/cgi-bin/message/send?access_token={self.get_access_token()}" 460 | send_values = { 461 | "touser": touser, 462 | "msgtype": "mpnews", 463 | "agentid": self.AGENTID, 464 | "mpnews": { 465 | "articles": [ 466 | { 467 | "title": title, 468 | "thumb_media_id": media_id, 469 | "author": "Author", 470 | "content_source_url": "", 471 | "content": message.replace("\n", "
"), 472 | "digest": message, 473 | } 474 | ] 475 | }, 476 | } 477 | send_msges = bytes(json.dumps(send_values), "utf-8") 478 | respone = requests.post(send_url, send_msges) 479 | respone = respone.json() 480 | return respone["errmsg"] 481 | 482 | 483 | def wecom_bot(title: str, content: str) -> None: 484 | """ 485 | 通过 企业微信机器人 推送消息。 486 | """ 487 | if not push_config.get("QYWX_KEY"): 488 | print("企业微信机器人 服务的 QYWX_KEY 未设置!!\n取消推送") 489 | return 490 | print("企业微信机器人服务启动") 491 | 492 | origin = "https://qyapi.weixin.qq.com" 493 | if push_config.get("QYWX_ORIGIN"): 494 | origin = push_config.get("QYWX_ORIGIN") 495 | 496 | url = f"{origin}/cgi-bin/webhook/send?key={push_config.get('QYWX_KEY')}" 497 | headers = {"Content-Type": "application/json;charset=utf-8"} 498 | data = {"msgtype": "text", "text": {"content": f"{title}\n\n{content}"}} 499 | response = requests.post( 500 | url=url, data=json.dumps(data), headers=headers, timeout=15 501 | ).json() 502 | 503 | if response["errcode"] == 0: 504 | print("企业微信机器人推送成功!") 505 | else: 506 | print("企业微信机器人推送失败!") 507 | 508 | 509 | def telegram_bot(title: str, content: str) -> None: 510 | """ 511 | 使用 telegram 机器人 推送消息。 512 | """ 513 | if not push_config.get("TG_BOT_TOKEN") or not push_config.get("TG_USER_ID"): 514 | print("tg 服务的 bot_token 或者 user_id 未设置!!\n取消推送") 515 | return 516 | print("tg 服务启动") 517 | 518 | if push_config.get("TG_API_HOST"): 519 | url = f"https://{push_config.get('TG_API_HOST')}/bot{push_config.get('TG_BOT_TOKEN')}/sendMessage" 520 | else: 521 | url = ( 522 | f"https://api.telegram.org/bot{push_config.get('TG_BOT_TOKEN')}/sendMessage" 523 | ) 524 | headers = {"Content-Type": "application/x-www-form-urlencoded"} 525 | payload = { 526 | "chat_id": str(push_config.get("TG_USER_ID")), 527 | "text": f"{title}\n\n{content}", 528 | "disable_web_page_preview": "true", 529 | } 530 | proxies = None 531 | if push_config.get("TG_PROXY_HOST") and push_config.get("TG_PROXY_PORT"): 532 | if push_config.get("TG_PROXY_AUTH") is not None and "@" not in push_config.get( 533 | "TG_PROXY_HOST" 534 | ): 535 | push_config["TG_PROXY_HOST"] = ( 536 | push_config.get("TG_PROXY_AUTH") 537 | + "@" 538 | + push_config.get("TG_PROXY_HOST") 539 | ) 540 | proxyStr = "http://{}:{}".format( 541 | push_config.get("TG_PROXY_HOST"), push_config.get("TG_PROXY_PORT") 542 | ) 543 | proxies = {"http": proxyStr, "https": proxyStr} 544 | response = requests.post( 545 | url=url, headers=headers, params=payload, proxies=proxies 546 | ).json() 547 | 548 | if response["ok"]: 549 | print("tg 推送成功!") 550 | else: 551 | print("tg 推送失败!") 552 | 553 | 554 | def aibotk(title: str, content: str) -> None: 555 | """ 556 | 使用 智能微秘书 推送消息。 557 | """ 558 | if ( 559 | not push_config.get("AIBOTK_KEY") 560 | or not push_config.get("AIBOTK_TYPE") 561 | or not push_config.get("AIBOTK_NAME") 562 | ): 563 | print("智能微秘书 的 AIBOTK_KEY 或者 AIBOTK_TYPE 或者 AIBOTK_NAME 未设置!!\n取消推送") 564 | return 565 | print("智能微秘书 服务启动") 566 | 567 | if push_config.get("AIBOTK_TYPE") == "room": 568 | url = "https://api-bot.aibotk.com/openapi/v1/chat/room" 569 | data = { 570 | "apiKey": push_config.get("AIBOTK_KEY"), 571 | "roomName": push_config.get("AIBOTK_NAME"), 572 | "message": {"type": 1, "content": f"【青龙快讯】\n\n{title}\n{content}"}, 573 | } 574 | else: 575 | url = "https://api-bot.aibotk.com/openapi/v1/chat/contact" 576 | data = { 577 | "apiKey": push_config.get("AIBOTK_KEY"), 578 | "name": push_config.get("AIBOTK_NAME"), 579 | "message": {"type": 1, "content": f"【青龙快讯】\n\n{title}\n{content}"}, 580 | } 581 | body = json.dumps(data).encode(encoding="utf-8") 582 | headers = {"Content-Type": "application/json"} 583 | response = requests.post(url=url, data=body, headers=headers).json() 584 | print(response) 585 | if response["code"] == 0: 586 | print("智能微秘书 推送成功!") 587 | else: 588 | print(f'智能微秘书 推送失败!{response["error"]}') 589 | 590 | 591 | def smtp(title: str, content: str) -> None: 592 | """ 593 | 使用 SMTP 邮件 推送消息。 594 | """ 595 | if ( 596 | not push_config.get("SMTP_SERVER") 597 | or not push_config.get("SMTP_SSL") 598 | or not push_config.get("SMTP_EMAIL") 599 | or not push_config.get("SMTP_PASSWORD") 600 | or not push_config.get("SMTP_NAME") 601 | ): 602 | print( 603 | "SMTP 邮件 的 SMTP_SERVER 或者 SMTP_SSL 或者 SMTP_EMAIL 或者 SMTP_PASSWORD 或者 SMTP_NAME 未设置!!\n取消推送" 604 | ) 605 | return 606 | print("SMTP 邮件 服务启动") 607 | 608 | message = MIMEText(content, "plain", "utf-8") 609 | message["From"] = formataddr( 610 | ( 611 | Header(push_config.get("SMTP_NAME"), "utf-8").encode(), 612 | push_config.get("SMTP_EMAIL"), 613 | ) 614 | ) 615 | message["To"] = formataddr( 616 | ( 617 | Header(push_config.get("SMTP_NAME"), "utf-8").encode(), 618 | push_config.get("SMTP_EMAIL"), 619 | ) 620 | ) 621 | message["Subject"] = Header(title, "utf-8") 622 | 623 | try: 624 | smtp_server = ( 625 | smtplib.SMTP_SSL(push_config.get("SMTP_SERVER")) 626 | if push_config.get("SMTP_SSL") == "true" 627 | else smtplib.SMTP(push_config.get("SMTP_SERVER")) 628 | ) 629 | smtp_server.login( 630 | push_config.get("SMTP_EMAIL"), push_config.get("SMTP_PASSWORD") 631 | ) 632 | smtp_server.sendmail( 633 | push_config.get("SMTP_EMAIL"), 634 | push_config.get("SMTP_EMAIL"), 635 | message.as_bytes(), 636 | ) 637 | smtp_server.close() 638 | print("SMTP 邮件 推送成功!") 639 | except Exception as e: 640 | print(f"SMTP 邮件 推送失败!{e}") 641 | 642 | 643 | def pushme(title: str, content: str) -> None: 644 | """ 645 | 使用 PushMe 推送消息。 646 | """ 647 | if not push_config.get("PUSHME_KEY"): 648 | print("PushMe 服务的 PUSHME_KEY 未设置!!\n取消推送") 649 | return 650 | print("PushMe 服务启动") 651 | 652 | url = f'https://push.i-i.me/?push_key={push_config.get("PUSHME_KEY")}' 653 | data = { 654 | "title": title, 655 | "content": content, 656 | } 657 | response = requests.post(url, data=data) 658 | 659 | if response.status_code == 200 and response.text == "success": 660 | print("PushMe 推送成功!") 661 | else: 662 | print(f"PushMe 推送失败!{response.status_code} {response.text}") 663 | 664 | 665 | def one() -> str: 666 | """ 667 | 获取一条一言。 668 | :return: 669 | """ 670 | url = "https://v1.hitokoto.cn/" 671 | res = requests.get(url).json() 672 | return res["hitokoto"] + " ----" + res["from"] 673 | 674 | 675 | if push_config.get("BARK_PUSH"): 676 | notify_function.append(bark) 677 | if push_config.get("CONSOLE"): 678 | notify_function.append(console) 679 | if push_config.get("DD_BOT_TOKEN") and push_config.get("DD_BOT_SECRET"): 680 | notify_function.append(dingding_bot) 681 | if push_config.get("FSKEY"): 682 | notify_function.append(feishu_bot) 683 | if push_config.get("GOBOT_URL") and push_config.get("GOBOT_QQ"): 684 | notify_function.append(go_cqhttp) 685 | if push_config.get("GOTIFY_URL") and push_config.get("GOTIFY_TOKEN"): 686 | notify_function.append(gotify) 687 | if push_config.get("IGOT_PUSH_KEY"): 688 | notify_function.append(iGot) 689 | if push_config.get("PUSH_KEY"): 690 | notify_function.append(serverJ) 691 | if push_config.get("DEER_KEY"): 692 | notify_function.append(pushdeer) 693 | if push_config.get("CHAT_URL") and push_config.get("CHAT_TOKEN"): 694 | notify_function.append(chat) 695 | if push_config.get("PUSH_PLUS_TOKEN"): 696 | notify_function.append(pushplus_bot) 697 | if push_config.get("QMSG_KEY") and push_config.get("QMSG_TYPE"): 698 | notify_function.append(qmsg_bot) 699 | if push_config.get("QYWX_AM"): 700 | notify_function.append(wecom_app) 701 | if push_config.get("QYWX_KEY"): 702 | notify_function.append(wecom_bot) 703 | if push_config.get("TG_BOT_TOKEN") and push_config.get("TG_USER_ID"): 704 | notify_function.append(telegram_bot) 705 | if ( 706 | push_config.get("AIBOTK_KEY") 707 | and push_config.get("AIBOTK_TYPE") 708 | and push_config.get("AIBOTK_NAME") 709 | ): 710 | notify_function.append(aibotk) 711 | if ( 712 | push_config.get("SMTP_SERVER") 713 | and push_config.get("SMTP_SSL") 714 | and push_config.get("SMTP_EMAIL") 715 | and push_config.get("SMTP_PASSWORD") 716 | and push_config.get("SMTP_NAME") 717 | ): 718 | notify_function.append(smtp) 719 | if push_config.get("PUSHME_KEY"): 720 | notify_function.append(pushme) 721 | 722 | 723 | def send(title: str, content: str) -> None: 724 | if not content: 725 | print(f"{title} 推送内容为空!") 726 | return 727 | 728 | # 根据标题跳过一些消息推送,环境变量:SKIP_PUSH_TITLE 用回车分隔 729 | skipTitle = os.getenv("SKIP_PUSH_TITLE") 730 | if skipTitle: 731 | if title in re.split("\n", skipTitle): 732 | print(f"{title} 在SKIP_PUSH_TITLE环境变量内,跳过推送!") 733 | return 734 | 735 | hitokoto = push_config.get("HITOKOTO") 736 | 737 | text = one() if hitokoto else "" 738 | content += "作者:YourAhTzu\n" + text 739 | 740 | ts = [ 741 | threading.Thread(target=mode, args=(title, content), name=mode.__name__) 742 | for mode in notify_function 743 | ] 744 | [t.start() for t in ts] 745 | [t.join() for t in ts] 746 | 747 | 748 | def main(): 749 | send("title", "content") 750 | 751 | 752 | if __name__ == "__main__": 753 | main() -------------------------------------------------------------------------------- /qbd.py: -------------------------------------------------------------------------------- 1 | ''' 2 | new Env('Q必达小程序'); 3 | 注册入口:weixin://dl/business/?t=GEK1Z5MV68f 4 | 账号密码登录 账号&密码多号@隔开 5 | ''' 6 | import requests 7 | import time 8 | import os 9 | def login(username, password): 10 | url = "http://xcx.wanhuida888.com/ht/web/login/loginNew?t=" + str(int(time.time() * 1000)) 11 | headers = { 12 | "Accept-Language": "zh-CN,zh;q=0.8", 13 | "User-Agent": "okhttp-okgo/jeasonlzy", 14 | "source": "ANDROID", 15 | "appId": "com.qsongq.fjqexpress", 16 | "version": "1835", 17 | "group": "", 18 | "token": "", 19 | "cookie": "group=", 20 | "Content-Type": "application/json;charset=utf-8", 21 | "Host": "xcx.wanhuida888.com", 22 | "Connection": "Keep-Alive", 23 | "Accept-Encoding": "gzip" 24 | } 25 | data = { 26 | "password": password, 27 | "account": username 28 | } 29 | response = requests.post(url, headers=headers, json=data) 30 | response_data = response.json() 31 | msg = response_data['msg'] 32 | token = response_data['data']['token'] 33 | print(f"账号登录结果:{msg}") 34 | return token 35 | def sign(token): 36 | url = "http://a2e403quwt.wuliucps.com/ht/web/mine/signIn?t=" + str(int(time.time() * 1000)) 37 | headers = { 38 | "Accept-Language": "zh-CN,zh;q=0.8", 39 | "User-Agent": "okhttp-okgo/jeasonlzy", 40 | "source": "ANDROID", 41 | "appId": "com.qsongq.fjqexpress", 42 | "version": "1835", 43 | "token": token, 44 | "Content-Type": "application/x-www-form-urlencoded", 45 | "Content-Length": "0", 46 | "Host": "a2e403quwt.wuliucps.com", 47 | "Connection": "Keep-Alive", 48 | "Accept-Encoding": "gzip" 49 | } 50 | response = requests.post(url, headers=headers) 51 | response_data = response.json() 52 | msg = response_data['msg'] 53 | print(f"账号签到结果:{msg}") 54 | def Video(token): 55 | url = "https://xcx.wanhuida888.com/ht/web/task/watchVideo?t=" + str(int(time.time() * 1000)) 56 | headers = { 57 | "Host": "xcx.wanhuida888.com", 58 | "Connection": "keep-alive", 59 | "Content-Length": "2", 60 | "charset": "utf-8", 61 | "sharecode": "83NPKAI", 62 | "appid": "wx92e73ad679eee047", 63 | "User-Agent": "Mozilla/5.0 (Linux; Android 12; RMX3562 Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Mobile Safari/537.36 XWEB/1160065 MMWEBSDK/20231202 MMWEBID/2307 MicroMessenger/8.0.47.2560(0x28002F30) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android", 64 | "content-type": "application/json", 65 | "source": "MINIAPP", 66 | "Accept-Encoding": "gzip,compress,br,deflate", 67 | "version": "108", 68 | "token": token, 69 | "Referer": "https://servicewechat.com/wx92e73ad679eee047/70/page-frame.html" 70 | } 71 | data = {} 72 | for i in range(3): 73 | response = requests.post(url, headers=headers, json=data) 74 | response_data = response.json() 75 | msg = response_data['msg'] 76 | print(f"广告获取积分{msg}") 77 | time.sleep(20 + i * 10) 78 | if __name__ == "__main__": 79 | qbd = os.environ.get('qbd') 80 | if not qbd: 81 | print("请设置qbd环境变量在运行") 82 | else: 83 | qbd_list = qbd.split('@') 84 | for num, qbd_item in enumerate(qbd_list, start=1): 85 | username, password = qbd_item.split('&') 86 | print(f"=====开始执行第{num}个账号任务=====") 87 | print("---------开始执行账号登录") 88 | token = login(username, password) 89 | if token: 90 | print("---------开始执行签到任务") 91 | sign(token) 92 | print("---------开始执行广告任务") 93 | Video(token) 94 | -------------------------------------------------------------------------------- /ql.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const got = require('got'); 4 | require('dotenv').config(); 5 | const { readFile } = require('fs/promises'); 6 | const path = require('path'); 7 | 8 | const qlDir = process.env.QL_DIR || '/ql'; 9 | const authFile = path.join(qlDir, 'config/auth.json'); 10 | 11 | const api = got.extend({ 12 | prefixUrl: 'http://localhost:5600', 13 | retry: { limit: 0 }, 14 | }); 15 | 16 | async function getToken() { 17 | const authConfig = JSON.parse(await readFile(authFile)); 18 | return authConfig.token; 19 | } 20 | 21 | module.exports.getEnvs = async () => { 22 | const token = await getToken(); 23 | const body = await api({ 24 | url: 'api/envs', 25 | searchParams: { 26 | searchValue: 'JD_COOKIE', 27 | t: Date.now(), 28 | }, 29 | headers: { 30 | Accept: 'application/json', 31 | authorization: `Bearer ${token}`, 32 | }, 33 | }).json(); 34 | return body.data; 35 | }; 36 | 37 | module.exports.getEnvsCount = async () => { 38 | const data = await this.getEnvs(); 39 | return data.length; 40 | }; 41 | 42 | module.exports.addEnv = async (cookie, remarks) => { 43 | const token = await getToken(); 44 | const body = await api({ 45 | method: 'post', 46 | url: 'api/envs', 47 | params: { t: Date.now() }, 48 | json: [{ 49 | name: 'JD_COOKIE', 50 | value: cookie, 51 | remarks, 52 | }], 53 | headers: { 54 | Accept: 'application/json', 55 | authorization: `Bearer ${token}`, 56 | 'Content-Type': 'application/json;charset=UTF-8', 57 | }, 58 | }).json(); 59 | return body; 60 | }; 61 | 62 | module.exports.updateEnv = async (cookie, eid, remarks) => { 63 | const token = await getToken(); 64 | const body = await api({ 65 | method: 'put', 66 | url: 'api/envs', 67 | params: { t: Date.now() }, 68 | json: { 69 | name: 'JD_COOKIE', 70 | value: cookie, 71 | _id: eid, 72 | remarks, 73 | }, 74 | headers: { 75 | Accept: 'application/json', 76 | authorization: `Bearer ${token}`, 77 | 'Content-Type': 'application/json;charset=UTF-8', 78 | }, 79 | }).json(); 80 | return body; 81 | }; 82 | 83 | module.exports.DisableCk = async (eid) => { 84 | const token = await getToken(); 85 | const body = await api({ 86 | method: 'put', 87 | url: 'api/envs/disable', 88 | params: { t: Date.now() }, 89 | body: JSON.stringify([eid]), 90 | headers: { 91 | Accept: 'application/json', 92 | authorization: `Bearer ${token}`, 93 | 'Content-Type': 'application/json;charset=UTF-8', 94 | }, 95 | }).json(); 96 | return body; 97 | }; 98 | 99 | module.exports.EnableCk = async (eid) => { 100 | const token = await getToken(); 101 | const body = await api({ 102 | method: 'put', 103 | url: 'api/envs/enable', 104 | params: { t: Date.now() }, 105 | body: JSON.stringify([eid]), 106 | headers: { 107 | Accept: 'application/json', 108 | authorization: `Bearer ${token}`, 109 | 'Content-Type': 'application/json;charset=UTF-8', 110 | }, 111 | }).json(); 112 | return body; 113 | }; 114 | 115 | module.exports.getstatus = async (eid) => { 116 | const envs = await this.getEnvs(); 117 | for (let i = 0; i < envs.length; i++) { 118 | if(envs[i]._id==eid){ 119 | return envs[i].status; 120 | } 121 | } 122 | return 99; 123 | }; 124 | 125 | module.exports.getEnvById = async (eid) => { 126 | const envs = await this.getEnvs(); 127 | for (let i = 0; i < envs.length; i++) { 128 | if(envs[i]._id==eid){ 129 | return envs[i].value; 130 | } 131 | } 132 | return ""; 133 | }; 134 | 135 | module.exports.delEnv = async (eid) => { 136 | const token = await getToken(); 137 | const body = await api({ 138 | method: 'delete', 139 | url: 'api/envs', 140 | params: { t: Date.now() }, 141 | body: JSON.stringify([eid]), 142 | headers: { 143 | Accept: 'application/json', 144 | authorization: `Bearer ${token}`, 145 | 'Content-Type': 'application/json;charset=UTF-8', 146 | }, 147 | }).json(); 148 | return body; 149 | }; 150 | -------------------------------------------------------------------------------- /sendNotify.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: lxk0301 https://gitee.com/lxk0301 3 | * @Date: 2020-08-19 16:12:40 4 | * @Last Modified by: whyour 5 | * @Last Modified time: 2021-5-1 15:00:54 6 | * sendNotify 推送通知功能 7 | * @param text 通知头 8 | * @param desp 通知体 9 | * @param params 某些推送通知方式点击弹窗可跳转, 例:{ url: 'https://abc.com' } 10 | * @param author 作者仓库等信息 例:`本通知 By:https://github.com/whyour/qinglong` 11 | */ 12 | 13 | const querystring = require('querystring'); 14 | const $ = new Env(); 15 | const timeout = 15000; //超时时间(单位毫秒) 16 | // =======================================gotify通知设置区域============================================== 17 | //gotify_url 填写gotify地址,如https://push.example.de:8080 18 | //gotify_token 填写gotify的消息应用token 19 | //gotify_priority 填写推送消息优先级,默认为0 20 | let GOTIFY_URL = ''; 21 | let GOTIFY_TOKEN = ''; 22 | let GOTIFY_PRIORITY = 0; 23 | // =======================================go-cqhttp通知设置区域=========================================== 24 | //gobot_url 填写请求地址http://127.0.0.1/send_private_msg 25 | //gobot_token 填写在go-cqhttp文件设置的访问密钥 26 | //gobot_qq 填写推送到个人QQ或者QQ群号 27 | //go-cqhttp相关API https://docs.go-cqhttp.org/api 28 | let GOBOT_URL = ''; // 推送到个人QQ: http://127.0.0.1/send_private_msg 群:http://127.0.0.1/send_group_msg 29 | let GOBOT_TOKEN = ''; //访问密钥 30 | let GOBOT_QQ = ''; // 如果GOBOT_URL设置 /send_private_msg 则需要填入 user_id=个人QQ 相反如果是 /send_group_msg 则需要填入 group_id=QQ群 31 | 32 | // =======================================微信server酱通知设置区域=========================================== 33 | //此处填你申请的SCKEY. 34 | //(环境变量名 PUSH_KEY) 35 | let SCKEY = ''; 36 | 37 | // =======================================PushDeer通知设置区域=========================================== 38 | //此处填你申请的PushDeer KEY. 39 | //(环境变量名 DEER_KEY) 40 | let PUSHDEER_KEY = ''; 41 | let PUSHDEER_URL = ''; 42 | 43 | // =======================================Synology Chat通知设置区域=========================================== 44 | //此处填你申请的CHAT_URL与CHAT_TOKEN 45 | //(环境变量名 CHAT_URL CHAT_TOKEN) 46 | let CHAT_URL = ''; 47 | let CHAT_TOKEN = ''; 48 | 49 | // =======================================Bark App通知设置区域=========================================== 50 | //此处填你BarkAPP的信息(IP/设备码,例如:https://api.day.app/XXXXXXXX) 51 | let BARK_PUSH = ''; 52 | //BARK app推送图标,自定义推送图标(需iOS15或以上) 53 | let BARK_ICON = 'https://qn.whyour.cn/logo.png'; 54 | //BARK app推送铃声,铃声列表去APP查看复制填写 55 | let BARK_SOUND = ''; 56 | //BARK app推送消息的分组, 默认为"QingLong" 57 | let BARK_GROUP = 'QingLong'; 58 | 59 | // =======================================telegram机器人通知设置区域=========================================== 60 | //此处填你telegram bot 的Token,telegram机器人通知推送必填项.例如:1077xxx4424:AAFjv0FcqxxxxxxgEMGfi22B4yh15R5uw 61 | //(环境变量名 TG_BOT_TOKEN) 62 | let TG_BOT_TOKEN = ''; 63 | //此处填你接收通知消息的telegram用户的id,telegram机器人通知推送必填项.例如:129xxx206 64 | //(环境变量名 TG_USER_ID) 65 | let TG_USER_ID = ''; 66 | //tg推送HTTP代理设置(不懂可忽略,telegram机器人通知推送功能中非必填) 67 | let TG_PROXY_HOST = ''; //例如:127.0.0.1(环境变量名:TG_PROXY_HOST) 68 | let TG_PROXY_PORT = ''; //例如:1080(环境变量名:TG_PROXY_PORT) 69 | let TG_PROXY_AUTH = ''; //tg代理配置认证参数 70 | //Telegram api自建的反向代理地址(不懂可忽略,telegram机器人通知推送功能中非必填),默认tg官方api(环境变量名:TG_API_HOST) 71 | let TG_API_HOST = 'api.telegram.org'; 72 | // =======================================钉钉机器人通知设置区域=========================================== 73 | //此处填你钉钉 bot 的webhook,例如:5a544165465465645d0f31dca676e7bd07415asdasd 74 | //(环境变量名 DD_BOT_TOKEN) 75 | let DD_BOT_TOKEN = ''; 76 | //密钥,机器人安全设置页面,加签一栏下面显示的SEC开头的字符串 77 | let DD_BOT_SECRET = ''; 78 | 79 | // =======================================企业微信基础设置=========================================== 80 | // 企业微信反向代理地址 81 | //(环境变量名 QYWX_ORIGIN) 82 | let QYWX_ORIGIN = ''; 83 | // =======================================企业微信机器人通知设置区域=========================================== 84 | //此处填你企业微信机器人的 webhook(详见文档 https://work.weixin.qq.com/api/doc/90000/90136/91770),例如:693a91f6-7xxx-4bc4-97a0-0ec2sifa5aaa 85 | //(环境变量名 QYWX_KEY) 86 | let QYWX_KEY = ''; 87 | 88 | // =======================================企业微信应用消息通知设置区域=========================================== 89 | /* 90 | 此处填你企业微信应用消息的值(详见文档 https://work.weixin.qq.com/api/doc/90000/90135/90236) 91 | 环境变量名 QYWX_AM依次填入 corpid,corpsecret,touser(注:多个成员ID使用|隔开),agentid,消息类型(选填,不填默认文本消息类型) 92 | 注意用,号隔开(英文输入法的逗号),例如:wwcff56746d9adwers,B-791548lnzXBE6_BWfxdf3kSTMJr9vFEPKAbh6WERQ,mingcheng,1000001,2COXgjH2UIfERF2zxrtUOKgQ9XklUqMdGSWLBoW_lSDAdafat 93 | 可选推送消息类型(推荐使用图文消息(mpnews)): 94 | - 文本卡片消息: 0 (数字零) 95 | - 文本消息: 1 (数字一) 96 | - 图文消息(mpnews): 素材库图片id, 可查看此教程(http://note.youdao.com/s/HMiudGkb)或者(https://note.youdao.com/ynoteshare1/index.html?id=1a0c8aff284ad28cbd011b29b3ad0191&type=note) 97 | */ 98 | let QYWX_AM = ''; 99 | 100 | // =======================================iGot聚合推送通知设置区域=========================================== 101 | //此处填您iGot的信息(推送key,例如:https://push.hellyw.com/XXXXXXXX) 102 | let IGOT_PUSH_KEY = ''; 103 | 104 | // =======================================push+设置区域======================================= 105 | //官方文档:http://www.pushplus.plus/ 106 | //PUSH_PLUS_TOKEN:微信扫码登录后一对一推送或一对多推送下面的token(您的Token),不提供PUSH_PLUS_USER则默认为一对一推送 107 | //PUSH_PLUS_USER: 一对多推送的“群组编码”(一对多推送下面->您的群组(如无则新建)->群组编码,如果您是创建群组人。也需点击“查看二维码”扫描绑定,否则不能接受群组消息推送) 108 | let PUSH_PLUS_TOKEN = ''; 109 | let PUSH_PLUS_USER = ''; 110 | 111 | // =======================================Cool Push设置区域======================================= 112 | //官方文档:https://cp.xuthus.cc/docs 113 | //QQ_SKEY: Cool Push登录授权后推送消息的调用代码Skey 114 | //QQ_MODE: 推送模式详情请登录获取QQ_SKEY后见https://cp.xuthus.cc/feat 115 | let QQ_SKEY = ''; 116 | let QQ_MODE = ''; 117 | 118 | // =======================================智能微秘书设置区域======================================= 119 | //官方文档:http://wechat.aibotk.com/docs/about 120 | //AIBOTK_KEY: 填写智能微秘书个人中心的apikey 121 | //AIBOTK_TYPE:填写发送的目标 room 或 contact, 填其他的不生效 122 | //AIBOTK_NAME: 填写群名或用户昵称,和上面的type类型要对应 123 | let AIBOTK_KEY = ''; 124 | let AIBOTK_TYPE = ''; 125 | let AIBOTK_NAME = ''; 126 | 127 | // =======================================飞书机器人设置区域======================================= 128 | //官方文档:https://www.feishu.cn/hc/zh-CN/articles/360024984973 129 | //FSKEY 飞书机器人的 FSKEY 130 | let FSKEY = ''; 131 | 132 | // =======================================SMTP 邮件设置区域======================================= 133 | // SMTP_SERVER: 填写 SMTP 发送邮件服务器,形如 smtp.exmail.qq.com:465 134 | // SMTP_SSL: 填写 SMTP 发送邮件服务器是否使用 SSL,内容应为 true 或 false 135 | // SMTP_EMAIL: 填写 SMTP 收发件邮箱,通知将会由自己发给自己 136 | // SMTP_PASSWORD: 填写 SMTP 登录密码,也可能为特殊口令,视具体邮件服务商说明而定 137 | // SMTP_NAME: 填写 SMTP 收发件人姓名,可随意填写 138 | let SMTP_SERVER = ''; 139 | let SMTP_SSL = 'false'; 140 | let SMTP_EMAIL = ''; 141 | let SMTP_PASSWORD = ''; 142 | let SMTP_NAME = ''; 143 | 144 | // =======================================PushMe通知设置区域=========================================== 145 | //官方文档:https://push.i-i.me/ 146 | //此处填你的PushMe KEY. 147 | let PUSHME_KEY = ''; 148 | 149 | //==========================云端环境变量的判断与接收========================= 150 | if (process.env.GOTIFY_URL) { 151 | GOTIFY_URL = process.env.GOTIFY_URL; 152 | } 153 | if (process.env.GOTIFY_TOKEN) { 154 | GOTIFY_TOKEN = process.env.GOTIFY_TOKEN; 155 | } 156 | if (process.env.GOTIFY_PRIORITY) { 157 | GOTIFY_PRIORITY = process.env.GOTIFY_PRIORITY; 158 | } 159 | 160 | if (process.env.GOBOT_URL) { 161 | GOBOT_URL = process.env.GOBOT_URL; 162 | } 163 | if (process.env.GOBOT_TOKEN) { 164 | GOBOT_TOKEN = process.env.GOBOT_TOKEN; 165 | } 166 | if (process.env.GOBOT_QQ) { 167 | GOBOT_QQ = process.env.GOBOT_QQ; 168 | } 169 | 170 | if (process.env.PUSH_KEY) { 171 | SCKEY = process.env.PUSH_KEY; 172 | } 173 | 174 | if (process.env.DEER_KEY) { 175 | PUSHDEER_KEY = process.env.DEER_KEY; 176 | PUSHDEER_URL = process.env.DEER_URL; 177 | } 178 | 179 | if (process.env.CHAT_URL) { 180 | CHAT_URL = process.env.CHAT_URL; 181 | } 182 | 183 | if (process.env.CHAT_TOKEN) { 184 | CHAT_TOKEN = process.env.CHAT_TOKEN; 185 | } 186 | 187 | if (process.env.QQ_SKEY) { 188 | QQ_SKEY = process.env.QQ_SKEY; 189 | } 190 | 191 | if (process.env.QQ_MODE) { 192 | QQ_MODE = process.env.QQ_MODE; 193 | } 194 | 195 | if (process.env.BARK_PUSH) { 196 | if ( 197 | process.env.BARK_PUSH.indexOf('https') > -1 || 198 | process.env.BARK_PUSH.indexOf('http') > -1 199 | ) { 200 | //兼容BARK自建用户 201 | BARK_PUSH = process.env.BARK_PUSH; 202 | } else { 203 | BARK_PUSH = `https://api.day.app/${process.env.BARK_PUSH}`; 204 | } 205 | if (process.env.BARK_ICON) { 206 | BARK_ICON = process.env.BARK_ICON; 207 | } 208 | if (process.env.BARK_SOUND) { 209 | BARK_SOUND = process.env.BARK_SOUND; 210 | } 211 | if (process.env.BARK_GROUP) { 212 | BARK_GROUP = process.env.BARK_GROUP; 213 | } 214 | } else { 215 | if ( 216 | BARK_PUSH && 217 | BARK_PUSH.indexOf('https') === -1 && 218 | BARK_PUSH.indexOf('http') === -1 219 | ) { 220 | //兼容BARK本地用户只填写设备码的情况 221 | BARK_PUSH = `https://api.day.app/${BARK_PUSH}`; 222 | } 223 | } 224 | if (process.env.TG_BOT_TOKEN) { 225 | TG_BOT_TOKEN = process.env.TG_BOT_TOKEN; 226 | } 227 | if (process.env.TG_USER_ID) { 228 | TG_USER_ID = process.env.TG_USER_ID; 229 | } 230 | if (process.env.TG_PROXY_AUTH) TG_PROXY_AUTH = process.env.TG_PROXY_AUTH; 231 | if (process.env.TG_PROXY_HOST) TG_PROXY_HOST = process.env.TG_PROXY_HOST; 232 | if (process.env.TG_PROXY_PORT) TG_PROXY_PORT = process.env.TG_PROXY_PORT; 233 | if (process.env.TG_API_HOST) TG_API_HOST = process.env.TG_API_HOST; 234 | 235 | if (process.env.DD_BOT_TOKEN) { 236 | DD_BOT_TOKEN = process.env.DD_BOT_TOKEN; 237 | if (process.env.DD_BOT_SECRET) { 238 | DD_BOT_SECRET = process.env.DD_BOT_SECRET; 239 | } 240 | } 241 | 242 | if (process.env.QYWX_ORIGIN) { 243 | QYWX_ORIGIN = process.env.QYWX_ORIGIN; 244 | } else { 245 | QYWX_ORIGIN = 'https://qyapi.weixin.qq.com'; 246 | } 247 | 248 | if (process.env.QYWX_KEY) { 249 | QYWX_KEY = process.env.QYWX_KEY; 250 | } 251 | 252 | if (process.env.QYWX_AM) { 253 | QYWX_AM = process.env.QYWX_AM; 254 | } 255 | 256 | if (process.env.IGOT_PUSH_KEY) { 257 | IGOT_PUSH_KEY = process.env.IGOT_PUSH_KEY; 258 | } 259 | 260 | if (process.env.PUSH_PLUS_TOKEN) { 261 | PUSH_PLUS_TOKEN = process.env.PUSH_PLUS_TOKEN; 262 | } 263 | if (process.env.PUSH_PLUS_USER) { 264 | PUSH_PLUS_USER = process.env.PUSH_PLUS_USER; 265 | } 266 | 267 | if (process.env.AIBOTK_KEY) { 268 | AIBOTK_KEY = process.env.AIBOTK_KEY; 269 | } 270 | if (process.env.AIBOTK_TYPE) { 271 | AIBOTK_TYPE = process.env.AIBOTK_TYPE; 272 | } 273 | if (process.env.AIBOTK_NAME) { 274 | AIBOTK_NAME = process.env.AIBOTK_NAME; 275 | } 276 | 277 | if (process.env.FSKEY) { 278 | FSKEY = process.env.FSKEY; 279 | } 280 | 281 | if (process.env.SMTP_SERVER) { 282 | SMTP_SERVER = process.env.SMTP_SERVER; 283 | } 284 | if (process.env.SMTP_SSL) { 285 | SMTP_SSL = process.env.SMTP_SSL; 286 | } 287 | if (process.env.SMTP_EMAIL) { 288 | SMTP_EMAIL = process.env.SMTP_EMAIL; 289 | } 290 | if (process.env.SMTP_PASSWORD) { 291 | SMTP_PASSWORD = process.env.SMTP_PASSWORD; 292 | } 293 | if (process.env.SMTP_NAME) { 294 | SMTP_NAME = process.env.SMTP_NAME; 295 | } 296 | if (process.env.PUSHME_KEY) { 297 | PUSHME_KEY = process.env.PUSHME_KEY; 298 | } 299 | //==========================云端环境变量的判断与接收========================= 300 | 301 | /** 302 | * sendNotify 推送通知功能 303 | * @param text 通知头 304 | * @param desp 通知体 305 | * @param params 某些推送通知方式点击弹窗可跳转, 例:{ url: 'https://abc.com' } 306 | * @param author 作者仓库等信息 例:`本通知 By:https://github.com/whyour/qinglong` 307 | * @returns {Promise} 308 | */ 309 | async function sendNotify( 310 | text, 311 | desp, 312 | params = {}, 313 | author = '\n\n本通知 By:https://github.com/whyour/qinglong', 314 | ) { 315 | let pushType = ["smallfawnPushWhite", "smallfawnPushBlack", 'default'] 316 | /* 判断 黑白名单 或默认模式 */ 317 | function checkSmallfawnPushType() { 318 | if (process.env.hasOwnProperty(pushType[0]) !== false) { 319 | return pushType[0]; 320 | } else if (process.env.hasOwnProperty(pushType[1]) !== false) { 321 | return pushType[1]; 322 | } else { 323 | return pushType[2]; 324 | } 325 | } 326 | /** 327 | * 检测 smallfawnPushWhite 或 smallfawnPushBlack 的变量 328 | * @param {*} variable smallfawnPushWhite 或 smallfawnPushBlack 329 | * @returns 数组 330 | */ 331 | function checkSmallfawnPush(variable) { 332 | if (typeof variable === 'string') { 333 | if (variable.includes('&') || variable.includes('#') || variable.includes('@')) { 334 | return variable.split(/[&#@]/); 335 | } else { 336 | return [variable]; 337 | } 338 | } else if (typeof variable === 'number') { 339 | return [variable.toString()]; 340 | } else { 341 | return []; 342 | } 343 | } 344 | 345 | let type = checkSmallfawnPushType() 346 | 347 | console.log(`\n\n============================================`) 348 | // 主要 // 349 | //判断是否是默认通知方式 350 | if (type !== pushType[2]) { 351 | //判断数组长度 352 | if (checkSmallfawnPush(process.env[type]).length == 0) { 353 | console.log(`通知变量[${type}] 无变量值 默认形式发送 脚本名字[${text}]\n如果需要请填写脚本名字到通知变量 @或&或#为 分隔符`); 354 | await push() 355 | } else { 356 | //判断黑白名单模式 357 | if (type == pushType[0]) { 358 | console.log(`通知变量为白名单模式`); 359 | if (checkSmallfawnPush(process.env[pushType[0]]).includes(text)) { 360 | console.log(`脚本名字[${text}] 在 通知变量白名单[${type}] 变量中 => 通知`); 361 | await push(); 362 | } else { 363 | console.log(`脚本名字[${text}] 不在 通知变量白名单[${type}] 变量中 => 不通知`) 364 | } 365 | } else if (type == pushType[1]) { 366 | console.log(`通知变量为黑名单模式`); 367 | if (checkSmallfawnPush(process.env[pushType[1]]).includes(text)) { 368 | console.log(`脚本名字[${text}] 在 通知变量黑名单[${type}] 变量中 => 不通知`); 369 | } else { 370 | console.log(`脚本名字[${text}] 不在 通知变量黑名单[${type}] 变量中 => 通知`) 371 | await push(); 372 | } 373 | } 374 | } 375 | } else { 376 | console.log(`无黑白名单变量 默认形式发送 脚本名字[${text}]`); 377 | console.log(`如需配置通知黑白名单请在环境变量或配置文件 添加变量白名单 ${pushType[0]} 或 黑名单 ${pushType[1]}二选一 @或&或#为 分隔符 填写脚本名字`); 378 | await push() 379 | } 380 | 381 | async function push() { 382 | //提供6种通知 383 | desp += author; //增加作者信息,防止被贩卖等 384 | 385 | // 根据标题跳过一些消息推送,环境变量:SKIP_PUSH_TITLE 用回车分隔 386 | let skipTitle = process.env.SKIP_PUSH_TITLE; 387 | if (skipTitle) { 388 | if (skipTitle.split('\n').includes(text)) { 389 | console.info(text + '在SKIP_PUSH_TITLE环境变量内,跳过推送!'); 390 | return; 391 | } 392 | } 393 | 394 | await Promise.all([ 395 | serverNotify(text, desp), //微信server酱 396 | pushPlusNotify(text, desp), //pushplus(推送加) 397 | ]); 398 | //由于上述两种微信通知需点击进去才能查看到详情,故text(标题内容)携带了账号序号以及昵称信息,方便不点击也可知道是哪个京东哪个活动 399 | text = text.match(/.*?(?=\s?-)/g) ? text.match(/.*?(?=\s?-)/g)[0] : text; 400 | await Promise.all([ 401 | BarkNotify(text, desp, params), //iOS Bark APP 402 | tgBotNotify(text, desp), //telegram 机器人 403 | ddBotNotify(text, desp), //钉钉机器人 404 | qywxBotNotify(text, desp), //企业微信机器人 405 | qywxamNotify(text, desp), //企业微信应用消息推送 406 | iGotNotify(text, desp, params), //iGot 407 | gobotNotify(text, desp), //go-cqhttp 408 | gotifyNotify(text, desp), //gotify 409 | ChatNotify(text, desp), //synolog chat 410 | PushDeerNotify(text, desp), //PushDeer 411 | aibotkNotify(text, desp), //智能微秘书 412 | fsBotNotify(text, desp), //飞书机器人 413 | smtpNotify(text, desp), //SMTP 邮件 414 | ]); 415 | } 416 | } 417 | 418 | function gotifyNotify(text, desp) { 419 | return new Promise((resolve) => { 420 | if (GOTIFY_URL && GOTIFY_TOKEN) { 421 | const options = { 422 | url: `${GOTIFY_URL}/message?token=${GOTIFY_TOKEN}`, 423 | body: `title=${encodeURIComponent(text)}&message=${encodeURIComponent( 424 | desp, 425 | )}&priority=${GOTIFY_PRIORITY}`, 426 | headers: { 427 | 'Content-Type': 'application/x-www-form-urlencoded', 428 | }, 429 | }; 430 | $.post(options, (err, resp, data) => { 431 | try { 432 | if (err) { 433 | console.log('gotify发送通知调用API失败!!\n'); 434 | console.log(err); 435 | } else { 436 | data = JSON.parse(data); 437 | if (data.id) { 438 | console.log('gotify发送通知消息成功🎉\n'); 439 | } else { 440 | console.log(`${data.message}\n`); 441 | } 442 | } 443 | } catch (e) { 444 | $.logErr(e, resp); 445 | } finally { 446 | resolve(); 447 | } 448 | }); 449 | } else { 450 | resolve(); 451 | } 452 | }); 453 | } 454 | 455 | function gobotNotify(text, desp) { 456 | return new Promise((resolve) => { 457 | if (GOBOT_URL) { 458 | const options = { 459 | url: `${GOBOT_URL}?access_token=${GOBOT_TOKEN}&${GOBOT_QQ}`, 460 | json: { message: `${text}\n${desp}` }, 461 | headers: { 462 | 'Content-Type': 'application/json', 463 | }, 464 | timeout, 465 | }; 466 | $.post(options, (err, resp, data) => { 467 | try { 468 | if (err) { 469 | console.log('发送go-cqhttp通知调用API失败!!\n'); 470 | console.log(err); 471 | } else { 472 | data = JSON.parse(data); 473 | if (data.retcode === 0) { 474 | console.log('go-cqhttp发送通知消息成功🎉\n'); 475 | } else if (data.retcode === 100) { 476 | console.log(`go-cqhttp发送通知消息异常: ${data.errmsg}\n`); 477 | } else { 478 | console.log(`go-cqhttp发送通知消息异常\n${JSON.stringify(data)}`); 479 | } 480 | } 481 | } catch (e) { 482 | $.logErr(e, resp); 483 | } finally { 484 | resolve(data); 485 | } 486 | }); 487 | } else { 488 | resolve(); 489 | } 490 | }); 491 | } 492 | 493 | function serverNotify(text, desp) { 494 | return new Promise((resolve) => { 495 | if (SCKEY) { 496 | //微信server酱推送通知一个\n不会换行,需要两个\n才能换行,故做此替换 497 | desp = desp.replace(/[\n\r]/g, '\n\n'); 498 | const options = { 499 | url: SCKEY.includes('SCT') 500 | ? `https://sctapi.ftqq.com/${SCKEY}.send` 501 | : `https://sc.ftqq.com/${SCKEY}.send`, 502 | body: `text=${text}&desp=${desp}`, 503 | headers: { 504 | 'Content-Type': 'application/x-www-form-urlencoded', 505 | }, 506 | timeout, 507 | }; 508 | $.post(options, (err, resp, data) => { 509 | try { 510 | if (err) { 511 | console.log('发送通知调用API失败!!\n'); 512 | console.log(err); 513 | } else { 514 | data = JSON.parse(data); 515 | //server酱和Server酱·Turbo版的返回json格式不太一样 516 | if (data.errno === 0 || data.data.errno === 0) { 517 | console.log('server酱发送通知消息成功🎉\n'); 518 | } else if (data.errno === 1024) { 519 | // 一分钟内发送相同的内容会触发 520 | console.log(`server酱发送通知消息异常: ${data.errmsg}\n`); 521 | } else { 522 | console.log(`server酱发送通知消息异常\n${JSON.stringify(data)}`); 523 | } 524 | } 525 | } catch (e) { 526 | $.logErr(e, resp); 527 | } finally { 528 | resolve(data); 529 | } 530 | }); 531 | } else { 532 | resolve(); 533 | } 534 | }); 535 | } 536 | 537 | function PushDeerNotify(text, desp) { 538 | return new Promise((resolve) => { 539 | if (PUSHDEER_KEY) { 540 | // PushDeer 建议对消息内容进行 urlencode 541 | desp = encodeURI(desp); 542 | const options = { 543 | url: PUSHDEER_URL || `https://api2.pushdeer.com/message/push`, 544 | body: `pushkey=${PUSHDEER_KEY}&text=${text}&desp=${desp}&type=markdown`, 545 | headers: { 546 | 'Content-Type': 'application/x-www-form-urlencoded', 547 | }, 548 | timeout, 549 | }; 550 | $.post(options, (err, resp, data) => { 551 | try { 552 | if (err) { 553 | console.log('发送通知调用API失败!!\n'); 554 | console.log(err); 555 | } else { 556 | data = JSON.parse(data); 557 | // 通过返回的result的长度来判断是否成功 558 | if ( 559 | data.content.result.length !== undefined && 560 | data.content.result.length > 0 561 | ) { 562 | console.log('PushDeer发送通知消息成功🎉\n'); 563 | } else { 564 | console.log(`PushDeer发送通知消息异常\n${JSON.stringify(data)}`); 565 | } 566 | } 567 | } catch (e) { 568 | $.logErr(e, resp); 569 | } finally { 570 | resolve(data); 571 | } 572 | }); 573 | } else { 574 | resolve(); 575 | } 576 | }); 577 | } 578 | 579 | function ChatNotify(text, desp) { 580 | return new Promise((resolve) => { 581 | if (CHAT_URL && CHAT_TOKEN) { 582 | // 对消息内容进行 urlencode 583 | desp = encodeURI(desp); 584 | const options = { 585 | url: `${CHAT_URL}${CHAT_TOKEN}`, 586 | body: `payload={"text":"${text}\n${desp}"}`, 587 | headers: { 588 | 'Content-Type': 'application/x-www-form-urlencoded', 589 | }, 590 | }; 591 | $.post(options, (err, resp, data) => { 592 | try { 593 | if (err) { 594 | console.log('发送通知调用API失败!!\n'); 595 | console.log(err); 596 | } else { 597 | data = JSON.parse(data); 598 | if (data.success) { 599 | console.log('Chat发送通知消息成功🎉\n'); 600 | } else { 601 | console.log(`Chat发送通知消息异常\n${JSON.stringify(data)}`); 602 | } 603 | } 604 | } catch (e) { 605 | $.logErr(e); 606 | } finally { 607 | resolve(data); 608 | } 609 | }); 610 | } else { 611 | resolve(); 612 | } 613 | }); 614 | } 615 | 616 | function BarkNotify(text, desp, params = {}) { 617 | return new Promise((resolve) => { 618 | if (BARK_PUSH) { 619 | const options = { 620 | url: `${BARK_PUSH}/${encodeURIComponent(text)}/${encodeURIComponent( 621 | desp, 622 | )}?icon=${BARK_ICON}&sound=${BARK_SOUND}&group=${BARK_GROUP}&${querystring.stringify( 623 | params, 624 | )}`, 625 | headers: { 626 | 'Content-Type': 'application/x-www-form-urlencoded', 627 | }, 628 | timeout, 629 | }; 630 | $.get(options, (err, resp, data) => { 631 | try { 632 | if (err) { 633 | console.log('Bark APP发送通知调用API失败!!\n'); 634 | console.log(err); 635 | } else { 636 | data = JSON.parse(data); 637 | if (data.code === 200) { 638 | console.log('Bark APP发送通知消息成功🎉\n'); 639 | } else { 640 | console.log(`${data.message}\n`); 641 | } 642 | } 643 | } catch (e) { 644 | $.logErr(e, resp); 645 | } finally { 646 | resolve(); 647 | } 648 | }); 649 | } else { 650 | resolve(); 651 | } 652 | }); 653 | } 654 | 655 | function tgBotNotify(text, desp) { 656 | return new Promise((resolve) => { 657 | if (TG_BOT_TOKEN && TG_USER_ID) { 658 | const options = { 659 | url: `https://${TG_API_HOST}/bot${TG_BOT_TOKEN}/sendMessage`, 660 | json: { 661 | chat_id: `${TG_USER_ID}`, 662 | text: `${text}\n\n${desp}`, 663 | disable_web_page_preview: true, 664 | }, 665 | headers: { 666 | 'Content-Type': 'application/json', 667 | }, 668 | timeout, 669 | }; 670 | if (TG_PROXY_HOST && TG_PROXY_PORT) { 671 | const tunnel = require('tunnel'); 672 | const agent = { 673 | https: tunnel.httpsOverHttp({ 674 | proxy: { 675 | host: TG_PROXY_HOST, 676 | port: TG_PROXY_PORT * 1, 677 | proxyAuth: TG_PROXY_AUTH, 678 | }, 679 | }), 680 | }; 681 | Object.assign(options, { agent }); 682 | } 683 | $.post(options, (err, resp, data) => { 684 | try { 685 | if (err) { 686 | console.log('telegram发送通知消息失败!!\n'); 687 | console.log(err); 688 | } else { 689 | data = JSON.parse(data); 690 | if (data.ok) { 691 | console.log('Telegram发送通知消息成功🎉。\n'); 692 | } else if (data.error_code === 400) { 693 | console.log( 694 | '请主动给bot发送一条消息并检查接收用户ID是否正确。\n', 695 | ); 696 | } else if (data.error_code === 401) { 697 | console.log('Telegram bot token 填写错误。\n'); 698 | } 699 | } 700 | } catch (e) { 701 | $.logErr(e, resp); 702 | } finally { 703 | resolve(data); 704 | } 705 | }); 706 | } else { 707 | resolve(); 708 | } 709 | }); 710 | } 711 | function ddBotNotify(text, desp) { 712 | return new Promise((resolve) => { 713 | const options = { 714 | url: `https://oapi.dingtalk.com/robot/send?access_token=${DD_BOT_TOKEN}`, 715 | json: { 716 | msgtype: 'text', 717 | text: { 718 | content: `${text}\n\n${desp}`, 719 | }, 720 | }, 721 | headers: { 722 | 'Content-Type': 'application/json', 723 | }, 724 | timeout, 725 | }; 726 | if (DD_BOT_TOKEN && DD_BOT_SECRET) { 727 | const crypto = require('crypto'); 728 | const dateNow = Date.now(); 729 | const hmac = crypto.createHmac('sha256', DD_BOT_SECRET); 730 | hmac.update(`${dateNow}\n${DD_BOT_SECRET}`); 731 | const result = encodeURIComponent(hmac.digest('base64')); 732 | options.url = `${options.url}×tamp=${dateNow}&sign=${result}`; 733 | $.post(options, (err, resp, data) => { 734 | try { 735 | if (err) { 736 | console.log('钉钉发送通知消息失败!!\n'); 737 | console.log(err); 738 | } else { 739 | data = JSON.parse(data); 740 | if (data.errcode === 0) { 741 | console.log('钉钉发送通知消息成功🎉。\n'); 742 | } else { 743 | console.log(`${data.errmsg}\n`); 744 | } 745 | } 746 | } catch (e) { 747 | $.logErr(e, resp); 748 | } finally { 749 | resolve(data); 750 | } 751 | }); 752 | } else if (DD_BOT_TOKEN) { 753 | $.post(options, (err, resp, data) => { 754 | try { 755 | if (err) { 756 | console.log('钉钉发送通知消息失败!!\n'); 757 | console.log(err); 758 | } else { 759 | data = JSON.parse(data); 760 | if (data.errcode === 0) { 761 | console.log('钉钉发送通知消息完成。\n'); 762 | } else { 763 | console.log(`${data.errmsg}\n`); 764 | } 765 | } 766 | } catch (e) { 767 | $.logErr(e, resp); 768 | } finally { 769 | resolve(data); 770 | } 771 | }); 772 | } else { 773 | resolve(); 774 | } 775 | }); 776 | } 777 | 778 | function qywxBotNotify(text, desp) { 779 | return new Promise((resolve) => { 780 | const options = { 781 | url: `${QYWX_ORIGIN}/cgi-bin/webhook/send?key=${QYWX_KEY}`, 782 | json: { 783 | msgtype: 'text', 784 | text: { 785 | content: `${text}\n\n${desp}`, 786 | }, 787 | }, 788 | headers: { 789 | 'Content-Type': 'application/json', 790 | }, 791 | timeout, 792 | }; 793 | if (QYWX_KEY) { 794 | $.post(options, (err, resp, data) => { 795 | try { 796 | if (err) { 797 | console.log('企业微信发送通知消息失败!!\n'); 798 | console.log(err); 799 | } else { 800 | data = JSON.parse(data); 801 | if (data.errcode === 0) { 802 | console.log('企业微信发送通知消息成功🎉。\n'); 803 | } else { 804 | console.log(`${data.errmsg}\n`); 805 | } 806 | } 807 | } catch (e) { 808 | $.logErr(e, resp); 809 | } finally { 810 | resolve(data); 811 | } 812 | }); 813 | } else { 814 | resolve(); 815 | } 816 | }); 817 | } 818 | 819 | function ChangeUserId(desp) { 820 | const QYWX_AM_AY = QYWX_AM.split(','); 821 | if (QYWX_AM_AY[2]) { 822 | const userIdTmp = QYWX_AM_AY[2].split('|'); 823 | let userId = ''; 824 | for (let i = 0; i < userIdTmp.length; i++) { 825 | const count = '账号' + (i + 1); 826 | const count2 = '签到号 ' + (i + 1); 827 | if (desp.match(count2)) { 828 | userId = userIdTmp[i]; 829 | } 830 | } 831 | if (!userId) userId = QYWX_AM_AY[2]; 832 | return userId; 833 | } else { 834 | return '@all'; 835 | } 836 | } 837 | 838 | function qywxamNotify(text, desp) { 839 | return new Promise((resolve) => { 840 | if (QYWX_AM) { 841 | const QYWX_AM_AY = QYWX_AM.split(','); 842 | const options_accesstoken = { 843 | url: `${QYWX_ORIGIN}/cgi-bin/gettoken`, 844 | json: { 845 | corpid: `${QYWX_AM_AY[0]}`, 846 | corpsecret: `${QYWX_AM_AY[1]}`, 847 | }, 848 | headers: { 849 | 'Content-Type': 'application/json', 850 | }, 851 | timeout, 852 | }; 853 | $.post(options_accesstoken, (err, resp, data) => { 854 | let html = desp.replace(/\n/g, '
'); 855 | let json = JSON.parse(data); 856 | let accesstoken = json.access_token; 857 | let options; 858 | 859 | switch (QYWX_AM_AY[4]) { 860 | case '0': 861 | options = { 862 | msgtype: 'textcard', 863 | textcard: { 864 | title: `${text}`, 865 | description: `${desp}`, 866 | url: 'https://github.com/whyour/qinglong', 867 | btntxt: '更多', 868 | }, 869 | }; 870 | break; 871 | 872 | case '1': 873 | options = { 874 | msgtype: 'text', 875 | text: { 876 | content: `${text}\n\n${desp}`, 877 | }, 878 | }; 879 | break; 880 | 881 | default: 882 | options = { 883 | msgtype: 'mpnews', 884 | mpnews: { 885 | articles: [ 886 | { 887 | title: `${text}`, 888 | thumb_media_id: `${QYWX_AM_AY[4]}`, 889 | author: `智能助手`, 890 | content_source_url: ``, 891 | content: `${html}`, 892 | digest: `${desp}`, 893 | }, 894 | ], 895 | }, 896 | }; 897 | } 898 | if (!QYWX_AM_AY[4]) { 899 | //如不提供第四个参数,则默认进行文本消息类型推送 900 | options = { 901 | msgtype: 'text', 902 | text: { 903 | content: `${text}\n\n${desp}`, 904 | }, 905 | }; 906 | } 907 | options = { 908 | url: `${QYWX_ORIGIN}/cgi-bin/message/send?access_token=${accesstoken}`, 909 | json: { 910 | touser: `${ChangeUserId(desp)}`, 911 | agentid: `${QYWX_AM_AY[3]}`, 912 | safe: '0', 913 | ...options, 914 | }, 915 | headers: { 916 | 'Content-Type': 'application/json', 917 | }, 918 | }; 919 | 920 | $.post(options, (err, resp, data) => { 921 | try { 922 | if (err) { 923 | console.log( 924 | '成员ID:' + 925 | ChangeUserId(desp) + 926 | '企业微信应用消息发送通知消息失败!!\n', 927 | ); 928 | console.log(err); 929 | } else { 930 | data = JSON.parse(data); 931 | if (data.errcode === 0) { 932 | console.log( 933 | '成员ID:' + 934 | ChangeUserId(desp) + 935 | '企业微信应用消息发送通知消息成功🎉。\n', 936 | ); 937 | } else { 938 | console.log(`${data.errmsg}\n`); 939 | } 940 | } 941 | } catch (e) { 942 | $.logErr(e, resp); 943 | } finally { 944 | resolve(data); 945 | } 946 | }); 947 | }); 948 | } else { 949 | resolve(); 950 | } 951 | }); 952 | } 953 | 954 | function iGotNotify(text, desp, params = {}) { 955 | return new Promise((resolve) => { 956 | if (IGOT_PUSH_KEY) { 957 | // 校验传入的IGOT_PUSH_KEY是否有效 958 | const IGOT_PUSH_KEY_REGX = new RegExp('^[a-zA-Z0-9]{24}$'); 959 | if (!IGOT_PUSH_KEY_REGX.test(IGOT_PUSH_KEY)) { 960 | console.log('您所提供的IGOT_PUSH_KEY无效\n'); 961 | resolve(); 962 | return; 963 | } 964 | const options = { 965 | url: `https://push.hellyw.com/${IGOT_PUSH_KEY.toLowerCase()}`, 966 | body: `title=${text}&content=${desp}&${querystring.stringify(params)}`, 967 | headers: { 968 | 'Content-Type': 'application/x-www-form-urlencoded', 969 | }, 970 | timeout, 971 | }; 972 | $.post(options, (err, resp, data) => { 973 | try { 974 | if (err) { 975 | console.log('发送通知调用API失败!!\n'); 976 | console.log(err); 977 | } else { 978 | if (typeof data === 'string') data = JSON.parse(data); 979 | if (data.ret === 0) { 980 | console.log('iGot发送通知消息成功🎉\n'); 981 | } else { 982 | console.log(`iGot发送通知消息失败:${data.errMsg}\n`); 983 | } 984 | } 985 | } catch (e) { 986 | $.logErr(e, resp); 987 | } finally { 988 | resolve(data); 989 | } 990 | }); 991 | } else { 992 | resolve(); 993 | } 994 | }); 995 | } 996 | 997 | function pushPlusNotify(text, desp) { 998 | return new Promise((resolve) => { 999 | if (PUSH_PLUS_TOKEN) { 1000 | desp = desp.replace(/[\n\r]/g, '
'); // 默认为html, 不支持plaintext 1001 | const body = { 1002 | token: `${PUSH_PLUS_TOKEN}`, 1003 | title: `${text}`, 1004 | content: `${desp}`, 1005 | topic: `${PUSH_PLUS_USER}`, 1006 | }; 1007 | const options = { 1008 | url: `https://www.pushplus.plus/send`, 1009 | body: JSON.stringify(body), 1010 | headers: { 1011 | 'Content-Type': ' application/json', 1012 | }, 1013 | timeout, 1014 | }; 1015 | $.post(options, (err, resp, data) => { 1016 | try { 1017 | if (err) { 1018 | console.log( 1019 | `push+发送${PUSH_PLUS_USER ? '一对多' : '一对一' 1020 | }通知消息失败!!\n`, 1021 | ); 1022 | console.log(err); 1023 | } else { 1024 | data = JSON.parse(data); 1025 | if (data.code === 200) { 1026 | console.log( 1027 | `push+发送${PUSH_PLUS_USER ? '一对多' : '一对一' 1028 | }通知消息完成。\n`, 1029 | ); 1030 | } else { 1031 | console.log( 1032 | `push+发送${PUSH_PLUS_USER ? '一对多' : '一对一' 1033 | }通知消息失败:${data.msg}\n`, 1034 | ); 1035 | } 1036 | } 1037 | } catch (e) { 1038 | $.logErr(e, resp); 1039 | } finally { 1040 | resolve(data); 1041 | } 1042 | }); 1043 | } else { 1044 | resolve(); 1045 | } 1046 | }); 1047 | } 1048 | 1049 | function aibotkNotify(text, desp) { 1050 | return new Promise((resolve) => { 1051 | if (AIBOTK_KEY && AIBOTK_TYPE && AIBOTK_NAME) { 1052 | let json = {}; 1053 | let url = ''; 1054 | switch (AIBOTK_TYPE) { 1055 | case 'room': 1056 | url = 'https://api-bot.aibotk.com/openapi/v1/chat/room'; 1057 | json = { 1058 | apiKey: `${AIBOTK_KEY}`, 1059 | roomName: `${AIBOTK_NAME}`, 1060 | message: { 1061 | type: 1, 1062 | content: `【青龙快讯】\n\n${text}\n${desp}`, 1063 | }, 1064 | }; 1065 | break; 1066 | case 'contact': 1067 | url = 'https://api-bot.aibotk.com/openapi/v1/chat/contact'; 1068 | json = { 1069 | apiKey: `${AIBOTK_KEY}`, 1070 | name: `${AIBOTK_NAME}`, 1071 | message: { 1072 | type: 1, 1073 | content: `【青龙快讯】\n\n${text}\n${desp}`, 1074 | }, 1075 | }; 1076 | break; 1077 | } 1078 | const options = { 1079 | url: url, 1080 | json, 1081 | headers: { 1082 | 'Content-Type': 'application/json', 1083 | }, 1084 | timeout, 1085 | }; 1086 | $.post(options, (err, resp, data) => { 1087 | try { 1088 | if (err) { 1089 | console.log('智能微秘书发送通知消息失败!!\n'); 1090 | console.log(err); 1091 | } else { 1092 | data = JSON.parse(data); 1093 | if (data.code === 0) { 1094 | console.log('智能微秘书发送通知消息成功🎉。\n'); 1095 | } else { 1096 | console.log(`${data.error}\n`); 1097 | } 1098 | } 1099 | } catch (e) { 1100 | $.logErr(e, resp); 1101 | } finally { 1102 | resolve(data); 1103 | } 1104 | }); 1105 | } else { 1106 | resolve(); 1107 | } 1108 | }); 1109 | } 1110 | 1111 | function fsBotNotify(text, desp) { 1112 | return new Promise((resolve) => { 1113 | if (FSKEY) { 1114 | const options = { 1115 | url: `https://open.feishu.cn/open-apis/bot/v2/hook/${FSKEY}`, 1116 | json: { msg_type: 'text', content: { text: `${text}\n\n${desp}` } }, 1117 | headers: { 1118 | 'Content-Type': 'application/json', 1119 | }, 1120 | timeout, 1121 | }; 1122 | $.post(options, (err, resp, data) => { 1123 | try { 1124 | if (err) { 1125 | console.log('发送通知调用API失败!!\n'); 1126 | console.log(err); 1127 | } else { 1128 | data = JSON.parse(data); 1129 | if (data.StatusCode === 0) { 1130 | console.log('飞书发送通知消息成功🎉\n'); 1131 | } else { 1132 | console.log(`${data.msg}\n`); 1133 | } 1134 | } 1135 | } catch (e) { 1136 | $.logErr(e, resp); 1137 | } finally { 1138 | resolve(data); 1139 | } 1140 | }); 1141 | } else { 1142 | resolve(); 1143 | } 1144 | }); 1145 | } 1146 | 1147 | async function smtpNotify(text, desp) { 1148 | if (![SMTP_SERVER, SMTP_EMAIL, SMTP_PASSWORD].every(Boolean)) { 1149 | return; 1150 | } 1151 | 1152 | try { 1153 | const nodemailer = require('nodemailer'); 1154 | const transporter = nodemailer.createTransport( 1155 | `${SMTP_SSL === 'true' ? 'smtps:' : 'smtp:'}//${SMTP_SERVER}`, 1156 | { 1157 | auth: { 1158 | user: SMTP_EMAIL, 1159 | pass: SMTP_PASSWORD, 1160 | }, 1161 | }, 1162 | ); 1163 | 1164 | const addr = SMTP_NAME ? `"${SMTP_NAME}" <${SMTP_EMAIL}>` : SMTP_EMAIL; 1165 | const info = await transporter.sendMail({ 1166 | from: addr, 1167 | to: addr, 1168 | subject: text, 1169 | text: desp, 1170 | }); 1171 | 1172 | if (!!info.messageId) { 1173 | console.log('SMTP发送通知消息成功🎉\n'); 1174 | return true; 1175 | } 1176 | console.log('SMTP发送通知消息失败!!\n'); 1177 | } catch (e) { 1178 | console.log('SMTP发送通知消息出现错误!!\n'); 1179 | console.log(e); 1180 | } 1181 | } 1182 | 1183 | function smtpNotify(text, desp) { 1184 | return new Promise((resolve) => { 1185 | if (SMTP_SERVER && SMTP_SSL && SMTP_EMAIL && SMTP_PASSWORD && SMTP_NAME) { 1186 | // todo: Node.js并没有内置的 smtp 实现,需要调用外部库,因为不清楚这个文件的模块依赖情况,所以留给有缘人实现 1187 | } else { 1188 | resolve(); 1189 | } 1190 | }); 1191 | } 1192 | 1193 | function PushMeNotify(text, desp) { 1194 | return new Promise((resolve) => { 1195 | if (PUSHME_KEY) { 1196 | const options = { 1197 | url: `https://push.i-i.me?push_key=${PUSHME_KEY}`, 1198 | json: { title: text, content: desp }, 1199 | headers: { 1200 | 'Content-Type': 'application/json', 1201 | }, 1202 | timeout, 1203 | }; 1204 | $.post(options, (err, resp, data) => { 1205 | try { 1206 | if (err) { 1207 | console.log('PushMeNotify发送通知调用API失败!!\n'); 1208 | console.log(err); 1209 | } else { 1210 | if (data === 'success') { 1211 | console.log('PushMe发送通知消息成功🎉\n'); 1212 | } else { 1213 | console.log(`${data}\n`); 1214 | } 1215 | } 1216 | } catch (e) { 1217 | $.logErr(e, resp); 1218 | } finally { 1219 | resolve(data); 1220 | } 1221 | }); 1222 | } else { 1223 | resolve(); 1224 | } 1225 | }); 1226 | } 1227 | 1228 | module.exports = { 1229 | sendNotify, 1230 | BARK_PUSH, 1231 | }; 1232 | 1233 | // prettier-ignore 1234 | function Env(t, s) { return new class { constructor(t, s) { this.name = t, this.data = null, this.dataFile = "box.dat", this.logs = [], this.logSeparator = "\n", this.startTime = (new Date).getTime(), Object.assign(this, s), this.log("", `\ud83d\udd14${this.name}, \u5f00\u59cb!`) } 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 } getScript(t) { return new Promise(s => { $.get({ url: t }, (t, e, i) => s(i)) }) } runScript(t, s) { return new Promise(e => { let i = this.getdata("@chavy_boxjs_userCfgs.httpapi"); i = i ? i.replace(/\n/g, "").trim() : i; let o = this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout"); o = o ? 1 * o : 20, o = s && s.timeout ? s.timeout : o; const [h, a] = i.split("@"), r = { url: `http://${a}/v1/scripting/evaluate`, body: { script_text: t, mock_type: "cron", timeout: o }, headers: { "X-Key": h, Accept: "*/*" } }; $.post(r, (t, s, i) => e(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), s = this.path.resolve(process.cwd(), this.dataFile), e = this.fs.existsSync(t), i = !e && this.fs.existsSync(s); if (!e && !i) return {}; { const i = e ? t : s; 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), s = this.path.resolve(process.cwd(), this.dataFile), e = this.fs.existsSync(t), i = !e && this.fs.existsSync(s), o = JSON.stringify(this.data); e ? this.fs.writeFileSync(t, o) : i ? this.fs.writeFileSync(s, o) : this.fs.writeFileSync(t, o) } } lodash_get(t, s, e) { const i = s.replace(/\[(\d+)\]/g, ".$1").split("."); let o = t; for (const t of i) if (o = Object(o)[t], void 0 === o) return e; return o } lodash_set(t, s, e) { return Object(t) !== t ? t : (Array.isArray(s) || (s = s.toString().match(/[^.[\]]+/g) || []), s.slice(0, -1).reduce((t, e, i) => Object(t[e]) === t[e] ? t[e] : t[e] = Math.abs(s[i + 1]) >> 0 == +s[i + 1] ? [] : {}, t)[s[s.length - 1]] = e, t) } getdata(t) { let s = this.getval(t); if (/^@/.test(t)) { const [, e, i] = /^@(.*?)\.(.*?)$/.exec(t), o = e ? this.getval(e) : ""; if (o) try { const t = JSON.parse(o); s = t ? this.lodash_get(t, i, "") : s } catch (t) { s = "" } } return s } setdata(t, s) { let e = !1; if (/^@/.test(s)) { const [, i, o] = /^@(.*?)\.(.*?)$/.exec(s), h = this.getval(i), a = i ? "null" === h ? null : h || "{}" : "{}"; try { const s = JSON.parse(a); this.lodash_set(s, o, t), e = this.setval(JSON.stringify(s), i) } catch (s) { const h = {}; this.lodash_set(h, o, t), e = this.setval(JSON.stringify(h), i) } } else e = $.setval(t, s); return e } 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, s) { return this.isSurge() || this.isLoon() ? $persistentStore.write(t, s) : this.isQuanX() ? $prefs.setValueForKey(t, s) : this.isNode() ? (this.data = this.loaddata(), this.data[s] = t, this.writedata(), !0) : this.data && this.data[s] || 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, s = (() => { })) { t.headers && (delete t.headers["Content-Type"], delete t.headers["Content-Length"]), this.isSurge() || this.isLoon() ? $httpClient.get(t, (t, e, i) => { !t && e && (e.body = i, e.statusCode = e.status), s(t, e, i) }) : this.isQuanX() ? $task.fetch(t).then(t => { const { statusCode: e, statusCode: i, headers: o, body: h } = t; s(null, { status: e, statusCode: i, headers: o, body: h }, h) }, t => s(t)) : this.isNode() && (this.initGotEnv(t), this.got(t).on("redirect", (t, s) => { try { const e = t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString(); this.ckjar.setCookieSync(e, null), s.cookieJar = this.ckjar } catch (t) { this.logErr(t) } }).then(t => { const { statusCode: e, statusCode: i, headers: o, body: h } = t; s(null, { status: e, statusCode: i, headers: o, body: h }, h) }, t => s(t))) } post(t, s = (() => { })) { if (t.body && t.headers && !t.headers["Content-Type"] && (t.headers["Content-Type"] = "application/x-www-form-urlencoded"), delete t.headers["Content-Length"], this.isSurge() || this.isLoon()) $httpClient.post(t, (t, e, i) => { !t && e && (e.body = i, e.statusCode = e.status), s(t, e, i) }); else if (this.isQuanX()) t.method = "POST", $task.fetch(t).then(t => { const { statusCode: e, statusCode: i, headers: o, body: h } = t; s(null, { status: e, statusCode: i, headers: o, body: h }, h) }, t => s(t)); else if (this.isNode()) { this.initGotEnv(t); const { url: e, ...i } = t; this.got.post(e, i).then(t => { const { statusCode: e, statusCode: i, headers: o, body: h } = t; s(null, { status: e, statusCode: i, headers: o, body: h }, h) }, t => s(t)) } } time(t) { let s = { "M+": (new Date).getMonth() + 1, "d+": (new Date).getDate(), "H+": (new Date).getHours(), "m+": (new Date).getMinutes(), "s+": (new Date).getSeconds(), "q+": Math.floor(((new Date).getMonth() + 3) / 3), S: (new Date).getMilliseconds() }; /(y+)/.test(t) && (t = t.replace(RegExp.$1, ((new Date).getFullYear() + "").substr(4 - RegExp.$1.length))); for (let e in s) new RegExp("(" + e + ")").test(t) && (t = t.replace(RegExp.$1, 1 == RegExp.$1.length ? s[e] : ("00" + s[e]).substr(("" + s[e]).length))); return t } msg(s = t, e = "", i = "", o) { const h = t => !t || !this.isLoon() && this.isSurge() ? t : "string" == typeof t ? this.isLoon() ? t : this.isQuanX() ? { "open-url": t } : void 0 : "object" == typeof t && (t["open-url"] || t["media-url"]) ? this.isLoon() ? t["open-url"] : this.isQuanX() ? t : void 0 : void 0; $.isMute || (this.isSurge() || this.isLoon() ? $notification.post(s, e, i, h(o)) : this.isQuanX() && $notify(s, e, i, h(o))), this.logs.push("", "==============\ud83d\udce3\u7cfb\u7edf\u901a\u77e5\ud83d\udce3=============="), this.logs.push(s), e && this.logs.push(e), i && this.logs.push(i) } log(...t) { t.length > 0 ? this.logs = [...this.logs, ...t] : console.log(this.logs.join(this.logSeparator)) } logErr(t, s) { const e = !this.isSurge() && !this.isQuanX() && !this.isLoon(); e ? $.log("", `\u2757\ufe0f${this.name}, \u9519\u8bef!`, t.stack) : $.log("", `\u2757\ufe0f${this.name}, \u9519\u8bef!`, t) } wait(t) { return new Promise(s => setTimeout(s, t)) } done(t = {}) { const s = (new Date).getTime(), e = (s - this.startTime) / 1e3; this.log("", `\ud83d\udd14${this.name}, \u7ed3\u675f! \ud83d\udd5b ${e} \u79d2`), this.log(), (this.isSurge() || this.isQuanX() || this.isLoon()) && $done(t) } }(t, s) } 1235 | -------------------------------------------------------------------------------- /tls.js: -------------------------------------------------------------------------------- 1 | /************************************** 2 | new Env('特仑苏'); 3 | 抓mall.telunsu.net域名中的Cookie和openid一天一次 4 | ******************************************/ 5 | var _0xodc='jsjiami.com.v7';function _0x42d9(_0x494c06,_0x4d08ae){const _0x189e33=_0x189e();return _0x42d9=function(_0x42d91a,_0xf65dbb){_0x42d91a=_0x42d91a-0x159;let _0x447c38=_0x189e33[_0x42d91a];if(_0x42d9['DBKlBz']===undefined){var _0xa4fbd6=function(_0x39e6b3){const _0x539be5='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0xba748e='',_0x45573e='';for(let _0x1e30cd=0x0,_0x156b44,_0x4aff6b,_0x355c58=0x0;_0x4aff6b=_0x39e6b3['charAt'](_0x355c58++);~_0x4aff6b&&(_0x156b44=_0x1e30cd%0x4?_0x156b44*0x40+_0x4aff6b:_0x4aff6b,_0x1e30cd++%0x4)?_0xba748e+=String['fromCharCode'](0xff&_0x156b44>>(-0x2*_0x1e30cd&0x6)):0x0){_0x4aff6b=_0x539be5['indexOf'](_0x4aff6b);}for(let _0x13b94e=0x0,_0x3a174c=_0xba748e['length'];_0x13b94e<_0x3a174c;_0x13b94e++){_0x45573e+='%'+('00'+_0xba748e['charCodeAt'](_0x13b94e)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x45573e);};const _0x2ce9b8=function(_0x17b7e8,_0x7b6bee){let _0x179822=[],_0x15c637=0x0,_0x5ebddf,_0x5bd186='';_0x17b7e8=_0xa4fbd6(_0x17b7e8);let _0x83ac9d;for(_0x83ac9d=0x0;_0x83ac9d<0x100;_0x83ac9d++){_0x179822[_0x83ac9d]=_0x83ac9d;}for(_0x83ac9d=0x0;_0x83ac9d<0x100;_0x83ac9d++){_0x15c637=(_0x15c637+_0x179822[_0x83ac9d]+_0x7b6bee['charCodeAt'](_0x83ac9d%_0x7b6bee['length']))%0x100,_0x5ebddf=_0x179822[_0x83ac9d],_0x179822[_0x83ac9d]=_0x179822[_0x15c637],_0x179822[_0x15c637]=_0x5ebddf;}_0x83ac9d=0x0,_0x15c637=0x0;for(let _0x410230=0x0;_0x410230<_0x17b7e8['length'];_0x410230++){_0x83ac9d=(_0x83ac9d+0x1)%0x100,_0x15c637=(_0x15c637+_0x179822[_0x83ac9d])%0x100,_0x5ebddf=_0x179822[_0x83ac9d],_0x179822[_0x83ac9d]=_0x179822[_0x15c637],_0x179822[_0x15c637]=_0x5ebddf,_0x5bd186+=String['fromCharCode'](_0x17b7e8['charCodeAt'](_0x410230)^_0x179822[(_0x179822[_0x83ac9d]+_0x179822[_0x15c637])%0x100]);}return _0x5bd186;};_0x42d9['ejHKQg']=_0x2ce9b8,_0x494c06=arguments,_0x42d9['DBKlBz']=!![];}const _0x1bef7c=_0x189e33[0x0],_0xc438e9=_0x42d91a+_0x1bef7c,_0x2834fb=_0x494c06[_0xc438e9];return!_0x2834fb?(_0x42d9['wgaIIw']===undefined&&(_0x42d9['wgaIIw']=!![]),_0x447c38=_0x42d9['ejHKQg'](_0x447c38,_0xf65dbb),_0x494c06[_0xc438e9]=_0x447c38):_0x447c38=_0x2834fb,_0x447c38;},_0x42d9(_0x494c06,_0x4d08ae);}function _0x189e(){const _0x5f366e=(function(){return[_0xodc,'wdfLjuuKsINYjSiaBmiUJW.PrckSoLTmRx.XKvn7==','A8oXAh8riCoB','mmk9FdKgW4KdW4r1hKZcHSke','t8ojgmoDWRnekmoCmSovW5VdLmkJ','cZGf','cSoiw1TO','WQlcPLGek+w8H+wKHUAiK+IHK+ETTowjVCogv8o2WRDM','56295yQj57I45PYYsc8','W4OPWR1XW4K','uCoEnCkRWPOWbmkBjSk3iCorW7u','W5bfW6dcJSowdY1llSkmfKldKIFdRLlcJSkaswlcQ8oinhiHWOBdTSkox8kX','W5JdNmoAWQFcT8oVW4hcRmkIa8kHbKa','t8okfSoAWRfbl8omd8o0W67dPmkd','k27dQmkNuNxdNwS','BdNdJ3e'].concat((function(){return['WO18W6yYWPpcH3G+y8oCWRJdHSo/','fSofWQm','w8odWPKMWRFdHMbpWQdcKCkd','566z5yQ25AwJ6lEZW4i','ymoyWP/dJrO','hSkwumkzW78','ACkKW654iCklvHpdRCo1WRFcSG3cGrZdN8k8q8ouWQpdGbnqWPG','D8o/kgbh','W4DzCmo9W4RdOgpcSq','WORcNmkdW7/dSW','W6f7W5PpWQPRW5FdQSkNW4pcVxK/W4aOW6ZcK8o2W4OquKn0WRHMWQetW7LxFfZdLaziW5q','WQXaW57cTa','gCkYWR8','hSoVWOq','uCoEmmkQWPi8b8kfgCkpc8okW6q','W6zbW67dL8kUWQemdSkLW6/cLCoKW74'].concat((function(){return['WO4oWOjbW47dGXO','jCkoW4VdMWvxW4hdOmo4WRfmz8oL','W543WRL1WOJcLYGksmovWRZdISos','n8kiW5VcMeO7mSoxq8kKWQhdHMG','y23dSZtcH8oJkG','W5ZcP8k4W5tdQSkPWQe','vwXwW60PWPdcGCkeiw/dOCkJ','BrddVGpdLJ5nnw7cIq4sse7dG8otjshdRZVdV8ojqs4skCoWW6VcJgtcQmopw8oXjmkXreFcHg4RW6yKWRuiWPmKWRWmu8oduqVdOv3cUSo0WOhcGmkqWPLxvWChjCkTWQvIkZzJWQvReSkEW5C','nSkuwSkeW6ODESkYD8k/WRVcVmoJEYPeW5q+nItcJbtcGNxcKWBcVCoNWOycgN8vELJcT0ZdI25uWQJdKColnKrXW7NdUCocWPdcHSkGWQyHlZTmySoFyCofW4VcRCkuWPWfW5SJWRvNlsFcPJr2vrydemoiW5ddQSokWRfdW7ddG8oaW4hcL8kIb0KNxa83fmk6g8oTm8kgW6JdL8kEbYCjkCk2W6CiaCkMW7NcT8kmEqqoW5JcJCowWOa7thxdUv3cUmkRrL/dNNL0WOepW5xcLmovWRO1WOtdLmkqW78bjCoUnmkUnmoQW6NdK2pdTmoRW7zPWRyGWQv2W6n/WPPMW7dcQtK3WOLGq3XkztJcG0RcJmkiDSkjW7xdUmkBB8kJWPxcKISgpSkyWPRcJCkzW63dIYBdLSo6W5ldOCocW7HmW4VdQmosiSkMlhtdUgaUWPBcMCo9oCkZW67cJMJdGSoOeNBdGhNcQwT2WOpcJ1/dImkYiqRdNSohsmoUvqJdM1xcRX7cPLpcHSo3dKegvmk2WQFdIIPygYxcRmk1wSkgpCoaj0ZcSh/cMSk7W67dNI9+W4neW7i9uCkiWO83WOmBhCkxW6JdIw3dR0hdSmoOW6hcNSkCWR3dGh8SWPr/WOVdI3C+WR3cVsqJW5mVuW','kK5+WQGkW59TW57cKmoHW4P3','WOtdQt/dUmkmAmkQW5ldLSkEW5ldGSoaEG','5BQS57UG5AET6AkJ55M+6isx5Bwi552V55+B54+Y','WQNcQfiiittdUdfwqrFcGI4','WQdcJ8k8'];}()));}()));}());_0x189e=function(){return _0x5f366e;};return _0x189e();};const _0x37397b=_0x42d9;if(function(_0x5e1a16,_0x293426,_0x35dd2a,_0x3d2c65,_0x41a74f,_0x1bbfd2,_0x44c400){return _0x5e1a16=_0x5e1a16>>0x2,_0x1bbfd2='hs',_0x44c400='hs',function(_0x7c8a8b,_0x2e5bd8,_0x2a9a24,_0x4642b4,_0x4b3ae3){const _0x62ef1a=_0x42d9;_0x4642b4='tfi',_0x1bbfd2=_0x4642b4+_0x1bbfd2,_0x4b3ae3='up',_0x44c400+=_0x4b3ae3,_0x1bbfd2=_0x2a9a24(_0x1bbfd2),_0x44c400=_0x2a9a24(_0x44c400),_0x2a9a24=0x0;const _0x1c0b9b=_0x7c8a8b();while(!![]&&--_0x3d2c65+_0x2e5bd8){try{_0x4642b4=parseInt(_0x62ef1a(0x174,'I3Gg'))/0x1*(-parseInt(_0x62ef1a(0x17c,'fNxA'))/0x2)+-parseInt(_0x62ef1a(0x15a,'Crao'))/0x3+-parseInt(_0x62ef1a(0x16c,'[8AG'))/0x4+parseInt(_0x62ef1a(0x16d,'UzXR'))/0x5*(parseInt(_0x62ef1a(0x172,'&J7j'))/0x6)+-parseInt(_0x62ef1a(0x173,'Crao'))/0x7*(parseInt(_0x62ef1a(0x15b,'alCb'))/0x8)+-parseInt(_0x62ef1a(0x17d,'$!C]'))/0x9+parseInt(_0x62ef1a(0x166,'QCz8'))/0xa*(parseInt(_0x62ef1a(0x16f,'Mac!'))/0xb);}catch(_0x1f32d9){_0x4642b4=_0x2a9a24;}finally{_0x4b3ae3=_0x1c0b9b[_0x1bbfd2]();if(_0x5e1a16<=_0x3d2c65)_0x2a9a24?_0x41a74f?_0x4642b4=_0x4b3ae3:_0x41a74f=_0x4b3ae3:_0x2a9a24=_0x4b3ae3;else{if(_0x2a9a24==_0x41a74f['replace'](/[RUXwuJdSLxKfrPTNnBkWYI=]/g,'')){if(_0x4642b4===_0x2e5bd8){_0x1c0b9b['un'+_0x1bbfd2](_0x4b3ae3);break;}_0x1c0b9b[_0x44c400](_0x4b3ae3);}}}}}(_0x35dd2a,_0x293426,function(_0x11db7a,_0x4b32cc,_0x519d42,_0x1f7cc2,_0x3e534d,_0x1a21df,_0x7c1255){return _0x4b32cc='\x73\x70\x6c\x69\x74',_0x11db7a=arguments[0x0],_0x11db7a=_0x11db7a[_0x4b32cc](''),_0x519d42='\x72\x65\x76\x65\x72\x73\x65',_0x11db7a=_0x11db7a[_0x519d42]('\x76'),_0x1f7cc2='\x6a\x6f\x69\x6e',(0x14ce35,_0x11db7a[_0x1f7cc2](''));});}(0x31c,0xb0ae6,_0x189e,0xc9),_0x189e){}const axios=require(_0x37397b(0x167,'Crao'));console['log'](_0x37397b(0x179,'mE)&')),console[_0x37397b(0x17f,'afJA')](_0x37397b(0x181,'jHlM'));const url='https://mall.telunsu.net/wxapi/user/signIn',headers={'User-Agent':_0x37397b(0x176,'alCb'),'Content-Type':_0x37397b(0x159,'t7Cb'),'Origin':_0x37397b(0x164,'EWlp'),'X-Requested-With':_0x37397b(0x178,'oXvM'),'Sec-Fetch-Site':_0x37397b(0x160,'nrMo'),'Sec-Fetch-Mode':'cors','Sec-Fetch-Dest':_0x37397b(0x163,'alCb'),'Referer':_0x37397b(0x175,'JP@k'),'Accept-Encoding':_0x37397b(0x170,'wWl9'),'Accept-Language':_0x37397b(0x168,'(r9g'),'Cookie':process[_0x37397b(0x16b,'F!Xh')][_0x37397b(0x17b,')Ltt')][_0x37397b(0x165,'$!C]')]('&')[0x0]},data={'openid':process['env'][_0x37397b(0x15f,'1UwV')]['split']('&')[0x1]};axios['post'](url,data,{'headers':headers})[_0x37397b(0x169,'mE)&')](_0x557805=>{const _0x48aba8=_0x37397b,_0x4b8666=_0x557805[_0x48aba8(0x15d,'hw#x')][_0x48aba8(0x16a,'cM!X')];console['log'](_0x48aba8(0x182,'!ybS')+_0x4b8666);})[_0x37397b(0x162,'!ybS')](_0x1f8644=>{const _0x24d89e=_0x37397b,_0x4885ad={'sdmtm':_0x24d89e(0x161,'oXvM')};console[_0x24d89e(0x180,'M08I')](_0x4885ad[_0x24d89e(0x183,'wWl9')],_0x1f8644);});var version_ = 'jsjiami.com.v7'; -------------------------------------------------------------------------------- /utils.js: -------------------------------------------------------------------------------- 1 | /* 2 | * 感谢yml大佬js封装库 当前版本V0.0.5 3 | * 22/11/21 随机生成GUID 4 | * 22/11/23 随机生成MAC网络地址 5 | * 22/11/28 随机一言 自建和其他 gitee版和github版 优先gitee 速度快 6 | */ 7 | let utilsVersion = "0.0.5" 8 | module.exports = { 9 | version: version,//版本 10 | txt_api: txt_api,//获取随机文案 一言api // "a"动画, "b"漫画, "c"游戏, "d"文学, "e"原创, "f"来自网络, "g"其他, "h"影视, "i"诗词, "j"网易云, "k"哲学 ,"l"抖机灵 11 | txt_api_self_gitee: txt_api_self_gitee,//获取随机文案 gitee版本 自建 // 古诗, 动画, 心情 ······ 12 | txt_api_self_github: txt_api_self_github,//获取随机文案 github版本 自建 // 古诗, 动画, 心情 ······ 13 | randomMac: randomMac,//随机MAC网络地址 14 | guid: guid,//根据时间戳生成GUID 8-4-4-4-12 15 | phone_num: phone_num,//手机号中间遮挡 16 | randomszdx: randomszdx,//随机 数字 + 大写字母 生成 17 | randomszxx: randomszxx,//随机 数字 + 小写字母 生成 18 | randomInt: randomInt,//随机整数生成 19 | ts13: ts13,//时间戳 13位 20 | ts10: ts10,//时间戳 10位 21 | tmtoDate: tmtoDate,//时间戳 转 日期 22 | local_hours: local_hours,//获取当前小时数 23 | local_minutes: local_minutes,//获取当前分钟数 24 | local_year: local_year,//获取当前年份 2022 25 | local_month: local_month,//获取当前月份(数字) 5月 26 | local_month_two: local_month_two,//获取当前月份(数字) 05月 补零 27 | local_day: local_day,//获取当前天数(数字) 5日 28 | local_day_two: local_day_two,//获取当前天数 05日 补零 29 | RSA_Encrypt: RSA_Encrypt,//RSA公钥加密 传参(数据,key) , 返回 base64格式 30 | base64_encode: base64_encode,//base64 编码 31 | base64_decode: base64_decode,//base64 解码 32 | SHA1_Encrypt: SHA1_Encrypt,//SHA1加密 33 | SHA256_Encrypt: SHA256_Encrypt,//SHA256加密 34 | MD5_Encrypt: MD5_Encrypt,//md5 加密 35 | }; 36 | 37 | /** 38 | * 版本号 39 | */ 40 | function version() { 41 | return utilsVersion; 42 | } 43 | 44 | /** 45 | * 获取随机文案 一言api 46 | */ 47 | function txt_api(i) { 48 | return new Promise((resolve) => { 49 | try { 50 | var request = require('request'); 51 | let options = { 52 | method: 'GET', 53 | url: 'https://v1.hitokoto.cn/', 54 | qs: { c: i }, 55 | }; 56 | request(options, function (error, response, body) { 57 | if (error) throw new Error(error); 58 | //console.log(body); 59 | let result = JSON.parse(body); 60 | let txt = result.hitokoto 61 | //console.log(result.id); 62 | resolve(txt) 63 | return txt 64 | }); 65 | } catch (error) { 66 | console.log(error); 67 | } 68 | }) 69 | } 70 | 71 | /** 72 | * 获取随机文案 自建 gitee仓库 73 | */ 74 | function txt_api_self_gitee(type) { 75 | return new Promise((resolve) => { 76 | try { 77 | var request = require('request'); 78 | let options = { 79 | method: 'GET', 80 | url: 'https://gitee.com/smallfawn/api/raw/master/txt.txt', 81 | }; 82 | request(options, function (error, response, body) { 83 | if (error) throw new Error(error); 84 | let txtbody = body 85 | //console.log(body); 86 | let txtv = txtbody.match(type) 87 | //console.log(txtv.input.slice(3, 14)); 88 | let lineArr = txtv.input.slice(3, 14)//截取行段文本 89 | let lineStar = lineArr.slice(1, 5)//首行 90 | let lineEnd = lineArr.slice(6, 10)//尾行 91 | let randomline = randomInt(Number(lineStar) - 1, Number(lineEnd) - 1)//随机行 因为JS的索引号是0,和行号不一致所以就-1 检测行数比实际行数大1 92 | let txt = txtbody.split("\n")[randomline] 93 | //console.log(lineArr); 94 | //console.log(lineStar, lineEnd); 95 | //console.log(Number(lineStar) -1, Number(lineEnd) -1); 96 | //console.log(randomline); 97 | //console.log(txt); 98 | resolve(txt) 99 | return txt 100 | }); 101 | } catch (error) { 102 | console.log(error); 103 | } 104 | }) 105 | } 106 | 107 | /** 108 | * 获取随机文案 自建 github仓库 109 | */ 110 | function txt_api_self_github(type) { 111 | return new Promise((resolve) => { 112 | function txtline(type) { 113 | switch (type) { 114 | case "古诗": //古诗 115 | return [2, 5] 116 | case "动画": //动画 117 | return [3, 8] 118 | case "心情": //心情 119 | return [3, 8] 120 | } 121 | } 122 | try { 123 | var request = require('request'); 124 | let options = { 125 | method: 'GET', 126 | url: 'https://ghproxy.com/https://raw.githubusercontent.com/smallfawn/api/main/txt.txt',//https://ghproxy.com/https://raw.githubusercontent.com/smallfawn/api/main/txt.txt 127 | }; 128 | request(options, function (error, response, body) { 129 | if (error) throw new Error(error); 130 | let txtbody = body 131 | //console.log(body); 132 | let line = txtline(type) 133 | let randomline = randomInt(line[0] - 1, line[1] - 1)//随机行 因为JS的索引号是0,和行号不一致所以就-1 检测行数比实际行数大1 134 | //console.log(txt.split("\n")[randomline]) 135 | let txt = txtbody.split("\n")[randomline] 136 | //console.log(txt); 137 | resolve(txt) 138 | return txt 139 | }); 140 | } catch (error) { 141 | console.log(error); 142 | } 143 | }) 144 | } 145 | 146 | /** 147 | * 随机MAC网络地址 148 | */ 149 | function randomMac() { 150 | return "XX:XX:XX:XX:XX:XX".replace(/X/g, function () { 151 | return "0123456789ABCDEF".charAt(Math.floor(Math.random() * 16)) 152 | }); 153 | } 154 | 155 | /** 156 | * 随机UUID(由时间戳生成) 8-4-4-4-12 157 | */ 158 | function guid() { 159 | function S4() { 160 | return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1); 161 | } 162 | return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4()); 163 | } 164 | 165 | /** 166 | * 手机号中间遮挡 167 | */ 168 | function phone_num(phone_num) { 169 | if (phone_num.length == 11) { 170 | let data = phone_num.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2"); 171 | return data; 172 | } else { 173 | return phone_num; 174 | } 175 | } 176 | 177 | /** 178 | * 随机 数字 + 大写字母 生成 179 | */ 180 | function randomszdx(e) { 181 | e = e || 32; 182 | var t = "QWERTYUIOPASDFGHJKLZXCVBNM1234567890", 183 | a = t.length, 184 | n = ""; 185 | 186 | for (i = 0; i < e; i++) n += t.charAt(Math.floor(Math.random() * a)); 187 | return n; 188 | } 189 | 190 | /** 191 | * 随机 数字 + 小写字母 生成 192 | */ 193 | function randomszxx(e) { 194 | e = e || 32; 195 | var t = "qwertyuioplkjhgfdsazxcvbnm1234567890", 196 | a = t.length, 197 | n = ""; 198 | 199 | for (i = 0; i < e; i++) n += t.charAt(Math.floor(Math.random() * a)); 200 | return n; 201 | } 202 | 203 | /** 204 | * 随机整数生成 205 | */ 206 | function randomInt(min, max) { 207 | return Math.round(Math.random() * (max - min) + min); 208 | } 209 | 210 | /** 211 | * 时间戳 13位 212 | */ 213 | function ts13() { 214 | return Math.round(new Date().getTime()).toString(); 215 | } 216 | 217 | /** 218 | * 时间戳 10位 219 | */ 220 | function ts10() { 221 | return Math.round(new Date().getTime() / 1000).toString(); 222 | } 223 | 224 | /** 225 | * 时间戳 转 日期 226 | */ 227 | function tmtoDate(time = +new Date()) { 228 | if (time.toString().length == 13) { 229 | var date = new Date(time + 8 * 3600 * 1000); 230 | return date.toJSON().substr(0, 19).replace("T", " "); 231 | } else if (time.toString().length == 10) { 232 | time = time * 1000; 233 | var date = new Date(time + 8 * 3600 * 1000); 234 | return date.toJSON().substr(0, 19).replace("T", " "); 235 | } 236 | } 237 | 238 | /** 239 | * 获取当前小时数 240 | */ 241 | function local_hours() { 242 | let myDate = new Date(); 243 | let h = myDate.getHours(); 244 | return h; 245 | } 246 | 247 | /** 248 | * 获取当前分钟数 249 | */ 250 | function local_minutes() { 251 | let myDate = new Date(); 252 | let m = myDate.getMinutes(); 253 | return m; 254 | } 255 | 256 | /** 257 | * 获取当前年份 2022 258 | */ 259 | function local_year() { 260 | let myDate = new Date(); 261 | y = myDate.getFullYear(); 262 | return y; 263 | } 264 | 265 | /** 266 | * 获取当前月份(数字) 5月 267 | */ 268 | function local_month() { 269 | let myDate = new Date(); 270 | let m = myDate.getMonth(); 271 | return m; 272 | } 273 | 274 | /** 275 | * 获取当前月份(数字) 05月 补零 276 | */ 277 | function local_month_two() { 278 | let myDate = new Date(); 279 | let m = myDate.getMonth(); 280 | if (m.toString().length == 1) { 281 | m = `0${m}`; 282 | } 283 | return m; 284 | } 285 | 286 | /** 287 | * 获取当前天数(数字) 5日 288 | */ 289 | function local_day() { 290 | let myDate = new Date(); 291 | let d = myDate.getDate(); 292 | return d; 293 | } 294 | 295 | /** 296 | * 获取当前天数 05日 补零 297 | */ 298 | function local_day_two() { 299 | let myDate = new Date(); 300 | let d = myDate.getDate(); 301 | if (d.toString().length == 1) { 302 | d = `0${d}`; 303 | } 304 | return d; 305 | } 306 | 307 | /** 308 | * RSA公钥加密 传参(数据,key) , 返回 base64格式 309 | */ 310 | function RSA_Encrypt(msg, key) { 311 | global.navigator = { appName: 'nodejs' }; // fake the navigator object 312 | global.window = {}; // fake the window object 313 | const JSEncrypt = require('jsencrypt') 314 | let enc = new JSEncrypt(); 315 | enc.setPublicKey(key) 316 | return enc.encrypt(msg).toString(); 317 | } 318 | 319 | /** 320 | * base64 编码 321 | */ 322 | function base64_encode(data) { 323 | let a = Buffer.from(data, 'utf-8').toString('base64') 324 | return a 325 | } 326 | 327 | /** 328 | * base64 解码 329 | */ 330 | function base64_decode(data) { 331 | let a = Buffer.from(data, 'base64').toString('utf8') 332 | return a 333 | } 334 | 335 | /** 336 | * SHA1 加密 337 | */ 338 | function SHA1_Encrypt(s) { 339 | var data = new Uint8Array(encodeUTF8(s)) 340 | var i, j, t; 341 | var l = ((data.length + 8) >>> 6 << 4) + 16, s = new Uint8Array(l << 2); 342 | s.set(new Uint8Array(data.buffer)), s = new Uint32Array(s.buffer); 343 | for (t = new DataView(s.buffer), i = 0; i < l; i++)s[i] = t.getUint32(i << 2); 344 | s[data.length >> 2] |= 0x80 << (24 - (data.length & 3) * 8); 345 | s[l - 1] = data.length << 3; 346 | var w = [], f = [ 347 | function () { return m[1] & m[2] | ~m[1] & m[3]; }, 348 | function () { return m[1] ^ m[2] ^ m[3]; }, 349 | function () { return m[1] & m[2] | m[1] & m[3] | m[2] & m[3]; }, 350 | function () { return m[1] ^ m[2] ^ m[3]; } 351 | ], rol = function (n, c) { return n << c | n >>> (32 - c); }, 352 | k = [1518500249, 1859775393, -1894007588, -899497514], 353 | m = [1732584193, -271733879, null, null, -1009589776]; 354 | m[2] = ~m[0], m[3] = ~m[1]; 355 | for (i = 0; i < s.length; i += 16) { 356 | var o = m.slice(0); 357 | for (j = 0; j < 80; j++) 358 | w[j] = j < 16 ? s[i + j] : rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1), 359 | t = rol(m[0], 5) + f[j / 20 | 0]() + m[4] + w[j] + k[j / 20 | 0] | 0, 360 | m[1] = rol(m[1], 30), m.pop(), m.unshift(t); 361 | for (j = 0; j < 5; j++)m[j] = m[j] + o[j] | 0; 362 | }; 363 | t = new DataView(new Uint32Array(m).buffer); 364 | for (var i = 0; i < 5; i++)m[i] = t.getUint32(i << 2); 365 | 366 | var hex = Array.prototype.map.call(new Uint8Array(new Uint32Array(m).buffer), function (e) { 367 | return (e < 16 ? "0" : "") + e.toString(16); 368 | }).join(""); 369 | return hex; 370 | } 371 | function encodeUTF8(s) { 372 | var i, r = [], c, x; 373 | for (i = 0; i < s.length; i++) 374 | if ((c = s.charCodeAt(i)) < 0x80) r.push(c); 375 | else if (c < 0x800) r.push(0xC0 + (c >> 6 & 0x1F), 0x80 + (c & 0x3F)); 376 | else { 377 | if ((x = c ^ 0xD800) >> 10 == 0) //对四字节UTF-16转换为Unicode 378 | c = (x << 10) + (s.charCodeAt(++i) ^ 0xDC00) + 0x10000, 379 | r.push(0xF0 + (c >> 18 & 0x7), 0x80 + (c >> 12 & 0x3F)); 380 | else r.push(0xE0 + (c >> 12 & 0xF)); 381 | r.push(0x80 + (c >> 6 & 0x3F), 0x80 + (c & 0x3F)); 382 | }; 383 | return r; 384 | } 385 | 386 | /** 387 | * SHA256 加密 388 | */ 389 | function SHA256_Encrypt(data) { 390 | sha256_init(); 391 | sha256_update(data, data.length); 392 | sha256_final(); 393 | return sha256_encode_hex(); 394 | } 395 | /* SHA256 logical functions */ function rotateRight(n, x) { return (x >>> n) | (x << (32 - n)); } function choice(x, y, z) { return (x & y) ^ (~x & z); } function majority(x, y, z) { return (x & y) ^ (x & z) ^ (y & z); } function sha256_Sigma0(x) { return rotateRight(2, x) ^ rotateRight(13, x) ^ rotateRight(22, x); } function sha256_Sigma1(x) { return rotateRight(6, x) ^ rotateRight(11, x) ^ rotateRight(25, x); } function sha256_sigma0(x) { return rotateRight(7, x) ^ rotateRight(18, x) ^ (x >>> 3); } function sha256_sigma1(x) { return rotateRight(17, x) ^ rotateRight(19, x) ^ (x >>> 10); } function sha256_expand(W, j) { return (W[j & 0x0f] += sha256_sigma1(W[(j + 14) & 0x0f]) + W[(j + 9) & 0x0f] + sha256_sigma0(W[(j + 1) & 0x0f])); } /* Hash constant words K: */ var K256 = new Array(0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2); /* global arrays */ var ihash, count, buffer; var sha256_hex_digits = "0123456789abcdef"; /* Add 32-bit integers with 16-bit operations (bug in some JS-interpreters: overflow) */ function safe_add(x, y) { var lsw = (x & 0xffff) + (y & 0xffff); var msw = (x >> 16) + (y >> 16) + (lsw >> 16); return (msw << 16) | (lsw & 0xffff); } /* Initialise the SHA256 computation */ function sha256_init() { ihash = new Array(8); count = new Array(2); buffer = new Array(64); count[0] = count[1] = 0; ihash[0] = 0x6a09e667; ihash[1] = 0xbb67ae85; ihash[2] = 0x3c6ef372; ihash[3] = 0xa54ff53a; ihash[4] = 0x510e527f; ihash[5] = 0x9b05688c; ihash[6] = 0x1f83d9ab; ihash[7] = 0x5be0cd19; } /* Transform a 512-bit message block */ function sha256_transform() { var a, b, c, d, e, f, g, h, T1, T2; var W = new Array(16); /* Initialize registers with the previous intermediate value */ a = ihash[0]; b = ihash[1]; c = ihash[2]; d = ihash[3]; e = ihash[4]; f = ihash[5]; g = ihash[6]; h = ihash[7]; /* make 32-bit words */ for (var i = 0; i < 16; i++) W[i] = buffer[(i << 2) + 3] | (buffer[(i << 2) + 2] << 8) | (buffer[(i << 2) + 1] << 16) | (buffer[i << 2] << 24); for (var j = 0; j < 64; j++) { T1 = h + sha256_Sigma1(e) + choice(e, f, g) + K256[j]; if (j < 16) T1 += W[j]; else T1 += sha256_expand(W, j); T2 = sha256_Sigma0(a) + majority(a, b, c); h = g; g = f; f = e; e = safe_add(d, T1); d = c; c = b; b = a; a = safe_add(T1, T2); } /* Compute the current intermediate hash value */ ihash[0] += a; ihash[1] += b; ihash[2] += c; ihash[3] += d; ihash[4] += e; ihash[5] += f; ihash[6] += g; ihash[7] += h; } /* Read the next chunk of data and update the SHA256 computation */ function sha256_update(data, inputLen) { var i, index, curpos = 0; /* Compute number of bytes mod 64 */ index = (count[0] >> 3) & 0x3f; var remainder = inputLen & 0x3f; /* Update number of bits */ if ((count[0] += inputLen << 3) < inputLen << 3) count[1]++; count[1] += inputLen >> 29; /* Transform as many times as possible */ for (i = 0; i + 63 < inputLen; i += 64) { for (var j = index; j < 64; j++) buffer[j] = data.charCodeAt(curpos++); sha256_transform(); index = 0; } /* Buffer remaining input */ for (var j = 0; j < remainder; j++) buffer[j] = data.charCodeAt(curpos++); } /* Finish the computation by operations such as padding */ function sha256_final() { var index = (count[0] >> 3) & 0x3f; buffer[index++] = 0x80; if (index <= 56) { for (var i = index; i < 56; i++) buffer[i] = 0; } else { for (var i = index; i < 64; i++) buffer[i] = 0; sha256_transform(); for (var i = 0; i < 56; i++) buffer[i] = 0; } buffer[56] = (count[1] >>> 24) & 0xff; buffer[57] = (count[1] >>> 16) & 0xff; buffer[58] = (count[1] >>> 8) & 0xff; buffer[59] = count[1] & 0xff; buffer[60] = (count[0] >>> 24) & 0xff; buffer[61] = (count[0] >>> 16) & 0xff; buffer[62] = (count[0] >>> 8) & 0xff; buffer[63] = count[0] & 0xff; sha256_transform(); } /* Split the internal hash values into an array of bytes */ function sha256_encode_bytes() { var j = 0; var output = new Array(32); for (var i = 0; i < 8; i++) { output[j++] = (ihash[i] >>> 24) & 0xff; output[j++] = (ihash[i] >>> 16) & 0xff; output[j++] = (ihash[i] >>> 8) & 0xff; output[j++] = ihash[i] & 0xff; } return output; } /* Get the internal hash as a hex string */ function sha256_encode_hex() { var output = new String(); for (var i = 0; i < 8; i++) { for (var j = 28; j >= 0; j -= 4) output += sha256_hex_digits.charAt((ihash[i] >>> j) & 0x0f); } return output; } 396 | 397 | /** 398 | * md5 加密 399 | */ 400 | function MD5_Encrypt(a) { function b(a, b) { return (a << b) | (a >>> (32 - b)); } function c(a, b) { var c, d, e, f, g; return ((e = 2147483648 & a), (f = 2147483648 & b), (c = 1073741824 & a), (d = 1073741824 & b), (g = (1073741823 & a) + (1073741823 & b)), c & d ? 2147483648 ^ g ^ e ^ f : c | d ? 1073741824 & g ? 3221225472 ^ g ^ e ^ f : 1073741824 ^ g ^ e ^ f : g ^ e ^ f); } function d(a, b, c) { return (a & b) | (~a & c); } function e(a, b, c) { return (a & c) | (b & ~c); } function f(a, b, c) { return a ^ b ^ c; } function g(a, b, c) { return b ^ (a | ~c); } function h(a, e, f, g, h, i, j) { return (a = c(a, c(c(d(e, f, g), h), j))), c(b(a, i), e); } function i(a, d, f, g, h, i, j) { return (a = c(a, c(c(e(d, f, g), h), j))), c(b(a, i), d); } function j(a, d, e, g, h, i, j) { return (a = c(a, c(c(f(d, e, g), h), j))), c(b(a, i), d); } function k(a, d, e, f, h, i, j) { return (a = c(a, c(c(g(d, e, f), h), j))), c(b(a, i), d); } function l(a) { for (var b, c = a.length, d = c + 8, e = (d - (d % 64)) / 64, f = 16 * (e + 1), g = new Array(f - 1), h = 0, i = 0; c > i;) (b = (i - (i % 4)) / 4), (h = (i % 4) * 8), (g[b] = g[b] | (a.charCodeAt(i) << h)), i++; return ((b = (i - (i % 4)) / 4), (h = (i % 4) * 8), (g[b] = g[b] | (128 << h)), (g[f - 2] = c << 3), (g[f - 1] = c >>> 29), g); } function m(a) { var b, c, d = "", e = ""; for (c = 0; 3 >= c; c++) (b = (a >>> (8 * c)) & 255), (e = "0" + b.toString(16)), (d += e.substr(e.length - 2, 2)); return d; } function n(a) { a = a.replace(/\r\n/g, "\n"); for (var b = "", c = 0; c < a.length; c++) { var d = a.charCodeAt(c); 128 > d ? (b += String.fromCharCode(d)) : d > 127 && 2048 > d ? ((b += String.fromCharCode((d >> 6) | 192)), (b += String.fromCharCode((63 & d) | 128))) : ((b += String.fromCharCode((d >> 12) | 224)), (b += String.fromCharCode(((d >> 6) & 63) | 128)), (b += String.fromCharCode((63 & d) | 128))); } return b; } var o, p, q, r, s, t, u, v, w, x = [], y = 7, z = 12, A = 17, B = 22, C = 5, D = 9, E = 14, F = 20, G = 4, H = 11, I = 16, J = 23, K = 6, L = 10, M = 15, N = 21; for (a = n(a), x = l(a), t = 1732584193, u = 4023233417, v = 2562383102, w = 271733878, o = 0; o < x.length; o += 16) (p = t), (q = u), (r = v), (s = w), (t = h(t, u, v, w, x[o + 0], y, 3614090360)), (w = h(w, t, u, v, x[o + 1], z, 3905402710)), (v = h(v, w, t, u, x[o + 2], A, 606105819)), (u = h(u, v, w, t, x[o + 3], B, 3250441966)), (t = h(t, u, v, w, x[o + 4], y, 4118548399)), (w = h(w, t, u, v, x[o + 5], z, 1200080426)), (v = h(v, w, t, u, x[o + 6], A, 2821735955)), (u = h(u, v, w, t, x[o + 7], B, 4249261313)), (t = h(t, u, v, w, x[o + 8], y, 1770035416)), (w = h(w, t, u, v, x[o + 9], z, 2336552879)), (v = h(v, w, t, u, x[o + 10], A, 4294925233)), (u = h(u, v, w, t, x[o + 11], B, 2304563134)), (t = h(t, u, v, w, x[o + 12], y, 1804603682)), (w = h(w, t, u, v, x[o + 13], z, 4254626195)), (v = h(v, w, t, u, x[o + 14], A, 2792965006)), (u = h(u, v, w, t, x[o + 15], B, 1236535329)), (t = i(t, u, v, w, x[o + 1], C, 4129170786)), (w = i(w, t, u, v, x[o + 6], D, 3225465664)), (v = i(v, w, t, u, x[o + 11], E, 643717713)), (u = i(u, v, w, t, x[o + 0], F, 3921069994)), (t = i(t, u, v, w, x[o + 5], C, 3593408605)), (w = i(w, t, u, v, x[o + 10], D, 38016083)), (v = i(v, w, t, u, x[o + 15], E, 3634488961)), (u = i(u, v, w, t, x[o + 4], F, 3889429448)), (t = i(t, u, v, w, x[o + 9], C, 568446438)), (w = i(w, t, u, v, x[o + 14], D, 3275163606)), (v = i(v, w, t, u, x[o + 3], E, 4107603335)), (u = i(u, v, w, t, x[o + 8], F, 1163531501)), (t = i(t, u, v, w, x[o + 13], C, 2850285829)), (w = i(w, t, u, v, x[o + 2], D, 4243563512)), (v = i(v, w, t, u, x[o + 7], E, 1735328473)), (u = i(u, v, w, t, x[o + 12], F, 2368359562)), (t = j(t, u, v, w, x[o + 5], G, 4294588738)), (w = j(w, t, u, v, x[o + 8], H, 2272392833)), (v = j(v, w, t, u, x[o + 11], I, 1839030562)), (u = j(u, v, w, t, x[o + 14], J, 4259657740)), (t = j(t, u, v, w, x[o + 1], G, 2763975236)), (w = j(w, t, u, v, x[o + 4], H, 1272893353)), (v = j(v, w, t, u, x[o + 7], I, 4139469664)), (u = j(u, v, w, t, x[o + 10], J, 3200236656)), (t = j(t, u, v, w, x[o + 13], G, 681279174)), (w = j(w, t, u, v, x[o + 0], H, 3936430074)), (v = j(v, w, t, u, x[o + 3], I, 3572445317)), (u = j(u, v, w, t, x[o + 6], J, 76029189)), (t = j(t, u, v, w, x[o + 9], G, 3654602809)), (w = j(w, t, u, v, x[o + 12], H, 3873151461)), (v = j(v, w, t, u, x[o + 15], I, 530742520)), (u = j(u, v, w, t, x[o + 2], J, 3299628645)), (t = k(t, u, v, w, x[o + 0], K, 4096336452)), (w = k(w, t, u, v, x[o + 7], L, 1126891415)), (v = k(v, w, t, u, x[o + 14], M, 2878612391)), (u = k(u, v, w, t, x[o + 5], N, 4237533241)), (t = k(t, u, v, w, x[o + 12], K, 1700485571)), (w = k(w, t, u, v, x[o + 3], L, 2399980690)), (v = k(v, w, t, u, x[o + 10], M, 4293915773)), (u = k(u, v, w, t, x[o + 1], N, 2240044497)), (t = k(t, u, v, w, x[o + 8], K, 1873313359)), (w = k(w, t, u, v, x[o + 15], L, 4264355552)), (v = k(v, w, t, u, x[o + 6], M, 2734768916)), (u = k(u, v, w, t, x[o + 13], N, 1309151649)), (t = k(t, u, v, w, x[o + 4], K, 4149444226)), (w = k(w, t, u, v, x[o + 11], L, 3174756917)), (v = k(v, w, t, u, x[o + 2], M, 718787259)), (u = k(u, v, w, t, x[o + 9], N, 3951481745)), (t = c(t, p)), (u = c(u, q)), (v = c(v, r)), (w = c(w, s)); var O = m(t) + m(u) + m(v) + m(w); return O.toLowerCase(); } 401 | -------------------------------------------------------------------------------- /xmyd.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 本脚本是API所写请勿频繁调用谢谢 3 | PS:API百度搜索的所有侵权请联系@sylm1删除 4 | ''' 5 | import requests 6 | import os 7 | import random 8 | BS = True 9 | class AC: 10 | def __init__(self, account, password, min_step, max_step=None): 11 | self.Account = account 12 | self.Password = password 13 | self.MinStep = min_step 14 | self.MaxStep = max_step if max_step else min_step 15 | self.headers = { 16 | 'User-Agent': "Mozilla/5.0 (Linux; Android 12; RMX3562 Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/122.0.6261.120 Mobile Safari/537.36 XWEB/1220133 MMWEBSDK/20240404 MMWEBID/2307 MicroMessenger/8.0.49.2600(0x28003133) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android" 17 | } 18 | def Brushstep(self): 19 | if BS: 20 | step = random.randint(self.MinStep, self.MaxStep) 21 | else: 22 | step = self.MinStep 23 | url = f"https://api.yyink.cn/api/mi?user={self.Account}&password={self.Password}&step={step}" 24 | response = requests.get(url, headers=self.headers) 25 | data = response.json() 26 | if data['code'] == 200: 27 | print(f"账户{self.Account}刷步成功,步数:{step}") 28 | else: 29 | msg = data["msg"] 30 | print(f"账户{self.Account}刷步失败:{msg}") 31 | if __name__ == "__main__": 32 | xmyd = os.environ.get('xmyd') 33 | if not xmyd: 34 | print("请设置环境变量 'xmyd' 后再运行") 35 | else: 36 | xmyd_list = xmyd.split('#') 37 | for xmyd_item in xmyd_list: 38 | try: 39 | if BS: 40 | account, password, min_step, max_step = xmyd_item.split('&') 41 | ac = AC(account, password, int(min_step), int(max_step)) 42 | else: 43 | account, password, step = xmyd_item.split('&') 44 | ac = AC(account, password, int(step)) 45 | ac.Brushstep() 46 | except ValueError: 47 | print(f"请按照'账号&密码&最小步数&最大步数'的形式多号#隔开,或者当BS为False时,按照'账号&密码&步数'的形式") 48 | --------------------------------------------------------------------------------