Collect seeded Qinglong script repositories

This commit is contained in:
Hermes Agent
2026-05-24 04:36:41 +00:00
parent 28d62fef03
commit ca1a4275e4
282 changed files with 143071 additions and 5 deletions

View File

@@ -0,0 +1,145 @@
# Source: https://github.com/AkenClub/ken-iMoutai-Script/blob/main/3_retrieve_shop_and_product_info.py
# Raw: https://raw.githubusercontent.com/AkenClub/ken-iMoutai-Script/main/3_retrieve_shop_and_product_info.py
# Repo: AkenClub/ken-iMoutai-Script
# Path: 3_retrieve_shop_and_product_info.py
# UploadedAt: 2025-11-20T09:54:34+08:00
# SHA256: 029d5d6421f5a3432bb04e3040139b27ff23131bba02594dfb2d8391b12992fd
# Category: APP版/抓包
# Evidence: cookie/token/authorization/header
import logging
import requests
import time
import datetime
"""
3、查询可预约的商品 和 售卖商店,获取 SHOP_ID、LAT、LNG 等数据
如果省份城市填写有问题,可以直接查看这个网址的 json 内容,找到自己的想要预约的商店信息。也可找到正确的省份城市信息后填入下面变量值运行脚本获取完整数据。
https://resource.moutai519.com.cn/mt-resource/resource/myserviceshops/1726025401183/myserviceshops.json
(若过期无法访问,可参考脚本里 get_shop_info 函数逻辑,查看 ["data"]["myserviceshops"]["url"] 获取最新网址)
"""
# ------ 填写以下 2 个变量值 --------
# 示例调用,省份和市区需要填写完整,
# 省份
PROVINCE_NAME = "广西壮族自治区"
# 城市
CITY_NAME = "南宁市"
# --------------------
# ***** 以下内容不用动 *****
'''
cron: 1 1 1 1 *
new Env("3_查询商品商店信息")
'''
logging.basicConfig(level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s')
# 获取可预约的商品信息
def get_item_info():
# 生成时间戳
timestamp = str(int(time.mktime(datetime.date.today().timetuple())) * 1000)
# 发送请求
api_url = f"https://static.moutai519.com.cn/mt-backend/xhr/front/mall/index/session/get/{timestamp}"
response = requests.get(api_url)
data = response.json()
if data["code"] != 2000:
raise Exception("获取商品信息失败")
# 解析响应
sessionId = data["data"]["sessionId"]
# 提取itemCode和title
item_list = data["data"]["itemList"]
result = [{
"itemCode": item["itemCode"],
"title": item.get("title", f"未知商品,可结合该商品图片链接来判断:{item.get('pictureV2', '无图片信息')},同时到 APP 核实。")
} for item in item_list]
return {"sessionId": sessionId, "itemList": result}
# 获取售卖商店信息
def get_shop_info(province_name, city_name):
# 第一步获取myserviceshops的URL
api_url = "https://static.moutai519.com.cn/mt-backend/xhr/front/mall/resource/get"
response = requests.get(api_url)
data = response.json()
if data["code"] != 2000:
raise Exception("获取资源信息失败")
myserviceshops_url = data["data"]["myserviceshops"]["url"]
# 第二步下载并解析myserviceshops.json
response = requests.get(myserviceshops_url)
shops_data = response.json()
# 第三步根据provinceName和cityName过滤数据
result = []
for _, shop_info in shops_data.items():
if shop_info["provinceName"] == province_name and shop_info[
"cityName"] == city_name:
result.append({
"lat": shop_info["lat"],
"lng": shop_info["lng"],
"name": shop_info["name"],
"shopId": shop_info["shopId"],
"fullAddress": shop_info["fullAddress"],
"cityName": shop_info["cityName"],
"provinceName": shop_info["provinceName"]
})
return result
if __name__ == "__main__":
# 获取商店信息
if not PROVINCE_NAME or not CITY_NAME:
logging.error("「获取商店信息-失败」:缺少必要参数")
raise Exception("缺少必要参数")
logging.info(f"「获取商店信息-开始」:{PROVINCE_NAME} - {CITY_NAME}")
shop_info = get_shop_info(PROVINCE_NAME, CITY_NAME)
logging.info(f"「查找到的商店信息」:")
logging.info("-------------------------")
for shop in shop_info:
logging.info(f"店铺名称: {shop['name']}")
logging.info(f"店铺ID: {shop['shopId']}")
logging.info(f"地址: {shop['fullAddress']}")
logging.info(f"纬度: {shop['lat']}")
logging.info(f"经度: {shop['lng']}")
logging.info("-------------------------")
logging.info(f"**** 请自行选择上面一个商店 ****")
logging.info("-------------------------")
# 获取可以预约的商品信息
try:
result = get_item_info()
except Exception as e:
logging.error(f"获取商品信息失败:{str(e)}")
raise
logging.info(
f"获取到 SessionId(可以理解为申购活动批次,每天都会变化,一般+1): {result['sessionId']}")
for item in result['itemList']:
logging.info(
f"获取到可预约商品itemCode: {item['itemCode']}, title: {item['title']}")
logging.info("****************************")
logging.info("记录以下信息用于后续预约:")
logging.info(f"省份 - PROVINCE{PROVINCE_NAME}")
logging.info(f"城市 - CITY{CITY_NAME}")
logging.info(f"店铺ID - SHOP_ID")
logging.info(f"纬度 - LAT可直接用店铺对应的纬度值 或者 自己实际的纬度值(自行想办法获取)")
logging.info(f"经度 - LNG可直接用店铺对应的经度值 或者 自己实际的经度值(自行想办法获取)")
logging.info(
f"需要预约的商品 ID 列表 - PRODUCT_ID_LIST对应 itemCode符号都是用英文符号例如['10941', '10923', '2478', '10942']"
)

View File

@@ -0,0 +1,197 @@
// # Source: https://github.com/smallfawn/QLScriptPublic/blob/main/tools/env.js
// # Raw: https://raw.githubusercontent.com/smallfawn/QLScriptPublic/main/tools/env.js
// # Repo: smallfawn/QLScriptPublic
// # Path: tools/env.js
// # UploadedAt: 2026-04-07T12:33:25Z
// # SHA256: 89a06fae1893022eebe3efe869870ddd87549ddaf1cd158c369060a81934cef9
// # Category: APP版/抓包
// # Evidence: cookie/token/authorization/header
//
// prettier-ignore
function Env(t, s) {
return new (class {
constructor(t, s) {
this.userIdx = 1;
this.userList = [];
this.userCount = 0;
this.name = t;
this.notifyStr = [];
this.logSeparator = "\n";
this.startTime = new Date().getTime();
Object.assign(this, s);
this.log(`\ud83d\udd14${this.name},\u5f00\u59cb!`);
this.bucket = this.bucket || ''
this.fs = require("fs");
if (this.isNode() && this.bucket) {
try {
if (!this.fs.existsSync(this.bucket)) {
this.fs.writeFileSync(this.bucket, JSON.stringify({}, null, 2));
this.log(`📁 已创建 bucket 文件: ${this.bucket}`);
}
} catch (e) {
this.log("❌ 初始化 bucket 失败: " + e.message);
}
}
}
async get(key, def = null) {
if (!this.isNode()) return def;
try {
const data = await this.fs.promises.readFile(this.bucket, "utf-8");
const json = JSON.parse(data);
return json.hasOwnProperty(key) ? json[key] : def;
} catch (e) {
this.log("❌ 读取bucket失败: " + e.message);
return def;
}
}
async set(key, value) {
if (!this.isNode()) return;
try {
const data = await this.fs.promises.readFile(this.bucket, "utf-8");
const json = JSON.parse(data);
json[key] = value;
await this.fs.promises.writeFile(this.bucket, JSON.stringify(json, null, 2));
} catch (e) {
this.log("❌ 写入bucket失败: " + e.message);
}
}
checkEnv(ckName) {
const envSplitor = ["&", "\n"];
let userCookie = (this.isNode() ? process.env[ckName] : "") || "";
this.userList = userCookie.split(envSplitor.find((o) => userCookie.includes(o)) || "&").filter((n) => n);
this.userCount = this.userList.length;
this.log(`共找到${this.userCount}个账号`);
}
toStr(v) {
if (v instanceof Error) return v.stack || v.message;
if (v && typeof v == "object") try { return JSON.stringify(v) } catch { return "[Complex Object]" }
return String(v);
}
async sendMsg() {
this.log("==============📣Center 通知📣==============")
let message = this.notifyStr.join(this.logSeparator);
if (this.isNode()) {
try {
const { sendNotify } = require("./sendNotify.js")
await sendNotify(this.name, message);
} catch (e) {
console.error(e.code === "MODULE_NOT_FOUND" ? "发送通知失败: 未找到 sendNotify.js 模块" : `发送通知失败: sendNotify.js 内部错误 (${e.message})`);
}
}
}
isNode() {
return "undefined" != typeof module && !!module.exports;
}
jsonToStr(obj, c = '&', encodeUrl = false) {
let ret = []
for (let keys of Object.keys(obj).sort()) {
let v = obj[keys]
if (v && encodeUrl) v = encodeURIComponent(v)
ret.push(keys + '=' + v)
}
return ret.join(c);
}
getURLParams(url) {
try { return Object.fromEntries(new URL(url, "http://localhost").searchParams) } catch { return {} }
}
isJSONString(str) {
try {
return JSON.parse(str) && typeof JSON.parse(str) === "object";
} catch (e) {
return false;
}
}
isJson(obj) {
var isjson =
typeof obj == "object" &&
Object.prototype.toString.call(obj).toLowerCase() ==
"[object object]" &&
!obj.length;
return isjson;
}
randomNumber(length) {
const characters = "0123456789";
return Array.from(
{ length },
() => characters[Math.floor(Math.random() * characters.length)]
).join("");
}
randomString(length) {
const characters = "abcdefghijklmnopqrstuvwxyz0123456789";
return Array.from(
{ length },
() => characters[Math.floor(Math.random() * characters.length)]
).join("");
}
uuid() {
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
/[xy]/g,
function (c) {
var r = (Math.random() * 16) | 0,
v = c == "x" ? r : (r & 0x3) | 0x8;
return v.toString(16);
}
);
}
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;
}
log(content) {
this.notifyStr.push(`[${this.time("HH:mm:ss")}]` + " " + this.toStr(content))
console.log(content)
}
wait(min, max = null) {
const ms = max == null ? min : Math.random() * (max - min + 1) + min | 0;
ms >= 1000 && this.log(`等待 ${(ms / 1000).toFixed(2)} 秒...`, { notify: false });
return new Promise(r => setTimeout(r, ms));
}
async done() {
await this.sendMsg();
const s = new Date().getTime(),
e = (s - this.startTime) / 1e3;
this.log(
`\ud83d\udd14${this.name},\u7ed3\u675f!\ud83d\udd5b ${e}\u79d2`
);
if (this.isNode()) {
process.exit(0);
}
}
parseCookie(ck) {
return typeof ck != "string" || !ck ? {} : Object.fromEntries(
ck.split(/;\s*/).filter(v => v.includes("=")).map(v => [v.slice(0, v.indexOf("=")), v.slice(v.indexOf("=") + 1)])
);
}
})(t, s);
}
module.exports = {
Env
}

View File

@@ -0,0 +1,149 @@
# Source: https://gitee.com/jdqlscript/toulu/blob/main/%E4%B8%87%E5%AE%B6%E4%B9%90.py
# Raw: https://gitee.com/jdqlscript/toulu/raw/main/%E4%B8%87%E5%AE%B6%E4%B9%90.py
# Repo: jdqlscript/toulu
# Path: 万家乐.py
# UploadedAt: 2025-06-28T11:18:42+08:00
# SHA256: 1adde72027d2e2407e706ee56bc7821d9a59d7ee9b9729563ba68d0b55e6d593
# Category: APP版/抓包
# Evidence: cookie/token/authorization/header
#by:哆啦A梦
#TL库
#https://github.com/3288588344/toulu.git
#抓包wakecloud.chinamacro.com域名中的cookie中钱sessionid
#多账号换行分割,一行一号
#账号环境变量名WJL
import requests
import time
import os
# 从环境变量中读取cookie
cookies = os.environ.get("WJL", "").split('\n')
# 设置请求头
headers = {
"Host": "wakecloud.chinamacro.com",
"Accept-Language": "zh",
"Content-Type": "application/json",
"Charset": "utf-8",
"Referer": "https://servicewechat.com/wx07b7a339bb2cf065/117/page-frame.html",
"Accept-Encoding": "gzip, deflate, br"
}
# 签到URL
sign_url = "https://wakecloud.chinamacro.com/wd-member/app/member/sign"
# 抽奖URL
draw_url = "https://wakecloud.chinamacro.com/mtool/app/luckywheel/draw"
# 抽奖请求体
draw_data = {"activityNo": 2025041400000001}
# 获取公告信息
def get_proclamation():
primary_url = "https://github.com/3288588344/toulu/raw/refs/heads/main/tl.txt"
backup_url = "https://tfapi.cn/TL/tl.json"
try:
response = requests.get(primary_url, timeout=10)
if response.status_code == 200:
print("\n" + "=" * 50)
print("📢 公告信息")
print("=" * 35)
print(response.text)
print("=" * 35 + "\n")
print("公告获取成功,开始执行任务...\n")
return
except requests.exceptions.RequestException as e:
print(f"获取公告时发生错误: {e}, 尝试备用链接...")
try:
response = requests.get(backup_url, timeout=10)
if response.status_code == 200:
print("\n" + "=" * 50)
print("📢 公告信息")
print("=" * 35)
print(response.text)
print("=" * 35 + "\n")
print("公告获取成功,开始执行任务...\n")
else:
print(f"⚠️ 获取公告失败,状态码: {response.status_code}")
except requests.exceptions.RequestException as e:
print(f"⚠️ 获取公告时发生错误: {e}, 可能是网络问题或链接无效。")
def sign_in(session_id):
"""签到功能"""
try:
# 更新请求头中的Cookie
headers["Cookie"] = f"sessionId={session_id}"
response = requests.get(sign_url, headers=headers)
if response.status_code == 200:
result = response.json()
if result.get("success", False):
print("签到成功!")
else:
print("签到失败,请检查原因。")
else:
print(f"签到请求失败,状态码: {response.status_code}")
except Exception as e:
print(f"签到发生错误: {e}")
def draw_prize(session_id):
"""抽奖功能抽奖3次"""
try:
# 更新请求头中的Cookie
headers["Cookie"] = f"sessionId={session_id}"
for i in range(3):
print(f"\n{i+1} 次抽奖中...")
response = requests.post(draw_url, headers=headers, json=draw_data)
if response.status_code == 200:
result = response.json()
if result.get("success", False):
gift_name = result["data"]["giftName"]
print(f"恭喜你抽到了: {gift_name}")
else:
print("抽奖失败")
else:
print(f"抽奖请求失败,状态码: {response.status_code}")
# 等待1秒再进行下一次抽奖
time.sleep(1)
except Exception as e:
print(f"抽奖发生错误: {e}")
def main():
if not cookies:
print("环境变量WJL中没有找到sessionid请检查配置。")
return
for idx, cookie in enumerate(cookies, 1):
if not cookie.strip():
continue
print(f"\n===== 开始处理第 {idx} 个账户 =====")
session_id = cookie.strip()
# 签到
print("开始签到...")
sign_in(session_id)
# 抽奖
print("\n开始抽奖...")
draw_prize(session_id)
print(f"===== 第 {idx} 个账户处理完成 =====\n")
if __name__ == "__main__":
# 获取公告
get_proclamation()
# 执行主程序
main()

View File

@@ -0,0 +1,752 @@
# Source: https://github.com/smallfawn/QLScriptPublic/blob/main/daily/bjxd.py
# Raw: https://raw.githubusercontent.com/smallfawn/QLScriptPublic/main/daily/bjxd.py
# Repo: smallfawn/QLScriptPublic
# Path: daily/bjxd.py
# UploadedAt: 2026-04-02T02:22:19Z
# SHA256: a680cf465f0ac16d7a83b7b70762ad13ce94b713829255df0a6390cfde87402e
# Category: APP版/抓包
# Evidence: cookie/token/authorization/header
"""
北京现代 APP 自动任务脚本
功能:自动完成签到、浏览文章、每日答题等任务
new Env("北京现代");
环境变量:
BJXD: str - 北京现代 APP api token (多个账号用英文逗号分隔,建议每个账号一个变量)
BJXD1/BJXD2/BJXD3: str - 北京现代 APP api token (每个账号一个变量)
BJXD_ANSWER: str - 预设答案 (可选, ABCD 中的一个)
AI_API_KEY: str - 通用 AI APIKey (可选)
AI_REQUEST_URL: str - 通用 AI 请求 URL (可选)
AI_MODEL: str - 通用 AI 模型名称 (可选)
AI_REQUEST_PARAMS: str - 通用 AI 请求参数 (可选, JSON 格式字符串)
HUNYUAN_API_KEY: str - 腾讯混元AI APIKey (已废弃,不建议使用)
GLM_API_KEY: str - 智谱 GLM AI APIKey (已废弃,不建议使用)
cron: 25 6 * * *
"""
import os
import random
import time
import json
from datetime import datetime
from typing import List, Dict, Any
import requests
from urllib3.exceptions import InsecureRequestWarning, InsecurePlatformWarning
# 禁用 SSL 警告
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
requests.packages.urllib3.disable_warnings(InsecurePlatformWarning)
class BeiJingHyundai:
"""北京现代APP自动任务类"""
# 基础配置
NAME = "北京现代 APP 自动任务"
BASE_URL = "https://bm2-api.bluemembers.com.cn"
# API endpoints
API_USER_INFO = "/v1/app/account/users/info"
API_MY_SCORE = "/v1/app/user/my_score"
API_TASK_LIST = "/v1/app/user/task/list"
API_SIGN_LIST = "/v1/app/user/reward_list"
API_SIGN_SUBMIT = "/v1/app/user/reward_report"
API_ARTICLE_LIST = "/v1/app/white/article/list2"
API_ARTICLE_DETAIL = "/v1/app/white/article/detail_app/{}"
API_ARTICLE_SCORE_SUBMIT = "/v1/app/score"
API_QUESTION_INFO = "/v1/app/special/daily/ask_info"
API_QUESTION_SUBMIT = "/v1/app/special/daily/ask_answer"
# 预设的备用 share_user_hid 列表
BACKUP_HIDS = [
"a6688ec1a9ee429fa7b68d50e0c92b1f",
"bb8cd2e44c7b45eeb8cc5f7fa71c3322",
"5f640c50061b400c91be326c8fe0accd",
"55a5d82dacd9417483ae369de9d9b82d",
]
def __init__(self):
"""初始化实例变量"""
self.token: str = "" # 当前用户token
self.user: Dict[str, Any] = {} # 当前用户信息
self.users: List[Dict[str, Any]] = [] # 所有用户信息列表
self.correct_answer: str = "" # 正确答案
self.preset_answer: str = "" # 预设答案
self.ai_hunyuan_api_key: str = "" # 腾讯混元AI APIKey兼容旧环境变量
self.ai_glm_api_key: str = "" # 智谱 GLM AI APIKey兼容旧环境变量
self.ai_api_key: str = "" # 通用 AI APIKey
self.ai_request_url: str = "" # AI 请求地址
self.ai_model: str = "" # AI 模型
self.ai_request_params: str = "" # AI 请求参数JSON字符串格式
self.wrong_answers: set = set() # 错误答案集合
self.log_content: str = "" # 日志内容
def log(self, content: str, print_to_console: bool = True) -> None:
"""添加日志"""
if print_to_console:
print(content)
self.log_content += content + "\n"
def push_notification(self) -> None:
"""推送通知"""
try:
QLAPI.notify(self.NAME, self.log_content)
except NameError:
print(f"\n\n🚀 推送通知\n\n{self.NAME}\n\n{self.log_content}")
def make_request(self, method: str, endpoint: str, **kwargs) -> Dict[str, Any]:
"""
发送API请求
Args:
method: 请求方法 (GET/POST)
endpoint: API端点
**kwargs: 请求参数
Returns:
Dict[str, Any]: API响应数据
"""
url = f"{self.BASE_URL}{endpoint}"
headers = {"token": self.token, "device": "iOS", "app-version": "8.31.2"}
if "headers" not in kwargs:
kwargs["headers"] = headers
else:
kwargs["headers"].update(headers)
try:
response = requests.request(method, url, timeout=30, **kwargs)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
self.log(f"❌ API request failed: {str(e)}")
return {"code": -1, "msg": str(e)}
def get_user_info(self) -> Dict[str, Any]:
"""
获取用户信息
Returns:
Dict[str, Any]: 用户信息字典,获取失败返回空字典
"""
response = self.make_request("GET", self.API_USER_INFO)
print(f"get_user_info API response ——> {response}")
if response.get("code") == 0:
data = response.get("data", {})
# 直接生成掩码后的手机号
masked_phone = f"{data.get('phone', '')[:3]}******{data.get('phone', '')[-2:]}"
return {
"token": self.token,
"hid": data.get("hid", ""),
"nickname": data.get("nickname", ""),
"phone": masked_phone, # 直接存储掩码后的手机号
"score_value": data.get("score_value", 0),
"share_user_hid": "",
"task": {"sign": False, "view": False, "question": False},
}
self.log(f"❌ 账号已失效, 请重新获取 token: {self.token}")
return {}
def get_score_details(self) -> None:
"""显示积分详情,包括总积分、今日变动和最近记录"""
params = {"page_no": "1", "page_size": "10"} # 获取最近10条记录
response = self.make_request("GET", self.API_MY_SCORE, params=params)
print(f"get_score_details API response ——> {response}")
if response.get("code") == 0:
data = response.get("data", {})
# 先获取今日记录
today = datetime.now().strftime("%Y-%m-%d")
points_record = data.get("points_record", {})
today_records = [
record
for record in points_record.get("list", [])
if record.get("created_at", "").startswith(today)
]
# 计算今日积分变化
today_score = sum(
int(record.get("score_str", "0").strip("+")) for record in today_records
)
today_score_str = f"+{today_score}" if today_score > 0 else str(today_score)
self.log(f"🎉 总积分: {data.get('score', 0)} | 今日积分变动: {today_score_str}")
# 输出今日积分记录
if today_records:
self.log("今日积分记录:")
for record in today_records:
self.log(
f"{record.get('created_at', '')} {record.get('desc', '')} {record.get('score_str', '')}"
)
else:
self.log("今日暂无积分变动")
# 任务相关
def check_task_status(self, user: Dict[str, Any]) -> None:
"""检查任务状态"""
response = self.make_request("GET", self.API_TASK_LIST)
print(f"get_task_status API response ——> {response}")
if response.get("code") != 0:
self.log(f'❌ 获取任务列表失败: {response.get("msg", "未知错误")}')
return
actions = response.get("data", {})
# 检查签到任务
if "action4" in actions:
user["task"]["sign"] = actions["action4"].get("status") == 1
else:
self.log("❌ task list action4 签到任务 不存在")
# 检查浏览文章任务
if "action12" in actions:
user["task"]["view"] = actions["action12"].get("status") == 1
else:
self.log("❌ task list action12 浏览文章任务 不存在")
# 检查答题任务
if "action39" in actions:
user["task"]["question"] = actions["action39"].get("status") == 1
else:
self.log("❌ task list action39 答题任务 不存在")
# 签到相关
def get_sign_info(self) -> None:
"""执行签到任务"""
max_attempts = 5 # 最大尝试次数
best_score = 0
best_params = None
for attempt in range(max_attempts):
response = self.make_request("GET", self.API_SIGN_LIST)
print(f"get_sign_info (attempt {attempt + 1}) API response ——> {response}")
if response.get("code") != 0:
self.log(f'❌ 获取签到列表失败: {response.get("msg", "未知错误")}')
break
data = response.get("data", {})
hid = data.get("hid", "")
reward_hash = data.get("rewardHash", "")
for item in data.get("list", []):
if item.get("hid") == hid:
current_score = item.get("score", 0)
print(
f"{attempt + 1}次获取签到列表: score={current_score} hid={hid} rewardHash={reward_hash}"
)
if current_score > best_score:
best_score = current_score
best_params = (hid, reward_hash, current_score)
print(f"当前可获得签到积分: {best_score}")
break
if attempt < max_attempts - 1: # 不是最后一次循环
print(f"继续尝试获取更高积分, 延时5-10s")
time.sleep(random.randint(5, 10))
else: # 最后一次循环 即将提交签到
print(f"即将提交签到, 延时3-4s")
time.sleep(random.randint(3, 4))
if best_params:
self.submit_sign(*best_params)
else:
self.log("❌ 未能获取到有效的签到参数")
def submit_sign(self, hid: str, reward_hash: str, score: int) -> None:
"""提交签到"""
json_data = {
"hid": hid,
"hash": reward_hash,
"sm_deviceId": "",
"ctu_token": None,
}
response = self.make_request("POST", self.API_SIGN_SUBMIT, json=json_data)
print(f"submit_sign API response ——> {response}")
if response.get("code") == 0:
self.log(f"✅ 签到成功 | 积分 +{score}")
else:
self.log(f'❌ 签到失败: {response.get("msg", "未知错误")}')
# 文章浏览相关
def get_article_list(self) -> List[str]:
"""获取文章列表"""
params = {
"page_no": "1",
"page_size": "20",
"type_hid": "",
}
response = self.make_request("GET", self.API_ARTICLE_LIST, params=params)
print(f"get_article_list API response ——> {response}")
if response.get("code") == 0:
# 从文章列表中随机选择3个ID
data = response.get("data", {})
article_list = [item.get("data_id", "") for item in data.get("list", []) if item.get("data_id")]
return random.sample(article_list, min(3, len(article_list)))
self.log(f'❌ 获取文章列表失败: {response.get("msg", "未知错误")}')
return []
def get_article_detail(self, article_id: str) -> None:
"""浏览文章"""
self.log(f"浏览文章 article_id: {article_id}")
endpoint = self.API_ARTICLE_DETAIL.format(article_id)
try:
# 调用make_request访问文章详情
response = self.make_request("GET", endpoint)
# 记录响应状态,便于调试
if response.get("code") == -1:
self.log(f"⚠️ 文章浏览异常: {response.get('msg', '未知错误')}")
else:
self.log(f"✅ 文章浏览成功")
except Exception as e:
# 捕获所有可能的异常,确保脚本不会在此处中断
self.log(f"❌ 文章浏览过程中发生异常: {str(e)}")
def submit_article_score(self) -> None:
"""提交文章积分"""
json_data = {
"ctu_token": "",
"action": 12,
}
response = self.make_request(
"POST", self.API_ARTICLE_SCORE_SUBMIT, json=json_data
)
print(f"submit_article_score API response ——> {response}")
if response.get("code") == 0:
data = response.get("data", {})
score = data.get("score", 0)
self.log(f"✅ 浏览文章成功 | 积分 +{score}")
else:
self.log(f'❌ 浏览文章失败: {response.get("msg", "未知错误")}')
# 答题相关
def get_question_info(self, share_user_hid: str) -> None:
"""执行答题任务"""
params = {"date": datetime.now().strftime("%Y%m%d")}
response = self.make_request("GET", self.API_QUESTION_INFO, params=params)
print(f"get_question_info API response ——> {response}")
if response.get("code") != 0:
self.log(f'❌ 获取问题失败: {response.get("msg", "未知错误")}')
return
data = response.get("data", {})
# data['state'] 1=表示未答题 2=已答题且正确 3=答错且未有人帮忙答题 4=答错但有人帮忙答题
if data.get("state") == 3:
self.log("今日已答题但回答错误,当前无人帮助答题,跳过")
return
if data.get("state") != 1:
if data.get("answer"):
answer = data.get("answer", [""])[0]
if answer in ["A", "B", "C", "D"]:
self.correct_answer = answer
self.log(f"今日已答题,跳过,答案:{answer}")
return
self.log("今日已答题,但未获取到答案,跳过")
return
question_info = data.get("question_info", {})
questions_hid = question_info.get("questions_hid", "")
# 构建问题字符串,只包含未被标记为错误的选项
question_str = f"{question_info.get('content', '')}\n"
valid_options = []
for option in question_info.get("option", []):
if option.get("option") not in self.wrong_answers:
valid_options.append(option)
question_str += f'{option.get("option", "")}. {option.get("option_content", "")}\n'
else:
print(f"跳过错误选项 {option.get('option', '')}. {option.get('option_content', '')}")
print(f"\n问题详情:\n{question_str}")
# 如果只剩一个选项,直接使用
if len(valid_options) == 1:
answer = valid_options[0]["option"]
self.log(f"仅剩一个选项,使用答案: {answer}")
time.sleep(random.randint(3, 5))
self.submit_question_answer(questions_hid, answer, share_user_hid)
return
# 获取答案并提交
answer = self.get_question_answer(question_str)
time.sleep(random.randint(3, 5))
self.submit_question_answer(questions_hid, answer, share_user_hid)
def get_ai_answer(self, question: str) -> str:
"""获取通用AI答案"""
if not self.ai_api_key or not self.ai_request_url or not self.ai_model:
return ""
headers = {
"Authorization": f"Bearer {self.ai_api_key}",
"Content-Type": "application/json",
}
# 构建默认的消息内容
system_prompt = "你是一位北京现代汽车品牌的专家,对车型配置非常熟悉。\n以下是一道单选题,请只从题目实际列出的选项里选择正确答案。\n注意:题目可能只给出 2 个或 3 个选项,并非永远 4 个。\n请仅输出对应选项的那个英文字母,不要输出任何其他字符。"
# 构建默认的 json_data
json_data = {
"model": self.ai_model,
"messages": [
{"role": "system", "content": system_prompt},
{"role": "user", "content": question}
]
}
# 如果提供了额外的请求参数,合并到 json_data 中
if self.ai_request_params:
try:
extra_params = json.loads(self.ai_request_params)
json_data.update(extra_params)
except json.JSONDecodeError as e:
print(f"❌ AI 请求参数解析失败: {str(e)}")
try:
print(f"通用 AI API request ——> {json_data}")
response = requests.post(
self.ai_request_url,
headers=headers,
json=json_data,
)
print(f"通用 AI API response status ——> {response.status_code}")
print(f"通用 AI API response text ——> {response.text}")
response.raise_for_status()
response_json = response.json()
# 获取AI回答内容并转大写
choices = response_json.get("choices", [])
if choices and len(choices) > 0:
message = choices[0].get("message", {})
ai_response = message.get("content", "").upper()
else:
ai_response = ""
# 使用集合操作找出有效答案
valid_answers = set("ABCD") - self.wrong_answers
found_answers = set(ai_response) & valid_answers
# 如果找到答案则返回其中一个
if found_answers:
return found_answers.pop()
else:
self.log(f"❌ 没有找到符合的 AI 答案")
return ""
except Exception as e:
self.log(f"通用 AI API 请求失败: {str(e)}")
return ""
def get_question_answer(self, question: str) -> str:
"""获取答题答案"""
# 1. 存在正确答案时,使用正确答案
if self.correct_answer:
self.log(f"使用历史正确答案: {self.correct_answer}")
return self.correct_answer
# 2. 存在预设答案时,使用预设答案
if self.preset_answer:
self.log(f"使用预设答案: {self.preset_answer}")
return self.preset_answer
# 3. 存在AI配置时使用通用AI方法获取答案
if self.ai_api_key and self.ai_request_url and self.ai_model:
ai_answer = self.get_ai_answer(question)
if ai_answer:
self.log(f"使用 AI 答案: {ai_answer}")
return ai_answer
# 4. 随机选择答案(排除错误答案)
answer = self.get_random_answer()
self.log(f"随机答题,答案: {answer}")
return answer
def get_random_answer(self) -> str:
"""获取随机答案,排除已知错误答案"""
available_answers = set(["A", "B", "C", "D"]) - self.wrong_answers
if not available_answers:
self.wrong_answers.clear()
available_answers = set(["A", "B", "C", "D"])
return random.choice(list(available_answers))
def get_answered_question(self) -> None:
"""从已答题账号获取答案"""
params = {"date": datetime.now().strftime("%Y%m%d")}
response = self.make_request("GET", self.API_QUESTION_INFO, params=params)
print(f"get_answered_question API response ——> {response}")
if response.get("code") != 0:
self.log(f'❌ 从已答题账号获取问题失败: {response.get("msg", "未知错误")}')
return
data = response.get("data", {})
# data['state'] 1=表示未答题 2=已答题且正确 4=已答题但错误
if response.get("code") == 0 and data.get("answer"):
answer = data.get("answer", [""])[0]
if answer in ["A", "B", "C", "D"]:
self.correct_answer = answer
self.log(f"从已答题账号获取到答案:{answer}")
return
self.log("从已答题账号获取答案失败")
def submit_question_answer(
self, question_id: str, answer: str, share_user_hid: str
) -> None:
"""提交答题答案"""
json_data = {
"answer": answer,
"questions_hid": question_id,
"ctu_token": "",
}
if share_user_hid:
json_data["date"] = datetime.now().strftime("%Y%m%d")
json_data["share_user_hid"] = share_user_hid
response = self.make_request("POST", self.API_QUESTION_SUBMIT, json=json_data)
print(f"submit_question_answer API response ——> {response}")
if response.get("code") == 0:
data = response.get("data", {})
if data.get("state") == 3: # 答错
# 记录错误答案
self.wrong_answers.add(answer)
# 如果是正确答案,清除它
if self.correct_answer == answer:
self.correct_answer = ""
# 如果是预设答案,清除它
if self.preset_answer == answer:
self.preset_answer = ""
self.log("❌ 答题错误")
elif data.get("state") == 2: # 答对了
if self.correct_answer != answer:
self.correct_answer = answer
score = data.get("answer_score", 0)
self.log(f"✅ 答题正确 | 积分 +{score}")
else:
self.log(f'❌ 答题失败: {response.get("msg", "未知错误")}')
def get_backup_share_hid(self, user_hid: str) -> str:
"""从备用 hid 列表中获取一个不同于用户自身的 hid"""
available_hids = [hid for hid in self.BACKUP_HIDS if hid != user_hid]
return random.choice(available_hids) if available_hids else ""
def run(self) -> None:
"""运行主程序"""
try:
from dotenv import load_dotenv
load_dotenv()
print("✅ dotenv 成功加载 .env 文件")
except ImportError:
print("⚠️ 缺少 dotenv 库, 青龙环境请忽略, 本地运行请安装此库")
# 使用列表保持顺序,使用集合实现去重
tokens = []
tokens_set = set()
# 方式1: 从BJXD环境变量获取(逗号分隔的多个token)
token_str = os.getenv("BJXD")
if token_str:
# 过滤空值并保持顺序添加
for token in token_str.split(","):
token = token.strip()
if token and token not in tokens_set:
tokens.append(token)
tokens_set.add(token)
# 方式2: 从BJXD1/BJXD2/BJXD3等环境变量获取
i = 1
empty_count = 0 # 记录连续空值的数量
while empty_count < 5: # 连续5个空值才退出
token = os.getenv(f"BJXD{i}")
if not token:
empty_count += 1
else:
token = token.strip()
if token and token not in tokens_set: # 确保token不是空字符串且未重复
empty_count = 0 # 重置连续空值计数
tokens.append(token)
tokens_set.add(token)
i += 1
if not tokens:
self.log(
"⛔️ 未获取到 tokens, 请检查环境变量 BJXD 或 BJXD1/BJXD2/... 是否填写"
)
self.push_notification()
return
self.log(f"👻 共获取到用户 token {len(tokens)}")
# 获取新的 AI 配置参数
self.ai_api_key = os.getenv("AI_API_KEY", "")
self.ai_request_url = os.getenv("AI_REQUEST_URL", "")
self.ai_model = os.getenv("AI_MODEL", "")
self.ai_request_params = os.getenv("AI_REQUEST_PARAMS", "")
# 兼容旧的环境变量
if not self.ai_api_key and not self.ai_request_url and not self.ai_model:
# 检查旧的腾讯混元 AI 配置
self.ai_hunyuan_api_key = os.getenv("HUNYUAN_API_KEY", "")
if self.ai_hunyuan_api_key:
self.ai_api_key = self.ai_hunyuan_api_key
self.ai_request_url = "https://api.hunyuan.cloud.tencent.com/v1/chat/completions"
self.ai_model = "hunyuan-turbo"
self.ai_request_params = json.dumps({"enable_enhancement": True, "force_search_enhancement": True, "enable_instruction_search": True})
self.log("💯 已获取到腾讯混元 AI 配置, 使用腾讯混元 AI 答题")
else:
self.log("😭 未设置腾讯混元 AI HUNYUAN_API_KEY 环境变量")
# 检查旧的智谱 GLM AI 配置
self.ai_glm_api_key = os.getenv("GLM_API_KEY", "")
if self.ai_glm_api_key:
self.ai_api_key = self.ai_glm_api_key
self.ai_request_url = "https://open.bigmodel.cn/api/paas/v4/chat/completions"
self.ai_model = "glm-4.5-flash"
self.ai_request_params = json.dumps({"do_sample": False})
self.log("💯 已获取到智谱 GLM AI 配置, 使用智谱 GLM AI 答题")
else:
self.log("😭 未设置智谱 GLM AI GLM_API_KEY 环境变量")
else:
# 使用新的 AI 配置
if self.ai_api_key and self.ai_request_url and self.ai_model:
self.log("💯 已获取到通用 AI 配置, 使用通用 AI 答题")
else:
self.log("⚠️ 通用 AI 配置不完整, 请检查 AI_API_KEY、AI_REQUEST_URL 和 AI_MODEL 环境变量")
# 获取预设答案
self.preset_answer = os.getenv("BJXD_ANSWER", "").upper()
if self.preset_answer:
if self.preset_answer in ["A", "B", "C", "D"]:
self.log(f"📝 已获取预设答案: {self.preset_answer}")
else:
self.preset_answer = ""
self.log("❌ 预设答案格式错误,仅支持 A/B/C/D")
self.log("获取用户信息")
# 获取所有用户信息
for token in tokens:
self.token = token
user = self.get_user_info()
if user:
self.users.append(user)
time.sleep(random.randint(3, 5))
if not self.users:
self.log("❌ 未获取到有效用户")
# 最后推送通知
self.push_notification()
return
# 设置分享用户ID
for i, user in enumerate(self.users):
prev_index = (i - 1) if i > 0 else len(self.users) - 1
# 如果有多个用户且上一个用户不是自己,使用上一个用户的 hid
if len(self.users) > 1 and self.users[prev_index].get("hid") != user.get("hid"):
user["share_user_hid"] = self.users[prev_index].get("hid", "")
else:
# 否则从备用 hid 列表中选择一个
user["share_user_hid"] = self.get_backup_share_hid(user.get("hid", ""))
# 执行任务
self.log("\n============ 执行任务 ============")
for i, user in enumerate(self.users, 1):
# 更新当前用户信息
self.token = user["token"]
self.user = user
# 随机延迟
if i > 1:
print("\n进行下一个账号, 等待 5-10 秒...")
time.sleep(random.randint(5, 10))
self.log(f"\n======== ▷ 第 {i} 个账号 ◁ ========")
# 打印用户信息
self.log(
f"👻 用户名: {self.user.get('nickname', '未知')} | "
f"手机号: {self.user.get('phone', '未知')} | "
f"积分: {self.user.get('score_value', 0)}\n"
f"🆔 用户hid: {self.user.get('hid', '')}\n"
f"🆔 分享hid: {self.user.get('share_user_hid', '')}"
)
# 检查任务状态
self.check_task_status(self.user)
self.log(f"任务状态: {self.user['task']}")
# 调试使用 设置任务状态
self.user["task"]["question"] = True
# self.user["task"]["sign"] = False
# self.user["task"]["view"] = False
# 获取任务状态
user_task = self.user.get("task", {})
# 任务:答题
if not user_task.get("question"):
self.get_question_info(self.user.get("share_user_hid", ""))
else:
self.log("✅ 答题任务 已完成,跳过")
if not self.correct_answer:
self.get_answered_question()
# 任务:签到
if not user_task.get("sign"):
self.get_sign_info()
time.sleep(random.randint(5, 10))
else:
self.log("✅ 签到任务 已完成,跳过")
# 任务:阅读文章
if not user_task.get("view"):
article_ids = self.get_article_list()
if article_ids:
for index, article_id in enumerate(article_ids): # 已经只有3篇了
self.log(f"🔄 开始处理第 {index + 1}/{len(article_ids)} 篇文章")
try:
self.get_article_detail(article_id)
except Exception as e:
self.log(f"❌ 第 {index + 1} 篇文章处理失败: {str(e)}")
# 每篇文章之间的延迟
time.sleep(random.randint(10, 15))
# 所有文章处理完成后提交积分
try:
self.submit_article_score()
except Exception as e:
self.log(f"❌ 提交文章积分失败: {str(e)}")
else:
self.log("✅ 浏览文章任务 已完成,跳过")
self.log("\n============ 积分详情 ============")
for i, user in enumerate(self.users, 1):
if i > 1:
print("\n进行下一个账号, 等待 5-10 秒...")
time.sleep(random.randint(5, 10))
# 更新当前用户信息
self.token = user["token"]
self.user = user
self.log(f"\n======== ▷ 第 {i} 个账号 ◁ ========")
# 打印用户信息
self.log(
f"👻 用户名: {self.user.get('nickname', '未知')} | 手机号: {self.user.get('phone', '未知')}"
)
# 显示积分详情
self.get_score_details()
# 最后推送通知
self.push_notification()
if __name__ == "__main__":
BeiJingHyundai().run()

View File

@@ -0,0 +1,258 @@
# Source: https://github.com/smallfawn/QLScriptPublic/blob/main/daily/quark.py
# Raw: https://raw.githubusercontent.com/smallfawn/QLScriptPublic/main/daily/quark.py
# Repo: smallfawn/QLScriptPublic
# Path: daily/quark.py
# UploadedAt: 2026-05-14T17:47:57+08:00
# SHA256: 6ffca99dbbda1318e011f003244908a1c83db172b3549699b254b309b0fe5a00
# Category: APP版/抓包
# Evidence: cookie/token/authorization/header
'''
new Env('夸克自动签到')
cron: 0 9 * * *
V2版-目前有效
使用移动端接口修复每日自动签到,移除原有的“登录验证”,参数有效期未知
V1版-已失效
受大佬 @Cp0204 的仓库项目启发改编
源码来自 GitHub 仓库https://github.com/Cp0204/quark-auto-save
提取“登录验证”“签到”“领取”方法封装到下文中的“Quark”类中
Author: BNDou
Date: 2024-03-15 21:43:06
LastEditTime: 2025-11-18 03:49:26
FilePath: \Auto_Check_In\checkIn_Quark.py
Description:
抓包流程:
【手机端】
①打开抓包,手机端访问抽奖页
②找到url为 https://drive-m.quark.cn/1/clouddrive/act/growth/reward 的请求信息
③复制整段url该链接后面必须要有参数: kps sign vcode粘贴到环境变量
环境变量名为 COOKIE_QUARK 多账户用 回车 或 && 分开
user字段是用户名 (可是随意填写,多账户方便区分)
例如: user=张三; url=https://drive-m.quark.cn/1/clouddrive/act/growth/reward?xxxxxx=xxxxxx&kps=abcdefg&sign=hijklmn&vcode=111111111;
旧版环境变量格式也兼容,例如: user=张三; kps=abcdefg; sign=hijklmn; vcode=111111111;
'''
import os
import re
import sys
import requests
# 测试用环境变量
# os.environ['COOKIE_QUARK'] = ''
try: # 异常捕捉
from notify import send # 导入消息通知模块
except Exception as err: # 异常捕捉
print('%s\n❌加载通知服务失败~' % err)
# 获取环境变量
def get_env():
# 判断 COOKIE_QUARK是否存在于环境变量
if "COOKIE_QUARK" in os.environ:
# 读取系统变量以 \n 或 && 分割变量
cookie_list = re.split('\n|&&', os.environ.get('COOKIE_QUARK'))
else:
# 标准日志输出
print('❌未添加COOKIE_QUARK变量')
send('夸克自动签到', '❌未添加COOKIE_QUARK变量')
# 脚本退出
sys.exit(0)
return cookie_list
class Quark:
'''
Quark类封装了签到、领取签到奖励的方法
'''
def __init__(self, user_data):
'''
初始化方法
:param user_data: 用户信息,用于后续的请求
'''
self.param = user_data
def convert_bytes(self, b):
'''
将字节转换为 MB GB TB
:param b: 字节数
:return: 返回 MB GB TB
'''
units = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
i = 0
while b >= 1024 and i < len(units) - 1:
b /= 1024
i += 1
return f"{b:.2f} {units[i]}"
def get_growth_info(self):
'''
获取用户当前的签到信息
:return: 返回一个字典,包含用户当前的签到信息
'''
url = "https://drive-m.quark.cn/1/clouddrive/capacity/growth/info"
querystring = {
"pr": "ucpro",
"fr": "android",
"kps": self.param.get('kps'),
"sign": self.param.get('sign'),
"vcode": self.param.get('vcode')
}
response = requests.get(url=url, params=querystring).json()
#print(response)
if response.get("data"):
return response["data"]
else:
return False
def get_growth_sign(self):
'''
获取用户当前的签到信息
:return: 返回一个字典,包含用户当前的签到信息
'''
url = "https://drive-m.quark.cn/1/clouddrive/capacity/growth/sign"
querystring = {
"pr": "ucpro",
"fr": "android",
"kps": self.param.get('kps'),
"sign": self.param.get('sign'),
"vcode": self.param.get('vcode')
}
data = {"sign_cyclic": True}
response = requests.post(url=url, json=data, params=querystring).json()
#print(response)
if response.get("data"):
return True, response["data"]["sign_daily_reward"]
else:
return False, response["message"]
def queryBalance(self):
'''
查询抽奖余额
'''
url = "https://coral2.quark.cn/currency/v1/queryBalance"
querystring = {
"moduleCode": "1f3563d38896438db994f118d4ff53cb",
"kps": self.param.get('kps'),
}
response = requests.get(url=url, params=querystring).json()
# print(response)
if response.get("data"):
return response["data"]["balance"]
else:
return response["msg"]
def do_sign(self):
'''
执行签到任务
:return: 返回一个字符串,包含签到结果
'''
log = ""
# 每日领空间
growth_info = self.get_growth_info()
if growth_info:
log += (
f" {'88VIP' if growth_info['88VIP'] else '普通用户'} {self.param.get('user')}\n"
f"💾 网盘总容量:{self.convert_bytes(growth_info['total_capacity'])}"
f"签到累计容量:")
if "sign_reward" in growth_info['cap_composition']:
log += f"{self.convert_bytes(growth_info['cap_composition']['sign_reward'])}\n"
else:
log += "0 MB\n"
if growth_info["cap_sign"]["sign_daily"]:
log += (
f"✅ 签到日志: 今日已签到+{self.convert_bytes(growth_info['cap_sign']['sign_daily_reward'])}"
f"连签进度({growth_info['cap_sign']['sign_progress']}/{growth_info['cap_sign']['sign_target']})\n"
)
else:
sign, sign_return = self.get_growth_sign()
if sign:
log += (
f"✅ 执行签到: 今日签到+{self.convert_bytes(sign_return)}"
f"连签进度({growth_info['cap_sign']['sign_progress'] + 1}/{growth_info['cap_sign']['sign_target']})\n"
)
else:
log += f"❌ 签到异常: {sign_return}\n"
else:
log += f"❌ 签到异常: 获取成长信息失败\n"
return log
def extract_params(url):
'''
从URL中提取所需的参数
:param url: 包含参数的URL
:return: 返回一个字典,包含所需的参数
'''
# 提取URL中的查询参数部分?后面的内容)
query_start = url.find('?')
query_string = url[query_start + 1:] if query_start != -1 else ''
# 解析查询参数
params = {}
for param in query_string.split('&'):
if '=' in param:
key, value = param.split('=', 1)
params[key] = value
# 返回所需的参数
return {
'kps': params.get('kps', ''),
'sign': params.get('sign', ''),
'vcode': params.get('vcode', '')
}
def main():
'''
主函数
:return: 返回一个字符串,包含签到结果
'''
msg = ""
global cookie_quark
cookie_quark = get_env()
print("✅ 检测到共", len(cookie_quark), "个夸克账号\n")
i = 0
while i < len(cookie_quark):
# 获取user_data参数
user_data = {} # 用户信息
for a in cookie_quark[i].replace(" ", "").split(';'):
if not a == '':
user_data.update({a[0:a.index('=')]: a[a.index('=') + 1:]})
# 从url参数中提取额外信息
if 'url' in user_data:
url_params = extract_params(user_data['url'])
user_data.update(url_params)
# print(user_data)
# 开始任务
log = f"🙍🏻‍♂️ 第{i + 1}个账号"
msg += log
# 登录
log = Quark(user_data).do_sign()
msg += log + "\n"
i += 1
print(msg)
try:
send('夸克自动签到', msg)
except Exception as err:
print('%s\n❌ 错误,请查看运行日志!' % err)
return msg[:-1]
if __name__ == "__main__":
print("----------夸克网盘开始签到----------")
main()
print("----------夸克网盘签到完毕----------")

View File

@@ -0,0 +1,123 @@
# Source: https://github.com/AkenClub/ken-iMoutai-Script/blob/main/1_generate_code.py
# Raw: https://raw.githubusercontent.com/AkenClub/ken-iMoutai-Script/main/1_generate_code.py
# Repo: AkenClub/ken-iMoutai-Script
# Path: 1_generate_code.py
# UploadedAt: 2025-11-20T09:54:34+08:00
# SHA256: 8c9e80a6466a2291a043e5852ed029aa0d610a9f58974757a3b82c4ecd675d34
# Category: APP版/账密
# Evidence: username/password/mobile/login
import time
import hashlib
import uuid
import requests
import logging
import json
import re
"""
1、获取登录验证码获取 DEVICE_ID、MT_VERSION 等数据
"""
# ------ 填写以下 1 个变量值 --------
# 填写手机号码,收到验证码后在 login.py 中填写验证码
PHONE_NUMBER = ""
# --------------------
# -------- 非必填 ------------
# 设备 ID留空则自动生成
# 若是想要保留之前的设备 ID可以在这里填写之前的值则不会生成新的设备 ID。
DEVICE_ID_DEFAULT = ""
# --------------------
'''
cron: 1 1 1 1 *
new Env("1_获取登录验证码")
'''
# ***** 以下内容不用动 *****
logging.basicConfig(level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s')
SALT = "2af72f100c356273d46284f6fd1dfc08"
def get_device_id():
if DEVICE_ID_DEFAULT:
return DEVICE_ID_DEFAULT
return str(uuid.uuid4())
def signature(content, time):
text = SALT + content + str(time)
md5 = hashlib.md5(text.encode()).hexdigest()
return md5
def send_code(mobile, device_id, mt_version):
cur_time = int(time.time() * 1000)
data = {
"mobile": mobile,
"md5": signature(mobile, cur_time),
"timestamp": str(cur_time)
}
headers = {
"MT-Device-ID": device_id,
"MT-APP-Version": mt_version,
"User-Agent": "iOS;16.3;Apple;?unrecognized?",
"Content-Type": "application/json"
}
url = "https://app.moutai519.com.cn/xhr/front/user/register/vcode"
response = requests.post(url, headers=headers, data=json.dumps(data))
json_response = response.json()
if json_response.get("code") == 2000:
logging.info(f"「发送验证码返回」:{json.dumps(json_response)}")
return True
else:
logging.error(f"「发送验证码-失败」:{json.dumps(json_response)}")
raise Exception("发送验证码错误")
def get_mt_version():
url = "https://apps.apple.com/cn/app/i%E8%8C%85%E5%8F%B0/id1600482450"
with requests.get(url) as response:
response.encoding = 'utf-8' # 确保使用正确的编码
html_content = response.text
# 使用正则表达式匹配版本号(已过时,这里只是作为兼容,避免又使用回这种规则)
pattern = re.compile(r'new__latest__version">(.*?)</p>', re.DOTALL)
match = pattern.search(html_content)
if not match:
# 新的匹配方式
pattern = re.compile(r'class="metadata[^"]*">\s*<h4[^>]*>(.*?)</h4>', re.DOTALL)
match = pattern.search(html_content)
if match:
mt_version = match.group(1).strip().replace('版本 ', '') # 去掉前后的空白字符
return mt_version
raise Exception("获取版本号失败")
if __name__ == "__main__":
# 判断 PHONE_NUMBER 是否为空
if not PHONE_NUMBER:
logging.error("「发送验证码-失败」:请填写手机号码")
raise Exception("请填写手机号码")
try:
mt_version = get_mt_version()
device_id = get_device_id()
# 发送验证码
if send_code(PHONE_NUMBER, device_id, mt_version):
logging.info(f"{PHONE_NUMBER}:验证码发送成功,请注意查收!")
logging.info("****************************")
logging.info("记录以下信息用于后续登录:")
logging.info(f"设备ID - DEVICE_ID{device_id}")
logging.info(f"版本号 - MT_VERSION{mt_version}")
except Exception as e:
logging.error(e)

View File

@@ -0,0 +1,104 @@
# Source: https://github.com/AkenClub/ken-iMoutai-Script/blob/main/2_login.py
# Raw: https://raw.githubusercontent.com/AkenClub/ken-iMoutai-Script/main/2_login.py
# Repo: AkenClub/ken-iMoutai-Script
# Path: 2_login.py
# UploadedAt: 2025-11-20T09:54:34+08:00
# SHA256: 153777702f935023b805885108b95cc7ecbd1b8f473d6024e20a4f594909fcba
# Category: APP版/账密
# Evidence: username/password/mobile/login
import time
import hashlib
import requests
import json
import logging
"""
2、登录获取 USER_ID、TOKEN、COOKIE 等数据
上一步获取到验证码后根据上一步输出的版本号和设备ID填入下面信息进行登录请求
运行后,输出用户信息,并记录用于后续预约。
"""
# ------ 填写以下 4 个变量值 --------
# 手机号码,和上一步的手机号码一致
PHONE_NUMBER = ''
# 验证码,填写收到的验证码
CODE = ""
# 设备 ID和上一步的设备 ID 一致
DEVICE_ID = ""
# 版本号,和上一步的版本号一致
MT_VERSION = ""
# --------------------
'''
cron: 1 1 1 1 *
new Env("2_登录")
'''
# ***** 以下内容不用动 *****
SALT = "2af72f100c356273d46284f6fd1dfc08"
logging.basicConfig(level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s')
def signature(content, time):
text = SALT + content + str(time)
md5 = hashlib.md5(text.encode()).hexdigest()
return md5
def login(mobile, code, device_id, mt_version):
cur_time = int(time.time() * 1000)
data = {
"mobile": mobile,
"vCode": code,
"md5": signature(mobile + code, cur_time),
"timestamp": str(cur_time),
"MT-APP-Version": mt_version
}
headers = {
"MT-Device-ID": device_id,
"MT-APP-Version": mt_version,
"User-Agent": "iOS;16.3;Apple;?unrecognized?",
"Content-Type": "application/json"
}
url = "https://app.moutai519.com.cn/xhr/front/user/register/login"
response = requests.post(url, headers=headers, data=json.dumps(data))
json_response = response.json()
# 输出登录请求的返回结果
logging.info(f"「登录请求返回」:{json.dumps(json_response)}")
if json_response.get("code") == 2000:
logging.info("「登录请求-成功」")
user_data = json_response.get("data", {})
filtered_data = {
k: v
for k, v in user_data.items() if k not in
["idType", "verifyStatus", "idCode", "birthday", "userTag"]
}
return filtered_data
else:
logging.error("「登录请求-失败」")
raise Exception("登录失败,本地错误日志已记录")
if __name__ == "__main__":
# 判断入参
if not PHONE_NUMBER or not CODE or not DEVICE_ID or not MT_VERSION:
logging.error("「登录请求-失败」:缺少必要参数")
raise Exception("缺少必要参数")
result = login(PHONE_NUMBER, CODE, DEVICE_ID, MT_VERSION)
logging.info(f"「结果:用户信息」:{json.dumps(result)}")
logging.info("****************************")
logging.info("记录以下信息用于后续预约:")
logging.info(f"手机号码 - PHONE_NUMBER{PHONE_NUMBER}")
logging.info(f"设备ID - DEVICE_ID{DEVICE_ID}")
logging.info(f"版本号 - MT_VERSION{MT_VERSION}")
logging.info(f"用户ID - USER_ID{result['userId']}")
logging.info(f"Token - TOKEN{result['token']}")
logging.info(f"Cookie - COOKIE{result['cookie']}")

View File

@@ -0,0 +1,276 @@
# Source: https://github.com/AkenClub/ken-iMoutai-Script/blob/main/98_check_reservation_result.py
# Raw: https://raw.githubusercontent.com/AkenClub/ken-iMoutai-Script/main/98_check_reservation_result.py
# Repo: AkenClub/ken-iMoutai-Script
# Path: 98_check_reservation_result.py
# UploadedAt: 2025-11-20T09:54:34+08:00
# SHA256: 43d3c06749fa2ee28e34dee08daf91b99b3b8eb224b7095e6bad3d444d3e10e2
# Category: APP版/账密
# Evidence: username/password/mobile/login
"""
98、查询申购结果
*** 需要安装依赖 PyJWT ***
通知:运行结果会调用青龙面板的通知渠道。
配置环境变量KEN_IMAOTAI_ENV
-- 在旧版本青龙(例如 v2.13.8)中,使用 $ 作为分隔符时会出现解析环境变量失败,此时可以把 `$` 分隔符换为 `#` 作为分隔符。
-- 📣 怕出错?**建议直接使用 `#` 作为分隔符即可** (2024-10-15 更新支持)。
内容格式为PHONE_NUMBER$USER_ID$DEVICE_ID$MT_VERSION$PRODUCT_ID_LIST$SHOP_ID^SHOP_MODE^PROVINCE^CITY$LAT$LNG$TOKEN$COOKIE
解释:手机号码$用户ID$设备ID$版本号$商品ID列表$店铺ID店铺缺货时自动采用的模式^省份^城市$纬度$经度$TOKEN$COOKIE
多个用户时使用 & 连接
说明:^SHOP_MODE^PROVINCE^CITY 为可选
常量。
- PHONE_NUMBER: 用户的手机号码。 --- 自己手机号码
- CODE: 短信验证码。 --- 运行 1_generate_code.py 获取
- DEVICE_ID: 设备的唯一标识符。 --- 运行 1_generate_code.py 获取
- MT_VERSION: 应用程序的版本号。 --- 运行 1_generate_code.py 获取
- USER_ID: 用户的唯一标识符。 --- 运行 2_login.py 获取
- TOKEN: 用于身份验证的令牌。 --- 运行 2_login.py 获取
- COOKIE: 用于会话管理的Cookie。 --- 运行 2_login.py 获取
- PRODUCT_ID_LIST: 商品ID列表表示用户想要预约的商品。--- 运行 3_retrieve_shop_and_product_info.py 获取
- SHOP_ID: 店铺的唯一标识符。 --- 运行 3_retrieve_shop_and_product_info.py 获取
可设置为 AUTO则根据 SHOP_MODE 的值来选择店铺 ID。
- SHOP_MODE店铺缺货模式可选值为NEAREST距离最近或INVENTORY库存最多。设置该值时需要同时设置 PROVINCE 和 CITY。
非必填,但 SHOP_ID 设置 AUTO 时为必填,需要同时设置 SHOP_MODE、PROVINCE 和 CITY。
- PROVINCE: 用户所在的省份。 --- 与 3_retrieve_shop_and_product_info.py 填写的省份一致
非必填,但 SHOP_MODE 设置为 NEAREST 或 INVENTORY 时为必填。
- CITY: 用户所在的城市。 --- 与 3_retrieve_shop_and_product_info.py 填写的城市一致
非必填,但 SHOP_MODE 设置为 NEAREST 或 INVENTORY 时为必填。
- LAT: 用户所在位置的纬度。 --- 运行 3_retrieve_shop_and_product_info.py 获取
- LNG: 用户所在位置的经度。 --- 运行 3_retrieve_shop_and_product_info.py 获取
"""
import datetime
import time
import requests
import json
import os
import ast
import io
import logging
import re
from notify import send
# 每日 18:03 定时查询并通知
'''
cron: 03 18 * * *
new Env("98_查询申购结果")
'''
# 创建 StringIO 对象
log_stream = io.StringIO()
# 配置 logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
# 创建控制台 Handler
console_handler = logging.StreamHandler()
console_handler.setFormatter(
logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
# 创建 StringIO Handler
stream_handler = logging.StreamHandler(log_stream)
# stream_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
# 将两个 Handler 添加到 logger
logger.addHandler(console_handler)
logger.addHandler(stream_handler)
# 调试模式
DEBUG = False
# 读取 KEN_IMAOTAI_ENV 环境变量
KEN_IMAOTAI_ENV = os.getenv('KEN_IMAOTAI_ENV', '')
# 解析 KEN_IMAOTAI_ENV 环境变量并保存到 user 列表
users = []
if KEN_IMAOTAI_ENV:
env_list = KEN_IMAOTAI_ENV.split('&')
for env in env_list:
try:
# 使用 re.split() 分割字符串,支持 '#' 和 '$'
split_values = re.split(r'[#$]', env)
PHONE_NUMBER, USER_ID, DEVICE_ID, MT_VERSION, PRODUCT_ID_LIST, SHOP_INFO, LAT, LNG, TOKEN, COOKIE = split_values
SHOP_MODE = ''
PROVINCE = ''
CITY = ''
if '^' in SHOP_INFO:
parts = SHOP_INFO.split('^')
if len(parts) > 1:
# 检测 parts 长度是否为 4否则抛出异常
if len(parts) != 4:
raise Exception(
"🚫 店铺缺货模式值错误,请检查是否为 SHOP_ID^SHOP_MODE^PROVINCE^CITY"
)
SHOP_ID, SHOP_MODE, PROVINCE, CITY = parts
# 检测 SHOP_MODE 是否为 NEAREST 或 INVENTORY
if SHOP_MODE not in ['NEAREST', 'INVENTORY', '']:
raise Exception(
"🚫 店铺缺货模式值错误,请检查 SHOP_MODE 值是否为 NEAREST<默认> 距离最近) 或 INVENTORY库存最多 或 空字符串(不选择其他店铺)"
)
# 如果 SHOP_MODE 值合法,则需要配合检测 PROVINCE 和 CITY 是否为空(接口需要用到这些值)
if not PROVINCE or not CITY:
raise Exception(
"🚫 店铺缺货模式值为 NEAREST 或 INVENTORY 时,需要同时设置 PROVINCE 和 CITY"
)
else:
logging.warning(
"🚨🚨 建议根据环境变量格式,设置 SHOP_ID^SHOP_MODE^PROVINCE^CITY 值,否则无法在指定店铺缺货时自动预约其他店铺!🚨🚨"
)
# 如果 SHOP_INFO 没有 ^ 符号,则 SHOP_ID 为 SHOP_INFO
SHOP_ID = SHOP_INFO
# 如果 SHOP_ID 为 AUTO检查 SHOP_MODE 是否为空
if SHOP_ID == 'AUTO' and not SHOP_MODE:
raise Exception(
"🚫 店铺缺货模式值错误SHOP_ID 值为 AUTO 时,需设置 SHOP_MODE、PROVINCE 和 CITY 值 "
)
user = {
'PHONE_NUMBER': PHONE_NUMBER.strip(),
'USER_ID': USER_ID.strip(),
'DEVICE_ID': DEVICE_ID.strip(),
'MT_VERSION': MT_VERSION.strip(),
'PRODUCT_ID_LIST': ast.literal_eval(PRODUCT_ID_LIST.strip()),
'SHOP_ID': SHOP_ID.strip(),
'SHOP_MODE': SHOP_MODE.strip(),
'PROVINCE': PROVINCE.strip(),
'CITY': CITY.strip(),
'LAT': LAT.strip(),
'LNG': LNG.strip(),
'TOKEN': TOKEN.strip(),
'COOKIE': COOKIE.strip()
}
# 检查字段是否完整且有值,不检查 SHOP_MODE、PROVINCE、CITY 字段PROVINCE 和 CITY 用于 SHOP_MODE 里,而 SHOP_MODE 可选)
required_fields = [
'PHONE_NUMBER', 'USER_ID', 'DEVICE_ID', 'MT_VERSION',
'PRODUCT_ID_LIST', 'SHOP_ID', 'LAT', 'LNG', 'TOKEN', 'COOKIE'
]
if all(user.get(field) for field in required_fields):
# 判断 PRODUCT_ID_LIST 长度是否大于 0
if len(user['PRODUCT_ID_LIST']) > 0:
users.append(user)
else:
raise Exception("🚫 预约商品列表 - PRODUCT_ID_LIST 值为空,请添加后重试")
else:
logging.info(f"🚫 用户信息不完整: {user}")
except Exception as e:
errText = f"🚫 KEN_IMAOTAI_ENV 环境变量格式错误: {e}"
send("i茅台预约日志", errText)
raise Exception(errText)
logging.info("找到以下用户配置:")
# 输出用户信息
for index, user in enumerate(users):
if DEBUG:
logging.info(f"用户 {index + 1}: {user}")
continue
logging.info(f"用户 {index + 1}: 📞 {user['PHONE_NUMBER']}")
else:
errText = "🚫 KEN_IMAOTAI_ENV 环境变量未定义"
send("i茅台预约日志", errText)
raise Exception(errText)
# 生成请求头
def generate_headers(device_id, mt_version, token):
mt_k = f'{int(time.time() * 1000)}'
headers = {
"User-Agent": "iOS;16.3;Apple;?unrecognized?",
"MT-Device-ID": device_id,
"MT-APP-Version": mt_version,
'MT-Token': token,
'MT-Network-Type': 'WIFI',
'MT-User-Tag': '0',
'MT-K': mt_k,
'MT-Bundle-ID': 'com.moutai.mall',
'MT-R': 'clips_OlU6TmFRag5rCXwbNAQ/Tz1SKlN8THcecBp/HGhHdw==',
'MT-SN': 'clips_ehwpSC0fLBggRnJAdxYgFiAYLxl9Si5PfEl/TC0afkw='
}
return headers
# 查询申购结果
def check_reservation_result(token, device_id, mt_version):
global DEBUG
try:
url = f"https://app.moutai519.com.cn/xhr/front/mall/reservation/list/pageOne/queryV2"
headers = generate_headers(device_id, mt_version, token)
response = requests.get(url, headers=headers)
resultData = json.loads(response.text)
resultCode = resultData.get("code")
if resultCode == 4820:
message = resultData.get("data", {}).get("updateDesc", "API 可能限制了 APP 版本,可以尝试重新生成环境变量")
raise Exception(f"({resultCode}){message}")
elif resultCode != 2000:
message = resultData.get("message")
raise Exception(f"({resultCode}){message}")
# 处理预约结果
reservations = resultData.get("data", {}).get("reservationItemVOS", [])
if not reservations:
logging.info("🚫 暂无申购记录")
return
# 获取当天日期
today = datetime.datetime.now().date()
today_str = today.strftime("%Y-%m-%d")
logging.info(f"📅 今天的日期是: {today_str}")
for item in reservations:
# 获取预约时间
reservation_time = datetime.datetime.fromtimestamp(
item.get("reservationTime") / 1000).date()
# 筛选今天预约的商品
if reservation_time == today:
status_text = {
0: "⌛️ 静候申购结果",
1: "❌ 申购失败",
2: "🎉 申购成功"
}.get(item.get("status"), "未知状态")
session_name = f"[{item.get('sessionName', '')}]" if item.get(
'sessionName') else ""
item_name = item.get("itemName", "")
item_id = item.get("itemId", "")
# 输出结果
logging.info(
f"🍺 {session_name}[{item_id}] {item_name}{status_text}")
except Exception as e:
logging.error(f"🚫 查询申购结果失败: {e}")
if __name__ == "__main__":
logging.info('--------------------------')
logging.info("💬 申购成功后将以短信形式通知您请您在申购成功次日18:00前选择支付方式并根据提示完成支付。")
for user in users:
try:
logging.info('--------------------------')
logging.info(f"📞 用户 {user['PHONE_NUMBER']} 开始查询申购结果")
check_reservation_result(user['TOKEN'],
user['DEVICE_ID'], user['MT_VERSION'])
except Exception as e:
logging.error(
f"🚫 用户 {user['PHONE_NUMBER']} 查询异常: {e},请到 App 上查看申购结果。")
logging.info('--------------------------')
logging.info("✅ 所有用户查询完成")
log_contents = log_stream.getvalue()
send("i茅台 查询申购结果日志:", log_contents)

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,158 @@
# Source: https://github.com/smallfawn/QLScriptPublic/blob/main/daily/360.py
# Raw: https://raw.githubusercontent.com/smallfawn/QLScriptPublic/main/daily/360.py
# Repo: smallfawn/QLScriptPublic
# Path: daily/360.py
# UploadedAt: 2026-04-07T07:05:19Z
# SHA256: 6ad9e6349174feff19123a743bc626bb84d6916c289d4ab3017d6b967b231a6e
# Category: web版/抓包
# Evidence: web/H5关键词 + cookie/token/header
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 作者: 青龙面板适配
# 说明: 360社区自动签到脚本青龙面板专用
# 依赖: requests
# new Env("360社区签到")
# 用法: 在青龙面板环境变量中设置 BBS360_COOKIE
# 请确保Cookie包含 __cfduid, uid 等必要字段
import os
import re
import time
import random
import requests
from dataclasses import dataclass
from typing import Optional, Tuple
SIGN_PAGE = "https://bbs.360.cn/dsu_paulsign-sign.html"
SIGN_API = "https://bbs.360.cn/plugin.php?id=dsu_paulsign:sign&operation=qiandao&infloat=1&inajax=1"
@dataclass
class CheckinResult:
ok: bool
status: str
detail: str
class BBS360Checkin:
"""360社区签到客户端青龙面板适配"""
def __init__(self, cookie: str, timeout: int = 20):
self.cookie = cookie.strip()
self.timeout = timeout
self.session = requests.Session()
self.session.headers.update({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "zh-CN,zh;q=0.9",
"Connection": "keep-alive",
"Cookie": self.cookie,
"Referer": "https://bbs.360.cn/",
})
def fetch_formhash(self) -> Tuple[Optional[str], str]:
"""拉取签到页并提取 formhash"""
resp = self.session.get(SIGN_PAGE, timeout=self.timeout, allow_redirects=True)
text = resp.text or ""
# 青龙面板特殊处理如果返回403可能是需要验证
if resp.status_code == 403:
return None, "403 Forbidden可能需要绑定手机号"
# 未登录/未绑定手机号时提示
if "您需要先登录才能继续本操作" in text or "请使用手机微信扫码安全登录" in text:
return None, "未登录或账号未绑定手机号需在360社区绑定手机号"
# 提取 formhash
m = re.search(r'formhash=([0-9a-zA-Z]{6,})', text)
if not m:
m = re.search(r'name="formhash"\s+value="([0-9a-zA-Z]{6,})"', text)
if not m:
return None, "未解析到 formhash页面结构可能变更"
return m.group(1), "OK"
def submit_checkin(self, formhash: str) -> CheckinResult:
"""提交签到请求"""
moods = ["kx", "ym", "tp", "ng", "wl"]
payload = {
"formhash": formhash,
"qdxq": random.choice(moods),
"qdmode": "1",
"todaysay": random.choice([
"打卡签到,愿一切顺利!",
"新的一天,继续加油~",
"保持热爱,奔赴山海。",
"今日签到,万事胜意。",
"坚持自律,慢慢变强。",
]),
"fastreply": "0",
}
resp = self.session.post(SIGN_API, data=payload, timeout=self.timeout)
raw = resp.text or ""
# 青龙面板特殊处理返回403或500
if resp.status_code != 200:
return CheckinResult(False, f"http_{resp.status_code}", f"HTTP {resp.status_code}")
# 检查签到结果
if "签到成功" in raw or ("恭喜" in raw and "签到" in raw):
return CheckinResult(True, "success", self._extract_message(raw) or "签到成功")
if "已经签到" in raw or "已签到" in raw or "请勿重复签到" in raw:
return CheckinResult(True, "already", self._extract_message(raw) or "今日已签到")
if ("formhash" in raw and "错误" in raw) or "请求无效" in raw:
return CheckinResult(False, "bad_formhash", self._extract_message(raw) or "formhash无效/过期")
return CheckinResult(False, "unknown", self._extract_message(raw) or raw[:200])
@staticmethod
def _extract_message(text: str) -> str:
"""提取提示信息"""
m = re.search(r"showmessage\('([^']+)'\)", text)
if m:
return m.group(1)
m = re.search(r"([^\n\r]{0,20}(签到|已签到|重复签到)[^\n\r]{0,40})", text)
if m:
return m.group(1)
return ""
def run(self) -> CheckinResult:
formhash, info = self.fetch_formhash()
if not formhash:
return CheckinResult(False, "no_login_or_parse_failed", info)
time.sleep(random.uniform(1.0, 2.5))
return self.submit_checkin(formhash)
def main():
# 青龙面板专用从环境变量获取Cookie
cookie = os.getenv("BBS360_COOKIE", "").strip()
if not cookie:
print("❌ 未设置环境变量 BBS360_COOKIE")
print("💡 请在青龙面板 → 环境变量 → 添加以下内容:")
print(" KEY: BBS360_COOKIE")
print(" VALUE: 从浏览器复制的完整Cookie包含__cfduid, uid等")
return
# 青龙面板特殊处理检测Cookie是否包含必要字段
if "__cfduid" not in cookie or "uid" not in cookie:
print("❌ Cookie无效缺少必要字段需包含__cfduid和uid")
print("💡 请重新复制Cookie")
print(" 1. 登录 bbs.360.cn → F12 → Application → Cookies")
print(" 2. 复制 bbs.360.cn 下的所有Cookie字段")
return
client = BBS360Checkin(cookie=cookie, timeout=20)
result = client.run()
# 青龙面板专用输出格式
if result.ok:
print(f"✅ 360签到成功 | {result.status} | {result.detail}")
else:
print(f"❌ 360签到失败 | {result.status} | {result.detail}")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,257 @@
# Source: https://github.com/smallfawn/QLScriptPublic/blob/main/daily/BREO.py
# Raw: https://raw.githubusercontent.com/smallfawn/QLScriptPublic/main/daily/BREO.py
# Repo: smallfawn/QLScriptPublic
# Path: daily/BREO.py
# UploadedAt: 2026-04-07T11:05:15Z
# SHA256: 446c598f98f635052297065eb89ca1d0a7ae4a9e0c9caf49cdb7b41cd1e8f585
# Category: web版/抓包
# Evidence: web/H5关键词 + cookie/token/header
#by:哆啦A梦
#入口:http://mx.qrurl.net/h5/wxa/link?sid=26407uif5Oq
#抓包breoplus.breo.cn的域名下的token多账号换行分割
#账号变量名:BREO
#new Env("BREO")
#cron 8 9,10,11 * * *
import requests
import json
import os
import time
def get_random_one_word():
try:
response = requests.get("https://uapis.cn/api/say")
if response.status_code == 200:
return response.text.strip()
else:
return "无法获取一言"
except Exception as e:
print(f"获取一言时出错: {e}")
return "无法获取一言"
def get_proclamation():
primary_url = "https://github.com/3288588344/toulu/raw/refs/heads/main/tl.txt"
backup_url = "https://tfapi.cn/TL/tl.json"
try:
response = requests.get(primary_url, timeout=10)
if response.status_code == 200:
print("\n" + "=" * 50)
print("📢 公告信息")
print("=" * 35)
print(response.text)
print("=" * 35 + "\n")
print("公告获取成功,开始执行任务...\n")
return
except requests.exceptions.RequestException as e:
print(f"获取公告时发生错误: {e}, 尝试备用链接...")
try:
response = requests.get(backup_url, timeout=10)
if response.status_code == 200:
print("\n" + "=" * 50)
print("📢 公告信息")
print("=" * 35)
print(response.text)
print("=" * 35 + "\n")
print("公告获取成功,开始执行任务...\n")
else:
print(f"⚠️ 获取公告失败,状态码: {response.status_code}")
except requests.exceptions.RequestException as e:
print(f"⚠️ 获取公告时发生错误: {e}, 可能是网络问题或链接无效。")
def post_to_breo(token, content, title):
url = "https://breoplus.breo.cn/breo-app/communityBaseInfo/releasePost"
headers = {
"token": token,
"device-type": "Xiaomi",
"device-version": "10",
"channel": "Breo",
"version_code": "30201",
"version": "3.2.1",
"encrypt": "1",
"Content-Type": "application/json; charset=UTF-8"
}
data = {
"anonymoused": 1,
"content": content,
"expressText": "",
"images": [],
"subTitle": "",
"title": title,
"topicText": ""
}
try:
response = requests.post(url, headers=headers, data=json.dumps(data))
if response.status_code == 200:
result = response.json()
if result.get("success", False):
print("✅ 发帖成功!")
print(f"帖子 ID: {result['result']['id']}")
print(f"帖子标题: {result['result']['title']}")
return result["result"]["id"]
else:
print(f"❌ 发帖失败,错误信息:{result.get('message', '未知错误')}")
return None
else:
print(f"❌ 请求失败,状态码:{response.status_code}")
return None
except Exception as e:
print(f"❌ 请求错误: {e}")
return None
def collect_post(token, post_id):
url = "https://breoplus.breo.cn/breo-app/communityBaseInfo/collect"
headers = {
"token": token,
"device-type": "Xiaomi",
"device-version": "10",
"channel": "Breo",
"version_code": "30201",
"version": "3.2.1",
"encrypt": "1",
"Content-Type": "application/json; charset=UTF-8"
}
data = {
"postId": post_id
}
try:
response = requests.post(url, headers=headers, data=json.dumps(data))
if response.status_code == 200:
result = response.json()
if result.get("success", False):
print("✅ 收藏成功!")
print(f"获得点数: {result['result']['point']}")
print(f"成长值: {result['result']['grow']}")
else:
print(f"❌ 收藏失败,错误信息:{result.get('message', '未知错误')}")
else:
print(f"❌ 请求失败,状态码:{response.status_code}")
except Exception as e:
print(f"❌ 请求错误: {e}")
def comment_post(token, post_id):
for _ in range(2): # 评论2次
comment_content = get_random_one_word() # 使用随机一言作为评论内容
url = "https://breoplus.breo.cn/breo-app/communityBaseInfo/comment"
headers = {
"token": token,
"device-type": "Xiaomi",
"device-version": "10",
"channel": "Breo",
"version_code": "30201",
"version": "3.2.1",
"encrypt": "1",
"Content-Type": "application/json; charset=UTF-8"
}
data = {
"anonymoused": 0,
"commentText": comment_content,
"postId": post_id
}
try:
response = requests.post(url, headers=headers, data=json.dumps(data))
if response.status_code == 200:
result = response.json()
if result.get("success", False):
print("✅ 评论成功!")
print(f"评论内容: {result['result']['rootOutVO']['commentText']}")
print(f"获得点数: {result['result']['point']}")
print(f"成长值: {result['result']['grow']}")
else:
print(f"❌ 评论失败,错误信息:{result.get('message', '未知错误')}")
else:
print(f"❌ 请求失败,状态码:{response.status_code}")
except Exception as e:
print(f"❌ 请求错误: {e}")
time.sleep(1) # 避免频繁请求
def browse_mall(token):
url = "https://breoplus.breo.cn/breo-app/user/po-task-info/mall"
headers = {
"token": token,
"device-type": "Xiaomi",
"device-version": "10",
"channel": "Breo",
"version_code": "30201",
"version": "3.2.1",
"encrypt": "1"
}
try:
response = requests.post(url, headers=headers)
if response.status_code == 200:
result = response.json()
if result.get("success", False):
print("✅ 浏览商城成功!")
print(f"获得点数: {result['result']['point']}")
print(f"成长值: {result['result']['grow']}")
else:
print(f"❌ 浏览商城失败,错误信息:{result.get('message', '未知错误')}")
else:
print(f"❌ 请求失败,状态码:{response.status_code}")
except Exception as e:
print(f"❌ 请求错误: {e}")
def punch_in(token):
url = "https://breoplus.breo.cn/breo-app/user/po-task-info/punch"
headers = {
"Host": "breoplus.breo.cn",
"Connection": "keep-alive",
"Content-Length": "0",
"content-type": "application/json",
"token": token,
"charset": "utf-8",
"Referer": "https://servicewechat.com/wx61457400e4212cec/304/page-frame.html",
"User-Agent": "Mozilla/5.0 (Linux; Android 10; MI 8 Build/QKQ1.190828.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/134.0.6998.136 Mobile Safari/537.36 XWEB/1340043 MMWEBSDK/20241202 MMWEBID/3628 MicroMessenger/8.0.56.2800(0x2800385E) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android",
"Accept-Encoding": "gzip, deflate, br"
}
try:
response = requests.post(url, headers=headers)
if response.status_code == 200:
result = response.json()
if result.get("success", False):
print("✅ 签到成功!")
print(f"获得点数: {result['result']['point']}")
print(f"成长值: {result['result']['grow']}")
else:
print(f"❌ 签到失败,错误信息:{result.get('message', '未知错误')}")
else:
print(f"❌ 请求失败,状态码:{response.status_code}")
except Exception as e:
print(f"❌ 请求错误: {e}")
if __name__ == "__main__":
# 获取公告
#get_proclamation()
# 从环境变量读取 token
tokens = os.getenv("BREO", "").splitlines()
if not tokens:
print("❌ 未检测到 账号信息,退出脚本。")
else:
print("=============== 开始执行任务 ===============")
for i, token in enumerate(tokens, 1):
if token.strip(): # 跳过空行
print(f"\n-------------- 账号 {i} 开始 --------------")
print("🚀 正在签到...")
punch_in(token)
print("\n📝 正在发布帖子...")
post_id = post_to_breo(token, "这是一个自动发布的帖子", "自动化测试")
if post_id:
print("\n⭐ 正在收藏帖子...")
collect_post(token, post_id)
print("\n💬 正在评论帖子...")
comment_post(token, post_id)
else:
print("❌ 发帖失败,跳过后续操作。")
print("\n🛒 正在浏览商城...")
browse_mall(token)
print(f"-------------- 账号 {i} 结束 --------------")
print("\n=============== 所有任务执行完毕 ===============")

View File

@@ -0,0 +1,255 @@
# Source: https://gitee.com/jdqlscript/toulu/blob/main/breo.py
# Raw: https://gitee.com/jdqlscript/toulu/raw/main/breo.py
# Repo: jdqlscript/toulu
# Path: breo.py
# UploadedAt: 2025-06-28T11:18:42+08:00
# SHA256: 647b98a9b738f298f61a064abe47421a4511e74520de74cd4653c39e236dcd5a
# Category: web版/抓包
# Evidence: web/H5关键词 + cookie/token/header
#by:哆啦A梦
#入口:http://api.0vsp.com/h5/wxa/link?sid=25424JXZCFp
#抓包breoplus.breo.cn的域名下的token多账号换行分割
#账号变量名:BREO
import requests
import json
import os
import time
def get_random_one_word():
try:
response = requests.get("https://uapis.cn/api/say")
if response.status_code == 200:
return response.text.strip()
else:
return "无法获取一言"
except Exception as e:
print(f"获取一言时出错: {e}")
return "无法获取一言"
def get_proclamation():
primary_url = "https://github.com/3288588344/toulu/raw/refs/heads/main/tl.txt"
backup_url = "https://tfapi.cn/TL/tl.json"
try:
response = requests.get(primary_url, timeout=10)
if response.status_code == 200:
print("\n" + "=" * 50)
print("📢 公告信息")
print("=" * 35)
print(response.text)
print("=" * 35 + "\n")
print("公告获取成功,开始执行任务...\n")
return
except requests.exceptions.RequestException as e:
print(f"获取公告时发生错误: {e}, 尝试备用链接...")
try:
response = requests.get(backup_url, timeout=10)
if response.status_code == 200:
print("\n" + "=" * 50)
print("📢 公告信息")
print("=" * 35)
print(response.text)
print("=" * 35 + "\n")
print("公告获取成功,开始执行任务...\n")
else:
print(f"⚠️ 获取公告失败,状态码: {response.status_code}")
except requests.exceptions.RequestException as e:
print(f"⚠️ 获取公告时发生错误: {e}, 可能是网络问题或链接无效。")
def post_to_breo(token, content, title):
url = "https://breoplus.breo.cn/breo-app/communityBaseInfo/releasePost"
headers = {
"token": token,
"device-type": "Xiaomi",
"device-version": "10",
"channel": "Breo",
"version_code": "30201",
"version": "3.2.1",
"encrypt": "1",
"Content-Type": "application/json; charset=UTF-8"
}
data = {
"anonymoused": 1,
"content": content,
"expressText": "",
"images": [],
"subTitle": "",
"title": title,
"topicText": ""
}
try:
response = requests.post(url, headers=headers, data=json.dumps(data))
if response.status_code == 200:
result = response.json()
if result.get("success", False):
print("✅ 发帖成功!")
print(f"帖子 ID: {result['result']['id']}")
print(f"帖子标题: {result['result']['title']}")
return result["result"]["id"]
else:
print(f"❌ 发帖失败,错误信息:{result.get('message', '未知错误')}")
return None
else:
print(f"❌ 请求失败,状态码:{response.status_code}")
return None
except Exception as e:
print(f"❌ 请求错误: {e}")
return None
def collect_post(token, post_id):
url = "https://breoplus.breo.cn/breo-app/communityBaseInfo/collect"
headers = {
"token": token,
"device-type": "Xiaomi",
"device-version": "10",
"channel": "Breo",
"version_code": "30201",
"version": "3.2.1",
"encrypt": "1",
"Content-Type": "application/json; charset=UTF-8"
}
data = {
"postId": post_id
}
try:
response = requests.post(url, headers=headers, data=json.dumps(data))
if response.status_code == 200:
result = response.json()
if result.get("success", False):
print("✅ 收藏成功!")
print(f"获得点数: {result['result']['point']}")
print(f"成长值: {result['result']['grow']}")
else:
print(f"❌ 收藏失败,错误信息:{result.get('message', '未知错误')}")
else:
print(f"❌ 请求失败,状态码:{response.status_code}")
except Exception as e:
print(f"❌ 请求错误: {e}")
def comment_post(token, post_id):
for _ in range(2): # 评论2次
comment_content = get_random_one_word() # 使用随机一言作为评论内容
url = "https://breoplus.breo.cn/breo-app/communityBaseInfo/comment"
headers = {
"token": token,
"device-type": "Xiaomi",
"device-version": "10",
"channel": "Breo",
"version_code": "30201",
"version": "3.2.1",
"encrypt": "1",
"Content-Type": "application/json; charset=UTF-8"
}
data = {
"anonymoused": 0,
"commentText": comment_content,
"postId": post_id
}
try:
response = requests.post(url, headers=headers, data=json.dumps(data))
if response.status_code == 200:
result = response.json()
if result.get("success", False):
print("✅ 评论成功!")
print(f"评论内容: {result['result']['rootOutVO']['commentText']}")
print(f"获得点数: {result['result']['point']}")
print(f"成长值: {result['result']['grow']}")
else:
print(f"❌ 评论失败,错误信息:{result.get('message', '未知错误')}")
else:
print(f"❌ 请求失败,状态码:{response.status_code}")
except Exception as e:
print(f"❌ 请求错误: {e}")
time.sleep(1) # 避免频繁请求
def browse_mall(token):
url = "https://breoplus.breo.cn/breo-app/user/po-task-info/mall"
headers = {
"token": token,
"device-type": "Xiaomi",
"device-version": "10",
"channel": "Breo",
"version_code": "30201",
"version": "3.2.1",
"encrypt": "1"
}
try:
response = requests.post(url, headers=headers)
if response.status_code == 200:
result = response.json()
if result.get("success", False):
print("✅ 浏览商城成功!")
print(f"获得点数: {result['result']['point']}")
print(f"成长值: {result['result']['grow']}")
else:
print(f"❌ 浏览商城失败,错误信息:{result.get('message', '未知错误')}")
else:
print(f"❌ 请求失败,状态码:{response.status_code}")
except Exception as e:
print(f"❌ 请求错误: {e}")
def punch_in(token):
url = "https://breoplus.breo.cn/breo-app/user/po-task-info/punch"
headers = {
"Host": "breoplus.breo.cn",
"Connection": "keep-alive",
"Content-Length": "0",
"content-type": "application/json",
"token": token,
"charset": "utf-8",
"Referer": "https://servicewechat.com/wx61457400e4212cec/304/page-frame.html",
"User-Agent": "Mozilla/5.0 (Linux; Android 10; MI 8 Build/QKQ1.190828.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/134.0.6998.136 Mobile Safari/537.36 XWEB/1340043 MMWEBSDK/20241202 MMWEBID/3628 MicroMessenger/8.0.56.2800(0x2800385E) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android",
"Accept-Encoding": "gzip, deflate, br"
}
try:
response = requests.post(url, headers=headers)
if response.status_code == 200:
result = response.json()
if result.get("success", False):
print("✅ 签到成功!")
print(f"获得点数: {result['result']['point']}")
print(f"成长值: {result['result']['grow']}")
else:
print(f"❌ 签到失败,错误信息:{result.get('message', '未知错误')}")
else:
print(f"❌ 请求失败,状态码:{response.status_code}")
except Exception as e:
print(f"❌ 请求错误: {e}")
if __name__ == "__main__":
# 获取公告
get_proclamation()
# 从环境变量读取 token
tokens = os.getenv("BREO", "").splitlines()
if not tokens:
print("❌ 未检测到 账号信息,退出脚本。")
else:
print("=============== 开始执行任务 ===============")
for i, token in enumerate(tokens, 1):
if token.strip(): # 跳过空行
print(f"\n-------------- 账号 {i} 开始 --------------")
print("🚀 正在签到...")
punch_in(token)
print("\n📝 正在发布帖子...")
post_id = post_to_breo(token, "这是一个自动发布的帖子", "自动化测试")
if post_id:
print("\n⭐ 正在收藏帖子...")
collect_post(token, post_id)
print("\n💬 正在评论帖子...")
comment_post(token, post_id)
else:
print("❌ 发帖失败,跳过后续操作。")
print("\n🛒 正在浏览商城...")
browse_mall(token)
print(f"-------------- 账号 {i} 结束 --------------")
print("\n=============== 所有任务执行完毕 ===============")

View File

@@ -0,0 +1,277 @@
# Source: https://gitee.com/jdqlscript/toulu/blob/main/Ruishu.py
# Raw: https://gitee.com/jdqlscript/toulu/raw/main/Ruishu.py
# Repo: jdqlscript/toulu
# Path: Ruishu.py
# UploadedAt: 2025-06-28T11:18:42+08:00
# SHA256: 0132420d27d358f8cd91749b877206aee7e2a86cec5cd99c8c119392e4d604f3
# Category: web版/抓包
# Evidence: web/H5关键词 + cookie/token/header
/*
#TL库:https://github.com/3288588344/toulu.git
#tg频道:https://t.me/TLtoulu
#QQ频道:https://pd.qq.com/s/672fku8ge
#微信机器人kckl6688
#公众号:哆啦A梦的藏宝箱
*/
import os
import ssl
import time
import json
import execjs
import base64
import random
import certifi
import aiohttp
import asyncio
import requests
from http import cookiejar
from Crypto.Cipher import DES3
from Crypto.Util.Padding import pad, unpad
from aiohttp import ClientSession, TCPConnector
import httpx
httpx._config.DEFAULT_CIPHERS += ":ALL:@SECLEVEL=1"
diffValue = 2
filename='Cache.js'
if os.path.exists(filename):
with open(filename, 'r', encoding='utf-8') as file:
fileContent = file.read()
else:
fileContent=''
class BlockAll(cookiejar.CookiePolicy):
return_ok = set_ok = domain_return_ok = path_return_ok = lambda self, *args, **kwargs: False
netscape = True
rfc2965 = hide_cookie2 = False
def printn(m):
print(f'\n{m}')
context = ssl.create_default_context()
context.set_ciphers('DEFAULT@SECLEVEL=1') # 低安全级别0/1
context.check_hostname = False # 禁用主机
context.verify_mode = ssl.CERT_NONE # 禁用证书
class DESAdapter(requests.adapters.HTTPAdapter):
def init_poolmanager(self, *args, **kwargs):
kwargs['ssl_context'] = context
return super().init_poolmanager(*args, **kwargs)
requests.DEFAULT_RETRIES = 0
requests.packages.urllib3.disable_warnings()
ss = requests.session()
ss.headers = {"User-Agent": "Mozilla/5.0 (Linux; Android 13; 22081212C Build/TKQ1.220829.002) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.97 Mobile Safari/537.36", "Referer": "https://wapact.189.cn:9001/JinDouMall/JinDouMall_independentDetails.html"}
ss.mount('https://', DESAdapter())
ss.cookies.set_policy(BlockAll())
runTime = 0
sleepTime = 1
key = b'1234567`90koiuyhgtfrdews'
iv = 8 * b'\0'
def encrypt(text):
cipher = DES3.new(key, DES3.MODE_CBC, iv)
ciphertext = cipher.encrypt(pad(text.encode(), DES3.block_size))
return ciphertext.hex()
def decrypt(text):
ciphertext = bytes.fromhex(text)
cipher = DES3.new(key, DES3.MODE_CBC, iv)
plaintext = unpad(cipher.decrypt(ciphertext), DES3.block_size)
return plaintext.decode()
def initCookie(getUrl='https://wapact.189.cn:9001/gateway/standQuery/detailNew/exchange'):
global js_code_ym, fileContent
cookie = ''
response = httpx.post(getUrl)
content = response.text.split(' content="')[2].split('" r=')[0]
code1 = response.text.split('$_ts=window')[1].split('</script><script type="text/javascript"')[0]
code1Content = '$_ts=window' + code1
Url = response.text.split('$_ts.lcd();</script><script type="text/javascript" charset="utf-8" src="')[1].split('" r=')[0]
urls = getUrl.split('/')
rsurl = urls[0] + '//' + urls[2] + Url
filename = 'Cache.js'
if fileContent == '':
if not os.path.exists(filename):
fileRes = httpx.get(rsurl)
fileContent = fileRes.text
if fileRes.status_code == 200:
with open(filename, 'w', encoding='utf-8') as file:
file.write(fileRes.text)
else:
print(f"Failed to download {rsurl}. Status code: {fileRes.status_code}")
if response.headers['Set-Cookie']:
cookie = response.headers['Set-Cookie'].split(';')[0].split('=')[1]
runJs = js_code_ym.replace('content_code', content).replace("'ts_code'", code1Content + fileContent)
execjsRun = RefererCookie(runJs)
return {
'cookie': cookie,
'execjsRun': execjsRun
}
def RefererCookie(runJs):
try:
execjsRun = execjs.compile(runJs)
return execjsRun
except execjs._exceptions.CompileError as e:
print(f"JavaScript 编译错误: {e}")
except execjs._exceptions.RuntimeError as e:
print(f"JavaScript 运行时错误: {e}")
except Exception as e:
print(f"其他错误: {e}")
js_code_ym = '''delete __filename
delete __dirname
ActiveXObject = undefined
window = global;
content="content_code"
navigator = {"platform": "Linux aarch64"}
navigator = {"userAgent": "CtClient;11.0.0;Android;13;22081212C;NTIyMTcw!#!MTUzNzY"}
location={
"href": "https://",
"origin": "",
"protocol": "",
"host": "",
"hostname": "",
"port": "",
"pathname": "",
"search": "",
"hash": ""
}
i = {length: 0}
base = {length: 0}
div = {
getElementsByTagName: function (res) {
console.log('div中的getElementsByTagName', res)
if (res === 'i') {
return i
}
return '<div></div>'
}
}
script = {
}
meta = [
{charset:"UTF-8"},
{
content: content,
getAttribute: function (res) {
console.log('meta中的getAttribute', res)
if (res === 'r') {
return 'm'
}
},
parentNode: {
removeChild: function (res) {
console.log('meta中的removeChild', res)
return content
}
},
}
]
form = '<form></form>'
window.addEventListener= function (res) {
console.log('window中的addEventListener:', res)
}
document = {
createElement: function (res) {
console.log('document中的createElement', res)
if (res === 'div') {
return div
} else if (res === 'form') {
return form
}
else{return res}
},
addEventListener: function (res) {
console.log('document中的addEventListener:', res)
},
appendChild: function (res) {
console.log('document中的appendChild', res)
return res
},
removeChild: function (res) {
console.log('document中的removeChild', res)
},
getElementsByTagName: function (res) {
console.log('document中的getElementsByTagName', res)
if (res === 'script') {
return script
}
if (res === 'meta') {
return meta
}
if (res === 'base') {
return base
}
},
getElementById: function (res) {
console.log('document中的getElementById', res)
if (res === 'root-hammerhead-shadow-ui') {
return null
}
}
}
setInterval = function () {}
setTimeout = function () {}
window.top = window
'ts_code'
function main() {
cookie = document.cookie.split(';')[0]
return cookie
}'''
async def main(timeValue):
global runTime, js_codeRead
tasks = []
init_result = initCookie()
if init_result:
cookie = init_result['cookie']
execjsRun = init_result['execjsRun']
else:
print("初始化 cookies 失败")
return
runcookie = {
'cookie': cookie,
'execjsRun': execjsRun
}
# 添加输出 cookies 的代码
cookies = {
'yiUIIlbdQT3fO': runcookie['cookie'],
'yiUIIlbdQT3fP': runcookie['execjsRun'].call('main').split('=')[1]
}
print(json.dumps(cookies)) # 确保输出是 JSON 格式的
if __name__ == "__main__":
asyncio.run(main(0))

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,473 @@
# Source: https://gitee.com/jdqlscript/zyqinglong/blob/main/sendNotify.py
# Raw: https://gitee.com/jdqlscript/zyqinglong/raw/main/sendNotify.py
# Repo: jdqlscript/zyqinglong
# Path: sendNotify.py
# UploadedAt: 2025-06-03T12:08:50+08:00
# SHA256: c3b909e625f5fce60874cd1324e5e9a62b581ca11ac7aeb7f6bec4dc45de2003
# Category: web版/抓包
# Evidence: web/H5关键词 + cookie/token/header
#!/usr/bin/env python3
# _*_ coding:utf-8 _*_
#Modify: Kirin
from curses.ascii import FS
import sys
import os, re
import requests
import json
import time
import hmac
import hashlib
import base64
import urllib.parse
from requests.adapters import HTTPAdapter
from urllib3.util import Retry
cur_path = os.path.abspath(os.path.dirname(__file__))
root_path = os.path.split(cur_path)[0]
sys.path.append(root_path)
# 通知服务
BARK = '' # bark服务,自行搜索; secrets可填;
BARK_PUSH='' # bark自建服务器要填完整链接结尾的/不要
PUSH_KEY = '' # Server酱的PUSH_KEY; secrets可填
TG_BOT_TOKEN = '' # tg机器人的TG_BOT_TOKEN; secrets可填1407203283:AAG9rt-6RDaaX0HBLZQq0laNOh898iFYaRQ
TG_USER_ID = '' # tg机器人的TG_USER_ID; secrets可填 1434078534
TG_API_HOST='' # tg 代理api
TG_PROXY_IP = '' # tg机器人的TG_PROXY_IP; secrets可填
TG_PROXY_PORT = '' # tg机器人的TG_PROXY_PORT; secrets可填
DD_BOT_TOKEN = '' # 钉钉机器人的DD_BOT_TOKEN; secrets可填
DD_BOT_SECRET = '' # 钉钉机器人的DD_BOT_SECRET; secrets可填
QQ_SKEY = '' # qq机器人的QQ_SKEY; secrets可填
QQ_MODE = '' # qq机器人的QQ_MODE; secrets可填
QYWX_AM = '' # 企业微信
QYWX_KEY = '' # 企业微信BOT
PUSH_PLUS_TOKEN = '' # 微信推送Plus+
FS_KEY = '' #飞书群BOT
notify_mode = []
message_info = ''''''
# GitHub action运行需要填写对应的secrets
if "BARK" in os.environ and os.environ["BARK"]:
BARK = os.environ["BARK"]
if "BARK_PUSH" in os.environ and os.environ["BARK_PUSH"]:
BARK_PUSH = os.environ["BARK_PUSH"]
if "PUSH_KEY" in os.environ and os.environ["PUSH_KEY"]:
PUSH_KEY = os.environ["PUSH_KEY"]
if "TG_BOT_TOKEN" in os.environ and os.environ["TG_BOT_TOKEN"] and "TG_USER_ID" in os.environ and os.environ["TG_USER_ID"]:
TG_BOT_TOKEN = os.environ["TG_BOT_TOKEN"]
TG_USER_ID = os.environ["TG_USER_ID"]
if "TG_API_HOST" in os.environ and os.environ["TG_API_HOST"]:
TG_API_HOST = os.environ["TG_API_HOST"]
if "DD_BOT_TOKEN" in os.environ and os.environ["DD_BOT_TOKEN"] and "DD_BOT_SECRET" in os.environ and os.environ["DD_BOT_SECRET"]:
DD_BOT_TOKEN = os.environ["DD_BOT_TOKEN"]
DD_BOT_SECRET = os.environ["DD_BOT_SECRET"]
if "QQ_SKEY" in os.environ and os.environ["QQ_SKEY"] and "QQ_MODE" in os.environ and os.environ["QQ_MODE"]:
QQ_SKEY = os.environ["QQ_SKEY"]
QQ_MODE = os.environ["QQ_MODE"]
# 获取pushplus+ PUSH_PLUS_TOKEN
if "PUSH_PLUS_TOKEN" in os.environ:
if len(os.environ["PUSH_PLUS_TOKEN"]) > 1:
PUSH_PLUS_TOKEN = os.environ["PUSH_PLUS_TOKEN"]
# print("已获取并使用Env环境 PUSH_PLUS_TOKEN")
# 获取企业微信应用推送 QYWX_AM
if "QYWX_AM" in os.environ:
if len(os.environ["QYWX_AM"]) > 1:
QYWX_AM = os.environ["QYWX_AM"]
if "QYWX_KEY" in os.environ:
if len(os.environ["QYWX_KEY"]) > 1:
QYWX_KEY = os.environ["QYWX_KEY"]
# print("已获取并使用Env环境 QYWX_AM")
#接入飞书webhook推送
if "FS_KEY" in os.environ:
if len(os.environ["FS_KEY"]) > 1:
FS_KEY = os.environ["FS_KEY"]
if BARK:
notify_mode.append('bark')
# print("BARK 推送打开")
if BARK_PUSH:
notify_mode.append('bark')
# print("BARK 推送打开")
if PUSH_KEY:
notify_mode.append('sc_key')
# print("Server酱 推送打开")
if TG_BOT_TOKEN and TG_USER_ID:
notify_mode.append('telegram_bot')
# print("Telegram 推送打开")
if DD_BOT_TOKEN and DD_BOT_SECRET:
notify_mode.append('dingding_bot')
# print("钉钉机器人 推送打开")
if QQ_SKEY and QQ_MODE:
notify_mode.append('coolpush_bot')
# print("QQ机器人 推送打开")
if PUSH_PLUS_TOKEN:
notify_mode.append('pushplus_bot')
# print("微信推送Plus机器人 推送打开")
if QYWX_AM:
notify_mode.append('wecom_app')
# print("企业微信机器人 推送打开")
if QYWX_KEY:
notify_mode.append('wecom_key')
# print("企业微信机器人 推送打开")
if FS_KEY:
notify_mode.append('fs_key')
# print("飞书机器人 推送打开")
def message(str_msg):
global message_info
print(str_msg)
message_info = "{}\n{}".format(message_info, str_msg)
sys.stdout.flush()
def bark(title, content):
print("\n")
if BARK:
try:
response = requests.get(
f"""https://api.day.app/{BARK}/{title}/{urllib.parse.quote_plus(content)}""").json()
if response['code'] == 200:
print('推送成功!')
else:
print('推送失败!')
except:
print('推送失败!')
if BARK_PUSH:
try:
response = requests.get(
f"""{BARK_PUSH}/{title}/{urllib.parse.quote_plus(content)}""").json()
if response['code'] == 200:
print('推送成功!')
else:
print('推送失败!')
except:
print('推送失败!')
print("bark服务启动")
if BARK=='' and BARK_PUSH=='':
print("bark服务的bark_token未设置!!\n取消推送")
return
def serverJ(title, content):
print("\n")
if not PUSH_KEY:
print("server酱服务的PUSH_KEY未设置!!\n取消推送")
return
print("serverJ服务启动")
data = {
"text": title,
"desp": content.replace("\n", "\n\n")
}
response = requests.post(f"https://sc.ftqq.com/{PUSH_KEY}.send", data=data).json()
if response['code'] == 0:
print('推送成功!')
else:
print('推送失败!')
# tg通知
def telegram_bot(title, content):
try:
print("\n")
bot_token = TG_BOT_TOKEN
user_id = TG_USER_ID
if not bot_token or not user_id:
print("tg服务的bot_token或者user_id未设置!!\n取消推送")
return
print("tg服务启动")
if TG_API_HOST:
if 'http' in TG_API_HOST:
url = f"{TG_API_HOST}/bot{TG_BOT_TOKEN}/sendMessage"
else:
url = f"https://{TG_API_HOST}/bot{TG_BOT_TOKEN}/sendMessage"
else:
url = f"https://api.telegram.org/bot{TG_BOT_TOKEN}/sendMessage"
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
payload = {'chat_id': str(TG_USER_ID), 'text': f'{title}\n\n{content}', 'disable_web_page_preview': 'true'}
proxies = None
if TG_PROXY_IP and TG_PROXY_PORT:
proxyStr = "http://{}:{}".format(TG_PROXY_IP, TG_PROXY_PORT)
proxies = {"http": proxyStr, "https": proxyStr}
try:
response = requests.post(url=url, headers=headers, params=payload, proxies=proxies).json()
except:
print('推送失败!')
if response['ok']:
print('推送成功!')
else:
print('推送失败!')
except Exception as e:
print(e)
def dingding_bot(title, content):
timestamp = str(round(time.time() * 1000)) # 时间戳
secret_enc = DD_BOT_SECRET.encode('utf-8')
string_to_sign = '{}\n{}'.format(timestamp, DD_BOT_SECRET)
string_to_sign_enc = string_to_sign.encode('utf-8')
hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
sign = urllib.parse.quote_plus(base64.b64encode(hmac_code)) # 签名
print('开始使用 钉钉机器人 推送消息...', end='')
url = f'https://oapi.dingtalk.com/robot/send?access_token={DD_BOT_TOKEN}&timestamp={timestamp}&sign={sign}'
headers = {'Content-Type': 'application/json;charset=utf-8'}
data = {
'msgtype': 'text',
'text': {'content': f'{title}\n\n{content}'}
}
response = requests.post(url=url, data=json.dumps(data), headers=headers, timeout=15).json()
if not response['errcode']:
print('推送成功!')
else:
print('推送失败!')
def coolpush_bot(title, content):
print("\n")
if not QQ_SKEY or not QQ_MODE:
print("qq服务的QQ_SKEY或者QQ_MODE未设置!!\n取消推送")
return
print("qq服务启动")
url=f"https://qmsg.zendee.cn/{QQ_MODE}/{QQ_SKEY}"
payload = {'msg': f"{title}\n\n{content}".encode('utf-8')}
response = requests.post(url=url, params=payload).json()
if response['code'] == 0:
print('推送成功!')
else:
print('推送失败!')
# push推送
def pushplus_bot(title, content):
try:
print("\n")
if not PUSH_PLUS_TOKEN:
print("PUSHPLUS服务的token未设置!!\n取消推送")
return
print("PUSHPLUS服务启动")
url = 'http://www.pushplus.plus/send'
data = {
"token": PUSH_PLUS_TOKEN,
"title": title,
"content": content
}
body = json.dumps(data).encode(encoding='utf-8')
headers = {'Content-Type': 'application/json'}
response = requests.post(url=url, data=body, headers=headers).json()
if response['code'] == 200:
print('推送成功!')
else:
print('推送失败!')
except Exception as e:
print(e)
def wecom_key(title, content):
print("\n")
if not QYWX_KEY:
print("QYWX_KEY未设置!!\n取消推送")
return
print("QYWX_KEY服务启动")
print("content"+content)
headers = {'Content-Type': 'application/json'}
data = {
"msgtype":"text",
"text":{
"content":title+"\n"+content.replace("\n", "\n\n")
}
}
print(f"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={QYWX_KEY}")
response = requests.post(f"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={QYWX_KEY}", json=data,headers=headers).json()
print(response)
# 飞书机器人推送
def fs_key(title, content):
print("\n")
if not FS_KEY:
print("FS_KEY未设置!!\n取消推送")
return
print("FS_KEY服务启动")
print("content"+content)
headers = {'Content-Type': 'application/json'}
data = {
"msg_type":"text",
"content":{
"text":title+"\n"+content.replace("\n", "\n\n")
}
}
print(f"https://open.feishu.cn/open-apis/bot/v2/hook/{FS_KEY}")
response = requests.post(f"https://open.feishu.cn/open-apis/bot/v2/hook/{FS_KEY}", json=data,headers=headers).json()
print(response)
# 企业微信 APP 推送
def wecom_app(title, content):
try:
if not QYWX_AM:
print("QYWX_AM 并未设置!!\n取消推送")
return
QYWX_AM_AY = re.split(',', QYWX_AM)
if 4 < len(QYWX_AM_AY) > 5:
print("QYWX_AM 设置错误!!\n取消推送")
return
corpid = QYWX_AM_AY[0]
corpsecret = QYWX_AM_AY[1]
touser = QYWX_AM_AY[2]
agentid = QYWX_AM_AY[3]
try:
media_id = QYWX_AM_AY[4]
except:
media_id = ''
wx = WeCom(corpid, corpsecret, agentid)
# 如果没有配置 media_id 默认就以 text 方式发送
if not media_id:
message = title + '\n\n' + content
response = wx.send_text(message, touser)
else:
response = wx.send_mpnews(title, content, media_id, touser)
if response == 'ok':
print('推送成功!')
else:
print('推送失败!错误信息如下:\n', response)
except Exception as e:
print(e)
class WeCom:
def __init__(self, corpid, corpsecret, agentid):
self.CORPID = corpid
self.CORPSECRET = corpsecret
self.AGENTID = agentid
def get_access_token(self):
url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken'
values = {'corpid': self.CORPID,
'corpsecret': self.CORPSECRET,
}
req = requests.post(url, params=values)
data = json.loads(req.text)
return data["access_token"]
def send_text(self, message, touser="@all"):
send_url = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=' + self.get_access_token()
send_values = {
"touser": touser,
"msgtype": "text",
"agentid": self.AGENTID,
"text": {
"content": message
},
"safe": "0"
}
send_msges = (bytes(json.dumps(send_values), 'utf-8'))
respone = requests.post(send_url, send_msges)
respone = respone.json()
return respone["errmsg"]
def send_mpnews(self, title, message, media_id, touser="@all"):
send_url = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=' + self.get_access_token()
send_values = {
"touser": touser,
"msgtype": "mpnews",
"agentid": self.AGENTID,
"mpnews": {
"articles": [
{
"title": title,
"thumb_media_id": media_id,
"author": "Author",
"content_source_url": "",
"content": message.replace('\n', '<br/>'),
"digest": message
}
]
}
}
send_msges = (bytes(json.dumps(send_values), 'utf-8'))
respone = requests.post(send_url, send_msges)
respone = respone.json()
return respone["errmsg"]
def send(title, content):
"""
使用 bark, telegram bot, dingding bot, server, feishuJ 发送手机推送
:param title:
:param content:
:return:
"""
for i in notify_mode:
if i == 'bark':
if BARK or BARK_PUSH:
bark(title=title, content=content)
else:
print('未启用 bark')
continue
if i == 'sc_key':
if PUSH_KEY:
serverJ(title=title, content=content)
else:
print('未启用 Server酱')
continue
elif i == 'dingding_bot':
if DD_BOT_TOKEN and DD_BOT_SECRET:
dingding_bot(title=title, content=content)
else:
print('未启用 钉钉机器人')
continue
elif i == 'telegram_bot':
if TG_BOT_TOKEN and TG_USER_ID:
telegram_bot(title=title, content=content)
else:
print('未启用 telegram机器人')
continue
elif i == 'coolpush_bot':
if QQ_SKEY and QQ_MODE:
coolpush_bot(title=title, content=content)
else:
print('未启用 QQ机器人')
continue
elif i == 'pushplus_bot':
if PUSH_PLUS_TOKEN:
pushplus_bot(title=title, content=content)
else:
print('未启用 PUSHPLUS机器人')
continue
elif i == 'wecom_app':
if QYWX_AM:
wecom_app(title=title, content=content)
else:
print('未启用企业微信应用消息推送')
continue
elif i == 'wecom_key':
if QYWX_KEY:
for i in range(int(len(content)/2000)+1):
wecom_key(title=title, content=content[i*2000:(i+1)*2000])
else:
print('未启用企业微信应用消息推送')
continue
elif i == 'fs_key':
if FS_KEY:
fs_key(title=title, content=content)
else:
print('未启用飞书机器人消息推送')
continue
else:
print('此类推送方式不存在')
print("xxxxxxxxxxxx")
def main():
send('title', 'content')
if __name__ == '__main__':
main()

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,486 @@
// # Source: https://github.com/smallfawn/QLScriptPublic/blob/main/wxapp/miaoyouHome.js
// # Raw: https://raw.githubusercontent.com/smallfawn/QLScriptPublic/main/wxapp/miaoyouHome.js
// # Repo: smallfawn/QLScriptPublic
// # Path: wxapp/miaoyouHome.js
// # UploadedAt: 2026-05-14T17:47:57+08:00
// # SHA256: 1329d61db9ba3db8767461e0d23af495fe2f6cfea2c89049bf66451b2a63ef63
// # Category: web版/抓包
// # Evidence: web/H5关键词 + cookie/token/header
//
/**
* cron 48 17 * * * miaoyouHome.js
* Show:微信公众号 庙友之家 每日签到 积分可换首饰
* 变量名:miaoyouHome
* 变量值:http://www.jumpingcarp.cn/scrm-rz-wechat-tzlm 公众号 左下角 每日签到 链接里面的headers 中的 COOKIE
* JSESSIONID= 的值 的值 的值 多账户@或换行
* scriptVersionNow = "0.0.1";
*/
const $ = new Env("wx_庙友之家");
const notify = $.isNode() ? require('../sendNotify') : '';
let ckName = "miaoyouHome";
let envSplitor = ["@", "\n"]; //多账号分隔符
let strSplitor = "&"; //多变量分隔符
let userIdx = 0;
let userList = [];
class UserInfo {
constructor(str) {
this.index = ++userIdx;
this.ck = str.split(strSplitor)[0]; //单账号多变量分隔符
this.ckStatus = true;
//定义在这里的headers会被get请求删掉content-type 而不会重置
}
async main() {
await this.task();
await this.userInfo()
}
async task() {
try {
let options = {
fn: "签到",
method: "post",
url: `http://www.jumpingcarp.cn/scrm-rz-wechat-tzlm/lotteryController/extractMemberAwards`,
headers: {
"Connection": "keep-alive",
//"Content-Length": "2",
"Accept": "application/json, text/plain, */*",
"X-Requested-With": "XMLHttpRequest",
"User-Agent": "Mozilla/5.0 (Linux; Android 10; MI 8 Lite Build/QKQ1.190910.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/111.0.5563.116 Mobile Safari/537.36 XWEB/1110017 MMWEBSDK/20231002 MMWEBID/2585 MicroMessenger/8.0.43.2480(0x28002B51) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64",
"Content-Type": "application/json;charset=UTF-8",
"Origin": "http://www.jumpingcarp.cn",
"Referer": "http://www.jumpingcarp.cn/scrm-rz-wechat-tzlm/index.html",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
"Cookie": "JSESSIONID=" + this.ck
},
body: JSON.stringify({})
}
let { body: result } = await $.httpRequest(options);
//console.log(options);
console.log(result);
} catch (e) {
console.log(e);
}
}
async userInfo() {
try {
let options = {
fn: "我的积分",
method: "post",
url: `http://www.jumpingcarp.cn/scrm-rz-wechat-tzlm/memberController/showMemberInfo`,
headers: {
"Connection": "keep-alive",
//"Content-Length": "2",
"Accept": "application/json, text/plain, */*",
"X-Requested-With": "XMLHttpRequest",
"User-Agent": "Mozilla/5.0 (Linux; Android 10; MI 8 Lite Build/QKQ1.190910.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/111.0.5563.116 Mobile Safari/537.36 XWEB/1110017 MMWEBSDK/20231002 MMWEBID/2585 MicroMessenger/8.0.43.2480(0x28002B51) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64",
"Content-Type": "application/json;charset=UTF-8",
"Origin": "http://www.jumpingcarp.cn",
"Referer": "http://www.jumpingcarp.cn/scrm-rz-wechat-tzlm/index.html",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
"Cookie": "JSESSIONID=" + this.ck
},
body: JSON.stringify({})
}
let { body: result } = await $.httpRequest(options);
//console.log(options);
//console.log(result);
if(result.code == 200){
$.log(`当前积分[${result.data.pointsBalance}]`)
}else {
console.log(result);
}
} catch (e) {
console.log(e);
}
}
}
async function start() {
let taskall = [];
for (let user of userList) {
if (user.ckStatus) {
taskall.push(await user.main());
}
}
await Promise.all(taskall);
}
!(async () => {
if (!(await checkEnv())) return;
if (userList.length > 0) {
await start();
}
await $.SendMsg($.logs.join("\n"))
})()
.catch((e) => console.log(e))
.finally(() => $.done());
//********************************************************
/**
* 变量检查与处理
* @returns
*/
async function checkEnv() {
let userCookie = ($.isNode() ? process.env[ckName] : $.getdata(ckName)) || "";
if (userCookie) {
let e = envSplitor[0];
for (let o of envSplitor)
if (userCookie.indexOf(o) > -1) {
e = o;
break;
}
for (let n of userCookie.split(e)) n && userList.push(new UserInfo(n));
} else {
console.log("未找到CK");
return;
}
return console.log(`共找到${userList.length}个账号`), true; //true == !0
}
/////////////////////////////////////////////////////////////////////////////////////
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) => {
this.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: "*/*" },
};
this.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.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 = this.setval(t, s);
return e;
}
getval(t) {
if (this.isSurge() || this.isLoon()) {
return $persistentStore.read(t);
} else if (this.isQuanX()) {
return $prefs.valueForKey(t);
} else if (this.isNode()) {
this.data = this.loaddata();
return this.data[t];
} else {
return this.data && this.data[t] || null;
}
}
setval(t, s) {
if (this.isSurge() || this.isLoon()) {
return $persistentStore.write(t, s);
} else if (this.isQuanX()) {
return $prefs.setValueForKey(t, s);
} else if (this.isNode()) {
this.data = this.loaddata();
this.data[s] = t;
this.writedata();
return true;
} else {
return 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();
if (t) {
t.headers = t.headers ? t.headers : {};
if (typeof t.headers.Cookie === "undefined" && typeof t.cookieJar === "undefined") {
t.cookieJar = this.ckjar;
}
}
}
/**
* @param {Object} options
* @returns {String} 将 Object 对象 转换成 queryStr: key=val&name=senku
*/
queryStr(options) {
return Object.entries(options)
.map(([key, value]) => `${key}=${typeof value === 'object' ? JSON.stringify(value) : value}`)
.join('&');
}
isJSONString(str) {
try {
var obj = JSON.parse(str);
if (typeof obj == 'object' && obj) {
return true;
} else {
return false;
}
} catch (e) {
return false;
}
}
isJson(obj) {
var isjson = typeof (obj) == "object" && Object.prototype.toString.call(obj).toLowerCase() == "[object object]" && !obj.length;
return isjson;
}
async SendMsg(message) {
if (!message) return;
if ($.isNode()) {
await notify.sendNotify($.name, message)
} else {
$.msg($.name, '', message)
}
}
async httpRequest(options) {
const t = {
...options
};
if (!t.headers) {
t.headers = {}
}
if (t.params) {
t.url += '?' + this.queryStr(t.params);
}
t.method = t.method.toLowerCase()
if (t.method.toLowerCase() === 'get') {
delete t.headers['Content-Type'];
delete t.headers['Content-Length'];
delete t["body"]
}
if (t.method.toLowerCase() === 'post') {
let contentType
if (!t.body) {
t.body = ""
} else {
if (typeof t.body == "string") {
if (this.isJSONString(t.body)) {
contentType = 'application/json'
} else {
contentType = 'application/x-www-form-urlencoded'
}
} else if (this.isJson(t.body)) {
t.body = JSON.stringify(t.body)
contentType = 'application/json'
}
}
if (!t.headers['Content-Type']) {
t.headers['Content-Type'] = contentType;
}
delete t.headers['Content-Length'];
}
if (this.isNode()) {
this.initGotEnv(t);
let httpResult = await this.got(t)
if (this.isJSONString(httpResult.body)) {
httpResult.body = JSON.parse(httpResult.body)
}
return httpResult;
}
}
randomNumber(length) {
const characters = '0123456789';
return Array.from({ length }, () => characters[Math.floor(Math.random() * characters.length)]).join('');
}
randomString(length) {
const characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
return Array.from({ length }, () => characters[Math.floor(Math.random() * characters.length)]).join('');
}
timeStamp() {
return new Date().getTime()
}
uuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0,
v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
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;
this.isMute ||
(this.isSurge() || this.isLoon()
? $notification.post(s, e, i, h(o))
: this.isQuanX() && $notify(s, e, i, h(o)));
let logs = ['', '==============📣系统通知📣=============='];
logs.push(t);
e ? logs.push(e) : '';
i ? logs.push(i) : '';
console.log(logs.join('\n'));
this.logs = this.logs.concat(logs);
}
log(...t) {
t.length > 0 && (this.logs = [...this.logs, ...t]),
console.log(t.join(this.logSeparator));
}
logErr(t, s) {
const e = !this.isSurge() && !this.isQuanX() && !this.isLoon();
e
? this.log("", `\u2757\ufe0f${this.name}, \u9519\u8bef!`, t.stack)
: this.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);
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,105 @@
# Source: https://gitee.com/jdqlscript/toulu/blob/main/%E4%B8%9C%E6%96%B9%E6%A3%98%E5%B8%82.py
# Raw: https://gitee.com/jdqlscript/toulu/raw/main/%E4%B8%9C%E6%96%B9%E6%A3%98%E5%B8%82.py
# Repo: jdqlscript/toulu
# Path: 东方棘市.py
# UploadedAt: 2025-06-28T11:18:42+08:00
# SHA256: 892b06ab7625881cee4a8ea91869b68862dc3e51d0e8dcfe32d4bff4e31a4e63
# Category: web版/抓包
# Evidence: web/H5关键词 + cookie/token/header
import requests
import os
#抓包域名https://ys.shajixueyuan.com/api/user_sign/sign
#取url请求中的token变量名dfjsck
#变量格式 token#备注,多账号换行或者用@连接
#【tl库】https://pd.qq.com/s/btv4bw7av
#联系3288588344
def sign(token, remark):
url = "https://ys.shajixueyuan.com/api/user_sign/sign"
headers = {
'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",
'token': token
}
response = requests.post(url, headers=headers)
data = response.json()
if data['code'] == 1:
msg = data['data']['msg']
energy_release = data["data"]["rewards_info"]["energy_release"]
print(f"[{remark}] 签到结果: {msg}, 释放 {energy_release} 能量果子")
else:
msg = data["msg"]
print(f"[{remark}] 签到失败原因: {msg}")
def issueRewards(token, remark):
url = "https://ys.shajixueyuan.com/api/quest.quest/issueRewards"
headers = {
'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",
'token': token
}
data = {
"quest_id": 4
}
response = requests.post(url, json=data, headers=headers)
data = response.json()
msg = data['msg']
print(f"[{remark}] 分享结果: {msg}")
def info(token, remark):
url = "https://ys.shajixueyuan.com/api/user/info"
headers = {
'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",
'token': token
}
response = requests.get(url, headers=headers)
data = response.json()
if data['code'] == 1:
remaining_fruits = float(data["data"]["remaining_fruits"])
nickname = data["data"]["nickname"]
print(f"[{remark}]:当前余额: {remaining_fruits}")
if remaining_fruits >= 0.3:
apply(token, remark)
else:
print(f"[{remark}] 余额不足,无法进行提现")
else:
msg = data["msg"]
print(f"[{remark}] 查询失败: {msg}")
def apply(token, remark):
url = "https://ys.shajixueyuan.com/api/user.user_withdraw/apply"
headers = {
'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",
'token': token
}
data = {
"fruit_withdraw_amount": "0.3",
"pay_gateway": "wechat"
}
response = requests.post(url, json=data, headers=headers)
data = response.json()
msg = data['msg']
print(f"[{remark}] 提现结果: {msg}")
if __name__ == "__main__":
tokens = os.environ.get('dfjsck')
if not tokens:
print("获取账号失败,请检查配置是否正确")
else:
# 将换行符替换为 @ 号,分割每个账号
tokens_list = [token.strip() for token in tokens.replace('@', '\n').split('\n') if token.strip()]
for index, item in enumerate(tokens_list, start=1):
parts = item.split('#')
token = parts[0].strip() # 提取 token
remark = parts[1].strip() if len(parts) > 1 else f"账号{index}" # 提取备注如果没有则用“账号X”代替
print(f"===== 开始执行第 {index} 个账号任务 =====")
print(f"账号: {remark}")
print(f"===== 开始执行签到任务 =====")
sign(token, remark)
print(f"===== 开始执行分享任务 =====")
issueRewards(token, remark)
print(f"===== 开始执行查询和提现任务 =====")
info(token, remark)
print("==============================")

View File

@@ -0,0 +1,592 @@
// # Source: https://gitee.com/jdqlscript/toulu/blob/main/%E4%B8%9C%E6%96%B9%E7%83%9F%E8%8D%89%E6%8A%A5App.js
// # Raw: https://gitee.com/jdqlscript/toulu/raw/main/%E4%B8%9C%E6%96%B9%E7%83%9F%E8%8D%89%E6%8A%A5App.js
// # Repo: jdqlscript/toulu
// # Path: 东方烟草报App.js
// # UploadedAt: 2025-06-28T11:18:42+08:00
// # SHA256: 1b5375a55de4fdf36651e7c45b9b2f0fbcceefb400e21472fe1f76baa51096bc
// # Category: web版/抓包
// # Evidence: web/H5关键词 + cookie/token/header
//
/**
* cron 5 15 * * *
* Show:东方烟草报App 积分换实物
* 变量名:dfycToken
* 变量值:POST请求任意链接包含https://eapp.eastobacco.com/index.php body中的token 多账号&分割 不是@ 和换行
* scriptVersionNow = "0.0.1";
QQ频道:https://pd.qq.com/s/672fku8ge
tg频道:https://t.me/TLtoulu
*/
const cookies = []
const $ = new Env("东方烟草报");
const notify = $.isNode() ? require('./sendNotify') : '';
let ckName = "dfycToken";
let envSplitor = ["&"]; //多账号分隔符
let strSplitor = "#"; //多变量分隔符
let userIdx = 0;
let userList = [];
let msg = ""
class UserInfo {
constructor(str) {
this.index = ++userIdx;
this.ck = str.split(strSplitor)[0]; //单账号多变量分隔符
this.ckStatus = true;
this.artList = []
}
async main() {
await this.user_info();
if (this.ckStatus) {
await this.task_daka()
await this.art_list()
if (this.artList.length !== 0) {
for (let i = 0; i < 3; i++) {
await this.task_read(this.artList[i].id, this.artList[i].catid)
await this.task_share(this.artList[i].id, this.artList[i].catid)
await this.task_like(this.artList[i].id, this.artList[i].catid)
}
}
}
}
async user_info() {
try {
let options = {
fn: "信息",
method: "post",
url: `https://eapp.eastobacco.com/index.php?m=api&c=user&a=userinfo`,
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: `platform=android&token=${this.ck}&timestamp=${Date.now()}&api_version=4`
}
let { body: result } = await $.httpRequest(options);
//console.log(options);
//console.log(result);
if (result.code == 200) {
$.log(`✅账号[${this.index}] 积分[${result.data.point}]🎉`)
this.ckStatus = true;
} else {
console.log(`❌账号[${this.index}] 用户查询: 失败`);
this.ckStatus = false;
console.log(result);
}
} catch (e) {
console.log(e);
}
}
async task_daka() {
try {
let options = {
fn: "打卡",
method: "post",
url: `https://eapp.eastobacco.com/index.php?m=api&c=user&a=daka`,
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: `platform=android&token=${this.ck}&timestamp=${Date.now()}&api_version=4`
}
let { body: result } = await $.httpRequest(options);
//console.log(options);
//console.log(result);
$.log(`✅账号[${this.index}] 打卡[${result.message}]🎉`)
} catch (e) {
console.log(e);
}
}
async art_list() {
try {
let options = {
fn: "文章列表",
method: "post",
url: `https://eapp.eastobacco.com/index.php?m=api&c=content&a=newsList_pub`,
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: `catid=1&num=20&page=1&api_version=4&platform=android&token=${this.ck}&timestamp=${Date.now()}`
}
let { body: result } = await $.httpRequest(options);
//console.log(options);
//console.log(result);
if (result.data.news) {
for (let news of result.data.news) {
this.artList.push(
{
id: news.id,
catid: news.catid,
title: news.title
}
)
}
console.log(`获取文章成功`);
} else {
console.log(`获取文章失败`);
}
} catch (e) {
console.log(e);
}
}
async task_read(id, catid) {
try {
let options = {
fn: "阅读",
method: "post",
url: `https://eapp.eastobacco.com/index.php?m=api&c=content&a=addvisite`,
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: `platform=android&token=${this.ck}&timestamp=${Date.now()}&api_version=4&newsid=${id}&catid=${catid}`
}
let { body: result } = await $.httpRequest(options);
//console.log(options);
//console.log(result);
if (result.code == 200) {
$.log(`✅账号[${this.index}] 阅读[${id}]成功🎉`)
} else {
$.log(`❌账号[${this.index}] 阅读[${id}]失败`)
}
} catch (e) {
console.log(e);
}
}
async task_share(id, catid) {
try {
let options = {
fn: "分享",
method: "post",
url: `https://eapp.eastobacco.com/index.php?m=api&c=user&a=addScoreZf`,
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: `platform=android&token=${this.ck}&timestamp=${Date.now()}&api_version=4&id=${id}&catid=${catid}`
}
let { body: result } = await $.httpRequest(options);
//console.log(options);
//console.log(result);
if (result.code == 200) {
$.log(`✅账号[${this.index}] 分享[${id}]成功🎉`)
} else {
$.log(`❌账号[${this.index}] 分享[${id}]失败`)
}
} catch (e) {
console.log(e);
}
}
async task_like(id, catid) {
try {
let options = {
fn: "点赞",
method: "post",
url: `https://eapp.eastobacco.com/index.php?m=api&c=content&a=dingcai`,
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: `platform=android&token=${this.ck}&timestamp=${Date.now()}&api_version=4&newsid=${id}&catid=${catid}`
}
let { body: result } = await $.httpRequest(options);
//console.log(options);
//console.log(result);
if (result.code == 200) {
$.log(`✅账号[${this.index}] 点赞[${id}]成功🎉`)
} else {
$.log(`❌账号[${this.index}] 点赞[${id}]失败`)
}
} catch (e) {
console.log(e);
}
}
}
async function start() {
let taskall = [];
for (let user of userList) {
if (user.ckStatus) {
taskall.push(await user.main());
}
}
await Promise.all(taskall);
}
!(async () => {
if (!(await checkEnv())) return;
if (userList.length > 0) {
await start();
}
await $.sendMsg($.logs.join("\n"))
})()
.catch((e) => console.log(e))
.finally(() => $.done());
//********************************************************
/**
* 变量检查与处理
* @returns
*/
async function checkEnv() {
let userCookie = ($.isNode() ? process.env[ckName] : cookies) || "";
if (userCookie) {
let e = envSplitor[0];
for (let o of envSplitor)
if (userCookie.indexOf(o) > -1) {
e = o;
break;
}
for (let n of userCookie.split(e)) n && userList.push(new UserInfo(n));
} else {
console.log("未找到CK");
return;
}
return console.log(`共找到${userList.length}个账号`), true; //true == !0
}
/////////////////////////////////////////////////////////////////////////////////////
// prettier-ignore
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;
}
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.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 = this.setval(t, s);
return e;
}
getval(t) {
if (this.isSurge() || this.isLoon()) {
return $persistentStore.read(t);
} else if (this.isQuanX()) {
return $prefs.valueForKey(t);
} else if (this.isNode()) {
this.data = this.loaddata();
return this.data[t];
} else {
return this.data && this.data[t] || null;
}
}
setval(t, s) {
if (this.isSurge() || this.isLoon()) {
return $persistentStore.write(t, s);
} else if (this.isQuanX()) {
return $prefs.setValueForKey(t, s);
} else if (this.isNode()) {
this.data = this.loaddata();
this.data[s] = t;
this.writedata();
return true;
} else {
return 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();
if (t) {
t.headers = t.headers ? t.headers : {};
if (typeof t.headers.Cookie === "undefined" && typeof t.cookieJar === "undefined") {
t.cookieJar = this.ckjar;
}
}
}
/**
* @param {Object} options
* @returns {String} 将 Object 对象 转换成 queryStr: key=val&name=senku
*/
queryStr(options) {
return Object.entries(options)
.map(([key, value]) => `${key}=${typeof value === 'object' ? JSON.stringify(value) : value}`)
.join('&');
}
isJSONString(str) {
try {
var obj = JSON.parse(str);
if (typeof obj == 'object' && obj) {
return true;
} else {
return false;
}
} catch (e) {
return false;
}
}
isJson(obj) {
var isjson = typeof (obj) == "object" && Object.prototype.toString.call(obj).toLowerCase() == "[object object]" && !obj.length;
return isjson;
}
async sendMsg(message) {
if (!message) return;
if ($.isNode()) {
await notify.sendNotify($.name, message)
} else {
$.msg($.name, '', message)
}
}
async httpRequest(options) {
let t = {
...options
};
if (!t.headers) {
t.headers = {}
}
if (t.params) {
t.url += '?' + this.queryStr(t.params);
}
t.method = t.method.toLowerCase();
if (t.method === 'get') {
delete t.headers['Content-Type'];
delete t.headers['Content-Length'];
delete t["body"]
}
if (t.method === 'post') {
let contentType;
if (!t.body) {
t.body = ""
} else {
if (typeof t.body == "string") {
if (this.isJSONString(t.body)) {
contentType = 'application/json'
} else {
contentType = 'application/x-www-form-urlencoded'
}
} else if (this.isJson(t.body)) {
t.body = JSON.stringify(t.body);
contentType = 'application/json';
}
}
if (!t.headers['Content-Type']) {
t.headers['Content-Type'] = contentType;
}
delete t.headers['Content-Length'];
}
if (this.isNode()) {
this.initGotEnv(t);
let httpResult = await this.got(t);
if (this.isJSONString(httpResult.body)) {
httpResult.body = JSON.parse(httpResult.body)
}
return httpResult;
}
if (this.isQuanX()) {
t.method = t.method.toUpperCase()
return new Promise((resolve, reject) => {
$task.fetch(t).then(response => {
if (this.isJSONString(response.body)) {
response.body = JSON.parse(response.body)
}
resolve(response)
})
})
}
}
randomNumber(length) {
const characters = '0123456789';
return Array.from({ length }, () => characters[Math.floor(Math.random() * characters.length)]).join('');
}
randomString(length) {
const characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
return Array.from({ length }, () => characters[Math.floor(Math.random() * characters.length)]).join('');
}
timeStamp() {
return new Date().getTime()
}
uuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0,
v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
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;
this.isMute ||
(this.isSurge() || this.isLoon()
? $notification.post(s, e, i, h(o))
: this.isQuanX() && $notify(s, e, i, h(o)));
let logs = ['', '==============📣系统通知📣=============='];
logs.push(t);
e ? logs.push(e) : '';
i ? logs.push(i) : '';
console.log(logs.join('\n'));
this.logs = this.logs.concat(logs);
}
log(...t) {
t.length > 0 && (this.logs = [...this.logs, ...t]),
console.log(t.join(this.logSeparator));
}
logErr(t, s) {
const e = !this.isSurge() && !this.isQuanX() && !this.isLoon();
e
? this.log("", `\u2757\ufe0f${this.name}, \u9519\u8bef!`, t.stack)
: this.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()
if (this.isNode()) {
process.exit(1)
}
if (this.isQuanX()) {
$done(t)
}
}
})(t, s);
}

View File

@@ -0,0 +1,240 @@
// # Source: https://github.com/smallfawn/QLScriptPublic/blob/main/daily/dfyc.js
// # Raw: https://raw.githubusercontent.com/smallfawn/QLScriptPublic/main/daily/dfyc.js
// # Repo: smallfawn/QLScriptPublic
// # Path: daily/dfyc.js
// # UploadedAt: 2026-04-07T12:21:56Z
// # SHA256: b2cb2a98f820da0170af6c58668227bc14d9226ab3f7344b1a73d6f705ebe91b
// # Category: web版/抓包
// # Evidence: web/H5关键词 + cookie/token/header
//
/*
------------------------------------------
@Author: sm
@Date: 2024.06.07 19:15
@Description: 东方烟草报App 积分换实物
cron: 10 8 * * *
------------------------------------------
#Notice:
变量名:dfycToken
POST请求任意链接包含https://eapp.eastobacco.com/index.php body中的token 多账号&分割或者换行
⚠️【免责声明】
------------------------------------------
1、此脚本仅用于学习研究不保证其合法性、准确性、有效性请根据情况自行判断本人对此不承担任何保证责任。
2、由于此脚本仅用于学习研究您必须在下载后 24 小时内将所有内容从您的计算机或手机或任何存储设备中完全删除,若违反规定引起任何事件本人对此均不负责。
3、请勿将此脚本用于任何商业或非法目的若违反规定请自行对此负责。
4、此脚本涉及应用与本人无关本人对因此引起的任何隐私泄漏或其他后果不承担任何责任。
5、本人对任何脚本引发的问题概不负责包括但不限于由脚本错误引起的任何损失和损害。
6、如果任何单位或个人认为此脚本可能涉嫌侵犯其权利应及时通知并提供身份证明所有权证明我们将在收到认证文件确认后删除此脚本。
7、所有直接或间接使用、查看此脚本的人均应该仔细阅读此声明。本人保留随时更改或补充此声明的权利。一旦您使用或复制了此脚本即视为您已接受此免责声明。
*/
const { Env } = require("../tools/env")
const $ = new Env("东方烟草报");
let ckName = `dfycToken`;
const strSplitor = "#";
const axios = require("axios");
const defaultUserAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.31(0x18001e31) NetType/WIFI Language/zh_CN miniProgram"
class Task {
constructor(env) {
this.index = $.userIdx++;
this.ck = env.split(strSplitor)[0]; //单账号多变量分隔符
this.ckStatus = true;
this.artList = []
}
async run() {
await this.user_info();
if (this.ckStatus) {
await this.task_daka()
await this.art_list()
if (this.artList.length !== 0) {
for (let i = 0; i < 3; i++) {
await this.task_read(this.artList[i].id, this.artList[i].catid)
await this.task_share(this.artList[i].id, this.artList[i].catid)
await this.task_like(this.artList[i].id, this.artList[i].catid)
}
}
}
}
async user_info() {
try {
let options = {
method: "post",
url: `https://eapp.eastobacco.com/index.php?m=api&c=user&a=userinfo`,
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
data: `platform=android&token=${this.ck}&timestamp=${Date.now()}&api_version=4`
}
let { data: result } = await axios.request(options);
//console.log(options);
//console.log(result);
if (result.code == 200) {
$.log(`✅账号[${this.index}] 积分[${result.data.point}]🎉`)
this.ckStatus = true;
} else {
console.log(`❌账号[${this.index}] 用户查询: 失败`);
this.ckStatus = false;
console.log(result);
}
} catch (e) {
console.log(e);
}
}
async task_daka() {
try {
let options = {
method: "post",
url: `https://eapp.eastobacco.com/index.php?m=api&c=user&a=daka`,
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
data: `platform=android&token=${this.ck}&timestamp=${Date.now()}&api_version=4`
}
let { data: result } = await axios.request(options);
//console.log(options);
//console.log(result);
$.log(`✅账号[${this.index}] 打卡[${result.message}]🎉`)
} catch (e) {
console.log(e);
}
}
async art_list() {
try {
let options = {
method: "post",
url: `https://eapp.eastobacco.com/index.php?m=api&c=content&a=newsList_pub`,
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
data: `catid=1&num=20&page=1&api_version=4&platform=android&token=${this.ck}&timestamp=${Date.now()}`
}
let { data: result } = await axios.request(options);
//console.log(options);
//console.log(result);
if (result.data.news) {
for (let news of result.data.news) {
this.artList.push(
{
id: news.id,
catid: news.catid,
title: news.title
}
)
}
console.log(`获取文章成功`);
} else {
console.log(`获取文章失败`);
}
} catch (e) {
console.log(e);
}
}
async task_read(id, catid) {
try {
let options = {
method: "post",
url: `https://eapp.eastobacco.com/index.php?m=api&c=content&a=addvisite`,
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
data: `platform=android&token=${this.ck}&timestamp=${Date.now()}&api_version=4&newsid=${id}&catid=${catid}`
}
let { data: result } = await axios.request(options);
//console.log(options);
//console.log(result);
if (result.code == 200) {
$.log(`✅账号[${this.index}] 阅读[${id}]成功🎉`)
} else {
$.log(`❌账号[${this.index}] 阅读[${id}]失败`)
}
} catch (e) {
console.log(e);
}
}
async task_share(id, catid) {
try {
let options = {
method: "post",
url: `https://eapp.eastobacco.com/index.php?m=api&c=user&a=addScoreZf`,
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
data: `platform=android&token=${this.ck}&timestamp=${Date.now()}&api_version=4&id=${id}&catid=${catid}`
}
let { data: result } = await axios.request(options);
//console.log(options);
//console.log(result);
if (result.code == 200) {
$.log(`✅账号[${this.index}] 分享[${id}]成功🎉`)
} else {
$.log(`❌账号[${this.index}] 分享[${id}]失败`)
}
} catch (e) {
console.log(e);
}
}
async task_like(id, catid) {
try {
let options = {
method: "post",
url: `https://eapp.eastobacco.com/index.php?m=api&c=content&a=dingcai`,
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
data: `platform=android&token=${this.ck}&timestamp=${Date.now()}&api_version=4&newsid=${id}&catid=${catid}`
}
let { data: result } = await axios.request(options);
//console.log(options);
//console.log(result);
if (result.code == 200) {
$.log(`✅账号[${this.index}] 点赞[${id}]成功🎉`)
} else {
$.log(`❌账号[${this.index}] 点赞[${id}]失败`)
}
} catch (e) {
console.log(e);
}
}
}
!(async () => {
await getNotice()
$.checkEnv(ckName);
for (let user of $.userList) {
await new Task(user).run();
}
})()
.catch((e) => console.log(e))
.finally(() => $.done());
async function getNotice() {
try {
let options = {
url: `https://ghproxy.net/https://raw.githubusercontent.com/smallfawn/Note/refs/heads/main/Notice.json`,
headers: {
"User-Agent": defaultUserAgent,
},
timeout:3000
}
let {
data: res
} = await axios.request(options);
$.log(res)
return res
} catch (e) {}
}

View File

@@ -0,0 +1,68 @@
# Source: https://gitee.com/jdqlscript/toulu/blob/main/%E4%B8%AD%E5%85%B4%E5%95%86%E5%9F%8E.py
# Raw: https://gitee.com/jdqlscript/toulu/raw/main/%E4%B8%AD%E5%85%B4%E5%95%86%E5%9F%8E.py
# Repo: jdqlscript/toulu
# Path: 中兴商城.py
# UploadedAt: 2025-06-28T11:18:42+08:00
# SHA256: 3fecf7b602ecddc6cf2ae9f9bc992c5b55dcbc333c15279dc6295ebe5f98cecc
# Category: web版/抓包
# Evidence: web/H5关键词 + cookie/token/header
'''
功能:中兴商城任务
一天5毛买东西可抵扣
抓手机端签到请求链接里面的accessToken=后面的字符串如dc487xxxx9d67填到环境变量'zxscck'里,多账号&连接网页版签到抓到的accessToken没有测试有可能能用
cron: 3 0 * * *
new Env('中兴商城');
'''
import requests
import os
try:
from notify import send
except:
pass
url = "https://www.ztemall.com/index.php/topapi"
headers = {
"Accept": "*/*",
"platform": "android",
"C-Version": "5.2.32.2308151406",
"User-Agent": "Mozilla/5.0 (Linux; Android 8.0.0; MI 5 Build/OPR1.170623.032; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/68.0.3440.91 Mobile Safari/537.36",
"model": "MI 5",
"Accept-Encoding": "gzip",
"Host": "www.ztemall.com",
"Connection": "Keep-Alive"
}
accounts = os.getenv('zxscck')
if accounts is None:
print('未检测到zxscck')
exit(1)
accounts_list = accounts.split('&')
print(f"获取到 {len(accounts_list)} 个账号\n")
result = []
for i, account in enumerate(accounts_list, start=1):
print(f"=======开始执行账号{i}=======\n")
params = {
"method": "member.checkIn.add",
"format": "json",
"v": "v1",
"accessToken": account
}
response = requests.get(url, headers=headers, params=params).json()
if response['errorcode'] == 0:
currentCheckInPoint = response['data']['currentCheckInPoint']
point = response['data']['point']
print(f"账号{i}签到成功,获得{currentCheckInPoint}积分,当前积分:{point}\n")
result.append(f"账号{i}签到成功,获得{currentCheckInPoint}积分,当前积分:{point}\n")
else:
msg = response['msg']
print(f"账号{i}签到失败,{msg}\n")
result.append(f"账号{i}签到失败,{msg}\n")
try:
send("中兴商城签到",f"{''.join(result)}")
except Exception as e:
print(f"消息推送失败:{e}\n{result}\n")

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,224 @@
# Source: https://github.com/smallfawn/QLScriptPublic/blob/main/backup/sysxc.py
# Raw: https://raw.githubusercontent.com/smallfawn/QLScriptPublic/main/backup/sysxc.py
# Repo: smallfawn/QLScriptPublic
# Path: backup/sysxc.py
# UploadedAt: 2026-05-14T17:47:57+08:00
# SHA256: b9f66359e357df42cb7ba689f5ae6ae61a49e64a850dba95a577e66b9226cff3
# Category: web版/抓包
# Evidence: web/H5关键词 + cookie/token/header
"""
new Env("书亦烧仙草python版")
1. 书亦烧仙草签到 抓包scrm-prod.shuyi.org.cn域名请求头里的auth
脚本仅供学习交流使用, 请在下载后24h内删除
2. cron 以防ocr识别出错每天运行两次左右
3. ddddocr搭建方法https://github.com/sml2h3/ocr_api_server #如果脚本里的失效请自行搭建
"""
import json,logging,os,sys,time,base64,requests
from os import environ, system, path
logger = logging.getLogger(name=None)
logging.Formatter("%(message)s")
logger.setLevel(logging.INFO)
logger.addHandler(logging.StreamHandler())
def load_send():
global send, mg
cur_path = path.abspath(path.dirname(__file__))
if path.exists(cur_path + "/notify.py"):
try:
from notify import send
print("加载通知服务成功!")
except:
send = False
print("加载通知服务失败~")
else:
send = False
print("加载通知服务失败~")
load_send()
try:
from Crypto.Cipher import AES
except:
logger.info(
"\n未检测到pycryptodome\n需要Python依赖里安装pycryptodome\n安装失败先linux依赖里安装gcc、python3-dev、libc-dev\n如果还是失败,重启容器,或者重启docker就能解决")
exit(0)
def setHeaders(i):
headers = {
"auth": cookies[i],
"hostname": "scrm-prod.shuyi.org.cn",
"content-type": "application/json",
"host": "scrm-prod.shuyi.org.cn",
"User-Agent": "Mozilla/5.0 (Linux; Android 10; V2203A Build/SP1A.210812.003; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/107.0.5304.141 Mobile Safari/537.36 XWEB/5023 MMWEBSDK/20221012 MMWEBID/1571 MicroMessenger/8.0.30.2260(0x28001E55) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android"
}
return headers
cookies = []
try:
cookies = os.environ["sysxc_auth"].split("&")
if len(os.environ["sysxc_auth"]) > 0:
logger.info("已获取并使用Env环境Cookie\n声明本脚本为学习python请勿用于非法用途\n")
except:
logger.info(
"【提示】请先添加sysxc_auth")
exit(3)
def getVCode(headers):
"""获取滑块图片"""
data = {
"captchaType": "blockPuzzle",
"clientUid": "slider-6292e85b-e871-4abd-89df-4d97709c6e0c",
"ts": int(time.time() * 1000)
}
url = 'https://scrm-prod.shuyi.org.cn/saas-gateway/api/agg-trade/v1/signIn/getVCode'
response = requests.post(url, json=data, headers=headers)
return response.json()
def ocr(tg,bg):
"""使用自有ocr识别滑块坐标"""
url = 'http://103.45.185.224:9898/slide/match/b64/json'
jsonstr = json.dumps({'target_img': tg, 'bg_img': bg})
response = requests.post(url, data=base64.b64encode(jsonstr.encode()).decode())
return response.json()
'''
采用AES对称加密算法
'''
BLOCK_SIZE = 16 # Bytes
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * \
chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]
def aesEncrypt(key, data):
'''
AES的ECB模式加密方法
:param key: 密钥
:param data:被加密字符串(明文)
:return:密文
'''
key = key.encode('utf8')
# 字符串补位
data = pad(data)
cipher = AES.new(key, AES.MODE_ECB)
# 加密后得到的是bytes类型的数据使用Base64进行编码,返回byte字符串
result = cipher.encrypt(data.encode())
encodestrs = base64.b64encode(result)
enctext = encodestrs.decode('utf8')
return enctext
def aesDecrypt(key, data):
'''
:param key: 密钥
:param data: 加密后的数据(密文)
:return:明文
'''
key = key.encode('utf8')
data = base64.b64decode(data)
cipher = AES.new(key, AES.MODE_ECB)
# 去补位
text_decrypted = unpad(cipher.decrypt(data))
text_decrypted = text_decrypted.decode('utf8')
return text_decrypted
def checkVCode(pointJson, token):
"""验证"""
try:
data = {
"captchaType": "blockPuzzle",
"pointJson": pointJson,
"token": token
}
url = 'https://scrm-prod.shuyi.org.cn/saas-gateway/api/agg-trade/v1/signIn/checkVCode'
response = requests.post(url, json=data, headers=headers)
result = response.json()
resultCode = result['resultCode']
resultMsg = result['resultMsg']
if resultCode == '0000':
logger.info(f"校验结果:成功")
else:
logger.info(f"校验结果: {resultMsg}")
time.sleep(3)
main()
except Exception as err:
print(err)
def check_sign(pointJson):
"""签到"""
try:
data = {
"captchaVerification": pointJson
}
url = 'https://scrm-prod.shuyi.org.cn/saas-gateway/api/agg-trade/v1/signIn/insertSignInV3'
response = requests.post(url, json=data, headers=headers)
result = response.json()
resultCode = result['resultCode']
resultMsg = result['resultMsg']
if resultCode == '0':
logger.info(f"签到结果:{result}")
send('书亦烧仙草签到通知', result)
else:
logger.info(f"签到结果: {resultMsg}")
send('书亦烧仙草签到通知', resultMsg)
except Exception as err:
print(err)
sys.exit(0)
def main():
logger.info("--------------------任务开始--------------------")
result = getVCode(headers)
bg = result['data']['originalImageBase64']
tg = result['data']['jigsawImageBase64']
key = result['data']['secretKey']
token = result['data']['token']
logger.info(f"本次口令为: {token}")
logger.info(f"本次密钥为: {key}")
time.sleep(1.5)
logger.info("--------------------识别滑块--------------------")
result = ocr(tg,bg)
res = result['result']['target']
d = (res[0])
logger.info(f"滑动距离为: {d}")
logger.info("--------------------执行算法--------------------")
aes_str = json.dumps({"x": d, "y": 5})
data = aes_str.replace(' ', '')
logger.info(f"加密前: {data}")
time.sleep(1.5)
ecdata = aesEncrypt(key, data)
aesDecrypt(key, ecdata)
pointJson = aesEncrypt(key, data)
logger.info(f"加密后: {pointJson}")
logger.info("--------------------校验滑块--------------------")
checkVCode(pointJson, token)
logger.info("--------------------开始签到--------------------")
str = (token + '---' + aes_str)
data = str.replace(' ', '')
ecdata = aesEncrypt(key, data)
aesDecrypt(key, ecdata)
pointJson = aesEncrypt(key, data)
time.sleep(0.5)
check_sign(pointJson)
if __name__ == '__main__':
for i in range(len(cookies)):
logger.info(f"\n开始第{i + 1}个账号")
headers = setHeaders(i)
main()
logger.info("所有账号执行完成\n")
sys.exit(0)

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,105 @@
# Source: https://gitee.com/jdqlscript/toulu/blob/main/%E5%8F%AD%E5%8D%A6%E4%BC%98%E9%80%89.py
# Raw: https://gitee.com/jdqlscript/toulu/raw/main/%E5%8F%AD%E5%8D%A6%E4%BC%98%E9%80%89.py
# Repo: jdqlscript/toulu
# Path: 叭卦优选.py
# UploadedAt: 2025-06-28T11:18:42+08:00
# SHA256: 4c1f172936322381345aa0d5f5ccbb8c5d23b31c613a4444b6d39257690420e1
# Category: web版/抓包
# Evidence: web/H5关键词 + cookie/token/header
#by:哆啦A梦
#TL库
#入口:http://api.0vsp.com/h5/wxa/link?sid=25423TwvStj
#抓包slb1.bg19.cn域名下的token填到环境变量BGYX就行
#多账号换行分割
import requests
import os
# 获取公告信息
def get_proclamation():
primary_url = "https://github.com/3288588344/toulu/raw/refs/heads/main/tl.txt"
backup_url = "https://tfapi.cn/TL/tl.json"
try:
response = requests.get(primary_url, timeout=10)
if response.status_code == 200:
print("\n" + "=" * 50)
print("📢 公告信息")
print("=" * 35)
print(response.text)
print("=" * 35 + "\n")
print("公告获取成功,开始执行任务...\n")
return
except requests.exceptions.RequestException as e:
print(f"获取公告时发生错误: {e}, 尝试备用链接...")
try:
response = requests.get(backup_url, timeout=10)
if response.status_code == 200:
print("\n" + "=" * 50)
print("📢 公告信息")
print("=" * 35)
print(response.text)
print("=" * 35 + "\n")
print("公告获取成功,开始执行任务...\n")
else:
print(f"⚠️ 获取公告失败,状态码: {response.status_code}")
except requests.exceptions.RequestException as e:
print(f"⚠️ 获取公告时发生错误: {e}, 可能是网络问题或链接无效。")
# 获取随机 User-Agent
def get_random_ua():
ua_api_url = "http://ck.tfapi.cn/ua.php"
try:
response = requests.get(ua_api_url)
response.raise_for_status()
data = response.json()
return data.get('user_agent', '')
except requests.exceptions.RequestException as e:
print(f"获取 User-Agent 失败:{e}")
return ''
# 获取环境变量中的 token
def get_tokens_from_env():
tokens = os.environ.get('BGYX', '')
if not tokens:
print("未找到环境变量 BGYX 或其值为空")
return []
return [token.strip() for token in tokens.split('\n') if token.strip()]
# 签到函数
def sign_in(token):
url = "https://slb1.bg19.cn/api/wanlshop/Punch/click"
headers = {
"Host": "slb1.bg19.cn",
"Connection": "keep-alive",
"content-type": "application/json;charset=UTF-8",
"token": token,
"App-Client": "mp-wanlshop",
"Accept-Language": "zh-CN,zh;q=0.9",
"charset": "utf-8",
"User-Agent": get_random_ua(),
"Accept-Encoding": "gzip, deflate, br"
}
try:
response = requests.get(url, headers=headers)
response.raise_for_status()
result = response.json()
if result.get("code") == 1 and "您打过卡了" in result.get("data", {}).get("msg", ""):
print("今日已签到,无需重复签到。")
else:
print("签到成功!")
except requests.exceptions.RequestException as e:
print(f"签到失败:{e}")
# 主函数
def main():
get_proclamation() # 获取公告
tokens = get_tokens_from_env()
if not tokens:
return
for token in tokens:
sign_in(token)
if __name__ == "__main__":
main()

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,129 @@
# Source: https://gitee.com/jdqlscript/toulu/blob/main/%E5%B0%8F%E7%B4%AB.py
# Raw: https://gitee.com/jdqlscript/toulu/raw/main/%E5%B0%8F%E7%B4%AB.py
# Repo: jdqlscript/toulu
# Path: 小紫.py
# UploadedAt: 2025-06-28T11:18:42+08:00
# SHA256: 04f1966f2f6b22487095d315cd1a6838defe98bf62d12665d0dfb9fb20adc56d
# Category: web版/抓包
# Evidence: web/H5关键词 + cookie/token/header
#入口:微信搜索小紫有约
#多个变量名用#分割
#变量名xzyy
#抓包sxkyziqidonglai.cn域名下的一整段cookie
import requests
import json
import os
# 获取环境变量中的多个 cookie多个 cookie 通过 # 分割
xzyy = os.environ.get('xzyy', '') # 例如: 'cookie1#cookie2#cookie3'
# 如果 xzyy 为空,则使用空列表,否则分割为多个 cookie
cookies = xzyy.split('#') if xzyy else []
# wxpusher 推送的配置信息
push_token = 'UID_Rj**********' # wxpusher的UID
push_title = '小紫有约' # 推送标题
push_content = '小紫有约签到通知\n\n' # 推送内容
wxapp_token = 'AT_aTsJ*********' # wxpusher的APPToken
def wxpusher_send():
"""
发送消息到wxpusher
"""
headers = {'Content-Type': 'application/json;charset=utf-8'}
data = {
"appToken": wxapp_token,
"uids": [push_token],
"topicIds": [],
"summary": push_title,
"content": push_content,
"contentType": 1,
"verifyPay": False
}
try:
response = requests.post('https://wxpusher.zjiecode.com/api/send/message', headers=headers, data=json.dumps(data))
# 获取响应的 JSON 数据
response_json = response.json()
print(f"wxpusher 推送: {response_json.get('msg', '没有返回 msg 字段')}")
except requests.exceptions.RequestException as e:
print(f"wxpusher 推送失败: {e}")
def get_announcement():
"""
获取公告信息
"""
external_url = 'https://github.com/3288588344/toulu/raw/refs/heads/main/tl.txt'
try:
response = requests.get(external_url)
if response.status_code == 200:
print( response.text)
print("公告获取成功,开始执行签到请求...")
else:
print(f"获取公告失败,状态码: {response.status_code}")
except requests.exceptions.RequestException as e:
print(f"获取公告时发生错误: {e}")
def sign_in(cookie_xz):
"""
执行签到请求
"""
url = "https://sxkyziqidonglai.cn/api/mobile/activity-v2/activity/launchByValidater"
headers = {
"Host": "sxkyziqidonglai.cn",
"Content-Length": "75",
"Sec-CH-UA-Platform": '"Android"',
"User-Agent": 'Mozilla/5.0 (Linux; Android 10; MI 8 Build/QKQ1.190828.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.103 Mobile Safari/537.36 XWEB/1300333 MMWEBSDK/20241202 MMWEBID/3628 MicroMessenger/8.0.56.2800(0x2800383A) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64',
"Accept": "application/json, text/plain, */*",
"Sec-CH-UA": '"Chromium";v="130", "Android WebView";v="130", "Not?A_Brand";v="99"',
"Content-Type": "application/json",
"Sec-CH-UA-Mobile": "?1",
"Origin": "https://sxkyziqidonglai.cn",
"X-Requested-With": "com.tencent.mm",
"Sec-Fetch-Site": "same-origin",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Dest": "empty",
"Referer": "https://sxkyziqidonglai.cn/activity/signIn?siteId=SITE_33254242630091515087&channelCode=WXjxriol8e8293wezu&actCode=SIGNIN202501201006598253",
"Accept-Encoding": "gzip, deflate, br, zstd",
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
"Cookie": cookie_xz
}
data = {
"actCode": "SIGNIN202501201006598253",
"siteId": "SITE_33254242630091515087"
}
try:
response = requests.post(url, headers=headers, data=json.dumps(data))
# 处理响应
if response.status_code == 200:
response_json = response.json()
if 'msg' in response_json:
print(f"{response_json['msg']}")
wxpusher_send() # 签到成功后发送推送
else:
print("请求成功,但未找到 'msg' 字段")
else:
response_json = response.json()
print(f"请求失败,状态码: {response.status_code}")
print(f"错误信息: {response_json.get('msg', '没有返回 msg 字段')}")
except requests.exceptions.RequestException as e:
print(f"签到请求失败: {e}")
if __name__ == "__main__":
# 获取公告
get_announcement()
if cookies:
# 循环遍历多个账号,进行签到
for index, cookie in enumerate(cookies, start=1):
print(f"正在为账号 {index} 执行签到...")
sign_in(cookie) # 执行签到
else:
print("没有找到任何可用的账号cookie程序退出。")

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,662 @@
// # Source: https://gitee.com/jdqlscript/toulu/blob/main/%E5%BF%83%E5%96%9C%E5%B0%8F%E7%A8%8B%E5%BA%8F.js
// # Raw: https://gitee.com/jdqlscript/toulu/raw/main/%E5%BF%83%E5%96%9C%E5%B0%8F%E7%A8%8B%E5%BA%8F.js
// # Repo: jdqlscript/toulu
// # Path: 心喜小程序.js
// # UploadedAt: 2025-06-28T11:18:42+08:00
// # SHA256: a195dc9ae52fc26b8357291a30f6778722f554879186e30c02249ebcf0411846
// # Category: web版/抓包
// # Evidence: web/H5关键词 + cookie/token/header
//
/**
* cron 9 9 * * * xx.js
* 变量名: xinxi
* 每天运行一次就行
* 报错是正常情况
* 变量值:api.xinc818.com 请求头中sso的值 多账户&或者换行
* scriptVersionNow = "0.0.1";
*/
const $ = new Env("心喜");
const notify = $.isNode() ? require('./sendNotify') : '';
let ckName = "xinxi";
let envSplitor = ["&", "\n"]; //多账号分隔符
let strSplitor = "#"; //多变量分隔符
let userIdx = 0;
let userList = [];
class Task {
constructor(str) {
this.index = ++userIdx;
this.ck = str.split(strSplitor)[0]; //单账号多变量分隔符
this.ckStatus = true;
this.userId = null
this.artList = []
this.goodsList = []
}
async main() {
await this.user_info();
if (this.ckStatus == true) {
await this.task_signin();
await this.task_lottery()
await this.task_share()
await this.task_goods()
await this.art_list()
if (this.artList.length > 0) {
await this.task_follow(this.artList[0])
}
await this.goods_list()
if (this.goodsList.length > 0) {
await this.task_like(this.goodsList[0])
}
}
}
async task_signin() {
try {
let result = await this.taskRequest("get", `https://api.xinc818.com/mini/sign/in?dailyTaskId=`)
//console.log(result);
if (result.code == 0) {
$.log(`✅账号[${this.index}] 签到状态【${result.data.flag}】获得积分【${result.data.integral}】🎉`)
} else {
console.log(`❌账号[${this.index}] 签到状态【false】`);
console.log(result);
}
} catch (e) {
console.log(e);
}
}
async user_info() {
try {
let result = await this.taskRequest("get", `https://api.xinc818.com/mini/user`)
//console.log(options);
console.log(result);
if (result.code == 0) {
$.log(`✅账号[${this.index}] 【${result.data.nickname}】积分【${result.data.integral}】🎉`)
this.userId = result.data.id
} else {
console.log(`❌账号[${this.index}] 用户查询【false】`);
console.log(result);
}
} catch (e) {
console.log(e);
}
}
//浏览30sAPI
async task_goods() {
try {
let result = await this.taskRequest("get", `https://api.xinc818.com/mini/dailyTask/browseGoods/22`)
//console.log(options);
console.log(result);
if (result.code == 0) {
if (result.data !== null) {
$.log(`✅账号[${this.index}] 完成浏览30s成功 获得【${result.data.singleReward}`)
} else {
console.log(`❌账号[${this.index}] 完成浏览30s任务失败`);
}
} else {
console.log(`❌账号[${this.index}] 完成浏览30s任务失败`);
console.log(result);
}
} catch (e) {
console.log(e);
}
}
//想要任务API
async task_like(id) {
console.log(`https://api.xinc818.com/mini/integralGoods/${id}?type=`)
try {
let goodsResult = await this.taskRequest("get", `https://api.xinc818.com/mini/integralGoods/${id}?type=`)
if (goodsResult.data) {
let likeResult = await this.taskRequest("post", `https://api.xinc818.com/mini/live/likeLiveItem`, { "isLike": true, "dailyTaskId": 20, "productId": Number(goodsResult.data.outerId) })
//console.log(options);
console.log(likeResult);
if (likeResult.code == 0) {
if (likeResult.data !== null) {
$.log(`✅账号[${this.index}] 完成点击想要任务成功 获得【${likeResult.data.singleReward}`)
} else {
console.log(`❌账号[${this.index}] 完成点击想要任务失败`);
}
} else {
console.log(`❌账号[${this.index}] 完成点击想要任务失败`);
console.log(likeResult);
}
}
} catch (e) {
console.log(e);
}
}
//关注用户API
async task_follow(pusherId) {
console.log(pusherId)
try {
let result = await this.taskRequest("post", `https://api.xinc818.com/mini/user/follow`, { "decision": true, "followUserId": pusherId })
//console.log(options);
console.log(result);
if (result.code == 0) {
if (result.data !== null) {
$.log(`✅账号[${this.index}] 完成关注用户任务成功 获得【${result.data.singleReward}`)
} else {
console.log(`❌账号[${this.index}] 完成关注用户任务失败`);
}
} else {
console.log(`❌账号[${this.index}] 完成关注用户任务失败`);
console.log(result);
}
} catch (e) {
console.log(e);
}
}
//抽奖API
async task_lottery() {
try {
let result = await this.taskRequest("post", `https://api.xinc818.com/mini/lottery/draw`, { "activity": 61, "batch": false, "isIntegral": false, "userId": Number(this.userId), "dailyTaskId": 9 })
//console.log(options);
console.log(result);
if (result.code == 0) {
if (result.data !== null) {
$.log(`✅账号[${this.index}] 完成抽奖成功 获得【${result.data.taskResult.singleReward}】积分 奖品【${result.data.lotteryResult.integral}`)
} else {
console.log(`❌账号[${this.index}] 完成抽奖失败`);
}
} else {
console.log(`❌账号[${this.index}] 完成抽奖失败`);
console.log(result);
}
} catch (e) {
console.log(e);
}
}
//分享API
async task_share() {
try {
let result = await this.taskRequest("get", `https://api.xinc818.com/mini/dailyTask/share`)
//console.log(options);
console.log(result);
if (result.code == 0) {
if (result.data !== null) {
$.log(`✅账号[${this.index}] 完成分享成功 获得【${result.data.singleReward}`)
} else {
console.log(`❌账号[${this.index}] 完成分享失败`);
}
} else {
console.log(`❌账号[${this.index}] 完成分享失败`);
console.log(result);
}
} catch (e) {
console.log(e);
}
}
//获取帖子列表API(包含用户和帖子)
async art_list() {
try {
let result = await this.taskRequest("get", `https://cdn-api.xinc818.com/mini/posts/sorts?sortType=COMMENT&pageNum=1&pageSize=10&groupClassId=0`)
//console.log(options);
console.log(result);
if (result.code == 0) {
if (result.data.list.length > 0) {
for (let i = 0; i < 2; i++)
this.artList.push(result.data.list[i].publisherId)
}
} else {
console.log(result);
}
} catch (e) {
console.log(e);
}
}
//获取商品API
async goods_list() {
try {
let result = await this.taskRequest("get", `https://cdn-api.xinc818.com/mini/integralGoods?orderField=sort&orderScheme=DESC&pageSize=10&pageNum=1`)
//console.log(options);
console.log(result);
if (result.code == 0) {
if (result.data.list.length > 0) {
for (let i = 0; i < 2; i++)
this.goodsList.push(result.data.list[i].id)
}
} else {
console.log(result);
}
} catch (e) {
console.log(e);
}
}
async taskRequest(method, url, body = "") {
//
let headers = {
//"Host": "api.xinc818.com",
"Connection": "keep-alive",
"charset": "utf-8",
"User-Agent": "Mozilla/5.0 (Linux; Android 10; MI 8 Lite Build/QKQ1.190910.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Mobile Safari/537.36 XWEB/1160027 MMWEBSDK/20231002 MMWEBID/2585 MicroMessenger/8.0.43.2480(0x28002B51) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android",
"content-type": "application/json",
"Accept-Encoding": "gzip,compress,br,deflate",
"sso": this.ck,
"Referer": "https://servicewechat.com/wx673f827a4c2c94fa/253/page-frame.html"
}
const reqeuestOptions = {
url: url,
method: method,
headers: headers
}
if (method !== "get") {
if (headers["Content-Type"] == "application/json") {
reqeuestOptions["body"] = JSON.stringify(body);
} else {
reqeuestOptions["body"] = body
}
}
let { body: result } = await $.httpRequest(reqeuestOptions)
return result
}
}
!(async () => {
if (!(await checkEnv())) return;
if (userList.length > 0) {
let taskall = [];
for (let user of userList) {
if (user.ckStatus) {
taskall.push(user.main());
}
}
await Promise.all(taskall);
}
await $.sendMsg($.logs.join("\n"))
})()
.catch((e) => console.log(e))
.finally(() => $.done());
//********************************************************
/**
* 变量检查与处理
* @returns
*/
async function checkEnv() {
let userCookie = ($.isNode() ? process.env[ckName] : $.getdata(ckName)) || "";
if (userCookie) {
let e = envSplitor[0];
for (let o of envSplitor)
if (userCookie.indexOf(o) > -1) {
e = o;
break;
}
for (let n of userCookie.split(e)) n && userList.push(new Task(n));
} else {
console.log(`未找到CK【${ckName}`);
return;
}
return console.log(`共找到${userList.length}个账号`), true; //true == !0
}
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;
}
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.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 = this.setval(t, s);
return e;
}
getval(t) {
if (this.isSurge() || this.isLoon()) {
return $persistentStore.read(t);
} else if (this.isQuanX()) {
return $prefs.valueForKey(t);
} else if (this.isNode()) {
this.data = this.loaddata();
return this.data[t];
} else {
return this.data && this.data[t] || null;
}
}
setval(t, s) {
if (this.isSurge() || this.isLoon()) {
return $persistentStore.write(t, s);
} else if (this.isQuanX()) {
return $prefs.setValueForKey(t, s);
} else if (this.isNode()) {
this.data = this.loaddata();
this.data[s] = t;
this.writedata();
return true;
} else {
return 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();
if (t) {
t.headers = t.headers ? t.headers : {};
if (typeof t.headers.Cookie === "undefined" && typeof t.cookieJar === "undefined") {
t.cookieJar = this.ckjar;
}
}
}
/**
* @param {Object} options
* @returns {String} 将 Object 对象 转换成 queryStr: key=val&name=senku
*/
queryStr(options) {
return Object.entries(options)
.map(([key, value]) => `${key}=${typeof value === 'object' ? JSON.stringify(value) : value}`)
.join('&');
}
//从url获取参数组成json
getURLParams(url) {
const params = {};
const queryString = url.split('?')[1];
if (queryString) {
const paramPairs = queryString.split('&');
paramPairs.forEach(pair => {
const [key, value] = pair.split('=');
params[key] = value;
});
}
return params;
}
isJSONString(str) {
try {
var obj = JSON.parse(str);
if (typeof obj == 'object' && obj) {
return true;
} else {
return false;
}
} catch (e) {
return false;
}
}
isJson(obj) {
var isjson = typeof (obj) == "object" && Object.prototype.toString.call(obj).toLowerCase() == "[object object]" && !obj.length;
return isjson;
}
async sendMsg(message) {
if (!message) return;
if ($.isNode()) {
await notify.sendNotify($.name, message)
} else {
$.msg($.name, '', message)
}
}
async httpRequest(options) {
let t = {
...options
};
if (!t.headers) {
t.headers = {}
}
if (t.params) {
t.url += '?' + this.queryStr(t.params);
}
t.method = t.method.toLowerCase();
if (t.method === 'get') {
delete t.headers['Content-Type'];
delete t.headers['Content-Length'];
delete t.headers['content-type'];
delete t.headers['content-length'];
delete t["body"]
}
if (t.method === 'post') {
let ContentType;
if (!t.body) {
t.body = ""
} else {
if (typeof t.body == "string") {
if (this.isJSONString(t.body)) {
ContentType = 'application/json'
} else {
ContentType = 'application/x-www-form-urlencoded'
}
} else if (this.isJson(t.body)) {
t.body = JSON.stringify(t.body);
ContentType = 'application/json';
}
}
if (!t.headers['Content-Type'] || !t.headers['content-type']) {
t.headers['Content-Type'] = ContentType;
}
delete t.headers['Content-Length'];
}
if (this.isNode()) {
this.initGotEnv(t);
let httpResult = await this.got(t);
if (this.isJSONString(httpResult.body)) {
httpResult.body = JSON.parse(httpResult.body)
}
return httpResult;
}
if (this.isQuanX()) {
t.method = t.method.toUpperCase()
return new Promise((resolve, reject) => {
$task.fetch(t).then(response => {
if (this.isJSONString(response.body)) {
response.body = JSON.parse(response.body)
}
resolve(response)
})
})
}
}
randomNumber(length) {
const characters = '0123456789';
return Array.from({ length }, () => characters[Math.floor(Math.random() * characters.length)]).join('');
}
randomString(length) {
const characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
return Array.from({ length }, () => characters[Math.floor(Math.random() * characters.length)]).join('');
}
timeStamp() {
return new Date().getTime()
}
uuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0,
v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
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;
this.isMute ||
(this.isSurge() || this.isLoon()
? $notification.post(s, e, i, h(o))
: this.isQuanX() && $notify(s, e, i, h(o)));
let logs = ['', '==============📣系统通知📣=============='];
logs.push(t);
e ? logs.push(e) : '';
i ? logs.push(i) : '';
console.log(logs.join('\n'));
this.logs = this.logs.concat(logs);
}
log(...t) {
t.length > 0 && (this.logs = [...this.logs, ...t]),
console.log(t.join(this.logSeparator));
}
logErr(t, s) {
const e = !this.isSurge() && !this.isQuanX() && !this.isLoon();
e
? this.log("", `\u2757\ufe0f${this.name}, \u9519\u8bef!`, t.stack)
: this.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()
if (this.isNode()) {
process.exit(1)
}
if (this.isQuanX()) {
$done(t)
}
}
})(t, s);
}

View File

@@ -0,0 +1,112 @@
# Source: https://gitee.com/jdqlscript/toulu/blob/main/%E6%8D%B7%E5%AE%89%E7%89%B9%E9%AA%91%E8%A1%8C.py
# Raw: https://gitee.com/jdqlscript/toulu/raw/main/%E6%8D%B7%E5%AE%89%E7%89%B9%E9%AA%91%E8%A1%8C.py
# Repo: jdqlscript/toulu
# Path: 捷安特骑行.py
# UploadedAt: 2025-06-28T11:18:42+08:00
# SHA256: cde00a24e7d22ffcf989388d81544ad9d81ac4e28168158970b40a866195c1fb
# Category: web版/抓包
# Evidence: web/H5关键词 + cookie/token/header
#抓包域名opo.giant.com.cn下的user_id就行
#多账号使用&分割
#by:哆啦A梦
import os
import requests
import json
# 定义请求的公共头部
COMMON_HEADERS = {
"Host": "opo.giant.com.cn",
"Content-Length": "23",
"Accept": "application/json, text/plain, */*",
"User-Agent": "Mozilla/5.0 (Linux; Android 10; MI 8 Build/QKQ1.190828.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.101 Mobile Safari/537.36 AgentWeb/5.0.0 UCBrowser/11.6.4.950 _giantapp/4.1.9",
"Content-Type": "application/x-www-form-urlencoded",
"Origin": "https://found.giant.com.cn",
"X-Requested-With": "com.giantkunshan.giant",
"Sec-Fetch-Site": "same-site",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Dest": "empty",
"Referer": "https://found.giant.com.cn/",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7"
}
# 定义请求的URL
API_URL = "https://opo.giant.com.cn/opo/index.php/day_pic/do_app_pic"
def get_announcement():
"""
获取公告信息
"""
external_url = "https://github.com/3288588344/toulu/raw/refs/heads/main/tl.txt"
try:
response = requests.get(external_url)
if response.status_code == 200:
print(response.text.strip()) # 打印公告内容
print("公告获取成功,开始执行签到请求...")
else:
print(f"获取公告失败,状态码: {response.status_code}")
except requests.exceptions.RequestException as e:
print(f"获取公告时发生错误: {e}")
def check_in(user_id):
"""
模拟签到操作。
"""
data = {"type": "1", "user_id": user_id}
return send_request(data)
def share_task(user_id):
"""
模拟分享任务。
"""
data = {"type": "2", "user_id": user_id}
return send_request(data)
def claim_share_reward(user_id):
"""
模拟领取分享任务积分。
"""
data = {"type": "3", "user_id": user_id}
return send_request(data)
def send_request(data):
"""
发送请求的通用函数。
"""
try:
response = requests.post(API_URL, headers=COMMON_HEADERS, data=data)
if response.status_code == 200:
response_data = response.json()
if response_data.get("status") == 1 and response_data.get("msg") == "ok":
return f"操作成功!"
else:
return f"操作失败,返回信息:{response_data.get('msg', '未知错误')}"
else:
return f"请求失败,状态码:{response.status_code}"
except Exception as e:
return f"请求时发生错误:{e}"
def main():
# 先获取公告
get_announcement()
user_ids_str = os.getenv("JATQX")
if not user_ids_str:
print("错误:未设置环境变量 JATQX请确保已正确配置。")
return
user_ids = user_ids_str.split("&")
for user_id in user_ids:
user_id = user_id.strip()
if user_id:
print(f"用户 {user_id}:开始执行任务")
print(f"用户 {user_id}:签到结果:{check_in(user_id)}")
print(f"用户 {user_id}:分享结果:{share_task(user_id)}")
print(f"用户 {user_id}:领取积分结果:{claim_share_reward(user_id)}")
print(f"用户 {user_id}:任务完成\n")
if __name__ == "__main__":
main()

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,154 @@
// # Source: https://github.com/smallfawn/QLScriptPublic/blob/main/daily/mtf.js
// # Raw: https://raw.githubusercontent.com/smallfawn/QLScriptPublic/main/daily/mtf.js
// # Repo: smallfawn/QLScriptPublic
// # Path: daily/mtf.js
// # UploadedAt: 2026-04-07T12:21:56Z
// # SHA256: 43c9ffb5194ec2154559fffe845949b7f31cb07bdf8a884b094ec1135c6c729c
// # Category: web版/抓包
// # Evidence: web/H5关键词 + cookie/token/header
//
/*
------------------------------------------
@Author: sm
@Date: 2024.06.07 19:15
@Description: 摩托范APP签到和抽奖
cron: 30 10 * * *
------------------------------------------
#Notice:
变量名 mtf
抓域名 api.58moto.com 下请求中 token和uid 的值填入变量 用#连接 多账户&或换行
⚠️【免责声明】
------------------------------------------
1、此脚本仅用于学习研究不保证其合法性、准确性、有效性请根据情况自行判断本人对此不承担任何保证责任。
2、由于此脚本仅用于学习研究您必须在下载后 24 小时内将所有内容从您的计算机或手机或任何存储设备中完全删除,若违反规定引起任何事件本人对此均不负责。
3、请勿将此脚本用于任何商业或非法目的若违反规定请自行对此负责。
4、此脚本涉及应用与本人无关本人对因此引起的任何隐私泄漏或其他后果不承担任何责任。
5、本人对任何脚本引发的问题概不负责包括但不限于由脚本错误引起的任何损失和损害。
6、如果任何单位或个人认为此脚本可能涉嫌侵犯其权利应及时通知并提供身份证明所有权证明我们将在收到认证文件确认后删除此脚本。
7、所有直接或间接使用、查看此脚本的人均应该仔细阅读此声明。本人保留随时更改或补充此声明的权利。一旦您使用或复制了此脚本即视为您已接受此免责声明。
*/
const { Env } = require("../tools/env")
const $ = new Env("摩托范");
let ckName = `mtf`;
const strSplitor = "#";
const axios = require("axios");
const defaultUserAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.31(0x18001e31) NetType/WIFI Language/zh_CN miniProgram"
class Task {
constructor(env) {
this.index = $.userIdx++
this.user = env.split(strSplitor);
this.token = this.user[0];
this.uid = this.user[1];
}
async run() {
await this.userInfo()
await this.signIn()
await this.drwa()
}
async userInfo() {
let options = {
method: 'POST',
url: `https://api.58moto.com/user/center/info/principal`,
headers: {
"token": this.token,
"content-type": "application/x-www-form-urlencoded"
},
data: "uid=" + this.uid
}
let { data: result } = await axios.request(options);
if (result?.code == 0) {
$.log(`查询成功:当前手机号${result.data.mobile} \n 用户昵称为${result.data.username} 🎉`);
} else {
$.log(`查询: 失败 ❌ 了呢,原因未知!`);
console.log(result);
}
}
async signIn() {
let options = {
method: 'POST',
url: `https://api.58moto.com/coins/task/dailyCheckIn`,
headers: {
"token": this.token,
"content-type": "application/x-www-form-urlencoded"
},
data: "uid=" + this.uid + "&weekDate=" + $.time('yyyyMMdd')
}
let { data: result } = await axios.request(options);
if (result?.code == 0) {
$.log(`签到成功:${result.data.contentDesc} 🎉`);
} else if (result?.code == 300101) {
$.log(`签到失败:${result.msg},请勿重复签到`);
} else {
$.log(`签到: 失败 ❌ 了呢,原因未知!`);
console.log(result);
}
}
async drwa() {
let options = {
method: 'POST',
url: `https://jsapi.58moto.com/coins/turntable/activity/draw`,
headers: {
"content-type": "application/x-www-form-urlencoded"
},
data: `token=${this.token}&uid=${this.uid}&autherid=${this.uid}&platform=2&version=3.66.80&deviceId=53B5DA97-C72D-4C19-A219-70D8A9A31290&bundleId=com.jdd.motorfans&activityId=24`
}
let { data: result } = await axios.request(options);
if (result?.code == 0) {
$.log(`抽奖成功:${result.data.awardName} 🎉`);
} else {
$.log(`抽奖: 失败 ❌ 了呢,原因未知!`);
console.log(result);
}
}
//做任务需要wtoken逆向 不想写
}
!(async () => {
await getNotice()
$.checkEnv(ckName);
for (let user of $.userList) {
await new Task(user).run();
}
})()
.catch((e) => console.log(e))
.finally(() => $.done());
async function getNotice() {
try {
let options = {
url: `https://ghproxy.net/https://raw.githubusercontent.com/smallfawn/Note/refs/heads/main/Notice.json`,
headers: {
"User-Agent": defaultUserAgent,
},
timeout:3000
}
let {
data: res
} = await axios.request(options);
$.log(res)
return res
} catch (e) {}
}

View File

@@ -0,0 +1,110 @@
# Source: https://gitee.com/jdqlscript/toulu/blob/main/%E6%B5%93%E4%BA%94%E7%9A%84%E9%85%92%E9%A6%86.py
# Raw: https://gitee.com/jdqlscript/toulu/raw/main/%E6%B5%93%E4%BA%94%E7%9A%84%E9%85%92%E9%A6%86.py
# Repo: jdqlscript/toulu
# Path: 浓五的酒馆.py
# UploadedAt: 2025-06-28T11:18:42+08:00
# SHA256: ee3ecc859af5c73b12b168aba0154178676c21cf9f7134d0dc43dcb64c34cd65
# Category: web版/抓包
# Evidence: web/H5关键词 + cookie/token/header
#入口:https://i.postimg.cc/7YjhgtCH/mmexport1742029346894.jpg
#抓包任意域名下的authorization注意不要开头的Bearer支持多账号
#环境变量名:NWDJG
#by:哆啦A梦
import requests
import os
tokens = os.getenv("NWDJG")
if not tokens:
raise ValueError("环境变量 NWDJG 未设置,请确保已正确配置环境变量。")
token_list = tokens.split("&")
headers_template = {
'xweb_xhr': '1',
'content-type': 'application/json',
'sec-fetch-site': 'cross-site',
'sec-fetch-mode': 'cors',
'sec-fetch-dest': 'empty',
'accept-language': 'zh-CN,zh;q=0.9',
}
sign_url = 'https://stdcrm.dtmiller.com/scrm-promotion-service/promotion/sign/today'
sign_params = {
'promotionId': 'PI67c25977540856000aac6ac0',
}
points_url = 'https://stdcrm.dtmiller.com/scrm-promotion-service/mini/wly/user/info'
def get_proclamation():
external_url = "https://github.com/3288588344/toulu/raw/refs/heads/main/tl.txt"
try:
response = requests.get(external_url)
if response.status_code == 200:
print(response.text)
print("公告获取成功,开始执行任务...")
else:
print(f"获取公告失败,状态码: {response.status_code}")
except requests.exceptions.RequestException as e:
print(f"获取公告时发生错误: {e}")
get_proclamation()
total_accounts = len(token_list)
success_count = 0
fail_count = 0
# 遍历每个账号,依次执行签到和查询积分任务
for index, token in enumerate(token_list, start=1):
print(f"\n正在处理账号 {index}/{total_accounts}...")
headers = headers_template.copy()
headers['authorization'] = f"Bearer {token}"
points_response = requests.get(points_url, headers=headers)
if points_response.status_code == 200:
points_data = points_response.json()
if points_data['code'] == 0:
mobile = points_data['data']['member']['mobile']
account_name = f"{mobile[:3]}*****{mobile[-3:]}"
print(f"账号:{account_name}")
else:
print(f"查询积分失败,{points_data['msg']}")
account_name = "未知"
else:
print(f"查询积分网络请求异常,状态码:{points_response.status_code},响应内容:{points_response.text}")
account_name = "未知"
print("正在尝试签到...")
sign_response = requests.get(sign_url, params=sign_params, headers=headers)
if sign_response.status_code == 200:
sign_data = sign_response.json()
if sign_data['code'] == 0:
print("签到成功!")
print(f"签到天数:{sign_data['data']['signDays']}")
print(f"是否已领取奖励:{sign_data['data']['isReceive']}")
print(f"奖励信息:{sign_data['data']['prize']['goodsName']},积分:{sign_data['data']['prize']['prizePoints']}")
success_count += 1
else:
print(f"签到失败,{sign_data['msg']}")
fail_count += 1
else:
print(f"签到网络请求异常,状态码:{sign_response.status_code},响应内容:{sign_response.text}")
fail_count += 1
print(f"\n任务完成!")
print(f"总账号数量:{total_accounts}")
print(f"签到成功账号:{success_count}")
print(f"签到失败账号:{fail_count}")

View File

@@ -0,0 +1,132 @@
// # Source: https://github.com/smallfawn/QLScriptPublic/blob/main/daily/aima.js
// # Raw: https://raw.githubusercontent.com/smallfawn/QLScriptPublic/main/daily/aima.js
// # Repo: smallfawn/QLScriptPublic
// # Path: daily/aima.js
// # UploadedAt: 2026-04-13T11:40:47Z
// # SHA256: c4bf13f4d1a0d91d73bf3e99005689874fbc95559f9b4b60ed3a55f883c90c0c
// # Category: web版/抓包
// # Evidence: web/H5关键词 + cookie/token/header
//
/*
爱玛会员俱乐部 - 自动签到脚本2026年2月修复版
✅ 修复点使用域名替代失效IP更新活动ID为100001180
✅ 支持环境Node.js
✅ 变量名aima
✅ 变量值access-token支持多账号用 & 或换行分隔)
*/
const { Env } = require("../tools/env")
const $ = new Env("爱玛会员俱乐部");
const axios = require('axios')
// ================== 配置区 ==================
const ACTIVITY_ID = "100001192"; // 2026年2月活动ID
const BASE_URL = "https://scrm.aimatech.com"; // 使用官方域名不再硬编码IP
const APP_ID = "scrm";
const USER_AGENT = "Mozilla/5.0 (Linux; Android 15; 23013RK75C Build/AQ3A.250226.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/142.0.7444.173 Mobile Safari/537.36 XWEB/1420229 MMWEBSDK/20251101 MMWEBID/6369 MicroMessenger/8.0.67.3000(0x28004333) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android";
// ================== 工具函数 ==================
function generateUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
const r = Math.random() * 16 | 0;
const v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
function md5(str) {
const crypto = require('crypto');
return crypto.createHash('md5').update(str).digest('hex');
}
// ================== 核心逻辑 ==================
async function signIn(token, index) {
try {
const timestamp = Date.now();
const traceLogId = generateUUID();
// 构造通用请求头
const headers = {
"App-Id": APP_ID,
"Time-Stamp": timestamp.toString(),
"TraceLog-Id": traceLogId,
"Access-Token": token.trim(),
"content-type": "application/json",
"User-Agent": USER_AGENT,
"charset": "utf-8",
"Referer": "https://servicewechat.com/wx2dcfb409fd5ddfb4/215/page-frame.html"
};
// 生成签名(按规则拼接)
const signStr = `${APP_ID}${timestamp}${traceLogId}${token.trim()}AimaScrm321_^`;
headers["Sign"] = md5(signStr).toLowerCase();
// 1. 查询签到状态
$.log(`🚀 账号【${index}】查询签到状态...`);
const searchRes = await axios.post(
`${BASE_URL}/aima/wxclient/mkt/activities/sign:search`,
{ activityId: ACTIVITY_ID },
{ headers, timeout: 10000 }
);
const data = searchRes.data;
if (data.content && data.content.signStatus === 1) {
$.log(`✅ 账号【${index}】今日已签到!`);
return;
}
// 2. 执行签到
$.log(`⏳ 账号【${index}】正在签到...`);
const joinRes = await axios.post(
`${BASE_URL}/aima/wxclient/mkt/activities/sign:join`,
{ activityId: ACTIVITY_ID, activitySceneId: null },
{ headers, timeout: 10000 }
);
if (joinRes.data.code === 200 || joinRes.data.code === 0) {
const point = joinRes.data.content?.point || 10;
$.log(`🎉 账号【${index}】签到成功!获得 ${point} 积分`);
} else {
throw new Error(`签到失败: ${JSON.stringify(joinRes.data)}`);
}
} catch (e) {
throw new Error(e.message || e);
}
}
// ================== 主函数 ==================
!(async () => {
console.log(`\n🔔 爱玛会员俱乐部, 开始!`);
// 获取 access-token支持多账号
let tokens = [];
if ($.isNode()) {
const env = process.env.aima;
if (env) {
tokens = env.split(/&|\n/).filter(t => t.trim());
}
}
if (tokens.length === 0) {
$.msg("❌ 未找到 access-token请配置变量 'aima'");
return;
}
console.log(`共找到${tokens.length}个账号`);
for (let i = 0; i < tokens.length; i++) {
try {
console.log(`\n🚀 user:【${i + 1}】 start work`);
await signIn(tokens[i], i + 1);
} catch (e) {
console.log(`❌ 账号【${i + 1}】执行失败: ${e.message}`);
}
}
// 发送通知
//await $.sendMsg($.logs.join("\n"));
})()
.catch((e) => console.log(e))
.finally(() => $.done());

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,100 @@
# Source: https://gitee.com/jdqlscript/toulu/blob/main/%E7%AC%AC%E4%B8%80%E7%94%B5%E5%8A%A8.py
# Raw: https://gitee.com/jdqlscript/toulu/raw/main/%E7%AC%AC%E4%B8%80%E7%94%B5%E5%8A%A8.py
# Repo: jdqlscript/toulu
# Path: 第一电动.py
# UploadedAt: 2025-06-28T11:18:42+08:00
# SHA256: 209af53a6ebb564eac88091192e8340740ae58df5af249d08a2205a670fff9b8
# Category: web版/抓包
# Evidence: web/H5关键词 + cookie/token/header
#环境变量 dydd
#有问题联系3288588344
#频道https://pd.qq.com/s/672fku8ge
import os
import requests
import time
import hashlib
# 获取青龙面板环境变量 dydd
dydd = os.environ.get('dydd', '')
# 按换行符分割账号,并过滤空行
accounts = [line.strip() for line in dydd.strip().split('\n') if line.strip()]
url = "https://app2.d1ev.com/api/user/add-integral"
# 公共参数
params_base = {
'app_id': "d1ev_app",
'appName': "第一电动",
'os': "android",
'osVer': "9",
'vName': "2.5.6",
'vCode': "20506"
}
headers = {
'User-Agent': "Dalvik/2.1.0 (Linux; U; Android 9; PCRT00 Build/PQ3A.190605.06201646)",
'Connection': "Keep-Alive",
'Accept-Encoding': "gzip",
'TE': "gzip, deflate; q=0.5"
}
# 定义任务列表,每个任务包括任务类型和执行次数
tasks = [
{'type': 11, 'name': '签到', 'count': 1},
{'type': 3, 'name': '分享', 'count': 3},
{'type': 5, 'name': '点赞', 'count': 5},
{'type': 2, 'name': '阅读', 'count': 1}
]
for account in accounts:
# 分割账号为 uid 和 token
parts = account.split('#')
if len(parts) != 2:
print(f"跳过无效格式账号: {account}")
continue
uid, token = parts
# 生成当前时间戳
current_timestamp = str(int(time.time()))
for task in tasks:
task_type = task['type']
task_name = task['name']
task_count = task['count']
for _ in range(task_count):
# 构造签名字符串
sign_str = f"OMKCy2UxZwn8e4Ak{params_base['appName']}{params_base['app_id']}{params_base['os']}{params_base['osVer']}{current_timestamp}{token}{task_type}{uid}{params_base['vCode']}{params_base['vName']}"
# 计算 MD5 签名
sign = hashlib.md5(sign_str.encode('utf-8')).hexdigest()
# 定义带有动态值的参数
params = {
'timestamp': current_timestamp,
'token': token,
'uid': uid,
'type': task_type,
'sign': sign.upper(),
**params_base
}
try:
# 发送 GET 请求
response = requests.get(url, params=params, headers=headers)
response.raise_for_status() # 如果请求失败,则抛出异常
# 打印任务执行结果
print(f"账号: {uid}, 任务: {task_name}, 响应: {response.text}")
except requests.exceptions.RequestException as e:
print(f"账号: {uid}, 任务: {task_name}, 请求失败: {e}")
# 任务间隔5秒
time.sleep(5)
# 任务类型间隔10秒
time.sleep(10)

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,83 @@
# Source: https://gitee.com/jdqlscript/toulu/blob/main/%E8%9C%9C%E9%9B%AA%E5%86%B0%E5%9F%8E.py
# Raw: https://gitee.com/jdqlscript/toulu/raw/main/%E8%9C%9C%E9%9B%AA%E5%86%B0%E5%9F%8E.py
# Repo: jdqlscript/toulu
# Path: 蜜雪冰城.py
# UploadedAt: 2025-06-28T11:18:42+08:00
# SHA256: 3365d3b2294be333c9e59e0f382c7a7e84e3fe65d0e027b478939841e0730a84
# Category: web版/抓包
# Evidence: web/H5关键词 + cookie/token/header
#有问题联系3288588344
#频道https://pd.qq.com/s/672fku8ge
import requests
import threading
from hashlib import md5 as md5Encode
# ----固定变量区----
marketingId = '1816854086004391938'
# 任务数和线程数
tasks_num = 100 # 运行 100 次
threads_num = 30 # 最大线程数 30 个
# ----自定义变量区----
token = '抓包token'#token填里面
round = '13:00'
secretword = '年度重磅 新品免单'#口令
headers = {
'Access-Token': token,
'Referer': 'https://mxsa-h5.mxbc.net/',
'Host': 'mxsa.mxbc.net',
'Origin': 'https://mxsa-h5.mxbc.net',
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.50(0x18003233) NetType/4G Language/zh_CN miniProgram/wx7696c66d2245d107',
'Content-type': 'application/json;charset=UTF-8',
}
def exchange():
try:
url = 'https://mxsa.mxbc.net/api/v1/h5/marketing/secretword/confirm'
param = f'marketingId={marketingId}&round={round}&s=2&secretword={secretword}c274bac6493544b89d9c4f9d8d542b84'
m = md5Encode(param.encode("utf8"))
sign = m.hexdigest()
body = {
"secretword": secretword,
"sign": sign,
"marketingId": marketingId,
"round": round,
"s": 2
}
res = requests.post(url, headers=headers, json=body)
print(f'任务开始: {res.text}')
except Exception as e:
print(f'任务失败: {e}')
def threading_run(tasks,threads):
for i in range(tasks):
if threading.active_count() < threads + 1 and tasks != 0:
t = threading.Thread(target=exchange)
t.start()
tasks -= 1
if threading.active_count() == threads + 1:
# 等待前面的进程结束后再执行后面的代码这里为1因为程序本身即为一个线程
while threading.active_count() == threads + 1:
pass
while threading.active_count() != 1:
pass
def start_task():
threading_run(tasks_num, threads_num)
if __name__ == '__main__':
# 手动执行任务
start_task()

View File

@@ -0,0 +1,101 @@
# Source: https://gitee.com/jdqlscript/toulu/blob/main/%E8%9C%9C%E9%9B%AA%E7%A7%92%E6%9D%80.py
# Raw: https://gitee.com/jdqlscript/toulu/raw/main/%E8%9C%9C%E9%9B%AA%E7%A7%92%E6%9D%80.py
# Repo: jdqlscript/toulu
# Path: 蜜雪秒杀.py
# UploadedAt: 2025-06-28T11:18:42+08:00
# SHA256: abf071122636d805eb08d25c42ad6dad1fe571426756167e12ca9d902644f3c4
# Category: web版/抓包
# Evidence: web/H5关键词 + cookie/token/header
#需要填的值在最下面
#蜜雪冰城抢券 填场次时间即可 比如11:00 拉到最下面自己填token进去 卡着58 59秒跑 跑之前开飞行或者挂爱加速 避免405黑ip 有叼毛已经用这个抢到了
import hashlib
import time
import requests
import datetime
response = requests.get("https://raw.githubusercontent.com/3288588344/toulu/main/tl.txt")
response.encoding = 'utf-8'
txt = response.text
print(txt)
def ts():
return str(int(time.time()*1000))
def wait(sleepTime):
nowTine = time.strftime('%H', time.localtime())
nextTime = str(int(nowTine) + 1).zfill(2)
print('脚本提前', sleepTime, f'活动开始时间{nextTime}:00:00')
timeArray = time.strptime(time.strftime('%Y%m%d') + f'{nextTime}0000', "%Y%m%d%H%M%S")
timeStamp = int(time.mktime(timeArray))
while True:
reduce_time = time.time() + sleepTime - timeStamp # 差值秒
if time.time() + sleepTime - timeStamp > 0:
print(
f"当前时间{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))},,提前结束{sleepTime}s")
break
else:
if abs(reduce_time) > 2: # 如果剩余时间大于2s则睡眠剩余的一半时间
print(
f"当前时间{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))},睡眠{abs(reduce_time) / 2}s")
time.sleep(abs(reduce_time) / 2)
class MXMS:
def __init__(self,atoken):
self.headers={
'Accept': 'application/json, text/plain, */*',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090b19)XWEB/9193',
'Origin': 'https://mxsa-h5.mxbc.net',
'Referer': 'https://mxsa-h5.mxbc.net/',
'Content-Type': 'application/json;charset=UTF-8',
'Access-Token': atoken
}
def mkpayload(self,params):
params.update({'stamp':ts()})
sorted_items = sorted(params.items())
formatted_string = '&'.join([f'{k}={v}' for k, v in sorted_items])+'c274bac6493544b89d9c4f9d8d542b84'
params.update({'sign':hashlib.md5(formatted_string.encode()).hexdigest()})
return params
def info(self):
u='https://mxsa.mxbc.net/api/v1/h5/marketing/secretword/info'
p={
'marketingId': marketingId,
's': '2',
}
p=self.mkpayload(p)
r=requests.get(u,headers=self.headers,params=p)
if 'marketingId' in r.text:
rj=r.json()
print('请确定一下参数是否你填写的一致')
print('marketingId',rj['data']['marketingId'])
print(rj['data']['hintWord'])
print('-'*50)
else:
print(r.text)
print('信息获取异常')
def confirm(self):
try:
u='https://mxsa.mxbc.net/api/v1/h5/marketing/secretword/confirm'
p={"marketingId":marketingId,"round":round,'s':'2',"secretword":secretword}
p = self.mkpayload(p)
r=requests.post(u,headers=self.headers,json=p,timeout=0.75)
print(r.text)
if '已达领取上限' in r.text:
return True
except Exception as e:
print(e)
def run(self):
self.info()
wait(0.005)
print(datetime.datetime.now())
for i in range(fb_cont):
if self.confirm()==True:
return True
time.sleep(0.75)
print(datetime.datetime.now())
if __name__ == '__main__':
atoken='eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUx'#填token
marketingId='1816854086004391938'
secretword = "好一朵美丽的茉莉花"#口令
fb_cont = 300
nowTine0 = time.strftime('%H', time.localtime())
nextTime0 = str(int(nowTine0) + 1).zfill(2)
round=nextTime0+":00"
api=MXMS(atoken)
api.run()

View File

@@ -0,0 +1,346 @@
# Source: https://gitee.com/jdqlscript/toulu/blob/main/%E9%87%91%E5%BE%BD%E9%85%92%E4%BC%9A%E5%91%98.py
# Raw: https://gitee.com/jdqlscript/toulu/raw/main/%E9%87%91%E5%BE%BD%E9%85%92%E4%BC%9A%E5%91%98.py
# Repo: jdqlscript/toulu
# Path: 金徽酒会员.py
# UploadedAt: 2025-06-28T11:18:42+08:00
# SHA256: 9fd75c1dd091a8a08d0f248e161e5ce52b2e81540a29e3361d4b5549bf9a263c
# Category: web版/抓包
# Evidence: web/H5关键词 + cookie/token/header
#by:哆啦A梦
#入口:http://api.0vsp.com/h5/wxa/link?sid=25430gykJTW
#抓包ucodeprod-openapi.jinhuijiu.com.cn域名下的Authorization和serialId格式Authorization#serialId
#多账号换行分割
import os
import requests
import json
import random
import time
def get_proclamation():
primary_url = "https://github.com/3288588344/toulu/raw/refs/heads/main/tl.txt"
backup_url = "https://tfapi.cn/TL/tl.json"
try:
response = requests.get(primary_url, timeout=10)
if response.status_code == 200:
print("📢 公告信息")
print("=" * 45)
print(response.text)
print("=" * 45 + "\n")
print("公告获取成功,开始执行任务...\n")
return
except requests.exceptions.RequestException as e:
print(f"获取公告时发生错误: {e}, 尝试备用链接...")
try:
response = requests.get(backup_url, timeout=10)
if response.status_code == 200:
print("\n" + "=" * 50)
print("📢 公告信息")
print("=" * 45)
print(response.text)
print("=" * 45 + "\n")
print("公告获取成功,开始执行任务...\n")
else:
print(f"⚠️ 获取公告失败,状态码: {response.status_code}")
except requests.exceptions.RequestException as e:
print(f"⚠️ 获取公告时发生错误: {e}, 可能是网络问题或链接无效。")
def get_desensitized_phone(response_data):
"""
从响应数据中提取并脱敏账号。
"""
phone_number = response_data.get("phoneNumber", "")
if phone_number and len(phone_number) >= 11:
return phone_number[:3] + "****" + phone_number[7:]
return "未知账号"
def fetch_user_metadata():
"""
从环境变量获取多账号信息,发送请求获取用户数据元,并对账号进行脱敏处理。
"""
env_variable = "JHHY"
url = "https://ucodeprod-openapi.jinhuijiu.com.cn/user/metadata"
account_info_list = os.getenv(env_variable, "").splitlines()
if not account_info_list:
print("环境变量JHHY未设置或格式不正确")
print("=" * 45)
return
for account_info in account_info_list:
if not account_info.strip():
continue
try:
token_part, serial_part = account_info.split("#", 1)
token = token_part.strip()
serial_id = serial_part.strip()
except ValueError:
print(f"警告: 账号信息格式错误")
print("=" * 45)
continue
headers = {
'Authorization': f"Bearer {token}",
'serialId': serial_id
}
try:
response = requests.get(url, headers=headers)
response.raise_for_status()
data = response.json()
desensitized_phone = get_desensitized_phone(data)
print(f"账号 {desensitized_phone} 获取账户信息成功")
print("=" * 45)
except requests.exceptions.RequestException as e:
print(f"账号 {account_info} 获取账号信息失败: {e}")
print("=" * 45)
except ValueError as e:
print(f"账号 {account_info} 账号数据解析失败: {e}")
print("=" * 45)
def perform_check_in():
"""
发送签到请求。
"""
env_variable = "JHHY"
checkin_url = "https://ucodeprod-openapi.jinhuijiu.com.cn/lottery/checkIn"
metadata_url = "https://ucodeprod-openapi.jinhuijiu.com.cn/user/metadata"
account_info_list = os.getenv(env_variable, "").splitlines()
if not account_info_list:
print("环境变量JHHY未设置或格式不正确")
print("=" * 45)
return
# 使用字典存储每个账号的脱敏手机号
account_desensitized_info = {}
# 首先获取每个账号的脱敏手机号
for account_info in account_info_list:
if not account_info.strip():
continue
try:
token_part, serial_part = account_info.split("#", 1)
auth_token = f"Bearer {token_part.strip()}"
serial_id = serial_part.strip()
except ValueError:
print(f"警告: 账号信息格式错误")
print("=" * 45)
continue
headers = {
'Authorization': auth_token,
'serialId': serial_id,
}
try:
# 获取账号信息并脱敏
metadata_response = requests.get(metadata_url, headers=headers)
metadata_response.raise_for_status()
metadata_data = metadata_response.json()
account_desensitized_info[account_info] = get_desensitized_phone(metadata_data)
except Exception as e:
# 这里只记录获取脱敏信息的错误,不输出
account_desensitized_info[account_info] = "未知账号"
# 进行签到
for account_info in account_info_list:
if not account_info.strip():
continue
desensitized_phone = account_desensitized_info.get(account_info, "未知账号")
try:
token_part, serial_part = account_info.split("#", 1)
auth_token = f"Bearer {token_part.strip()}"
serial_id = serial_part.strip()
except ValueError:
print(f"警告: 账号信息格式错误")
print("=" * 45)
continue
params = {
'longitude': "119.24095916748047",
'latitude': "34.2840690612793"
}
payload = {
"promotionCode": "signIn",
"promotionId": 1001867,
"longitude": 119.24095916748047,
"latitude": 34.2840690612793
}
headers = {
'Content-Type': "application/json",
'Authorization': auth_token,
'serialId': serial_id,
}
try:
response = requests.post(checkin_url, params=params, data=json.dumps(payload), headers=headers)
response.raise_for_status()
response_data = response.json()
if response_data.get("success", False):
if "今日已签到" in response_data.get("message", ""):
print(f"账号 {desensitized_phone} 今日已签到")
print("=" * 45)
else:
print(f"账号 {desensitized_phone} 签到成功")
print("=" * 45)
else:
error_message = response_data.get('message', '未知错误')
if "今日已签到" in error_message:
print(f"账号 {desensitized_phone} 今日已签到")
print("=" * 45)
else:
print(f"账号 {desensitized_phone} 签到失败: {error_message}")
print("=" * 45)
except requests.exceptions.RequestException as e:
# 检查是否有返回的响应内容
if hasattr(e, 'response') and e.response is not None:
try:
error_response = e.response.json()
error_message = error_response.get('emsg', error_response.get('message', '未知错误'))
# 检查是否是已签到的错误
if "今日已签到" in error_message:
print(f"账号 {desensitized_phone} 今日已签到")
print("=" * 45)
else:
print(f"账号 {desensitized_phone} 签到失败: {error_message}")
print("=" * 45)
except ValueError:
# 如果响应内容不是JSON格式直接输出原始内容
print(f"账号 {desensitized_phone} 签到失败: {e.response.text}")
print("=" * 45)
else:
# 如果没有响应内容,输出通用错误提示
print(f"账号 {desensitized_phone} 签到失败: 网络请求失败,请检查网络连接后重试")
print("=" * 45)
def complete_tasks(task_ids):
"""
完成指定任务,并加入随机延迟
"""
url = "https://ucodeprod-openapi.jinhuijiu.com.cn/task/complete"
env_variable = "JHHY"
account_info_list = os.getenv(env_variable, "").splitlines()
if not account_info_list:
print("环境变量JHHY未设置或格式不正确")
print("=" * 45)
return
# 首先获取每个账号的脱敏手机号和认证信息
account_info_map = {}
for account_info in account_info_list:
if not account_info.strip():
continue
try:
token_part, serial_part = account_info.split("#", 1)
token = token_part.strip()
serial_id = serial_part.strip()
except ValueError:
print(f"警告: 账号信息格式错误")
print("=" * 45)
continue
# 获取账号脱敏信息
headers = {
'Authorization': f"Bearer {token}",
'serialId': serial_id,
}
try:
metadata_response = requests.get("https://ucodeprod-openapi.jinhuijiu.com.cn/user/metadata", headers=headers)
metadata_response.raise_for_status()
metadata_data = metadata_response.json()
desensitized_phone = get_desensitized_phone(metadata_data)
account_info_map[account_info] = {
'token': token,
'serial_id': serial_id,
'desensitized_phone': desensitized_phone
}
except Exception as e:
account_info_map[account_info] = {
'token': token,
'serial_id': serial_id,
'desensitized_phone': "未知账号"
}
# 对每个账号完成任务
for account_info, info in account_info_map.items():
desensitized_phone = info['desensitized_phone']
token = info['token']
serial_id = info['serial_id']
headers = {
'Content-Type': "application/json",
'Authorization': f"Bearer {token}",
'serialId': serial_id
}
for task_id in task_ids:
payload = {
"taskId": task_id,
"auto": True
}
try:
response = requests.post(url, data=json.dumps(payload), headers=headers)
# 不再调用raise_for_status因为我们需要捕获400状态码
if response.status_code == 200:
data = response.json()
# 如果任务完成成功
if data.get('success', False):
task_name = data.get('lotteryResultVo', {}).get('prizes', [{}])[0].get('remark', '未知任务')
print("=" * 45)
print(f"账号 {desensitized_phone} 任务 '{task_name}'ID: {task_id})成功完成!")
print("=" * 45)
else:
error_message = data.get('message', '未知错误')
print(f"账号 {desensitized_phone} 任务 ID {task_id} 完成失败: {error_message}")
elif response.status_code == 400:
error_data = response.json()
if error_data.get('ecode') == 41041 and "用户已完成任务" in error_data.get('emsg', ''):
print(f"账号 {desensitized_phone} 任务 ID {task_id} 已完成")
print("=" * 45)
else:
print(f"账号 {desensitized_phone} 任务 ID {task_id} 完成失败: 状态码400错误信息: {response.text}")
print("=" * 45)
else:
print(f"账号 {desensitized_phone} 任务 ID {task_id} 完成失败: 状态码 {response.status_code},响应内容: {response.text}")
print("=" * 45)
# 随机延迟0-20秒
delay_time = random.uniform(0, 20)
print(f"账号 {desensitized_phone} 在完成任务后延迟 {delay_time:.2f}")
print("=" * 45)
time.sleep(delay_time)
except requests.exceptions.RequestException as e:
print(f"账号 {desensitized_phone} 请求任务 ID {task_id} 时发生网络错误:{e}")
print("=" * 45)
except ValueError as e:
print(f"账号 {desensitized_phone} 解析任务 ID {task_id} 响应内容失败:{e}")
print("=" * 45)
# 主函数
def main():
#获取公告
get_proclamation()
# 签到任务
perform_check_in()
# 完成任务
task_ids = [100016, 100017, 10018]
complete_tasks(task_ids)
if __name__ == "__main__":
main()

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,155 @@
# Source: https://github.com/smallfawn/QLScriptPublic/blob/main/daily/51dalili.py
# Raw: https://raw.githubusercontent.com/smallfawn/QLScriptPublic/main/daily/51dalili.py
# Repo: smallfawn/QLScriptPublic
# Path: daily/51dalili.py
# UploadedAt: 2026-05-14T17:47:57+08:00
# SHA256: fea43cd7c31202227b74942f467d38857faf034019bfd0d73b876d100c47b55a
# Category: web版/账密
# Evidence: web/H5关键词 + username/password/login
#51代理每日签到
#new Env("51代理自动签到")
import requests
from bs4 import BeautifulSoup
import time
import os
def login_to_51daili():
# 从环境变量读取账号和密码
username = os.getenv('dali51user')
password = os.getenv('daili51pass')
if not username or not password:
print("错误: 请设置环境变量 dali51user 和 daili51pass")
return None
# 第一次请求获取登录令牌和PHPSESSID
print("正在获取登录令牌和PHPSESSID...")
session = requests.Session()
try:
# 初始headers仅包含User-Agent
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
# 发送GET请求获取登录页面
response = session.get('https://www.51daili.com', headers=headers, timeout=10)
response.raise_for_status()
# 从响应头中获取PHPSESSID
phpsessid = None
if 'set-cookie' in response.headers:
cookies = response.headers['set-cookie'].split(';')
for cookie in cookies:
if 'PHPSESSID' in cookie:
phpsessid = cookie.split('=')[1]
break
# 解析HTML获取令牌
soup = BeautifulSoup(response.text, 'html.parser')
token_input = soup.find('input', {'name': '__login_token__'})
if token_input:
login_token = token_input.get('value')
print(f"成功获取登录令牌: {login_token}")
else:
print("未找到登录令牌,使用默认令牌")
login_token = "14f2877f31842495ff24e3d73036158a"
if phpsessid:
print(f"成功获取PHPSESSID: {phpsessid}")
else:
print("未能从响应头中获取PHPSESSID使用默认值")
phpsessid = "qkheban0ocfthart1bk7s861kn"
# 准备登录数据和更新headers
login_data = {
'__login_token__': login_token,
'account': username,
'password': password,
'ticket': '1',
'keeplogin': '1',
'is_read': '1'
}
# 更新headers添加Cookie
headers['Cookie'] = f"PHPSESSID={phpsessid};tncode_check=ok"
print("正在尝试登录...")
time.sleep(1) # 添加短暂延迟
# 发送POST请求进行登录
login_url = 'https://www.51daili.com/index/user/login.html'
login_response = session.post(login_url, data=login_data, headers=headers, timeout=10)
login_response.raise_for_status()
# 检查登录是否成功
if login_response.status_code == 200:
print("登录请求已发送,状态码: 200")
# 尝试从响应头中查找token
print("响应头:", login_response.headers)
token = None
# 检查Set-Cookie头
if 'set-cookie' in login_response.headers:
cookies = login_response.headers['set-cookie'].split(';')
for cookie in cookies:
if 'token' in cookie.lower():
print(f"找到token cookie: {cookie}")
# 提取token值
token_parts = cookie.split('=')
if len(token_parts) >= 2:
token = token_parts[1].strip()
break
# 如果没有在Set-Cookie中找到检查其他头字段
if not token:
for key, value in login_response.headers.items():
if 'token' in key.lower():
print(f"找到token头: {key}: {value}")
token = value
break
if token:
print(f"成功获取token: {token}")
# 使用token请求签到页面
signin_headers = headers.copy()
# 添加token到Cookie
signin_headers['Cookie'] = f"{signin_headers.get('Cookie', '')}; token={token}"
signin_headers['Referer'] = 'https://www.51daili.com/'
print("正在请求签到页面...")
signin_response = session.get(
'https://www.51daili.com/index/user/signin.html',
headers=signin_headers,
timeout=10
)
signin_response.raise_for_status()
print("签到页面响应内容:")
print(signin_response.text)
else:
print("未能从登录响应中提取token")
else:
print(f"登录请求返回异常状态码: {login_response.status_code}")
return session
except requests.exceptions.RequestException as e:
print(f"请求过程中发生错误: {e}")
return None
if __name__ == "__main__":
print("51代理登录示例")
print("=" * 30)
session = login_to_51daili()
if session:
print("登录流程完成")
# 这里可以继续使用session进行后续操作
else:
print("登录失败")

View File

@@ -0,0 +1,376 @@
# Source: https://github.com/AkenClub/ken-iMoutai-Script/blob/main/5_travel.py
# Raw: https://raw.githubusercontent.com/AkenClub/ken-iMoutai-Script/main/5_travel.py
# Repo: AkenClub/ken-iMoutai-Script
# Path: 5_travel.py
# UploadedAt: 2025-11-20T09:54:34+08:00
# SHA256: df64a760c6c34918f55f14d59e7fc1125fccaa7cef71b2e6d5f0fd9bab9f9e7b
# Category: web版/账密
# Evidence: web/H5关键词 + username/password/login
"""
5、旅行 & 获取小茅运、首次分享奖励
通知:运行结果会调用青龙面板的通知渠道。
配置环境变量KEN_IMAOTAI_ENV
-- 在旧版本青龙(例如 v2.13.8)中,使用 $ 作为分隔符时会出现解析环境变量失败,此时可以把 `$` 分隔符换为 `#` 作为分隔符。
-- 📣 怕出错?**建议直接使用 `#` 作为分隔符即可** (2024-10-15 更新支持)。
内容格式为PHONE_NUMBER$USER_ID$DEVICE_ID$MT_VERSION$PRODUCT_ID_LIST$SHOP_ID^SHOP_MODE^PROVINCE^CITY$LAT$LNG$TOKEN$COOKIE
解释:手机号码$用户ID$设备ID$版本号$商品ID列表$店铺ID店铺缺货时自动采用的模式^省份^城市$纬度$经度$TOKEN$COOKIE
多个用户时使用 & 连接。
说明:^SHOP_MODE^PROVINCE^CITY 为可选
常量。
- PHONE_NUMBER: 用户的手机号码。 --- 自己手机号码
- CODE: 短信验证码。 --- 运行 1_generate_code.py 获取
- DEVICE_ID: 设备的唯一标识符。 --- 运行 1_generate_code.py 获取
- MT_VERSION: 应用程序的版本号。 --- 运行 1_generate_code.py 获取
- USER_ID: 用户的唯一标识符。 --- 运行 2_login.py 获取
- TOKEN: 用于身份验证的令牌。 --- 运行 2_login.py 获取
- COOKIE: 用于会话管理的Cookie。 --- 运行 2_login.py 获取
- PRODUCT_ID_LIST: 商品ID列表表示用户想要预约的商品。--- 运行 3_retrieve_shop_and_product_info.py 获取
- SHOP_ID: 店铺的唯一标识符。 --- 运行 3_retrieve_shop_and_product_info.py 获取
可设置为 AUTO则根据 SHOP_MODE 的值来选择店铺 ID。
- SHOP_MODE店铺缺货模式可选值为NEAREST距离最近或INVENTORY库存最多。设置该值时需要同时设置 PROVINCE 和 CITY。
非必填,但 SHOP_ID 设置 AUTO 时为必填,需要同时设置 SHOP_MODE、PROVINCE 和 CITY。
- PROVINCE: 用户所在的省份。 --- 与 3_retrieve_shop_and_product_info.py 填写的省份一致
非必填,但 SHOP_MODE 设置为 NEAREST 或 INVENTORY 时为必填。
- CITY: 用户所在的城市。 --- 与 3_retrieve_shop_and_product_info.py 填写的城市一致
非必填,但 SHOP_MODE 设置为 NEAREST 或 INVENTORY 时为必填。
- LAT: 用户所在位置的纬度。 --- 运行 3_retrieve_shop_and_product_info.py 获取
- LNG: 用户所在位置的经度。 --- 运行 3_retrieve_shop_and_product_info.py 获取
"""
import requests
import json
from datetime import datetime
import logging
import os
import ast
import io
import re
from notify import send
# 每日 9:12 执行,可自行修改。旅行一个周期 30 天,最多获取 30 小茅运,每次旅行基本可获 1 ~ 3 个小茅运,所以一天一次旅行足矣。
# 如需每日旅行多次,示例 12 9-20/4 * * * 表示 9:12 到 20:12 期间每隔 4 小时执行一次,包括 9:12 和 20:12。
# 比如 12 9,20 * * * 表示 9:12、20:12 执行。
'''
cron: 12 9 * * *
new Env("5_旅行相关")
'''
# 创建 StringIO 对象
log_stream = io.StringIO()
# 配置 logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
# 创建控制台 Handler
console_handler = logging.StreamHandler()
console_handler.setFormatter(
logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
# 创建 StringIO Handler
stream_handler = logging.StreamHandler(log_stream)
# stream_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
# 将两个 Handler 添加到 logger
logger.addHandler(console_handler)
logger.addHandler(stream_handler)
# 读取 KEN_IMAOTAI_ENV 环境变量
KEN_IMAOTAI_ENV = os.getenv('KEN_IMAOTAI_ENV', '')
# 解析 KEN_IMAOTAI_ENV 环境变量并保存到 user 列表
users = []
if KEN_IMAOTAI_ENV:
env_list = KEN_IMAOTAI_ENV.split('&')
for env in env_list:
try:
# 使用 re.split() 分割字符串,支持 '#' 和 '$'
split_values = re.split(r'[#$]', env)
PHONE_NUMBER, USER_ID, DEVICE_ID, MT_VERSION, PRODUCT_ID_LIST, SHOP_ID, LAT, LNG, TOKEN, COOKIE = split_values
user = {
'PHONE_NUMBER': PHONE_NUMBER.strip(),
'USER_ID': USER_ID.strip(),
'DEVICE_ID': DEVICE_ID.strip(),
'MT_VERSION': MT_VERSION.strip(),
'PRODUCT_ID_LIST': ast.literal_eval(PRODUCT_ID_LIST.strip()),
'SHOP_ID': SHOP_ID.strip(),
'LAT': LAT.strip(),
'LNG': LNG.strip(),
'TOKEN': TOKEN.strip(),
'COOKIE': COOKIE.strip()
}
# 检查字段是否完整且有值
required_fields = [
'PHONE_NUMBER', 'USER_ID', 'DEVICE_ID', 'MT_VERSION',
'PRODUCT_ID_LIST', 'SHOP_ID', 'LAT', 'LNG', 'TOKEN', 'COOKIE'
]
if all(user.get(field) for field in required_fields):
# 判断 PRODUCT_ID_LIST 长度是否大于 0
if len(user['PRODUCT_ID_LIST']) > 0:
users.append(user)
else:
raise Exception("🚫 预约商品列表 - PRODUCT_ID_LIST 值为空,请添加后重试")
else:
logging.info(f"🚫 用户信息不完整: {user}")
except Exception as e:
logging.info(f"🚫 KEN_IMAOTAI_ENV 环境变量格式错误: {e}")
logging.info("找到以下用户配置:")
# 输出用户信息
for index, user in enumerate(users):
logging.info(f"用户 {index + 1}: 📞 {user['PHONE_NUMBER']}")
else:
logging.info("🚫 KEN_IMAOTAI_ENV 环境变量未定义")
base_url = "https://h5.moutai519.com.cn/game"
# 生成请求头
def generate_headers(device_id, mt_version, cookie, lat=None, lng=None):
headers = {
"MT-Device-ID": device_id,
"MT-APP-Version": mt_version,
"User-Agent": "iOS;16.3;Apple;?unrecognized?",
"Cookie": f"MT-Token-Wap={cookie};MT-Device-ID-Wap={device_id};"
}
if lat and lng:
headers["MT-Lat"] = lat
headers["MT-Lng"] = lng
return headers
# 获得旅行奖励
def travel_reward(device_id, mt_version, cookie, lat, lng):
# 9-20点才能领取旅行奖励
current_hour = datetime.now().hour
if not (9 <= current_hour < 20):
raise Exception("🚫 活动未开始开始时间9点-20点")
page_data = get_user_isolation_page_data(device_id, mt_version, cookie)
logging.info(f"【旅行前】用户数据:")
status = page_data.get("status")
remain_chance = page_data.get("remainChance")
energy_reward_value = page_data.get("energy_reward_value")
energy = page_data.get("energy")
end_time = page_data.get("end_time")
# 打印旅行前获得的用户数据
log_travel_status(page_data)
# 如果存在未领取的耐力值奖励,则领取
if energy_reward_value > 0:
# 获取申购耐力值
get_energy_award(cookie, device_id, mt_version, lat, lng)
energy += energy_reward_value
# 本月剩余旅行奖励
current_period_can_convert_xmy_num = get_exchange_rate_info(
device_id, mt_version, cookie)
if current_period_can_convert_xmy_num <= 0:
raise Exception("🚫 当月无可领取奖励,直接结束旅行。")
logging.info(f"📈当月可领取小茅运数量:{current_period_can_convert_xmy_num}")
# 进行中
if status == 2:
formatted_date = datetime.fromtimestamp(
end_time / 1000).strftime("%Y-%m-%d %H:%M:%S")
raise Exception(f"🚫 旅行暂未结束,本次旅行结束时间:{formatted_date}")
# 已完成
if status == 3:
travel_reward_xmy = get_xm_travel_reward(device_id, mt_version, cookie)
logging.info(f"🎁 本次旅行将奖励小茅运:{travel_reward_xmy}")
try:
# 领取旅行获取的小茅运
reward_result = receive_reward(device_id, lat, lng, cookie,
mt_version)
logging.info(f"🎁 领取小茅运结果:{reward_result}")
except Exception as e:
logging.error(f"🚫 领取小茅运失败: {e}")
try:
# 首次分享获取耐力
share_result = share_reward(device_id, lat, lng, cookie,
mt_version)
# 如果分享成功,则耐力值加 10用于后续判断是否足够耐力值旅行
energy += 10
logging.info(f"🎁 分享奖励结果:{share_result}")
except Exception as e:
logging.error(f"🚫 分享奖励失败: {e}")
# 本次旅行奖励领取后, 当月实际剩余旅行奖励
if travel_reward_xmy > current_period_can_convert_xmy_num:
raise Exception("🚫 当月无可领取奖励,当月不再旅行")
# 如果是未开始状态或者 status 已完成且领取了奖励,则开始新的旅行
if remain_chance < 1:
raise Exception("🚫 当日旅行次数已耗尽")
elif energy < 100:
raise Exception(f"🚫 无法旅行耐力不足100, 当前耐力值:{energy}")
else:
# 小茅运旅行活动
start_travel(device_id, mt_version, cookie)
def log_travel_status(page_data):
status = page_data.get("status")
remain_chance = page_data.get("remainChance")
xmy = page_data.get("xmy")
energy = page_data.get("energy")
energy_reward_value = page_data.get("energy_reward_value")
logging.info(
f"🌟当前旅行状态: {'未开始' if status == 1 else '进行中' if status == 2 else '已完成'}"
)
logging.info(f"📅当日剩余旅行次数: {remain_chance}")
logging.info(f"💫小茅运: {xmy}")
logging.info(f"💪耐力值: {energy}")
logging.info(f"🎁未领取的耐力值奖励: {energy_reward_value}")
# 领取旅行获取的小茅运
def receive_reward(device_id, lat, lng, cookie, mt_version):
url = f"{base_url}/xmTravel/receiveReward"
headers = generate_headers(device_id, mt_version, cookie, lat, lng)
response = requests.post(url, headers=headers)
body = response.json()
if body.get("code") != 2000:
raise Exception(body)
return body.get("data")
# 领取每日首次分享获取耐力
def share_reward(device_id, lat, lng, cookie, mt_version):
url = f"{base_url}/xmTravel/shareReward"
headers = generate_headers(device_id, mt_version, cookie, lat, lng)
response = requests.post(url, headers=headers)
body = response.json()
if body.get("code") != 2000:
raise Exception(body)
return body.get("data")
# 开始旅行
def start_travel(device_id, mt_version, cookie):
url = f"{base_url}/xmTravel/startTravel"
headers = generate_headers(device_id, mt_version, cookie)
response = requests.post(url, headers=headers)
body = response.json()
if body.get("code") != 2000:
raise Exception(f"🚫 开始旅行失败:{body.get('message')}")
start_travel_timestamp = body.get("data").get("startTravelTs", 0)
start_travel_str = datetime.fromtimestamp(
start_travel_timestamp / 1000).strftime("%Y-%m-%d %H:%M:%S")
logging.info(f"✅ 开始旅行成功,旅行开始时间:{start_travel_str}")
# 查询 可获取小茅运
def get_xm_travel_reward(device_id, mt_version, cookie):
url = f"{base_url}/xmTravel/getXmTravelReward"
headers = generate_headers(device_id, mt_version, cookie)
response = requests.get(url, headers=headers)
body = response.json()
if body.get("code") != 2000:
raise Exception(f"🚫 {body.get('message')}")
# 例如 1.95,可能会返回 None
travel_reward_xmy = body.get("data").get("travelRewardXmy")
return travel_reward_xmy if travel_reward_xmy is not None else 0
# 获取用户数据,查询旅行状态、剩余可领取小茅运数量等
def get_user_isolation_page_data(device_id, mt_version, cookie):
url = f"{base_url}/isolationPage/getUserIsolationPageData"
headers = generate_headers(device_id, mt_version, cookie)
params = {"__timestamp": int(datetime.now().timestamp())}
response = requests.get(url, headers=headers, params=params)
body = response.json()
if body.get("code") != 2000:
raise Exception(f"🚫 获取用户数据 失败:{body.get('message')}")
data = body.get("data")
# xmy: 小茅运值
xmy = data.get("xmy")
# energy: 耐力值
energy = data.get("energy")
xm_travel = data.get("xmTravel")
energy_reward = data.get("energyReward")
# status: 1. 未开始 2. 进行中 3. 已完成
status = xm_travel.get("status")
# travelEndTime: 旅行结束时间
travel_end_time = xm_travel.get("travelEndTime")
# remainChance 今日剩余旅行次数
remain_chance = xm_travel.get("remainChance")
# 可领取申购耐力值奖励
energy_value = energy_reward.get("value")
end_time = travel_end_time * 1000
result = {
"remainChance": remain_chance,
"status": status,
"xmy": xmy,
"energy_reward_value": energy_value,
"energy": energy,
"end_time": end_time
}
return result
# 获取申购耐力值
def get_energy_award(cookie, device_id, mt_version, lat, lng):
url = f"{base_url}/isolationPage/getUserEnergyAward"
headers = generate_headers(device_id, mt_version, cookie, lat, lng)
response = requests.post(url, headers=headers)
body = response.text
json_object = json.loads(body)
if json_object.get("code") != 200:
raise Exception(f"🚫 {json_object.get('message')}")
return body
# 获取本月剩余奖励耐力值
def get_exchange_rate_info(device_id, mt_version, cookie):
url = f"{base_url}/synthesize/exchangeRateInfo"
headers = generate_headers(device_id, mt_version, cookie)
params = {"__timestamp": int(datetime.now().timestamp())}
response = requests.get(url, headers=headers, params=params)
body = response.json()
if body.get("code") != 2000:
raise Exception(f"🚫 {body.get('message')}")
# 返回本月剩余奖励耐力值
return body.get("data").get("currentPeriodCanConvertXmyNum")
if __name__ == "__main__":
for user in users:
logging.info('--------------------------')
logging.info(f"🧾 用户:{user['PHONE_NUMBER']},执行旅行")
try:
travel_reward(user['DEVICE_ID'], user['MT_VERSION'],
user['COOKIE'], user['LAT'], user['LNG'])
except Exception as e:
logging.error(f"🚫 旅行失败: {e}")
finally:
page_data = get_user_isolation_page_data(user['DEVICE_ID'],
user['MT_VERSION'],
user['COOKIE'])
logging.info(f"【旅行后】用户数据:")
log_travel_status(page_data)
logging.info('--------------------------')
logging.info("✅ 所有用户旅行完成")
log_contents = log_stream.getvalue()
send("i茅台旅行-日志:", log_contents)

View File

@@ -0,0 +1,282 @@
# Source: https://github.com/AkenClub/ken-iMoutai-Script/blob/main/99_check_for_validity.py
# Raw: https://raw.githubusercontent.com/AkenClub/ken-iMoutai-Script/main/99_check_for_validity.py
# Repo: AkenClub/ken-iMoutai-Script
# Path: 99_check_for_validity.py
# UploadedAt: 2025-11-20T09:54:34+08:00
# SHA256: b7dac1c2a41406aad9c26c8d92adf0b74a6bcbae0947eb820a674bd18047d6c4
# Category: web版/账密
# Evidence: web/H5关键词 + username/password/login
"""
99、检查 TOKEN、COOKIE 有效期
*** 需要安装依赖 PyJWT ***
通知:运行结果会调用青龙面板的通知渠道。
配置环境变量KEN_IMAOTAI_ENV
-- 在旧版本青龙(例如 v2.13.8)中,使用 $ 作为分隔符时会出现解析环境变量失败,此时可以把 `$` 分隔符换为 `#` 作为分隔符。
-- 📣 怕出错?**建议直接使用 `#` 作为分隔符即可** (2024-10-15 更新支持)。
内容格式为PHONE_NUMBER$USER_ID$DEVICE_ID$MT_VERSION$PRODUCT_ID_LIST$SHOP_ID^SHOP_MODE^PROVINCE^CITY$LAT$LNG$TOKEN$COOKIE
解释:手机号码$用户ID$设备ID$版本号$商品ID列表$店铺ID店铺缺货时自动采用的模式^省份^城市$纬度$经度$TOKEN$COOKIE
多个用户时使用 & 连接
说明:^SHOP_MODE^PROVINCE^CITY 为可选
常量。
- PHONE_NUMBER: 用户的手机号码。 --- 自己手机号码
- CODE: 短信验证码。 --- 运行 1_generate_code.py 获取
- DEVICE_ID: 设备的唯一标识符。 --- 运行 1_generate_code.py 获取
- MT_VERSION: 应用程序的版本号。 --- 运行 1_generate_code.py 获取
- USER_ID: 用户的唯一标识符。 --- 运行 2_login.py 获取
- TOKEN: 用于身份验证的令牌。 --- 运行 2_login.py 获取
- COOKIE: 用于会话管理的Cookie。 --- 运行 2_login.py 获取
- PRODUCT_ID_LIST: 商品ID列表表示用户想要预约的商品。--- 运行 3_retrieve_shop_and_product_info.py 获取
- SHOP_ID: 店铺的唯一标识符。 --- 运行 3_retrieve_shop_and_product_info.py 获取
可设置为 AUTO则根据 SHOP_MODE 的值来选择店铺 ID。
- SHOP_MODE店铺缺货模式可选值为NEAREST距离最近或INVENTORY库存最多。设置该值时需要同时设置 PROVINCE 和 CITY。
非必填,但 SHOP_ID 设置 AUTO 时为必填,需要同时设置 SHOP_MODE、PROVINCE 和 CITY。
- PROVINCE: 用户所在的省份。 --- 与 3_retrieve_shop_and_product_info.py 填写的省份一致
非必填,但 SHOP_MODE 设置为 NEAREST 或 INVENTORY 时为必填。
- CITY: 用户所在的城市。 --- 与 3_retrieve_shop_and_product_info.py 填写的城市一致
非必填,但 SHOP_MODE 设置为 NEAREST 或 INVENTORY 时为必填。
- LAT: 用户所在位置的纬度。 --- 运行 3_retrieve_shop_and_product_info.py 获取
- LNG: 用户所在位置的经度。 --- 运行 3_retrieve_shop_and_product_info.py 获取
"""
import datetime
import time
import requests
import json
import os
import ast
import io
import jwt
import logging
import re
from notify import send
# 每日 18:05 定时检查并通知
'''
cron: 05 18 * * *
new Env("99_检查 TOKEN、COOKIE 有效期")
'''
# 创建 StringIO 对象
log_stream = io.StringIO()
# 配置 logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
# 创建控制台 Handler
console_handler = logging.StreamHandler()
console_handler.setFormatter(
logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
# 创建 StringIO Handler
stream_handler = logging.StreamHandler(log_stream)
# stream_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
# 将两个 Handler 添加到 logger
logger.addHandler(console_handler)
logger.addHandler(stream_handler)
# 调试模式
DEBUG = False
# 读取 KEN_IMAOTAI_ENV 环境变量
KEN_IMAOTAI_ENV = os.getenv('KEN_IMAOTAI_ENV', '')
# 解析 KEN_IMAOTAI_ENV 环境变量并保存到 user 列表
users = []
if KEN_IMAOTAI_ENV:
env_list = KEN_IMAOTAI_ENV.split('&')
for env in env_list:
try:
# 使用 re.split() 分割字符串,支持 '#' 和 '$'
split_values = re.split(r'[#$]', env)
PHONE_NUMBER, USER_ID, DEVICE_ID, MT_VERSION, PRODUCT_ID_LIST, SHOP_INFO, LAT, LNG, TOKEN, COOKIE = split_values
SHOP_MODE = ''
PROVINCE = ''
CITY = ''
if '^' in SHOP_INFO:
parts = SHOP_INFO.split('^')
if len(parts) > 1:
# 检测 parts 长度是否为 4否则抛出异常
if len(parts) != 4:
raise Exception(
"🚫 店铺缺货模式值错误,请检查是否为 SHOP_ID^SHOP_MODE^PROVINCE^CITY"
)
SHOP_ID, SHOP_MODE, PROVINCE, CITY = parts
# 检测 SHOP_MODE 是否为 NEAREST 或 INVENTORY
if SHOP_MODE not in ['NEAREST', 'INVENTORY', '']:
raise Exception(
"🚫 店铺缺货模式值错误,请检查 SHOP_MODE 值是否为 NEAREST<默认> 距离最近) 或 INVENTORY库存最多 或 空字符串(不选择其他店铺)"
)
# 如果 SHOP_MODE 值合法,则需要配合检测 PROVINCE 和 CITY 是否为空(接口需要用到这些值)
if not PROVINCE or not CITY:
raise Exception(
"🚫 店铺缺货模式值为 NEAREST 或 INVENTORY 时,需要同时设置 PROVINCE 和 CITY"
)
else:
logging.warning(
"🚨🚨 建议根据环境变量格式,设置 SHOP_ID^SHOP_MODE^PROVINCE^CITY 值,否则无法在指定店铺缺货时自动预约其他店铺!🚨🚨"
)
# 如果 SHOP_INFO 没有 ^ 符号,则 SHOP_ID 为 SHOP_INFO
SHOP_ID = SHOP_INFO
# 如果 SHOP_ID 为 AUTO检查 SHOP_MODE 是否为空
if SHOP_ID == 'AUTO' and not SHOP_MODE:
raise Exception(
"🚫 店铺缺货模式值错误SHOP_ID 值为 AUTO 时,需设置 SHOP_MODE、PROVINCE 和 CITY 值 "
)
user = {
'PHONE_NUMBER': PHONE_NUMBER.strip(),
'USER_ID': USER_ID.strip(),
'DEVICE_ID': DEVICE_ID.strip(),
'MT_VERSION': MT_VERSION.strip(),
'PRODUCT_ID_LIST': ast.literal_eval(PRODUCT_ID_LIST.strip()),
'SHOP_ID': SHOP_ID.strip(),
'SHOP_MODE': SHOP_MODE.strip(),
'PROVINCE': PROVINCE.strip(),
'CITY': CITY.strip(),
'LAT': LAT.strip(),
'LNG': LNG.strip(),
'TOKEN': TOKEN.strip(),
'COOKIE': COOKIE.strip()
}
# 检查字段是否完整且有值,不检查 SHOP_MODE、PROVINCE、CITY 字段PROVINCE 和 CITY 用于 SHOP_MODE 里,而 SHOP_MODE 可选)
required_fields = [
'PHONE_NUMBER', 'USER_ID', 'DEVICE_ID', 'MT_VERSION',
'PRODUCT_ID_LIST', 'SHOP_ID', 'LAT', 'LNG', 'TOKEN', 'COOKIE'
]
if all(user.get(field) for field in required_fields):
# 判断 PRODUCT_ID_LIST 长度是否大于 0
if len(user['PRODUCT_ID_LIST']) > 0:
users.append(user)
else:
raise Exception("🚫 预约商品列表 - PRODUCT_ID_LIST 值为空,请添加后重试")
else:
logging.info(f"🚫 用户信息不完整: {user}")
except Exception as e:
errText = f"🚫 KEN_IMAOTAI_ENV 环境变量格式错误: {e}"
send("i茅台预约日志", errText)
raise Exception(errText)
logging.info("找到以下用户配置:")
# 输出用户信息
for index, user in enumerate(users):
if DEBUG:
logging.info(f"用户 {index + 1}: {user}")
continue
logging.info(f"用户 {index + 1}: 📞 {user['PHONE_NUMBER']}")
else:
errText = "🚫 KEN_IMAOTAI_ENV 环境变量未定义"
send("i茅台预约日志", errText)
raise Exception(errText)
# 生成请求头
def generate_headers(device_id, mt_version, cookie, lat=None, lng=None):
headers = {
"MT-Device-ID": device_id,
"MT-APP-Version": mt_version,
"User-Agent": "iOS;16.3;Apple;?unrecognized?",
"Cookie": f"MT-Token-Wap={cookie};MT-Device-ID-Wap={device_id};"
}
if lat and lng:
headers["MT-Lat"] = lat
headers["MT-Lng"] = lng
return headers
# 检查 JWT 有效期
def check_jwt(jwt_value):
# 解码 JWT
try:
# 注意:此处的密钥应与生成 JWT 时使用的密钥一致
decoded = jwt.decode(jwt_value, options={"verify_signature": False})
# 获取 exp 时间戳
exp_timestamp = decoded.get("exp")
if exp_timestamp:
# 转换为日期
exp_date = datetime.datetime.fromtimestamp(
exp_timestamp, tz=datetime.timezone.utc)
# 获取当前时间
current_date = datetime.datetime.now(datetime.timezone.utc)
exp_date_str = exp_date.strftime('%Y-%m-%d %H:%M:%S')
# 判断是否过期
if current_date > exp_date:
logging.info(
f"⚠️ TOKEN 已过期: {exp_date_str},请重新执行 第1、2步 脚本获取最新 TOKEN、COOKIE 值。"
)
else:
logging.info(f"✅ TOKEN 有效: 过期时间为 {exp_date_str}")
else:
logging.warning("⚠️ TOKEN 中没有 'exp' 字段")
except jwt.DecodeError:
logging.error("⚠️ TOKEN 解析失败")
# 获取用户信息 测试 API 是否调用成功
def check_api(cookie, device_id, mt_version, lat, lng):
global DEBUG
try:
timestamp = str(
int(time.mktime(datetime.date.today().timetuple())) * 1000)
url = f"https://h5.moutai519.com.cn/game/userinfo?__timestamp={timestamp}&"
headers = generate_headers(device_id, mt_version, cookie, lat, lng)
response = requests.post(url, headers=headers)
progress_data = json.loads(response.text)
if progress_data.get("code") != 2000:
message = progress_data.get("message")
raise Exception({message})
if DEBUG:
logging.info(f"✅ 测试通过: {progress_data}")
return
logging.info("✅ 测试通过")
except Exception as e:
logging.error(f"🚫 测试不通过: {e}")
logging.error(f"⚠️ TOKEN、COOKIE 值真的失效啦!建议及时更新!否则无法正常预约和旅行咯!")
if __name__ == "__main__":
logging.info('--------------------------')
logging.info(
'💬 TOKEN 有效期时间不一定准确,一般上下浮动 6 小时,以真实 API 连接的结果为准。同时建议临近有效期时手动更新 TOKEN、COOKIE不用等到过期再去更新。'
)
for user in users:
try:
logging.info('--------------------------')
logging.info(f"📞 用户 {user['PHONE_NUMBER']} 开始检查")
logging.info(f"🔍 开始检查 TOKEN 有效期")
check_jwt(user['TOKEN'])
logging.info(f"🔍 开始测试真实 API 连接")
check_api(user['COOKIE'], user['DEVICE_ID'], user['MT_VERSION'],
user['LAT'], user['LNG'])
except Exception as e:
logging.error(
f"🚫 用户 {user['PHONE_NUMBER']} 检查异常: {e},请手动执行 4、5 脚本,检查 TOKEN、COOKIE 是否过期"
)
logging.info('--------------------------')
logging.info("✅ 所有用户检查完成")
log_contents = log_stream.getvalue()
send("i茅台 TOKEN、COOKIE 有效期检查日志:", log_contents)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,888 @@
// # Source: https://github.com/imoki/sign_script/blob/main/polymerization/PUSH.js
// # Raw: https://raw.githubusercontent.com/imoki/sign_script/main/polymerization/PUSH.js
// # Repo: imoki/sign_script
// # Path: polymerization/PUSH.js
// # UploadedAt: 2025-08-25T21:29:14+08:00
// # SHA256: 03f616e38dec8c5f1c9aaf545820f572e718dde1c354f8d67974394f4fc42e4f
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
/*
脚本名称PUSH.js
脚本兼容: airsript 1.0、airscript 2.0
更新时间20241226
具备功能:
1. 多渠道推送
2. 独立推送、消息池推送
3. 消息过期判断
4. 长度分片、分隔符分片
5. 优先级排序
6. 单日多次推送
7. 消息池内格式自动排版
支持推送:
bark、pushplus、Server酱、邮箱
钉钉、discord、企业微信
息知、即时达、wxpusher
*/
var sheetNameConfig = "CONFIG"; // 总配置表
var sheetNamePush = "PUSH"; // 推送表名称
var sheetNameEmail = "EMAIL"; // 邮箱表
var flagSubConfig = 0; // 激活分配置工作表标志
var flagConfig = 0; // 激活主配置工作表标志
var flagPush = 0; // 激活推送工作表标志
var line = 21; // 指定读取从第2行到第line行的内容
var message = ""; // 待发送的消息
var messagePushHeader = ""; // 存放在总消息的头部默认是pushHeader,如【xxxx】
var pushHeader = ""
var separator = "##########MOKU##########" // 分割符分割消息。可用于PUSH.js灵活推送
var maxMessageLength = 512; // 设置最大长度,超过这个长度则分片发送
var messageDistance = 256; // 消息距离用于匹配100字符内最近的行
var version = 1 // 版本类型自动识别并适配。默认为airscript 1.0否则为2.0Beta
var separator = "##########MOKU##########" // 分割符分割消息。可用于PUSH.js灵活推送
var maxMessageLength = 400; // 设置最大长度,超过这个长度则分片发送
var messageDistance = 100; // 消息距离用于匹配100字符内最近的行
var jsonPush = [
{ name: "bark", key: "xxxxxx", flag: "0" },
{ name: "pushplus", key: "xxxxxx", flag: "0" },
{ name: "ServerChan", key: "xxxxxx", flag: "0" },
{ name: "email", key: "xxxxxx", flag: "0" },
{ name: "dingtalk", key: "xxxxxx", flag: "0" },
{ name: "discord", key: "xxxxxx", flag: "0" },
{ name: "qywx", key: "xxxxxx", flag: "0" },
{ name: "xizhi", key: "xxxxxx", flag: "0" },
{ name: "jishida", key: "xxxxxx", flag: "0" },
{ name: "wxpusher", key: "xxxxxx", flag: "0" },
]; // 推送数据flag=1则推送
var jsonEmail = {
server: "",
port: "",
sender: "",
authorizationCode: "",
};
// airscript检测版本
function checkVesion(){
try{
let temp = Application.Range("A1").Text;
Application.Range("A1").Value = temp
console.log("😶‍🌫️ 检测到当前airscript版本为1.0进行1.0适配")
}catch{
console.log("😶‍🌫️ 检测到当前airscript版本为2.0进行2.0适配")
version = 2
}
}
// 消息分片,以换行符为分割,自动检索切割位置符号
function splitMessage(data) {
let chunks = [];
let start = 0;
while (start < data.length) {
let end = start + maxMessageLength;
if (end >= data.length) {
chunks.push(data.slice(start));
break;
}
// 查找距离 maxMessageLength 在 20 字符以内的最近的换行符
let newlineIndex = data.lastIndexOf('【', end + parseInt(messageDistance));
// console.log(newlineIndex)
if (newlineIndex > start && newlineIndex >= end - parseInt(messageDistance)) {
end = newlineIndex;
}
chunks.push(data.slice(start, end));
start = end;
}
return chunks
}
// 纯长度分片
// function splitMessage(data) {
// let chunks = [];
// for (let i = 0; i < data.length; i += maxMessageLength) {
// chunks.push(data.slice(i, i + maxMessageLength));
// }
// return chunks
// // chunks.forEach((chunk, index) => {
// // // let message = `${index + 1}/${chunks.length}: ${chunk}`;
// // bark(message, key)
// // });
// }
// 去除首尾换行和空格
function customTrim(str) {
return str.replace(/^\s+|\s+$/g, '');
}
// 获取时间
function getDate(){
let currentDate = new Date();
// 2024/07/04
// currentDate = currentDate.getFullYear() + '' + (currentDate.getMonth() + 1).toString().padStart(2, '0') + '' + currentDate.getDate().toString().padStart(2, '0');
currentDate = currentDate.getFullYear() + '/' + (currentDate.getMonth() + 1).toString() + '/' + currentDate.getDate().toString();
return currentDate
}
checkVesion()
// 当天时间
var todayDate = getDate()
getPush() // 读取推送配置
var msgArray = [] // 存放消息内容
getMessage() // 读取消息配置
sendNotify() // 消息推送
// console.log(jsonPush)
// console.log(jsonEmail)
// 激活工作表函数
function ActivateSheet(sheetName) {
let flag = 0;
try {
// 激活工作表
let sheet = Application.Sheets.Item(sheetName);
sheet.Activate();
console.log("🥚 激活工作表:" + sheet.Name);
flag = 1;
} catch {
flag = 0;
console.log("🍳 无法激活工作表,工作表可能不存在");
}
return flag;
}
// 对推送数据进行处理
function jsonPushHandle(pushName, pushFlag, pushKey) {
let length = jsonPush.length;
for (let i = 0; i < length; i++) {
if (jsonPush[i].name == pushName) {
if (pushFlag == "是") {
jsonPush[i].flag = 1;
jsonPush[i].key = pushKey;
}else{ // 不推送
jsonPush[i].flag = 0;
jsonPush[i].key = pushKey;
}
}
}
}
// 读取推送配置
function getPush(){
flagPush = ActivateSheet(sheetNamePush); // 激活推送表
// 推送工作表存在
if (flagPush == 1) {
console.log("🍳 开始读取推送工作表");
let pushName; // 推送类型
let pushKey;
let pushFlag; // 是否推送标志
for (let i = 2; i <= line; i++) {
// 从工作表中读取推送数据
pushName = Application.Range("A" + i).Text;
pushKey = Application.Range("B" + i).Text;
pushFlag = Application.Range("C" + i).Text;
if (pushName == "") {
// 如果为空行,则提前结束读取
break;
}
jsonPushHandle(pushName, pushFlag, pushKey);
}
// console.log(jsonPush)
}
// 邮箱配置函数
emailConfig();
}
// 休眠
function sleep(d) {
for (var t = Date.now(); Date.now() - t <= d; );
}
// 推送优先级排序
function sortMsgArrayByPriority(msgArray) {
return msgArray.sort((a, b) => b.priority - a.priority);
}
// 读取消息配置
function getMessage(){
flagConfig = ActivateSheet(sheetNameConfig); // 激活主配置表
// 主配置工作表存在
if (flagConfig == 1) {
console.log("🍳 开始读取主配置表");
// var configTitleMapping = {
// '工作表的名称': 'name',
// '备注': 'note',
// '只推送失败消息(是/否)': 'pushFailureOnly',
// '推送昵称(是/否)': 'pushNickname',
// '是否存活': 'isAlive',
// '更新时间': 'updateTime',
// '消息': 'message',
// '推送时间': 'pushTime',
// '推送方式': 'pushMethod',
// '是否通知': 'notify',
// '加入消息池': 'addToMessagePool',
// '推送优先级': 'pushPriority',
// '当日可推送次数': 'dailyPushLimit',
// '当日剩余推送次数': 'remainingDailyPushes',
// };
for (let i = 2; i <= 100; i++) {
// 从工作表中读取推送数据
let msgDict = {
"pos": 0, // 位置记录在表格的第几行从2开始
"name": "", // 名称
"note": "", // 备注
// "onlyError": "", // 只推送错误消息
"update":"", // 脚本更新时间,即脚本是否已执行
"msg" : "", // 待推送消息
"date": "", // 推送时间,即单天是否已推送
"methodPush":"", // 推送方式
"flagPush" : "", // 是否通知
"pool":"", // 是否加入消息池,加入消息池的都会整合为一条消息统一推送
"priority":"0", // 优先级,根据优先级来对消息前后顺序进行排序
"dailyPushLimit":1, // 当日可推送次数
"remainingDailyPushes": "" // 当日剩余推送次数
}
msgDict.pos = i // 位置在第几行从2开始
msgDict["name"] = Application.Range("A" + i).Text; // 工作表名称
msgDict.note = Application.Range("B" + i).Text; // 备注
// msgDict.onlyError = Application.Range("C" + i).Text; // 只推送错误消息
msgDict.update = Application.Range("F" + i).Text; // 脚本更新时间,即脚本是否已执行
msgDict.msg = Application.Range("G" + i).Text; // 待推送消息
msgDict.date = Application.Range("H" + i).Text; // 推送时间,即单天是否已推送
msgDict.methodPush = Application.Range("I" + i).Text; // 推送方式
msgDict.flagPush = Application.Range("J" + i).Text; // 是否通知
msgDict.pool = Application.Range("K" + i).Text; // 是否加入消息池,加入消息池的都会整合为一条消息统一推送
msgDict.priority = Application.Range("L" + i).Text; // 优先级,根据优先级来对消息前后顺序进行排序
msgDict.dailyPushLimit = Application.Range("M" + i).Text; // 当日可推送次数
msgDict.remainingDailyPushes = Application.Range("N" + i).Text; // 当日剩余推送次数
if (msgDict.name == "") {
// 如果为空行,则提前结束读取
break; // 提前退出,提高效率
}
// console.log(msgDict)
msgArray.push(msgDict)
}
// 根据优先级排序,值大的排前面
msgArray = sortMsgArrayByPriority(msgArray)
// console.log(msgArray)
}
}
// 将日期转换为一串可比较的数字 2024/9/17 -> 20240917。隔月存在问题
function convertToDateNumber(dateString) {
const [year, month, day] = dateString.split('/').map(Number);
return year * 10000 + (month * 100) + day;
}
// 计算两个日期之间的距离
function dateDistance(oldDate, newDate){
// 定义两个日期2024/9/17
let date1 = new Date(oldDate);
let date2 = new Date(newDate);
let diffInMilliseconds = date2 - date1; // 计算两个日期之间的毫秒差
let diffInDays = diffInMilliseconds / (1000 * 60 * 60 * 24); // 将毫秒差转换为天数
return diffInDays // 返回天数 0-n
}
// 推送器
function sendMessage(msgCurrentDict = "", msgPool = "", msgAppend = ""){
let shards = [] // 分割符分片数据,一级分割
if(msgCurrentDict != ""){
// 独立推送
console.log("🚀 消息推送:" + msgCurrentDict.note)
// 消息分片
// 方式1按照指定分割符分片 separator
shards = msgCurrentDict.msg.split(separator); // // 分割符分片数据,一级分割
let chunks = []
for(let i=0; i<shards.length; i++){
strTrim = customTrim(shards[i]) + "\n\n" // 消息内间隔。去除首位空格和换行然后在末尾拼接2个换行。
chunks = splitMessage(strTrim) // 长度限制分割,二级分割
// console.log(chunks)
// console.log(chunks.length)
for (let j = 0; j < chunks.length; j++) {
pushMessage(chunks[j], msgCurrentDict.methodPush, "【" + msgCurrentDict.note + "】",)
sleep(2000)
}
}
}else{
// 消息池推送
console.log("🚀 艾默库消息池推送")
// 消息分片
// 方式1按照指定分割符分片 separator
msgPool += msgAppend // 追加数据
shards = msgPool.split(separator);
let chunks = []
for(let i=0; i<shards.length;i++){
strTrim = customTrim(shards[i]) + "\n\n" // 消息内间隔。去除首位空格和换行然后在末尾拼接2个换行
chunks = splitMessage(strTrim)
// console.log(chunks)
// console.log(chunks.length)
for (let j = 0; j < chunks.length; j++) {
// console.log(chunks[i])
pushMessage(chunks[j], "@all", "【" + "艾默库消息池" + "】\n")
sleep(2000)
}
}
}
}
// 发送消息
function sendNotify(){
ActivateSheet(sheetNameConfig); // 激活主配置表
// console.log("🍳 开始发送消息");
let msgCurrentDict = ""
let msgPool = ""
let msgAppend = "" // 追加到消息池末尾的信息
let shards = [] // 分割符分片数据,一级分割
for (let i = 0; i < msgArray.length; i++) {
msgCurrentDict = msgArray[i]
// console.log(msgCurrentDict)
// {"name":"aliyundrive_multiuser","note":"阿里云盘(多用户版)","msg":"","date":"","methodPush":"","flagPush":"@all"}
// 从读取推送数据
// if(msgCurrentDict.flagPush == "是" && msgCurrentDict.update != "" && msgCurrentDict.date == ""){ // 第一次执行时更新时间不为空,推送时间为空
// }
// console.log(msgCurrentDict.date)
// console.log(todayDate)
// 消息池的先不推送,最后统一推送
// 1. 消息池判断,使得消息池内的消息最后统一推送
// 2. 是否推送判断,使得仅勾选是的才进行推送
// 3. 推送时间判断使得仅今天未推送才进行推送如果今天已推送就不再推送了目的是可以一天不同时间段任意设置多个定时PUSH推送脚本
// 4. 过期消息判断如果运行时间是2天前的消息就不再推送了
// 5. 时间不一致判断,更新时间和推送时间不一致才推送,此判断也可以使昨天成功且今天未成功的情况不推送。即只有今天成功且未推送的情况才进行推送
// 6. 时间一致额外推送判断。即一天多次运行,并多次推送
// console.log(msgCurrentDict.update) 2024/9/29 脚本运行时间
// console.log(msgCurrentDict.date) // 2024/10/30 上一次推送时间
// todayDate = "2024/11/1" // 测试
// // 计算是否能额外推送
// msgDict.dailyPushLimit // 当日可推送次数
// msgDict.remainingDailyPushes // 当日剩余推送次数
// 1. 消息池判断
// 2. 是否推送判断
if(msgCurrentDict.pool == "否" && msgCurrentDict.flagPush == "是")
{
// 独立推送
// 3.进行消息检测
// 4.进行过期消息判断
if(msgCurrentDict.msg != "" && dateDistance(msgCurrentDict.update, todayDate) <= 2 && dateDistance(msgCurrentDict.update, todayDate) >= 0)
{
// 5.时间不一致判断
if(msgCurrentDict.update != msgCurrentDict.date && msgCurrentDict.date != todayDate )
{
// 时间不一致说明未推送。消息为空不进行推送。今天未推送
// 进行推送
// pushMessage(msgCurrentDict.msg, msgCurrentDict.methodPush, "【" + msgCurrentDict.note + "】",)
sendMessage(msgCurrentDict)
// 写入推送的时间
// Application.Range("H" + (i + 2)).Value = todayDate
if(version == 1){
Application.Range("H" + msgCurrentDict.pos).Value = todayDate
// 更新推送次数。读取当日可推送次数,写入当日剩余推送次数。写入当日剩余推送次数 = 当日可推送次数 - 1
Application.Range("N" + msgCurrentDict.pos).Value = parseInt(msgCurrentDict.dailyPushLimit) - 1
}else{
Application.Range("H" + msgCurrentDict.pos).Value2 = todayDate
// 更新推送次数。读取当日可推送次数,写入当日剩余推送次数。写入当日剩余推送次数 = 当日可推送次数 - 1
Application.Range("N" + msgCurrentDict.pos).Value2 = parseInt(msgCurrentDict.dailyPushLimit) - 1
}
}else{
// 6.时间一致额外推送判断
// 时间一致,计算是否推送
if(parseInt(msgCurrentDict.remainingDailyPushes) > 0){
sendMessage(msgCurrentDict)
if(version == 1){
// 写入推送的时间
Application.Range("H" + msgCurrentDict.pos).Value = todayDate
// 更新推送次数。读取当日可推送次数,写入当日剩余推送次数。写入当日剩余推送次数 = 当日可推送次数 - 1
Application.Range("N" + msgCurrentDict.pos).Value = parseInt(msgCurrentDict.remainingDailyPushes) - 1
}else{
// 写入推送的时间
Application.Range("H" + msgCurrentDict.pos).Value2 = todayDate
// 更新推送次数。读取当日可推送次数,写入当日剩余推送次数。写入当日剩余推送次数 = 当日可推送次数 - 1
Application.Range("N" + msgCurrentDict.pos).Value2 = parseInt(msgCurrentDict.remainingDailyPushes) - 1
}
}
}
}
}else{
if(msgCurrentDict.pool == "是" && msgCurrentDict.flagPush == "是"){
// 消息池推送
// 3.进行消息检测
// 4.进行过期消息判断
if(msgCurrentDict.msg != "" && dateDistance(msgCurrentDict.update, todayDate) <= 2 && dateDistance(msgCurrentDict.update, todayDate) >= 0)
{
// 5.时间不一致判断
if(msgCurrentDict.update != msgCurrentDict.date && msgCurrentDict.date != todayDate ){
// 时间不一致说明未推送。
// 进行消息池生成
// 对分片消息进行特异化处理,只取第一条分片,后续分片放在消息池的末尾
shards = msgCurrentDict.msg.split(separator); // // 分割符分片数据,一级分割
// console.log(shards)
msgPool += "【" + msgCurrentDict.note + "】" + shards[0] + "\n" // 取分割后的第一条
for(let j=1; j<shards.length; j++){ // 后续一级分割分片数据放入追加数据当中
msgAppend += "【" + msgCurrentDict.note + "】" + shards[j] + "\n" // 取分割后的第一条
}
if(version == 1){
// 写入推送的时间
// Application.Range("H" + (i + 2)).Value = todayDate
Application.Range("H" + msgCurrentDict.pos).Value = todayDate
// 更新推送次数。读取当日可推送次数,写入当日剩余推送次数。写入当日剩余推送次数 = 当日可推送次数 - 1
Application.Range("N" + msgCurrentDict.pos).Value = parseInt(msgCurrentDict.dailyPushLimit) - 1
}else{
// 写入推送的时间
// Application.Range("H" + (i + 2)).Value = todayDate
Application.Range("H" + msgCurrentDict.pos).Value2 = todayDate
// 更新推送次数。读取当日可推送次数,写入当日剩余推送次数。写入当日剩余推送次数 = 当日可推送次数 - 1
Application.Range("N" + msgCurrentDict.pos).Value2 = parseInt(msgCurrentDict.dailyPushLimit) - 1
}
}else{
// 6.时间一致额外推送判断
// 时间一致,计算是否推送
if(parseInt(msgCurrentDict.remainingDailyPushes) > 0){
// 进行消息池生成
// 对分片消息进行特异化处理,只取第一条分片,后续分片放在消息池的末尾
shards = msgCurrentDict.msg.split(separator); // // 分割符分片数据,一级分割
// console.log(shards)
msgPool += "【" + msgCurrentDict.note + "】" + shards[0] + "\n" // 取分割后的第一条
for(let j=1; j<shards.length; j++){ // 后续一级分割分片数据放入追加数据当中
msgAppend += "【" + msgCurrentDict.note + "】" + shards[j] + "\n" // 取分割后的第一条
}
if(version == 1){
// 写入推送的时间
Application.Range("H" + msgCurrentDict.pos).Value = todayDate
// 更新推送次数。读取当日可推送次数,写入当日剩余推送次数。写入当日剩余推送次数 = 当日可推送次数 - 1
Application.Range("N" + msgCurrentDict.pos).Value = parseInt(msgCurrentDict.remainingDailyPushes) - 1
}else{
// 写入推送的时间
Application.Range("H" + msgCurrentDict.pos).Value2 = todayDate
// 更新推送次数。读取当日可推送次数,写入当日剩余推送次数。写入当日剩余推送次数 = 当日可推送次数 - 1
Application.Range("N" + msgCurrentDict.pos).Value2 = parseInt(msgCurrentDict.remainingDailyPushes) - 1
}
}
}
}
// console.log("🧩 加入消息池:" + msgCurrentDict.note)
// msgPool += "【" + msgCurrentDict.note + "】" + msgCurrentDict.msg + "\n"
}else{
// console.log("🍳 不进行推送:" + msgCurrentDict.note)
}
}
}
// console.log(msgPool)
// 消息池推送,消息池默认以@all方式推送
let msgPoolJuice = msgPool.replace(/\n/g, ''); // 判断消息池内是否有数据
// console.log(msgPoolJuice)
if(msgPoolJuice != ""){ // 消息池内有消息才推送
// pushMessage(msgPool, "@all", "【" + "艾默库消息池" + "】\n")
sendMessage("", msgPool, msgAppend)
}
console.log("🎉 推送结束")
}
// 使用正则表达式匹配以'http://'或'https://'开头的字符串
function isHttpOrHttpsUrl(url) {
// '^'表示字符串的开始,'i'表示不区分大小写
const regex = /^(http:\/\/|https:\/\/)/i;
// match() 方法返回一个包含匹配结果的数组,如果没有匹配项则返回 null
return url.match(regex) !== null;
}
// 消息分割,返回消息推送方式数组
function pushSplit(method){
// console.log(method)
let arry = []
arry = method.split("&") // 使用&作为分隔符
// console.log(arry)
return arry
}
// 总推送
function pushMessage(message, method, pushHeader){
messagePushHeader = pushHeader
if (method == "@all") { // 所有渠道都推送
// console.log("🚀 所有渠道都推送");
// message = messagePushHeader + message // 消息头最前方默认存放【xxxx】
let length = jsonPush.length;
let name;
let key;
for (let i = 0; i < length; i++) {
if (jsonPush[i].flag == 1) {
name = jsonPush[i].name;
key = jsonPush[i].key;
let keySub = pushSplit(key)
for (let i = 0; i < keySub.length; i++) {
pushUnit(message, keySub[i], name)
}
}
}
} else {
// console.log("🚀 多消息推送");
let arry = pushSplit(method)
let methodCurrent = ""
let length = jsonPush.length;
let name;
let key;
for (let i = 0; i < arry.length; i++) {
methodCurrent = arry[i]
// console.log(methodCurrent)
for (let i = 0; i < length; i++) {
name = jsonPush[i].name;
if(name == methodCurrent){
// console.log(methodCurrent)
if (jsonPush[i].flag == 1) {
key = jsonPush[i].key;
let keySub = pushSplit(key)
for (let i = 0; i < keySub.length; i++) {
pushUnit(message, keySub[i], name)
}
}
break; // 找到推送方式就提前退出
}
}
}
}
}
// 推送执行
function pushUnit(message, key, name){
try{
if (name == "bark") {
bark(message, key);
} else if (name == "pushplus") {
pushplus(message, key);
} else if (name == "ServerChan") {
serverchan(message, key);
} else if (name == "email") {
email(message);
} else if (name == "dingtalk") {
dingtalk(message, key);
} else if (name == "discord") {
discord(message, key);
}else if (name == "qywx"){
qywx(message, key);
} else if (name == "xizhi") {
xizhi(message, key);
}else if (name == "jishida"){
jishida(message, key);
}else if (name == "wxpusher"){
wxpusher(message, key)
}
}catch{
console.log("📢 存在推送失败:" + name)
}
}
// 推送bark消息
function bark(message, key) {
message = messagePushHeader + message // 消息头最前方默认存放【xxxx】
message = encodeURIComponent(message)
BARK_ICON = "https://s21.ax1x.com/2024/06/23/pkrUkfe.png"
let url = ""
if(isHttpOrHttpsUrl(key)){ // 以http开头
url = key + "/" + message + "/" + "?icon=" + BARK_ICON
}else{
url = "https://api.day.app/" + key + "/" + message + "/" + "?icon=" + BARK_ICON;
}
// 若需要修改推送的分组,则将上面一行改为如下的形式
// let url = 'https://api.day.app/' + bark_id + "/" + message + "?group=分组名";
let resp = HTTP.get(url, {
headers: { "Content-Type": "application/x-www-form-urlencoded" },
});
// console.log(resp.json())
sleep(5000);
}
// 推送pushplus消息
function pushplus(message, key) {
message = encodeURIComponent(message)
let url = ""
if(isHttpOrHttpsUrl(key)){ // 以http开头
url = key + "&content=" + message + "&title=" + messagePushHeader;
}else{
url = "http://www.pushplus.plus/send?token=" + key + "&content=" + message + "&title=" + messagePushHeader; // 增加标题
}
// url = "http://www.pushplus.plus/send?token=" + key + "&content=" + message;
// let resp = HTTP.fetch(url, {
// method: "get",
// });
headers = {}
resp = HTTP.get(url, {headers: headers,});
sleep(5000);
}
// 推送serverchan消息方糖
function serverchan(message, key) {
message = message.replace(/\n/g, '\n\n'); // 单独适配,将一个换行变成两个,以实现换行
message = encodeURIComponent(message)
let url = ""
if(isHttpOrHttpsUrl(key)){ // 以http开头
url = key + "?title=" + messagePushHeader + "&desp=" + message;
}else{
url = "https://sctapi.ftqq.com/" + key + ".send?title=" + messagePushHeader + "&desp=" + message;
}
// let resp = HTTP.fetch(url, {
// method: "get",
// });
headers = {}
resp = HTTP.get(url, {headers: headers,});
sleep(5000);
}
// email邮箱推送
function email(message) {
var myDate = new Date(); // 创建一个表示当前时间的 Date 对象
var data_time = myDate.toLocaleDateString(); // 获取当前日期的字符串表示
let server = jsonEmail.server;
let port = parseInt(jsonEmail.port); // 转成整形
let sender = jsonEmail.sender;
let authorizationCode = jsonEmail.authorizationCode;
let mailer;
mailer = SMTP.login({
host: server,
port: port,
username: sender,
password: authorizationCode,
secure: true,
});
mailer.send({
from: pushHeader + "<" + sender + ">",
to: sender,
subject: pushHeader + " - " + data_time,
text: message,
});
// console.log("🍳 已发送邮件至:" + sender);
console.log("🍳 已发送邮件");
sleep(5000);
}
// 邮箱配置
function emailConfig() {
// console.log("🍳 开始读取邮箱配置");
let length = jsonPush.length; // 因为此json数据可无序因此需要遍历
let name;
for (let i = 0; i < length; i++) {
name = jsonPush[i].name;
if (name == "email") {
if (jsonPush[i].flag == 1 || 1) { // 始终读取
let flag = ActivateSheet(sheetNameEmail); // 激活邮箱表
// 邮箱表存在
// var email = {
// 'email':'', 'port':'', 'sender':'', 'authorizationCode':''
// } // 有效配置
if (flag == 1) {
console.log("🍳 开始读取邮箱表");
for (let i = 2; i <= 2; i++) {
// 从工作表中读取推送数据
jsonEmail.server = Application.Range("A" + i).Text;
jsonEmail.port = Application.Range("B" + i).Text;
jsonEmail.sender = Application.Range("C" + i).Text;
jsonEmail.authorizationCode = Application.Range("D" + i).Text;
if (Application.Range("A" + i).Text == "") {
// 如果为空行,则提前结束读取
break;
}
}
// console.log(jsonEmail)
}
break;
}
}
}
}
// 推送钉钉机器人
function dingtalk(message, key) {
message = messagePushHeader + message // 消息头最前方默认存放【xxxx】
let url = ""
if(isHttpOrHttpsUrl(key)){ // 以http开头
url = key
}else{
url = "https://oapi.dingtalk.com/robot/send?access_token=" + key;
}
let resp = HTTP.post(url, { msgtype: "text", text: { content: message } });
// console.log(resp.text())
sleep(5000);
}
// 推送Discord机器人
function discord(message, key) {
message = messagePushHeader + message // 消息头最前方默认存放【xxxx】
let url = key;
let resp = HTTP.post(url, { content: message });
//console.log(resp.text())
sleep(5000);
}
// 企业微信群推送机器人
function qywx(message, key) {
message = messagePushHeader + "\n" + message // 消息头最前方默认存放【xxxx】
let url = ""
if(isHttpOrHttpsUrl(key)){ // 以http开头
url = key
}else{
url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=" + key;
}
data = {
"msgtype": "text",
"text": {
"content": message
}
}
let resp = HTTP.post(url, data);
// console.log(resp.json())
sleep(5000);
}
// 息知 https://xizhi.qqoq.net/{key}.send?title=标题&content=内容
function xizhi(message, key) {
message = message.replace(/\n/g, '\n\n'); // 单独适配,将一个换行变成两个,以实现换行
message = encodeURIComponent(message)
let url = ""
if(isHttpOrHttpsUrl(key)){ // 以http开头
url = key + "?title=" + messagePushHeader + "&content=" + message;
}else{
url = "https://xizhi.qqoq.net/" + key + ".send?title=" + messagePushHeader + "&content=" + message; // 增加标题
}
// let resp = HTTP.fetch(url, {
// method: "get",
// });
headers = {}
resp = HTTP.get(url, {headers: headers,});
sleep(5000);
}
// jishida http://push.ijingniu.cn/send?key=&head=&body=
function jishida(message, key) {
message = encodeURIComponent(message)
let url = ""
if(isHttpOrHttpsUrl(key)){ // 以http开头
url = key + "&head=" + messagePushHeader + "&body=" + message;
}else{
url = "http://push.ijingniu.cn/send?key=" + key + "&head=" + messagePushHeader + "&body=" + message; // 增加标题
}
// let resp = HTTP.fetch(url, {
// method: "get",
// });
headers = {}
resp = HTTP.get(url, {headers: headers,});
sleep(5000);
}
// wxpusher 适配两种模式:极简推送、标准推送
function wxpusher(message, key) {
message = message.replace(/\n/g, '<br>'); // 单独适配,将/n换行变成<br>,以实现换行
message = encodeURIComponent(message)
let keyarry= key.split("|") // 使用|作为分隔符
if(keyarry.length == 1){
// console.log("采用SPT极简推送")
// https://wxpusher.zjiecode.com/api/send/message/你获取到的SPT/你要发送的内容
// https://wxpusher.zjiecode.com/api/send/message/xxxx/ThisIsSendContent
let url = ""
if(isHttpOrHttpsUrl(key)){ // 以http开头
// end = key.slice(-1)
if(key.endsWith("/")){
// 形如https://wxpusher.zjiecode.com/api/send/message/你获取到的SPT/
url = key + message
}else if(key.endsWith("ThisIsSendContent")){
// 形如https://wxpusher.zjiecode.com/api/send/message/xxxx/ThisIsSendContent
key = key.slice(0, -"ThisIsSendContent".length); // 去掉末尾的"ThisIsSendContent"
url = key + message
}else{
// 形如https://wxpusher.zjiecode.com/api/send/message/你获取到的SPT
url = key + "/" + message
}
}else{
// 形如你获取到的SPT
url = "https://wxpusher.zjiecode.com/api/send/message/" + key + "/" + message
}
// console.log(url)
// let resp = HTTP.fetch(url, {
// method: "get",
// });
headers = {}
resp = HTTP.get(url, {headers: headers,});
// console.log(resp.text())
}else{
// console.log("采用标准推送")
let appToken = keyarry[0]
let uid = keyarry[1]
let url = ""
if(isHttpOrHttpsUrl(key)){ // 以http开头
url = key + "&verifyPayType=0&content=" + message
}else{
url = "https://wxpusher.zjiecode.com/api/send/message/?appToken=" + appToken + "&uid=" + uid + "&verifyPayType=0&content=" + message
}
// console.log(url)
// let resp = HTTP.fetch(url, {
// method: "get",
// });
headers = {}
resp = HTTP.get(url, {headers: headers,});
// console.log(resp.json())
}
sleep(5000);
}

View File

@@ -0,0 +1,477 @@
// # Source: https://github.com/imoki/sign_script/blob/main/polymerization/TEMPLATE.js
// # Raw: https://raw.githubusercontent.com/imoki/sign_script/main/polymerization/TEMPLATE.js
// # Repo: imoki/sign_script
// # Path: polymerization/TEMPLATE.js
// # UploadedAt: 2025-08-25T21:29:14+08:00
// # SHA256: ca814940e5cbd3784e70cfaaa7afb736e723a557b0a6169c20fa88a55a484c90
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
// 某雪(修改这里,这里填是什么名称)
// 20240512 (修改这里)
var sheetNameSubConfig = "mouxue"; // 分配置表名称修改这里这里填表的名称需要和UPDATE文件中的一致自定义的
var pushHeader = "【某雪论坛】"; //(修改这里,这里给自己看的,随便填)
var sheetNameConfig = "CONFIG"; // 总配置表
var sheetNamePush = "PUSH"; // 推送表名称
var sheetNameEmail = "EMAIL"; // 邮箱表
var flagSubConfig = 0; // 激活分配置工作表标志
var flagConfig = 0; // 激活主配置工作表标志
var flagPush = 0; // 激活推送工作表标志
var line = 21; // 指定读取从第2行到第line行的内容
var message = ""; // 待发送的消息
var messageArray = []; // 待发送的消息数据,每个元素都是某个账号的消息。目的是将不同用户消息分离,方便个性化消息配置
var messageOnlyError = 0; // 0为只推送失败消息1则为推送成功消息。
var messageNickname = 0; // 1为推送位置标识昵称/单元格Ax昵称为空时0为不推送位置标识
var messageHeader = []; // 存放每个消息的头部单元格A3。目的是分离附加消息和执行结果消息
var messagePushHeader = pushHeader; // 存放在总消息的头部默认是pushHeader,如【xxxx】
var version = 1 // 版本类型自动识别并适配。默认为airscript 1.0否则为2.0Beta
var separator = "##########MOKU##########" // 分割符分割消息。可用于PUSH.js灵活推送
var maxMessageLength = 400; // 设置最大长度,超过这个长度则分片发送
var messageDistance = 100; // 消息距离用于匹配100字符内最近的行
var jsonPush = [
{ name: "bark", key: "xxxxxx", flag: "0" },
{ name: "pushplus", key: "xxxxxx", flag: "0" },
{ name: "ServerChan", key: "xxxxxx", flag: "0" },
{ name: "email", key: "xxxxxx", flag: "0" },
{ name: "dingtalk", key: "xxxxxx", flag: "0" },
{ name: "discord", key: "xxxxxx", flag: "0" },
]; // 推送数据flag=1则推送
var jsonEmail = {
server: "",
port: "",
sender: "",
authorizationCode: "",
}; // 有效邮箱配置
flagConfig = ActivateSheet(sheetNameConfig); // 激活推送表
// 主配置工作表存在
if (flagConfig == 1) {
console.log("开始读取主配置表");
let name; // 名称
let onlyError;
let nickname;
for (let i = 2; i <= 100; i++) {
// 从工作表中读取推送数据
name = Application.Range("A" + i).Text;
onlyError = Application.Range("C" + i).Text;
nickname = Application.Range("D" + i).Text;
if (name == "") {
// 如果为空行,则提前结束读取
break; // 提前退出,提高效率
}
if (name == sheetNameSubConfig) {
if (onlyError == "是") {
messageOnlyError = 1;
console.log("只推送错误消息");
}
if (nickname == "是") {
messageNickname = 1;
console.log("单元格用昵称替代");
}
break; // 提前退出,提高效率
}
}
}
flagPush = ActivateSheet(sheetNamePush); // 激活推送表
// 推送工作表存在
if (flagPush == 1) {
console.log("开始读取推送工作表");
let pushName; // 推送类型
let pushKey;
let pushFlag; // 是否推送标志
for (let i = 2; i <= line; i++) {
// 从工作表中读取推送数据
pushName = Application.Range("A" + i).Text;
pushKey = Application.Range("B" + i).Text;
pushFlag = Application.Range("C" + i).Text;
if (pushName == "") {
// 如果为空行,则提前结束读取
break;
}
jsonPushHandle(pushName, pushFlag, pushKey);
}
// console.log(jsonPush)
}
// 邮箱配置函数
emailConfig();
flagSubConfig = ActivateSheet(sheetNameSubConfig); // 激活分配置表
if (flagSubConfig == 1) {
console.log("开始读取分配置表");
for (let i = 2; i <= line; i++) {
var cookie = Application.Range("A" + i).Text;
var exec = Application.Range("B" + i).Text;
if (cookie == "") {
// 如果为空行,则提前结束读取
break;
}
if (exec == "是") {
execHandle(cookie, i);
}
}
message = messageMerge()// 将消息数组融合为一条总消息
push(message); // 推送消息
}
// 将消息数组融合为一条总消息
function messageMerge(){
for(i=0; i<messageArray.length; i++){
if(messageArray[i] != "" && messageArray[i] != null)
{
message += messageHeader[i] + messageArray[i] + " "; // 加上推送头
}
}
if(message != "")
{
console.log(message) // 打印总消息
}
return message
}
// 总推送
function push(message) {
if (message != "") {
message = messagePushHeader + message // 消息头最前方默认存放【xxxx】
let length = jsonPush.length;
let name;
let key;
for (let i = 0; i < length; i++) {
if (jsonPush[i].flag == 1) {
name = jsonPush[i].name;
key = jsonPush[i].key;
if (name == "bark") {
bark(message, key);
} else if (name == "pushplus") {
pushplus(message, key);
} else if (name == "ServerChan") {
serverchan(message, key);
} else if (name == "email") {
email(message);
} else if (name == "dingtalk") {
dingtalk(message, key);
} else if (name == "discord") {
discord(message, key);
}
}
}
} else {
console.log("消息为空不推送");
}
}
// 推送bark消息
function bark(message, key) {
if (key != "") {
let url = "https://api.day.app/" + key + "/" + message;
// 若需要修改推送的分组,则将上面一行改为如下的形式
// let url = 'https://api.day.app/' + bark_id + "/" + message + "?group=分组名";
let resp = HTTP.get(url, {
headers: { "Content-Type": "application/x-www-form-urlencoded" },
});
sleep(5000);
}
}
// 推送pushplus消息
function pushplus(message, key) {
if (key != "") {
// url = "http://www.pushplus.plus/send?token=" + key + "&content=" + message;
url = "http://www.pushplus.plus/send?token=" + key + "&content=" + message + "&title=" + pushHeader; // 增加标题
let resp = HTTP.fetch(url, {
method: "get",
});
sleep(5000);
}
}
// 推送serverchan消息
function serverchan(message, key) {
if (key != "") {
url =
"https://sctapi.ftqq.com/" +
key +
".send" +
"?title=消息推送" +
"&desp=" +
message;
let resp = HTTP.fetch(url, {
method: "get",
});
sleep(5000);
}
}
// email邮箱推送
function email(message) {
var myDate = new Date(); // 创建一个表示当前时间的 Date 对象
var data_time = myDate.toLocaleDateString(); // 获取当前日期的字符串表示
let server = jsonEmail.server;
let port = parseInt(jsonEmail.port); // 转成整形
let sender = jsonEmail.sender;
let authorizationCode = jsonEmail.authorizationCode;
let mailer;
mailer = SMTP.login({
host: server,
port: port,
username: sender,
password: authorizationCode,
secure: true,
});
mailer.send({
from: pushHeader + "<" + sender + ">",
to: sender,
subject: pushHeader + " - " + data_time,
text: message,
});
// console.log("已发送邮件至:" + sender);
console.log("已发送邮件");
sleep(5000);
}
// 邮箱配置
function emailConfig() {
console.log("开始读取邮箱配置");
let length = jsonPush.length; // 因为此json数据可无序因此需要遍历
let name;
for (let i = 0; i < length; i++) {
name = jsonPush[i].name;
if (name == "email") {
if (jsonPush[i].flag == 1) {
let flag = ActivateSheet(sheetNameEmail); // 激活邮箱表
// 邮箱表存在
// var email = {
// 'email':'', 'port':'', 'sender':'', 'authorizationCode':''
// } // 有效配置
if (flag == 1) {
console.log("开始读取邮箱表");
for (let i = 2; i <= 2; i++) {
// 从工作表中读取推送数据
jsonEmail.server = Application.Range("A" + i).Text;
jsonEmail.port = Application.Range("B" + i).Text;
jsonEmail.sender = Application.Range("C" + i).Text;
jsonEmail.authorizationCode = Application.Range("D" + i).Text;
if (Application.Range("A" + i).Text == "") {
// 如果为空行,则提前结束读取
break;
}
}
// console.log(jsonEmail)
}
break;
}
}
}
}
// 推送钉钉机器人
function dingtalk(message, key) {
let url = "https://oapi.dingtalk.com/robot/send?access_token=" + key;
let resp = HTTP.post(url, { msgtype: "text", text: { content: message } });
// console.log(resp.text())
sleep(5000);
}
// 推送Discord机器人
function discord(message, key) {
let url = key;
let resp = HTTP.post(url, { content: message });
//console.log(resp.text())
sleep(5000);
}
function sleep(d) {
for (var t = Date.now(); Date.now() - t <= d; );
}
// 激活工作表函数
function ActivateSheet(sheetName) {
let flag = 0;
try {
// 激活工作表
let sheet = Application.Sheets.Item(sheetName);
sheet.Activate();
console.log("激活工作表:" + sheet.Name);
flag = 1;
} catch {
flag = 0;
console.log("无法激活工作表,工作表可能不存在");
}
return flag;
}
// 对推送数据进行处理
function jsonPushHandle(pushName, pushFlag, pushKey) {
let length = jsonPush.length;
for (let i = 0; i < length; i++) {
if (jsonPush[i].name == pushName) {
if (pushFlag == "是") {
jsonPush[i].flag = 1;
jsonPush[i].key = pushKey;
}
}
}
}
// cookie字符串转json格式
function cookie_to_json(cookies) {
var cookie_text = cookies;
var arr = [];
var text_to_split = cookie_text.split(";");
for (var i in text_to_split) {
var tmp = text_to_split[i].split("=");
arr.push('"' + tmp.shift().trim() + '":"' + tmp.join(":").trim() + '"');
}
var res = "{\n" + arr.join(",\n") + "\n}";
return JSON.parse(res);
}
// 获取10 位时间戳
function getts10() {
var ts = Math.round(new Date().getTime() / 1000).toString();
return ts;
}
// 获取13位时间戳
function getts13(){
// var ts = Math.round(new Date().getTime()/1000).toString() // 获取10 位时间戳
let ts = new Date().getTime()
return ts
}
// 符合UUID v4规范的随机字符串 b9ab98bb-b8a9-4a8a-a88a-9aab899a88b9
function generateUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0,
v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
function getUUIDDigits(length) {
var uuid = generateUUID();
return uuid.replace(/-/g, '').substr(16, length);
}
// 获取sign返回小写
function getsign(data) {
var sign = Crypto.createHash("md5")
.update(data, "utf8")
.digest("hex")
// .toUpperCase() // 大写
.toString();
return sign;
}
// 具体的执行函数
function execHandle(cookie, pos) {
let messageSuccess = "";
let messageFail = "";
let messageName = "";
// 推送昵称或单元格,还是不推送位置标识
if (messageNickname == 1) {
// 推送昵称或单元格
messageName = Application.Range("C" + pos).Text;
if(messageName == "")
{
messageName = "单元格A" + pos + "";
}
}
posLabel = pos-2 ; // 存放下标从0开始
messageHeader[posLabel] = messageName
// =================修改这块区域,区域开始=================
url1 = "https://bbs.mouxue.com/user-signin.htm"; // url修改这里这里填抓包获取到的地址
// 修改这里这里填抓包获取header全部抄进来就可以了按照如下用引号包裹的格式其中小写的cookie是从表格中读取到的值。
headers= {
"Cookie": cookie,
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.70",
}
// 修改这里这里填抓包获取data全部抄进来就可以了按照如下用引号包裹的格式。POST请求才需要这个GET请求就不用它了
data = {
"csrf_token":"",
}
// (修改这里,以下请求方式三选一即可)
// 请求方式1POST请求抓包的data数据格式是 {"aaa":"xxx","bbb":"xxx"} 。则用这个
resp = HTTP.post(
url1,
JSON.stringify(data),
{ headers: headers }
);
// // 请求方式2POST请求抓包的data数据格式是 aaa=xxx&bbb=xxx 。则用这个
// resp = HTTP.post(
// url1,
// data,
// { headers: headers }
// );
// // 请求方式3GET请求无data数据。则用这个
// resp = HTTP.get(
// url1,
// { headers: headers }
// );
if (resp.status == 200) {
resp = resp.json();
console.log(resp)
// (修改这里,这里就是自己写了,根据抓包的响应自行修改)
// 接收到的响应数据是json格式如下假设有2种情况
// 情况1{"code": "0","message": "签到成功"}
// 情况2{"code":"-1","message":"签到失败"}
respcode = resp["code"] // 通过resp["键名"]的方式获取值.假设响应数据是情况1则读取到数字“0”
// respmsg = resp["message"] // 通过resp["键名"]的方式获取值假设响应数据是情况1这里取到的值就是“签到成功”
if(respcode == 0) // 通过code值来判断是不是签到成功由抓包的情况1知道0代表签到成功了,所以让code与0比较
{
// 这里是签到成功
content = "签到成功 " // // 给自己看的,双引号内可以随便写
messageSuccess += content;
console.log(content)
}
else
{
// 这里是签到失败
msg = "签到失败 " // 给自己看的,可以随便写,如 msg = "失败啦! " 。
content = msg + " "
messageFail += content;
console.log(content)
}
} else {
content = "签到失败 "
messageFail += content;
console.log(content);
}
// =================修改这块区域,区域结束=================
sleep(2000);
if (messageOnlyError == 1) {
messageArray[posLabel] = messageFail;
} else {
messageArray[posLabel] = messageFail + " " + messageSuccess;
}
if(messageArray[posLabel] != "")
{
console.log(messageArray[posLabel]);
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,485 @@
// # Source: https://github.com/imoki/sign_script/blob/main/polymerization/vivo.js
// # Raw: https://raw.githubusercontent.com/imoki/sign_script/main/polymerization/vivo.js
// # Repo: imoki/sign_script
// # Path: polymerization/vivo.js
// # UploadedAt: 2025-08-25T21:29:14+08:00
// # SHA256: 572c90bb000b944d156e0272a67a372ae37e710b553502a9a53dcf19d0bbc9c4
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
/*
name: "vivo社区"
cron: 45 0 9 * * *
脚本兼容: 金山文档1.0金山文档2.0
更新时间20241226
环境变量名:无
环境变量值:无
备注需要Cookie。
cookie填写vivo社区网页版中获取的refresh_token。F12 -> NetWork(中文名叫"网络") -> 按一下Ctrl+R -> newbbs/ -> cookie
vivo社区网址https://bbs.vivo.com.cn/newbbs/
*/
var sheetNameSubConfig = "vivo"; // 分配置表名称
var pushHeader = "【vivo社区】";
var sheetNameConfig = "CONFIG"; // 总配置表
var sheetNamePush = "PUSH"; // 推送表名称
var sheetNameEmail = "EMAIL"; // 邮箱表
var flagSubConfig = 0; // 激活分配置工作表标志
var flagConfig = 0; // 激活主配置工作表标志
var flagPush = 0; // 激活推送工作表标志
var line = 21; // 指定读取从第2行到第line行的内容
var message = ""; // 待发送的消息
var messageArray = []; // 待发送的消息数据,每个元素都是某个账号的消息。目的是将不同用户消息分离,方便个性化消息配置
var messageOnlyError = 0; // 0为只推送失败消息1则为推送成功消息。
var messageNickname = 0; // 1为推送位置标识昵称/单元格Ax昵称为空时0为不推送位置标识
var messageHeader = []; // 存放每个消息的头部单元格A3。目的是分离附加消息和执行结果消息
var messagePushHeader = pushHeader; // 存放在总消息的头部默认是pushHeader,如【xxxx】
var version = 1 // 版本类型自动识别并适配。默认为airscript 1.0否则为2.0Beta
var separator = "##########MOKU##########" // 分割符分割消息。可用于PUSH.js灵活推送
var maxMessageLength = 400; // 设置最大长度,超过这个长度则分片发送
var messageDistance = 100; // 消息距离用于匹配100字符内最近的行
var jsonPush = [
{ name: "bark", key: "xxxxxx", flag: "0" },
{ name: "pushplus", key: "xxxxxx", flag: "0" },
{ name: "ServerChan", key: "xxxxxx", flag: "0" },
{ name: "email", key: "xxxxxx", flag: "0" },
{ name: "dingtalk", key: "xxxxxx", flag: "0" },
{ name: "discord", key: "xxxxxx", flag: "0" },
]; // 推送数据flag=1则推送
var jsonEmail = {
server: "",
port: "",
sender: "",
authorizationCode: "",
}; // 有效邮箱配置
// =================青龙适配开始===================
qlSwitch = 0
// =================青龙适配结束===================
// =================金山适配开始===================
// airscript检测版本
function checkVesion(){
try{
let temp = Application.Range("A1").Text;
Application.Range("A1").Value = temp
console.log("😶‍🌫️ 检测到当前airscript版本为1.0进行1.0适配")
}catch{
console.log("😶‍🌫️ 检测到当前airscript版本为2.0进行2.0适配")
version = 2
}
}
// 推送相关
// 获取时间
function getDate(){
let currentDate = new Date();
currentDate = currentDate.getFullYear() + '/' + (currentDate.getMonth() + 1).toString() + '/' + currentDate.getDate().toString();
return currentDate
}
// 将消息写入CONFIG表中作为消息队列之后统一发送
function writeMessageQueue(message){
// 当天时间
let todayDate = getDate()
flagConfig = ActivateSheet(sheetNameConfig); // 激活主配置表
// 主配置工作表存在
if (flagConfig == 1) {
console.log("✨ 开始将结果写入主配置表");
for (let i = 2; i <= 100; i++) {
if(version == 1){
// 找到指定的表行
if(Application.Range("A" + (i + 2)).Value == sheetNameSubConfig){
// 写入更新的时间
Application.Range("F" + (i + 2)).Value = todayDate
// 写入消息
Application.Range("G" + (i + 2)).Value = message
console.log("✨ 写入结果完成");
break;
}
}else{
// 找到指定的表行
if(Application.Range("A" + (i + 2)).Value2 == sheetNameSubConfig){
// 写入更新的时间
Application.Range("F" + (i + 2)).Value2 = todayDate
// 写入消息
Application.Range("G" + (i + 2)).Value2 = message
console.log("✨ 写入结果完成");
break;
}
}
}
}
}
// 总推送
function push(message) {
writeMessageQueue(message) // 将消息写入CONFIG表中
// if (message != "") {
// // message = messagePushHeader + message // 消息头最前方默认存放【xxxx】
// let length = jsonPush.length;
// let name;
// let key;
// for (let i = 0; i < length; i++) {
// if (jsonPush[i].flag == 1) {
// name = jsonPush[i].name;
// key = jsonPush[i].key;
// if (name == "bark") {
// bark(message, key);
// } else if (name == "pushplus") {
// pushplus(message, key);
// } else if (name == "ServerChan") {
// serverchan(message, key);
// } else if (name == "email") {
// email(message);
// } else if (name == "dingtalk") {
// dingtalk(message, key);
// } else if (name == "discord") {
// discord(message, key);
// }
// }
// }
// } else {
// console.log("🍳 消息为空不推送");
// }
}
// 推送bark消息
function bark(message, key) {
if (key != "") {
message = messagePushHeader + message // 消息头最前方默认存放【xxxx】
message = encodeURIComponent(message)
BARK_ICON = "https://s21.ax1x.com/2024/06/23/pkrUkfe.png"
let url = "https://api.day.app/" + key + "/" + message + "/" + "?icon=" + BARK_ICON;
// 若需要修改推送的分组,则将上面一行改为如下的形式
// let url = 'https://api.day.app/' + bark_id + "/" + message + "?group=分组名";
let resp = HTTP.get(url, {
headers: { "Content-Type": "application/x-www-form-urlencoded" },
});
sleep(5000);
}
}
// 推送pushplus消息
function pushplus(message, key) {
if (key != "") {
message = encodeURIComponent(message)
// url = "http://www.pushplus.plus/send?token=" + key + "&content=" + message;
url = "http://www.pushplus.plus/send?token=" + key + "&content=" + message + "&title=" + pushHeader; // 增加标题
let resp = HTTP.fetch(url, {
method: "get",
});
sleep(5000);
}
}
// 推送serverchan消息
function serverchan(message, key) {
if (key != "") {
url =
"https://sctapi.ftqq.com/" +
key +
".send" +
"?title=" + messagePushHeader +
"&desp=" +
message;
let resp = HTTP.fetch(url, {
method: "get",
});
sleep(5000);
}
}
// email邮箱推送
function email(message) {
var myDate = new Date(); // 创建一个表示当前时间的 Date 对象
var data_time = myDate.toLocaleDateString(); // 获取当前日期的字符串表示
let server = jsonEmail.server;
let port = parseInt(jsonEmail.port); // 转成整形
let sender = jsonEmail.sender;
let authorizationCode = jsonEmail.authorizationCode;
let mailer;
mailer = SMTP.login({
host: server,
port: port,
username: sender,
password: authorizationCode,
secure: true,
});
mailer.send({
from: pushHeader + "<" + sender + ">",
to: sender,
subject: pushHeader + " - " + data_time,
text: message,
});
// console.log("🍳 已发送邮件至:" + sender);
console.log("🍳 已发送邮件");
sleep(5000);
}
// 邮箱配置
function emailConfig() {
console.log("🍳 开始读取邮箱配置");
let length = jsonPush.length; // 因为此json数据可无序因此需要遍历
let name;
for (let i = 0; i < length; i++) {
name = jsonPush[i].name;
if (name == "email") {
if (jsonPush[i].flag == 1) {
let flag = ActivateSheet(sheetNameEmail); // 激活邮箱表
// 邮箱表存在
// var email = {
// 'email':'', 'port':'', 'sender':'', 'authorizationCode':''
// } // 有效配置
if (flag == 1) {
console.log("🍳 开始读取邮箱表");
for (let i = 2; i <= 2; i++) {
// 从工作表中读取推送数据
jsonEmail.server = Application.Range("A" + i).Text;
jsonEmail.port = Application.Range("B" + i).Text;
jsonEmail.sender = Application.Range("C" + i).Text;
jsonEmail.authorizationCode = Application.Range("D" + i).Text;
if (Application.Range("A" + i).Text == "") {
// 如果为空行,则提前结束读取
break;
}
}
// console.log(jsonEmail)
}
break;
}
}
}
}
// 推送钉钉机器人
function dingtalk(message, key) {
message = messagePushHeader + message // 消息头最前方默认存放【xxxx】
let url = "https://oapi.dingtalk.com/robot/send?access_token=" + key;
let resp = HTTP.post(url, { msgtype: "text", text: { content: message } });
// console.log(resp.text())
sleep(5000);
}
// 推送Discord机器人
function discord(message, key) {
message = messagePushHeader + message // 消息头最前方默认存放【xxxx】
let url = key;
let resp = HTTP.post(url, { content: message });
//console.log(resp.text())
sleep(5000);
}
// =================金山适配结束===================
// =================共用开始===================
// main() // 入口
// function main(){
checkVesion() // 版本检测,以进行不同版本的适配
flagConfig = ActivateSheet(sheetNameConfig); // 激活推送表
// 主配置工作表存在
if (flagConfig == 1) {
console.log("🍳 开始读取主配置表");
let name; // 名称
let onlyError;
let nickname;
for (let i = 2; i <= 100; i++) {
// 从工作表中读取推送数据
name = Application.Range("A" + i).Text;
onlyError = Application.Range("C" + i).Text;
nickname = Application.Range("D" + i).Text;
if (name == "") {
// 如果为空行,则提前结束读取
break; // 提前退出,提高效率
}
if (name == sheetNameSubConfig) {
if (onlyError == "是") {
messageOnlyError = 1;
console.log("🍳 只推送错误消息");
}
if (nickname == "是") {
messageNickname = 1;
console.log("🍳 单元格用昵称替代");
}
break; // 提前退出,提高效率
}
}
}
flagPush = ActivateSheet(sheetNamePush); // 激活推送表
// 推送工作表存在
if (flagPush == 1) {
console.log("🍳 开始读取推送工作表");
let pushName; // 推送类型
let pushKey;
let pushFlag; // 是否推送标志
for (let i = 2; i <= line; i++) {
// 从工作表中读取推送数据
pushName = Application.Range("A" + i).Text;
pushKey = Application.Range("B" + i).Text;
pushFlag = Application.Range("C" + i).Text;
if (pushName == "") {
// 如果为空行,则提前结束读取
break;
}
jsonPushHandle(pushName, pushFlag, pushKey);
}
// console.log(jsonPush)
}
// 邮箱配置函数
emailConfig();
flagSubConfig = ActivateSheet(sheetNameSubConfig); // 激活分配置表
if (flagSubConfig == 1) {
console.log("🍳 开始读取分配置表");
if(qlSwitch != 1){ // 金山文档
for (let i = 2; i <= line; i++) {
var cookie = Application.Range("A" + i).Text;
var exec = Application.Range("B" + i).Text;
if (cookie == "") {
// 如果为空行,则提前结束读取
break;
}
if (exec == "是") {
execHandle(cookie, i);
}
}
message = messageMerge()// 将消息数组融合为一条总消息
push(message); // 推送消息
}else{
for (let i = 2; i <= line; i++) {
var cookie = Application.Range("A" + i).Text;
var exec = Application.Range("B" + i).Text;
if (cookie == "") {
// 如果为空行,则提前结束读取
break;
}
if (exec == "是") {
console.log("🧑 开始执行用户:" + "1" )
execHandle(cookie, i);
break; // 只取一个
}
}
}
}
// }
// 激活工作表函数
function ActivateSheet(sheetName) {
let flag = 0;
try {
// 激活工作表
let sheet = Application.Sheets.Item(sheetName);
sheet.Activate();
console.log("🥚 激活工作表:" + sheet.Name);
flag = 1;
} catch {
flag = 0;
console.log("🍳 无法激活工作表,工作表可能不存在");
}
return flag;
}
// 对推送数据进行处理
function jsonPushHandle(pushName, pushFlag, pushKey) {
let length = jsonPush.length;
for (let i = 0; i < length; i++) {
if (jsonPush[i].name == pushName) {
if (pushFlag == "是") {
jsonPush[i].flag = 1;
jsonPush[i].key = pushKey;
}
}
}
}
// 将消息数组融合为一条总消息
function messageMerge(){
// console.log(messageArray)
let message = ""
for(i=0; i<messageArray.length; i++){
if(messageArray[i] != "" && messageArray[i] != null)
{
message += "\n" + messageHeader[i] + messageArray[i] + ""; // 加上推送头
}
}
if(message != "")
{
console.log("✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨")
console.log(message + "\n") // 打印总消息
console.log("✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨")
}
return message
}
function sleep(d) {
for (var t = Date.now(); Date.now() - t <= d; );
}
// 获取sign返回小写
function getsign(data) {
var sign = Crypto.createHash("md5")
.update(data, "utf8")
.digest("hex")
// .toUpperCase() // 大写
.toString();
return sign;
}
// =================共用结束===================
// cookie字符串转json格式
function cookie_to_json(cookies) {
var cookie_text = cookies;
var arr = [];
var text_to_split = cookie_text.split(";");
for (var i in text_to_split) {
var tmp = text_to_split[i].split("=");
arr.push('"' + tmp.shift().trim() + '":"' + tmp.join(":").trim() + '"');
}
var res = "{\n" + arr.join(",\n") + "\n}";
return JSON.parse(res);
}
// 获取10 位时间戳
function getts10() {
var ts = Math.round(new Date().getTime() / 1000).toString();
return ts;
}
// 获取13位时间戳
function getts13(){
// var ts = Math.round(new Date().getTime()/1000).toString() // 获取10 位时间戳
let ts = new Date().getTime()
return ts
}
// 符合UUID v4规范的随机字符串 b9ab98bb-b8a9-4a8a-a88a-9aab899a88b9
function generateUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0,
v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
function getUUIDDigits(length) {
var uuid = generateUUID();
return uuid.replace(/-/g, '').substr(16, length);
}
function lottery(url,headers,data,count){messageSuccess="";messageFail="";resp=HTTP['\u0070\u006F\u0073\u0074'](url,JSON['\u0073\u0074\u0072\u0069\u006E\u0067\u0069\u0066\u0079'](data),{'\u0068\u0065\u0061\u0064\u0065\u0072\u0073':headers});if(resp['\u0073\u0074\u0061\u0074\u0075\u0073']==(194721^194665)){resp=resp['\u006A\u0073\u006F\u006E']();code=resp["code"];if(code==(666571^666571)){prizeName=resp["\u0064\u0061\u0074\u0061"]["data"]["prizeName"];content="\uD83C\uDF08\u0020"+"\u7B2C"+count+"\u62BD\u5956\uFF1A"+prizeName+"\u000A";messageSuccess+=content;console['\u006C\u006F\u0067'](content);}else{respmsg=resp["\u006D\u0073\u0067"];content=" \uDCE2\uD83D".split("").reverse().join("")+"\u7B2C"+count+"\u62BD\u5956"+respmsg+"\u000A";messageFail+=content;console['\u006C\u006F\u0067'](content);}}else{content=" \uDCE2\uD83D".split("").reverse().join("")+"\u7B2C"+count+"\u62BD\u5956\u5931\u8D25\u000A";messageFail+=content;console['\u006C\u006F\u0067'](content);}msg=[messageSuccess,messageFail];return msg;}
function execHandle(cookie,pos,_0x2dfg,_0xdc9d8a,_0xbaf5ae){var _0x0180ga=(751269^751277)+(118745^118746);_0x2dfg="";_0x0180ga='\u0066\u0065\u0069\u006A\u006A\u0062';_0xdc9d8a="";_0xbaf5ae="";if(messageNickname==(335776^335777)){_0xbaf5ae=Application['\u0052\u0061\u006E\u0067\u0065']("\u0043"+pos)['\u0054\u0065\u0078\u0074'];if(_0xbaf5ae==""){_0xbaf5ae="\u5355\u5143\u683C\u0041"+pos+"";}}posLabel=pos-(660894^660892);messageHeader[posLabel]=" \uDE80\uD83D\u200D\uDC68\uD83D".split("").reverse().join("")+_0xbaf5ae;var _0x6d9fd="tsiLyrettol/nIngis/ytinummoc/ipa/nc.moc.oviv.sbb//:sptth".split("").reverse().join("");var _0x19a="\u0068\u0074\u0074\u0070\u0073\u003A\u002F\u002F\u0062\u0062\u0073\u002E\u0076\u0069\u0076\u006F\u002E\u0063\u006F\u006D\u002E\u0063\u006E\u002F\u0061\u0070\u0069\u002F\u0063\u006F\u006D\u006D\u0075\u006E\u0069\u0074\u0079\u002F\u0073\u0069\u0067\u006E\u0049\u006E\u002F\u0071\u0075\u0065\u0072\u0079\u0053\u0069\u0067\u006E\u0049\u006E\u0066\u006F";var _0x8fe=(158797^158792)+(899890^899899);var _0xf886cf="\u0068\u0074\u0074\u0070\u0073\u003A\u002F\u002F\u0062\u0062\u0073\u002E\u0076\u0069\u0076\u006F\u002E\u0063\u006F\u006D\u002E\u0063\u006E\u002F\u0061\u0070\u0069\u002F\u0063\u006F\u006D\u006D\u0075\u006E\u0069\u0074\u0079\u002F\u0073\u0069\u0067\u006E\u0049\u006E\u002F\u0073\u0069\u0067\u006E\u0049\u006E\u004C\u006F\u0074\u0074\u0065\u0072\u0079";_0x8fe="ajmhbe".split("").reverse().join("");lotteryNum=800031^800028;headers={"\u0048\u006F\u0073\u0074":"\u0062\u0062\u0073\u002E\u0076\u0069\u0076\u006F\u002E\u0063\u006F\u006D\u002E\u0063\u006E","\u0043\u006F\u006F\u006B\u0069\u0065":cookie,"Content-Type":"\u0061\u0070\u0070\u006C\u0069\u0063\u0061\u0074\u0069\u006F\u006E\u002F\u006A\u0073\u006F\u006E\u003B\u0063\u0068\u0061\u0072\u0073\u0065\u0074\u003D\u0075\u0074\u0066\u002D\u0038","User-Agent":"\u004D\u006F\u007A\u0069\u006C\u006C\u0061\u002F\u0035\u002E\u0030\u0020\u0028\u0057\u0069\u006E\u0064\u006F\u0077\u0073\u0020\u004E\u0054\u0020\u0031\u0030\u002E\u0030\u003B\u0020\u0057\u0069\u006E\u0036\u0034\u003B\u0020\u0078\u0036\u0034\u0029\u0020\u0041\u0070\u0070\u006C\u0065\u0057\u0065\u0062\u004B\u0069\u0074\u002F\u0035\u0033\u0037\u002E\u0033\u0036\u0020\u0028\u004B\u0048\u0054\u004D\u004C\u002C\u0020\u006C\u0069\u006B\u0065\u0020\u0047\u0065\u0063\u006B\u006F\u0029\u0020\u0043\u0068\u0072\u006F\u006D\u0065\u002F\u0034\u0036\u002E\u0030\u002E\u0032\u0034\u0038\u0036\u002E\u0030\u0020\u0053\u0061\u0066\u0061\u0072\u0069\u002F\u0035\u0033\u0037\u002E\u0033\u0036\u0020\u0045\u0064\u0067\u0065\u002F\u0031\u0033\u002E\u0031\u0030\u0035\u0038\u0036"};data={"signInId":1};resp=HTTP['\u0070\u006F\u0073\u0074'](_0x19a,JSON['\u0073\u0074\u0072\u0069\u006E\u0067\u0069\u0066\u0079'](data),{"headers":headers});if(resp['\u0073\u0074\u0061\u0074\u0075\u0073']==(716349^716533)){resp=resp['\u006A\u0073\u006F\u006E']();code=resp["\u0063\u006F\u0064\u0065"];if(code==(246515^246515)){content="\uD83C\uDF89\u0020"+" \u529F\u6210\u5230\u7B7E".split("").reverse().join("");_0x2dfg+=content;console['\u006C\u006F\u0067'](content);}else{content=" \u274C".split("").reverse().join("")+"\u7B7E\u5230\u5931\u8D25\u0020";_0xdc9d8a+=content;console['\u006C\u006F\u0067'](content);}}else{content="\u274C\u0020"+"\u7B7E\u5230\u5931\u8D25\u0020";_0xdc9d8a+=content;console['\u006C\u006F\u0067'](content);}data={"\u006C\u006F\u0074\u0074\u0065\u0072\u0079\u0041\u0063\u0074\u0069\u0076\u0069\u0074\u0079\u0049\u0064":1,"\u006C\u006F\u0074\u0074\u0065\u0072\u0079\u0054\u0079\u0070\u0065":0};for(i=830706^830706;i<lotteryNum;i++){console['\u006C\u006F\u0067']("\uD83C\uDF73\u0020\u7B2C"+(i+(563073^563072))+"\u6B21\u62BD\u5956");msg=lottery(_0xf886cf,headers,data,i+(922456^922457));_0x2dfg+=msg[227906^227906];_0xdc9d8a+=msg[110596^110597];}sleep(608555^610043);if(messageOnlyError==(140754^140755)){messageArray[posLabel]=_0xdc9d8a;}else{if(_0xdc9d8a!=""){messageArray[posLabel]=_0xdc9d8a+"\u0020"+_0x2dfg;}else{messageArray[posLabel]=_0x2dfg;}}if(messageArray[posLabel]!=""){console['\u006C\u006F\u0067'](messageArray[posLabel]);}}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,378 @@
# Source: https://github.com/smallfawn/QLScriptPublic/blob/main/backup/wangchao.py
# Raw: https://raw.githubusercontent.com/smallfawn/QLScriptPublic/main/backup/wangchao.py
# Repo: smallfawn/QLScriptPublic
# Path: backup/wangchao.py
# UploadedAt: 2026-05-14T17:47:57+08:00
# SHA256: 5766bea96f254c536c58c331c970b56736855666f52792e2058a28daee3fa274
# Category: web版/账密
# Evidence: web/H5关键词 + username/password/login
import hashlib
from gmalg import SM2
import math
import time
import requests
import datetime
import os
from urllib.parse import urlparse, parse_qs
import random
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
import base64
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
import urllib.parse
import json
debug=0
account_id = ""
def jm(password):
public_key_base64 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD6XO7e9YeAOs+cFqwa7ETJ+WXizPqQeXv68i5vqw9pFREsrqiBTRcg7wB0RIp3rJkDpaeVJLsZqYm5TW7FWx/iOiXFc+zCPvaKZric2dXCw27EvlH5rq+zwIPDAJHGAfnn1nmQH7wR3PCatEIb8pz5GFlTHMlluw4ZYmnOwg+thwIDAQAB"
public_key_der = base64.b64decode(public_key_base64)
key = RSA.importKey(public_key_der)
cipher = PKCS1_v1_5.new(key)
password_bytes = password.encode('utf-8')
encrypted_password = cipher.encrypt(password_bytes)
encrypted_password_base64 = base64.b64encode(encrypted_password).decode('utf-8')
url_encoded_data = urllib.parse.quote(encrypted_password_base64)
return url_encoded_data
#生成设备号
def generate_random_uuid():
# 设备号其实可以写死,保险起见选择随机生成
uuid_str = '00000000-{:04x}-{:04x}-0000-0000{:08x}'.format(
random.randint(0, 0xfff) | 0x4000,
random.randint(0, 0x3fff) | 0x8000,
random.getrandbits(32)
)
return uuid_str
# 签名并获取认证码
def sign(phone, password):
url_encoded_data = jm(password)
url = "https://passport.tmuyun.com/web/oauth/credential_auth"
payload = f"client_id=10019&password={url_encoded_data}&phone_number={phone}"
print(payload)
headers = {
'User-Agent': "ANDROID;13;10019;6.0.2;1.0;null;MEIZU 20",
'Connection': "Keep-Alive",
'Accept-Encoding': "gzip",
'Content-Type': "application/x-www-form-urlencoded",
'Cache-Control': "no-cache",
'X-SIGNATURE': "185d21c6f3e9ec4af43e0065079b8eb7f1bb054134481e57926fcc45e304b896",
}
response = requests.post(url, data=payload, headers=headers)
print(response.json())
code = response.json()['data']['authorization_code']['code']
url = "https://vapp.taizhou.com.cn/api/zbtxz/login"
payload = f"check_token=&code={code}&token=&type=-1&union_id="
headers = {
'User-Agent': "6.0.2;{deviceid};Meizu MEIZU 20;Android;13;tencent;6.10.0",
'Connection': "Keep-Alive",
'Accept-Encoding': "gzip",
'Content-Type': "application/x-www-form-urlencoded",
'X-SESSION-ID': "66586b383f293a7173e4c8f4",
'X-REQUEST-ID': "110c1987-1637-4f4e-953e-e35272bb891e",
'X-TIMESTAMP': "1717072109065",
'X-SIGNATURE': "a69f171e284594a5ecc4baa1b2299c99167532b9795122bae308f27592e94381",
'X-TENANT-ID': "64",
'Cache-Control': "no-cache"
}
response = requests.post(url, data=payload, headers=headers)
message = response.json()['message']
account_id = response.json()['data']['account']['id']
session_id = response.json()['data']['session']['id']
name = response.json()['data']['account']['nick_name']
return message, account_id, session_id, name
#生成验证码
def generate_md5(input_str):
md5_obj = hashlib.md5()
input_str_encoded = input_str.encode('utf-8')
md5_obj.update(input_str_encoded)
return md5_obj.hexdigest()
#获取阅读的JSESSIONID
def get_special_cookie():
special_cookie_url = f'https://xmt.taizhou.com.cn/prod-api/user-read/app/login?id={account_id}&sessionId={session_id}&deviceId={deviceid}'
headers = {
'Host': 'xmt.taizhou.com.cn',
'User-Agent': 'Mozilla/5.0 (Linux; Android 13; MEIZU 20 Build/QKQ1.190828.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.101 Mobile Safari/537.36;xsb_wangchao;xsb_wangchao;6.0.2;native_app;6.10.0',
'Accept': '*/*',
'X-Requested-With': 'com.shangc.tiennews.taizhou',
'Sec-Fetch-Site': 'same-origin',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Dest': 'empty',
'Referer': 'https://xmt.taizhou.com.cn/readingAward-v7-3/?gaze_control=01',
'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
}
response = requests.get(special_cookie_url, headers=headers)
if debug and response.status_code == 200:
print('执行任务获取阅读jse')
print('下面是访问的url\n',special_cookie_url)
print('下面是访问的headers\n',headers)
print('下面是返回的response\n',response.headers)
if response.status_code == 200 and response.headers['Set-Cookie']:
jsessionid1 =response.headers['Set-Cookie'].split(';')[0]+';'
print('获取特殊cookie成功',jsessionid1)
return response.headers['Set-Cookie']
else:
print('获取jsesesionid失败',response.headers)
#获取日期
def get_current_date():
now = datetime.datetime.now()
year_str = str(now.year)
month_str = f"0{now.month}" if now.month < 10 else str(now.month)
day_str = f"0{now.day}" if now.day < 10 else str(now.day)
print(f"当前日期{year_str}{month_str}{day_str}")
return year_str + month_str + day_str
#获取阅读列表
def fetch_article_list():
headers = {
'Host': 'xmt.taizhou.com.cn',
'User-Agent': 'Mozilla/5.0 (Linux; Android 13; MEIZU 20 Build/QKQ1.190828.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.101 Mobile Safari/537.36;xsb_wangchao;xsb_wangchao;6.0.2;native_app;6.10.0',
'Accept': '*/*',
'X-Requested-With': 'com.shangc.tiennews.taizhou',
'Sec-Fetch-Site': 'same-origin',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Dest': 'empty',
'Referer': 'https://xmt.taizhou.com.cn/readingAward-v7-3/?gaze_control=01',
'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
'cookie': f'{special_cookie};'
}
url=f'https://xmt.taizhou.com.cn/prod-api/user-read/list/{get_current_date()}'
response = requests.get(url, headers=headers)
if debug and response.status_code == 200:
print('执行任务获取阅读列表')
print('下面是访问的url\n',url)
print('下面是访问的headers\n',headers)
print('下面是返回的response\n',response.headers)
msg = response.json()['msg']
print(msg)
return response.json()
def encrypt_with_sm2(article_id, account_id):
# 获取当前时间戳
timestamp = int(time.time() * 1000)
# 构造数据
data = {
"timestamp": timestamp,
"articleId": article_id,
"accountId": account_id
}
# 将数据序列化为JSON字符串
data_json = json.dumps(data, separators=(',', ':'))
print("Data to be encrypted:", data_json)
# SM2公钥确保公钥以04开头未压缩格式
public_key_hex = "04A50803A27F000D6B310607EBA2A1C899E82872C0B538CA41DB6F0183B4C7E164DAFC6946ABF93C8AF1C0AD96D0E770D29264EF9F907DDBAE97A2A0BB1036D4AC"
public_key = bytes.fromhex(public_key_hex)
# 创建SM2对象
sm2_crypt = SM2(pk=public_key)
# 加密数据
encrypted_data = sm2_crypt.encrypt(data_json.encode('utf-8'))
print(len(encrypted_data.hex()))
# 返回加密后的十六进制字符串
encrypted_data_hex = encrypted_data.hex()
#去掉前面两位
encrypted_data_hex = encrypted_data_hex[2:]
return encrypted_data_hex
#阅读文章
def mark_article_as_read(article_id,retry_count=3):
headers = {
'Host': 'xmt.taizhou.com.cn',
'User-Agent': 'Mozilla/5.0 (Linux; Android 13; MEIZU 20 Build/QKQ1.190828.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.101 Mobile Safari/537.36;xsb_wangchao;xsb_wangchao;6.0.2;native_app;6.10.0',
'Accept': '*/*',
'X-Requested-With': 'com.shangc.tiennews.taizhou',
'Sec-Fetch-Site': 'same-origin',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Dest': 'empty',
'Referer': 'https://xmt.taizhou.com.cn/readingAward-v7-3/?gaze_control=01',
'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
'cookie': f'{special_cookie}',
}
timestamp_str = str(math.floor(time.time() * 1000))
signature = encrypt_with_sm2(article_id,account_id)
url = f'https://xmt.taizhou.com.cn/prod-api/already-read/article/new?signature={signature}'
print(url)
# 创建一个包含重试策略的会话
session = requests.Session()
retries = Retry(total=5, backoff_factor=1, status_forcelist=[502, 503, 504])
session.mount('https://', HTTPAdapter(max_retries=retries))
for attempt in range(retry_count):
try:
response = session.get(url, headers=headers, timeout=10)
if response.status_code == 200:
print(response.text)
return
else:
print(f"请求失败,状态码: {response.status_code}, 响应内容: {response.text}")
except requests.exceptions.RequestException as e:
print(f"请求失败 (尝试 {attempt + 1}/{retry_count}): {e}")
time.sleep(2) # 在重试前增加延迟
# 登录并获取抽奖JSESSIONID
def login(account_id, session_id, retry_count=3):
base_url = 'https://srv-app.taizhou.com.cn'
url = f'{base_url}/tzrb/user/loginWC'
headers = {
'Host': 'srv-app.taizhou.com.cn',
'Connection': 'keep-alive',
'Pragma': 'no-cache',
'Cache-Control': 'no-cache',
'User-Agent': 'Mozilla/5.0 (Linux; Android 13; MEIZU 20 Build/QKQ1.190828.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.101 Mobile Safari/537.36;xsb_wangchao;xsb_wangchao;6.0.2;native_app;6.10.0',
'Accept': '*/*',
'X-Requested-With': 'com.shangc.tiennews.taizhou',
'Sec-Fetch-Site': 'same-origin',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Dest': 'empty',
'Referer': 'https://srv-app.taizhou.com.cn/luckdraw/',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7'
}
params = {
'accountId': account_id,
'sessionId': session_id
}
# 创建一个包含重试策略的会话
session = requests.Session()
retries = Retry(total=5, backoff_factor=1, status_forcelist=[502, 503, 504])
session.mount('https://', HTTPAdapter(max_retries=retries))
for attempt in range(retry_count):
try:
response = session.get(url, params=params, headers=headers, timeout=10)
if response.status_code == 200:
cookies_dict = response.cookies.get_dict()
s_JSESSIONID = '; '.join([f'{k}={v}' for k, v in cookies_dict.items()])
return s_JSESSIONID
else:
print(f"请求失败,状态码: {response.status_code}, 响应内容: {response.text}")
except requests.exceptions.RequestException as e:
print(f"请求失败 (尝试 {attempt + 1}/{retry_count}): {e}")
time.sleep(2) # 在重试前增加延迟
return None
#抽奖
def cj(jsessionid, retry_count=3):
url = "https://srv-app.taizhou.com.cn/tzrb/userAwardRecordUpgrade/saveUpdate"
payload = "activityId=67&sessionId=undefined&sig=undefined&token=undefined"
headers = {
'Host': 'srv-app.taizhou.com.cn',
'Connection': 'keep-alive',
'Content-Length': '63',
'User-Agent': 'Mozilla/5.0 (Linux; Android 10; MI 8 Build/QKQ1.190828.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.101 Mobile Safari/537.36;xsb_wangchao;xsb_wangchao;6.0.2;native_app;6.10.0',
'Content-type': 'application/x-www-form-urlencoded',
'Accept': '*/*',
'Origin': 'https://srv-app.taizhou.com.cn',
'X-Requested-With': 'com.shangc.tiennews.taizhou',
'Sec-Fetch-Site': 'same-origin',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Dest': 'empty',
'Referer': 'https://srv-app.taizhou.com.cn/luckdraw-ra-1/',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
'Cookie': f'{jsessionid}'
}
# 创建一个包含重试策略的会话
session = requests.Session()
retries = Retry(total=4, backoff_factor=1, status_forcelist=[502, 503, 504])
session.mount('https://', HTTPAdapter(max_retries=retries))
for attempt in range(retry_count):
try:
response = session.post(url, data=payload, headers=headers, timeout=10)
if response.status_code == 200:
print(response.text)
display_draw_results(jsessionid)
return # 成功则退出函数
else:
print(f"POST 请求失败,状态码: {response.status_code}, 响应内容: {response.text}")
except requests.exceptions.RequestException as e:
print(f"POST 请求失败 (尝试 {attempt + 1}/{retry_count}): {e}")
time.sleep(2) # 在重试前增加延迟
#查询抽奖结果
def display_draw_results(cookies):
draw_result_headers = {
'Host': 'srv-app.taizhou.com.cn',
'Connection': 'keep-alive',
'User-Agent': 'Mozilla/5.0 (Linux; Android 13; MEIZU 20 Build/QKQ1.190828.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.101 Mobile Safari/537.36;xsb_wangchao;xsb_wangchao;6.0.2;native_app;6.10.0',
'Accept': '*/*',
'X-Requested-With': 'com.shangc.tiennews.taizhou',
'Sec-Fetch-Site': 'same-origin',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Dest': 'empty',
'Referer': 'https://srv-app.taizhou.com.cn/luckdraw-awsc-231023/',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
'Cookie': f'{cookies}',
}
result_url = 'https://srv-app.taizhou.com.cn/tzrb/userAwardRecordUpgrade/pageList?pageSize=10&pageNum=1&activityId=67'
result_data = requests.get(result_url, headers=draw_result_headers).json()["data"]["records"]
for record in result_data:
create_time_str = str(record["createTime"])
award_name_str = str(record["awardName"])
print(f"{create_time_str}---------{award_name_str}")
# 从环境变量中读取账户和密码
accounts = os.getenv("wangchaoAccount")
if not accounts:
print("❌未找到环境变量!")
else:
accounts_list = accounts.split("&")
print(f"一共在环境变量中获取到 {len(accounts_list)} 个账号")
for account in accounts_list:
password, phone = account.split("#")
message, account_id, session_id, name = sign(phone, password)
deviceid = generate_random_uuid()
print()
if account_id and session_id:
mobile = phone[:3] + "*" * 4 + phone[7:]
print(f"账号 {mobile} 登录成功")
special_cookie = get_special_cookie()
print(f"账号 {mobile} 获取阅读列表")
article_list = fetch_article_list()
for article in article_list['data']['articleIsReadList']:
article_title = article['title']
if article['isRead'] == True :
print(f"√文章{article_title}已读")
time.sleep(0.5)
continue
else:
time.sleep(random.uniform(3.5, 4.5))
article_id = article['id']
print(f"账号 {mobile} 阅读文章 {article_title}")
mark_article_as_read(article_id)
time.sleep(1)
jsessionid = login(account_id, session_id)
if jsessionid:
print('去抽奖')
cj(jsessionid)
else:
print(f"获取 JSESSIONID 失败")
else:
print(f"账号 {phone} 登录失败")
# 每个账号登录后延迟...
print("等待 5 秒后继续下一个账号...")
time.sleep(5)
print("所有账号处理完毕")

View File

@@ -0,0 +1,707 @@
// # Source: https://github.com/imoki/sign_script/blob/main/polymerization/wnflb.js
// # Raw: https://raw.githubusercontent.com/imoki/sign_script/main/polymerization/wnflb.js
// # Repo: imoki/sign_script
// # Path: polymerization/wnflb.js
// # UploadedAt: 2025-08-25T21:29:14+08:00
// # SHA256: a0c784cb397ebb321cc918c6d14410bb2e9902d6e2236b6893b2c6fa2779cd01
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
/*
name: "万能福利吧"
cron: 45 0 9 * * *
脚本兼容: 金山文档1.0金山文档2.0
更新时间20241226
环境变量名:无
环境变量值:无
备注需要cookie。F12 -> "NetWork"(中文名叫"网络") -> 按一下Ctrl+R -> www.wnflb2023.com -> cookie
有门槛,没账号的不用折腾。
万能福利吧网址https://www.wnflb2023.com
*/
var sheetNameSubConfig = "wnflb"; // 分配置表名称
var pushHeader = "【万能福利吧】";
var sheetNameConfig = "CONFIG"; // 总配置表
var sheetNamePush = "PUSH"; // 推送表名称
var sheetNameEmail = "EMAIL"; // 邮箱表
var flagSubConfig = 0; // 激活分配置工作表标志
var flagConfig = 0; // 激活主配置工作表标志
var flagPush = 0; // 激活推送工作表标志
var line = 21; // 指定读取从第2行到第line行的内容
var message = ""; // 待发送的消息
var messageArray = []; // 待发送的消息数据,每个元素都是某个账号的消息。目的是将不同用户消息分离,方便个性化消息配置
var messageOnlyError = 0; // 0为只推送失败消息1则为推送成功消息。
var messageNickname = 0; // 1为推送位置标识昵称/单元格Ax昵称为空时0为不推送位置标识
var messageHeader = []; // 存放每个消息的头部单元格A3。目的是分离附加消息和执行结果消息
var messagePushHeader = pushHeader; // 存放在总消息的头部默认是pushHeader,如【xxxx】
var version = 1 // 版本类型自动识别并适配。默认为airscript 1.0否则为2.0Beta
var separator = "##########MOKU##########" // 分割符分割消息。可用于PUSH.js灵活推送
var maxMessageLength = 400; // 设置最大长度,超过这个长度则分片发送
var messageDistance = 100; // 消息距离用于匹配100字符内最近的行
var jsonPush = [
{ name: "bark", key: "xxxxxx", flag: "0" },
{ name: "pushplus", key: "xxxxxx", flag: "0" },
{ name: "ServerChan", key: "xxxxxx", flag: "0" },
{ name: "email", key: "xxxxxx", flag: "0" },
{ name: "dingtalk", key: "xxxxxx", flag: "0" },
{ name: "discord", key: "xxxxxx", flag: "0" },
]; // 推送数据flag=1则推送
var jsonEmail = {
server: "",
port: "",
sender: "",
authorizationCode: "",
}; // 有效邮箱配置
// =================青龙适配开始===================
qlSwitch = 0
// =================青龙适配结束===================
// =================金山适配开始===================
// airscript检测版本
function checkVesion(){
try{
let temp = Application.Range("A1").Text;
Application.Range("A1").Value = temp
console.log("😶‍🌫️ 检测到当前airscript版本为1.0进行1.0适配")
}catch{
console.log("😶‍🌫️ 检测到当前airscript版本为2.0进行2.0适配")
version = 2
}
}
// 推送相关
// 获取时间
function getDate(){
let currentDate = new Date();
currentDate = currentDate.getFullYear() + '/' + (currentDate.getMonth() + 1).toString() + '/' + currentDate.getDate().toString();
return currentDate
}
// 将消息写入CONFIG表中作为消息队列之后统一发送
function writeMessageQueue(message){
// 当天时间
let todayDate = getDate()
flagConfig = ActivateSheet(sheetNameConfig); // 激活主配置表
// 主配置工作表存在
if (flagConfig == 1) {
console.log("✨ 开始将结果写入主配置表");
for (let i = 2; i <= 100; i++) {
if(version == 1){
// 找到指定的表行
if(Application.Range("A" + (i + 2)).Value == sheetNameSubConfig){
// 写入更新的时间
Application.Range("F" + (i + 2)).Value = todayDate
// 写入消息
Application.Range("G" + (i + 2)).Value = message
console.log("✨ 写入结果完成");
break;
}
}else{
// 找到指定的表行
if(Application.Range("A" + (i + 2)).Value2 == sheetNameSubConfig){
// 写入更新的时间
Application.Range("F" + (i + 2)).Value2 = todayDate
// 写入消息
Application.Range("G" + (i + 2)).Value2 = message
console.log("✨ 写入结果完成");
break;
}
}
}
}
}
// 总推送
function push(message) {
writeMessageQueue(message) // 将消息写入CONFIG表中
// if (message != "") {
// // message = messagePushHeader + message // 消息头最前方默认存放【xxxx】
// let length = jsonPush.length;
// let name;
// let key;
// for (let i = 0; i < length; i++) {
// if (jsonPush[i].flag == 1) {
// name = jsonPush[i].name;
// key = jsonPush[i].key;
// if (name == "bark") {
// bark(message, key);
// } else if (name == "pushplus") {
// pushplus(message, key);
// } else if (name == "ServerChan") {
// serverchan(message, key);
// } else if (name == "email") {
// email(message);
// } else if (name == "dingtalk") {
// dingtalk(message, key);
// } else if (name == "discord") {
// discord(message, key);
// }
// }
// }
// } else {
// console.log("🍳 消息为空不推送");
// }
}
// 推送bark消息
function bark(message, key) {
if (key != "") {
message = messagePushHeader + message // 消息头最前方默认存放【xxxx】
message = encodeURIComponent(message)
BARK_ICON = "https://s21.ax1x.com/2024/06/23/pkrUkfe.png"
let url = "https://api.day.app/" + key + "/" + message + "/" + "?icon=" + BARK_ICON;
// 若需要修改推送的分组,则将上面一行改为如下的形式
// let url = 'https://api.day.app/' + bark_id + "/" + message + "?group=分组名";
let resp = HTTP.get(url, {
headers: { "Content-Type": "application/x-www-form-urlencoded" },
});
sleep(5000);
}
}
// 推送pushplus消息
function pushplus(message, key) {
if (key != "") {
message = encodeURIComponent(message)
// url = "http://www.pushplus.plus/send?token=" + key + "&content=" + message;
url = "http://www.pushplus.plus/send?token=" + key + "&content=" + message + "&title=" + pushHeader; // 增加标题
let resp = HTTP.fetch(url, {
method: "get",
});
sleep(5000);
}
}
// 推送serverchan消息
function serverchan(message, key) {
if (key != "") {
url =
"https://sctapi.ftqq.com/" +
key +
".send" +
"?title=" + messagePushHeader +
"&desp=" +
message;
let resp = HTTP.fetch(url, {
method: "get",
});
sleep(5000);
}
}
// email邮箱推送
function email(message) {
var myDate = new Date(); // 创建一个表示当前时间的 Date 对象
var data_time = myDate.toLocaleDateString(); // 获取当前日期的字符串表示
let server = jsonEmail.server;
let port = parseInt(jsonEmail.port); // 转成整形
let sender = jsonEmail.sender;
let authorizationCode = jsonEmail.authorizationCode;
let mailer;
mailer = SMTP.login({
host: server,
port: port,
username: sender,
password: authorizationCode,
secure: true,
});
mailer.send({
from: pushHeader + "<" + sender + ">",
to: sender,
subject: pushHeader + " - " + data_time,
text: message,
});
// console.log("🍳 已发送邮件至:" + sender);
console.log("🍳 已发送邮件");
sleep(5000);
}
// 邮箱配置
function emailConfig() {
console.log("🍳 开始读取邮箱配置");
let length = jsonPush.length; // 因为此json数据可无序因此需要遍历
let name;
for (let i = 0; i < length; i++) {
name = jsonPush[i].name;
if (name == "email") {
if (jsonPush[i].flag == 1) {
let flag = ActivateSheet(sheetNameEmail); // 激活邮箱表
// 邮箱表存在
// var email = {
// 'email':'', 'port':'', 'sender':'', 'authorizationCode':''
// } // 有效配置
if (flag == 1) {
console.log("🍳 开始读取邮箱表");
for (let i = 2; i <= 2; i++) {
// 从工作表中读取推送数据
jsonEmail.server = Application.Range("A" + i).Text;
jsonEmail.port = Application.Range("B" + i).Text;
jsonEmail.sender = Application.Range("C" + i).Text;
jsonEmail.authorizationCode = Application.Range("D" + i).Text;
if (Application.Range("A" + i).Text == "") {
// 如果为空行,则提前结束读取
break;
}
}
// console.log(jsonEmail)
}
break;
}
}
}
}
// 推送钉钉机器人
function dingtalk(message, key) {
message = messagePushHeader + message // 消息头最前方默认存放【xxxx】
let url = "https://oapi.dingtalk.com/robot/send?access_token=" + key;
let resp = HTTP.post(url, { msgtype: "text", text: { content: message } });
// console.log(resp.text())
sleep(5000);
}
// 推送Discord机器人
function discord(message, key) {
message = messagePushHeader + message // 消息头最前方默认存放【xxxx】
let url = key;
let resp = HTTP.post(url, { content: message });
//console.log(resp.text())
sleep(5000);
}
// =================金山适配结束===================
// =================共用开始===================
// main() // 入口
// function main(){
checkVesion() // 版本检测,以进行不同版本的适配
flagConfig = ActivateSheet(sheetNameConfig); // 激活推送表
// 主配置工作表存在
if (flagConfig == 1) {
console.log("🍳 开始读取主配置表");
let name; // 名称
let onlyError;
let nickname;
for (let i = 2; i <= 100; i++) {
// 从工作表中读取推送数据
name = Application.Range("A" + i).Text;
onlyError = Application.Range("C" + i).Text;
nickname = Application.Range("D" + i).Text;
if (name == "") {
// 如果为空行,则提前结束读取
break; // 提前退出,提高效率
}
if (name == sheetNameSubConfig) {
if (onlyError == "是") {
messageOnlyError = 1;
console.log("🍳 只推送错误消息");
}
if (nickname == "是") {
messageNickname = 1;
console.log("🍳 单元格用昵称替代");
}
break; // 提前退出,提高效率
}
}
}
flagPush = ActivateSheet(sheetNamePush); // 激活推送表
// 推送工作表存在
if (flagPush == 1) {
console.log("🍳 开始读取推送工作表");
let pushName; // 推送类型
let pushKey;
let pushFlag; // 是否推送标志
for (let i = 2; i <= line; i++) {
// 从工作表中读取推送数据
pushName = Application.Range("A" + i).Text;
pushKey = Application.Range("B" + i).Text;
pushFlag = Application.Range("C" + i).Text;
if (pushName == "") {
// 如果为空行,则提前结束读取
break;
}
jsonPushHandle(pushName, pushFlag, pushKey);
}
// console.log(jsonPush)
}
// 邮箱配置函数
emailConfig();
flagSubConfig = ActivateSheet(sheetNameSubConfig); // 激活分配置表
if (flagSubConfig == 1) {
console.log("🍳 开始读取分配置表");
if(qlSwitch != 1){ // 金山文档
for (let i = 2; i <= line; i++) {
var cookie = Application.Range("A" + i).Text;
var exec = Application.Range("B" + i).Text;
if (cookie == "") {
// 如果为空行,则提前结束读取
break;
}
if (exec == "是") {
execHandle(cookie, i);
}
}
message = messageMerge()// 将消息数组融合为一条总消息
push(message); // 推送消息
}else{
for (let i = 2; i <= line; i++) {
var cookie = Application.Range("A" + i).Text;
var exec = Application.Range("B" + i).Text;
if (cookie == "") {
// 如果为空行,则提前结束读取
break;
}
if (exec == "是") {
console.log("🧑 开始执行用户:" + "1" )
execHandle(cookie, i);
break; // 只取一个
}
}
}
}
// }
// 激活工作表函数
function ActivateSheet(sheetName) {
let flag = 0;
try {
// 激活工作表
let sheet = Application.Sheets.Item(sheetName);
sheet.Activate();
console.log("🥚 激活工作表:" + sheet.Name);
flag = 1;
} catch {
flag = 0;
console.log("🍳 无法激活工作表,工作表可能不存在");
}
return flag;
}
// 对推送数据进行处理
function jsonPushHandle(pushName, pushFlag, pushKey) {
let length = jsonPush.length;
for (let i = 0; i < length; i++) {
if (jsonPush[i].name == pushName) {
if (pushFlag == "是") {
jsonPush[i].flag = 1;
jsonPush[i].key = pushKey;
}
}
}
}
// 将消息数组融合为一条总消息
function messageMerge(){
// console.log(messageArray)
let message = ""
for(i=0; i<messageArray.length; i++){
if(messageArray[i] != "" && messageArray[i] != null)
{
message += "\n" + messageHeader[i] + messageArray[i] + ""; // 加上推送头
}
}
if(message != "")
{
console.log("✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨")
console.log(message + "\n") // 打印总消息
console.log("✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨")
}
return message
}
function sleep(d) {
for (var t = Date.now(); Date.now() - t <= d; );
}
// 获取sign返回小写
function getsign(data) {
var sign = Crypto.createHash("md5")
.update(data, "utf8")
.digest("hex")
// .toUpperCase() // 大写
.toString();
return sign;
}
// =================共用结束===================
// cookie字符串转json格式
function cookie_to_json(cookies) {
var cookie_text = cookies;
var arr = [];
var text_to_split = cookie_text.split(";");
for (var i in text_to_split) {
var tmp = text_to_split[i].split("=");
arr.push('"' + tmp.shift().trim() + '":"' + tmp.join(":").trim() + '"');
}
var res = "{\n" + arr.join(",\n") + "\n}";
return JSON.parse(res);
}
// 获取10 位时间戳
function getts10() {
var ts = Math.round(new Date().getTime() / 1000).toString();
return ts;
}
// 获取13位时间戳
function getts13(){
// var ts = Math.round(new Date().getTime()/1000).toString() // 获取10 位时间戳
let ts = new Date().getTime()
return ts
}
// 符合UUID v4规范的随机字符串 b9ab98bb-b8a9-4a8a-a88a-9aab899a88b9
function generateUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0,
v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
function getUUIDDigits(length) {
var uuid = generateUUID();
return uuid.replace(/-/g, '').substr(16, length);
}
// 具体的执行函数
function execHandle(cookie, pos) {
let messageSuccess = "";
let messageFail = "";
let messageName = "";
// 推送昵称或单元格,还是不推送位置标识
if (messageNickname == 1) {
// 推送昵称或单元格
messageName = Application.Range("C" + pos).Text;
if(messageName == "")
{
messageName = "单元格A" + pos + "";
}
}
posLabel = pos-2 ; // 存放下标从0开始
messageHeader[posLabel] = "👨‍🚀 " + messageName
// try {
var url1 = "https://www.wnflb2023.com/plugin.php?id=fx_checkin:list"; // 获取formhash、判断成功+获取积分
var url2 = "https://www.wnflb2023.com/plugin.php?id=fx_checkin%3Acheckin&infloat=yes&handlekey=fx_checkin&inajax=1&ajaxtarget=fwin_content_fx_checkin" // 签到
headers={
"Host": "www.wnflb2023.com",
// "Content-Type": "application/x-www-form-urlencoded",
"Cookie":cookie,
// "Cookie":""
}
// 获取formhash
resp = HTTP.get(
url1,
{ headers: headers }
);
// 正则匹配
formhash = ""
// const Reg = /你已经连续签到(.*?)天,再接再厉!/i;
Reg = [
/formhash=(.+?)&/i,
/showmenu">积分: (.+?)<\/a>/i,
]
valueName = [
"formhash", "签到前积分",
]
html = resp.text();
// console.log(html)
for(i=0; i< Reg.length; i++)
{
flagTrue = Reg[i].test(html); // 判断是否存在字符串
if (flagTrue == true) {
let result = Reg[i].exec(html); // 提取匹配的字符串,["你已经连续签到 1 天,再接再厉!"," 1 "]
// result = result[0];
result = result[1];
if(i == 1){
content = "🎉 " + valueName[i] + ":" + result + " "
messageSuccess += content;
}else
{
formhash = result
content = "🍳 formhash:" + result + " "
}
console.log(content)
} else {
content = "❌ " + "formhash获取失败 "
messageFail += content;
}
}
// 签到
headers={
"Host": "www.wnflb2023.com",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-CN,zh;q=0.9",
// "Content-Type": "application/x-www-form-urlencoded",
"X-Requested-With":"XMLHttpRequest",
"Cookie":cookie,
"Referer":"https://www.wnflb2023.com/",
"DNT":1,
}
params = "&formhash=" + formhash + "&" + formhash
url2 = url2 + params
// console.log(url2)
resp = HTTP.get(
url2,
{ headers: headers }
);
// console.log(resp.text())
// <?xml version="1.0" encoding="utf-8"?>
// <root><![CDATA[<h3 class="flb"><em>提示信息</em><span><a href="javascript:;" class="flbc" onclick="hideWindow('fx_checkin');" title="关闭">关闭</a></span></h3>
// <div class="c altw">
// <div class="alert_right"><script type="text/javascript" reload="1">if(typeof errorhandle_fx_checkin=='function') {errorhandle_fx_checkin('签到成功,您今日第3874个签到,累计签到2851天!', {});}hideWindow('fx_checkin');showDialog('签到成功,您今日第3874个签到,累计签到2851天!', 'right', null, null, 0, null, null, null, null, null, null);</script><script type="text/javascript">fx_chk_menu=true;$('fx_checkin_topb').innerHTML="<a href=\"plugin.php?id=fx_checkin:list\" onmouseover=\"fx_checkin_menu('fx_checkin_topb');\"><img id=\"fx_checkin_b\" src=\"source/plugin/fx_checkin/images/mini2.gif\" style=\"position:relative;top:5px;height:18px;\"></a>";$('fx_checkin_menut').innerHTML="<em>签到成功!</em><p>您今天第<i>3874</i>个签到,签到排名竞争激烈,记得每天都来签到哦!</p>";$('fx_checkin_menub').innerHTML="已连续签到:<i>8</i>天,累计签到:<i>2851</i>天";</script></div>
// </div>
// <p class="o pns">
// <button type="button" class="pn pnc" id="closebtn" onclick="hideWindow('fx_checkin');"><strong>确定</strong></button>
// <script type="text/javascript" reload="1">if($('closebtn')) {$('closebtn').focus();}</script>
// </p>
// ]]></root>
// <?xml version="1.0" encoding="utf-8"?>
// <root><![CDATA[<h3 class="flb"><em>提示信息</em><span><a href="javascript:;" class="flbc" onclick="hideWindow('fx_checkin');" title="关闭">关闭</a></span></h3>
// <div class="c altw">
// <div class="alert_right"><script type="text/javascript" reload="1">if(typeof errorhandle_fx_checkin=='function') {errorhandle_fx_checkin('签名出错-2,请重新登陆后签到1!', {});}hideWindow('fx_checkin');showDialog('签名出错-2,请重新登陆后签到1!', 'right', null, null, 0, null, null, null, null, null, null);</script></div>
// </div>
// <p class="o pns">
// <button type="button" class="pn pnc" id="closebtn" onclick="hideWindow('fx_checkin');"><strong>确定</strong></button>
// <script type="text/javascript" reload="1">if($('closebtn')) {$('closebtn').focus();}</script>
// </p>
// ]]></root>
// 获取签到天数数据、获取积分
headers={
"Host": "www.wnflb2023.com",
// "Content-Type": "application/x-www-form-urlencoded",
"Cookie":cookie,
// "Cookie":""
}
resp = HTTP.get(
url1,
{ headers: headers }
);
// console.log(resp.text())
// 正则匹配
// const Reg = /你已经连续签到(.*?)天,再接再厉!/i;
Reg = [
/累计签到:<i>(.+?)<\/i>天/i,
/已连续签到:<i>(.+?)<\/i>天/i,
/showmenu">积分: (.+?)<\/a>/i,
]
valueName = [
"累计签天数", "已连签天数","当前积分",
]
html = resp.text();
// console.log(html)
resultall = ""
for(i=0; i< Reg.length; i++)
{
flagTrue = Reg[i].test(html); // 判断是否存在字符串
if (flagTrue == true) {
let result = Reg[i].exec(html); // 提取匹配的字符串,["你已经连续签到 1 天,再接再厉!"," 1 "]
// result = result[0];
result = result[1];
if(result == "{days}" || result == "{constant}" ){
}else{
content = "🎉 " + valueName[i] + ":" + result + " "
messageSuccess += content;
console.log(content)
}
} else {
content = "❌ " +"签到数据获取失败 "
messageFail += content;
}
}
// // 获取积分
// // 正则匹配,获取formhash
// formhash = ""
// // const Reg = /你已经连续签到(.*?)天,再接再厉!/i;
// Reg = [
// /formhash=(.+?)&/i,
// /showmenu">积分: (.+?)<\/a>/i,
// ]
// valueName = [
// "formhash", "当前积分",
// ]
// // html = resp.text();
// // console.log(html)
// for(i=0; i< Reg.length; i++)
// {
// flagTrue = Reg[i].test(html); // 判断是否存在字符串
// if (flagTrue == true) {
// let result = Reg[i].exec(html); // 提取匹配的字符串,["你已经连续签到 1 天,再接再厉!"," 1 "]
// // result = result[0];
// result = result[1];
// formhash = result
// if(i == 1){
// content = valueName[i] + ":" + result + " "
// messageSuccess += content;
// }else
// {
// content = "formhash:" + result + " "
// }
// console.log(content)
// } else {
// content = "formhash获取失败 "
// messageFail += content;
// }
// }
// } catch {
// messageFail += messageName + "失败";
// }
sleep(2000);
if (messageOnlyError == 1) {
messageArray[posLabel] = messageFail;
} else {
if(messageFail != ""){
messageArray[posLabel] = messageFail + " " + messageSuccess;
}else{
messageArray[posLabel] = messageSuccess;
}
}
if(messageArray[posLabel] != "")
{
console.log(messageArray[posLabel]);
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,124 @@
// # Source: https://github.com/smallfawn/QLScriptPublic/blob/main/daily/chinaMobile.js
// # Raw: https://raw.githubusercontent.com/smallfawn/QLScriptPublic/main/daily/chinaMobile.js
// # Repo: smallfawn/QLScriptPublic
// # Path: daily/chinaMobile.js
// # UploadedAt: 2026-05-14T17:47:57+08:00
// # SHA256: e5179e073c2c16d19741c34ac5e61b83a965616f8437b5ca88a4916dc9d25dec
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
/*
------------------------------------------
@Author: sm
@Date: 2024.06.07 19:15
@Description: 中国移动APP签到
cron: 30 7 * * *
------------------------------------------
#Notice:
变量名:chinaMobile
变量值:https://wx.10086.cn/qwhdhub/api/抓COOKIE中的QWHD_SESSION_TOKEN的值多个账号用&或者换行分隔
⚠️【免责声明】
------------------------------------------
1、此脚本仅用于学习研究不保证其合法性、准确性、有效性请根据情况自行判断本人对此不承担任何保证责任。
2、由于此脚本仅用于学习研究您必须在下载后 24 小时内将所有内容从您的计算机或手机或任何存储设备中完全删除,若违反规定引起任何事件本人对此均不负责。
3、请勿将此脚本用于任何商业或非法目的若违反规定请自行对此负责。
4、此脚本涉及应用与本人无关本人对因此引起的任何隐私泄漏或其他后果不承担任何责任。
5、本人对任何脚本引发的问题概不负责包括但不限于由脚本错误引起的任何损失和损害。
6、如果任何单位或个人认为此脚本可能涉嫌侵犯其权利应及时通知并提供身份证明所有权证明我们将在收到认证文件确认后删除此脚本。
7、所有直接或间接使用、查看此脚本的人均应该仔细阅读此声明。本人保留随时更改或补充此声明的权利。一旦您使用或复制了此脚本即视为您已接受此免责声明。
*/
const { Env } = require("../tools/env")
const $ = new Env("中国移动APP");
let ckName = `chinaMobile`;
const strSplitor = "#";
const axios = require("axios");
const defaultUserAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.31(0x18001e31) NetType/WIFI Language/zh_CN miniProgram"
class Task {
constructor(env) {
this.index = $.userIdx++
this.user = env.split(strSplitor);
this.token = this.user[0];
}
async run() {
await this.signIn()
}
async signIn() {
let toDay = $.time("yyyyMMdd");
let options = {
method: 'POST',
url: 'https://wx.10086.cn/qwhdhub/api/mark/mark31/domark',
headers: {
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_7_15 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148/wkwebview leadeon/12.0.9/CMCCIT',
'x-requested-with': 'XMLHttpRequest',
'Sec-Fetch-Site': 'same-origin',
'Accept-Language': 'zh-CN,zh-Hans;q=0.9',
'Sec-Fetch-Mode': 'cors',
'Content-Type': 'application/json;charset=UTF-8',
'Origin': 'https://wx.10086.cn',
'Referer': 'https://wx.10086.cn/qwhdhub/qwhdmark/1021122301?channelId=P00000057578&yx=9000239640&redCode=rec_feedHotZoneApp_P00000057578&token=QWHDSSOD20260403T185702396DU1021122301Htb7t4R457104',
'login-check': '1',
'Sec-Fetch-Dest': 'empty',
'Cookie': "QWHD_SESSION_TOKEN=" + this.token,
},
data: JSON.stringify({
"date": toDay
})
};
let { data: result } = await axios.request(options);
if (result?.code == 'SUCCESS') {
//打印签到结果
$.log(`🌸账号[${this.index}]` + `🕊签到成功🎉`);
} else {
$.log(`🌸账号[${this.index}] 签到-失败:${result.msg}`)
}
}
}
!(async () => {
await getNotice()
$.checkEnv(ckName);
for (let user of $.userList) {
await new Task(user).run();
}
})()
.catch((e) => console.log(e))
.finally(() => $.done());
async function getNotice() {
try {
let options = {
url: `https://ghproxy.net/https://raw.githubusercontent.com/smallfawn/Note/refs/heads/main/Notice.json`,
headers: {
"User-Agent": defaultUserAgent,
},
timeout:3000
}
let {
data: res
} = await axios.request(options);
$.log(res)
return res
} catch (e) {}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,803 @@
// # Source: https://github.com/imoki/sign_script/blob/main/polymerization/ddmc_ddyt.js
// # Raw: https://raw.githubusercontent.com/imoki/sign_script/main/polymerization/ddmc_ddyt.js
// # Repo: imoki/sign_script
// # Path: polymerization/ddmc_ddyt.js
// # UploadedAt: 2025-08-25T21:29:14+08:00
// # SHA256: 8848c2ac8c9c09a61d016a63d4ebba5937c435dca08666179c5a2be34ed1df8f
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
/*
name: "叮咚鱼塘"
cron: 45 0 9 * * *
脚本兼容: 金山文档1.0金山文档2.0
更新时间20241025
环境变量名:无
环境变量值:无
备注需要Cookie、seedId、propsId。
"叮咚买菜"APP然后用抓包软件进行抓包分别在叮咚鱼塘中点击喂饲料在果园中点击浇水就能抓到含有Cookie、seedId和propsId的包。
*/
var sheetNameSubConfig = "ddmc"; // 分配置表名称
let sheetNameSubConfig2 = "ddmc_ddyt";
var pushHeader = "【叮咚鱼塘】";
var sheetNameConfig = "CONFIG"; // 总配置表
var sheetNamePush = "PUSH"; // 推送表名称
var sheetNameEmail = "EMAIL"; // 邮箱表
var flagSubConfig = 0; // 激活分配置工作表标志
var flagConfig = 0; // 激活主配置工作表标志
var flagPush = 0; // 激活推送工作表标志
var line = 21; // 指定读取从第2行到第line行的内容
var message = ""; // 待发送的消息
var messageArray = []; // 待发送的消息数据,每个元素都是某个账号的消息。目的是将不同用户消息分离,方便个性化消息配置
var messageOnlyError = 0; // 0为只推送失败消息1则为推送成功消息。
var messageNickname = 0; // 1为推送位置标识昵称/单元格Ax昵称为空时0为不推送位置标识
var messageHeader = []; // 存放每个消息的头部单元格A3。目的是分离附加消息和执行结果消息
var messagePushHeader = pushHeader; // 存放在总消息的头部默认是pushHeader,如【xxxx】
var version = 1 // 版本类型自动识别并适配。默认为airscript 1.0否则为2.0Beta
var separator = "##########MOKU##########" // 分割符分割消息。可用于PUSH.js灵活推送
var maxMessageLength = 400; // 设置最大长度,超过这个长度则分片发送
var messageDistance = 100; // 消息距离用于匹配100字符内最近的行
var jsonPush = [
{ name: "bark", key: "xxxxxx", flag: "0" },
{ name: "pushplus", key: "xxxxxx", flag: "0" },
{ name: "ServerChan", key: "xxxxxx", flag: "0" },
{ name: "email", key: "xxxxxx", flag: "0" },
{ name: "dingtalk", key: "xxxxxx", flag: "0" },
{ name: "discord", key: "xxxxxx", flag: "0" },
]; // 推送数据flag=1则推送
var jsonEmail = {
server: "",
port: "",
sender: "",
authorizationCode: "",
}; // 有效邮箱配置
// =================青龙适配开始===================
qlSwitch = 0
// =================青龙适配结束===================
// =================金山适配开始===================
// airscript检测版本
function checkVesion(){
try{
let temp = Application.Range("A1").Text;
Application.Range("A1").Value = temp
console.log("😶‍🌫️ 检测到当前airscript版本为1.0进行1.0适配")
}catch{
console.log("😶‍🌫️ 检测到当前airscript版本为2.0进行2.0适配")
version = 2
}
}
// 推送相关
// 获取时间
function getDate(){
let currentDate = new Date();
currentDate = currentDate.getFullYear() + '/' + (currentDate.getMonth() + 1).toString() + '/' + currentDate.getDate().toString();
return currentDate
}
// 将消息写入CONFIG表中作为消息队列之后统一发送
function writeMessageQueue(message){
// 当天时间
let todayDate = getDate()
flagConfig = ActivateSheet(sheetNameConfig); // 激活主配置表
// 主配置工作表存在
if (flagConfig == 1) {
console.log("✨ 开始将结果写入主配置表");
for (let i = 2; i <= 100; i++) {
// 找到指定的表行
if(Application.Range("A" + (i + 2)).Value == sheetNameSubConfig2){
// 写入更新的时间
Application.Range("F" + (i + 2)).Value = todayDate
// 写入消息
Application.Range("G" + (i + 2)).Value = message
console.log("✨ 写入结果完成");
break;
}
}
}
}
// 总推送
function push(message) {
writeMessageQueue(message) // 将消息写入CONFIG表中
// if (message != "") {
// // message = messagePushHeader + message // 消息头最前方默认存放【xxxx】
// let length = jsonPush.length;
// let name;
// let key;
// for (let i = 0; i < length; i++) {
// if (jsonPush[i].flag == 1) {
// name = jsonPush[i].name;
// key = jsonPush[i].key;
// if (name == "bark") {
// bark(message, key);
// } else if (name == "pushplus") {
// pushplus(message, key);
// } else if (name == "ServerChan") {
// serverchan(message, key);
// } else if (name == "email") {
// email(message);
// } else if (name == "dingtalk") {
// dingtalk(message, key);
// } else if (name == "discord") {
// discord(message, key);
// }
// }
// }
// } else {
// console.log("🍳 消息为空不推送");
// }
}
// 推送bark消息
function bark(message, key) {
if (key != "") {
message = messagePushHeader + message // 消息头最前方默认存放【xxxx】
message = encodeURIComponent(message)
BARK_ICON = "https://s21.ax1x.com/2024/06/23/pkrUkfe.png"
let url = "https://api.day.app/" + key + "/" + message + "/" + "?icon=" + BARK_ICON;
// 若需要修改推送的分组,则将上面一行改为如下的形式
// let url = 'https://api.day.app/' + bark_id + "/" + message + "?group=分组名";
let resp = HTTP.get(url, {
headers: { "Content-Type": "application/x-www-form-urlencoded" },
});
sleep(5000);
}
}
// 推送pushplus消息
function pushplus(message, key) {
if (key != "") {
message = encodeURIComponent(message)
// url = "http://www.pushplus.plus/send?token=" + key + "&content=" + message;
url = "http://www.pushplus.plus/send?token=" + key + "&content=" + message + "&title=" + pushHeader; // 增加标题
let resp = HTTP.fetch(url, {
method: "get",
});
sleep(5000);
}
}
// 推送serverchan消息
function serverchan(message, key) {
if (key != "") {
url =
"https://sctapi.ftqq.com/" +
key +
".send" +
"?title=" + messagePushHeader +
"&desp=" +
message;
let resp = HTTP.fetch(url, {
method: "get",
});
sleep(5000);
}
}
// email邮箱推送
function email(message) {
var myDate = new Date(); // 创建一个表示当前时间的 Date 对象
var data_time = myDate.toLocaleDateString(); // 获取当前日期的字符串表示
let server = jsonEmail.server;
let port = parseInt(jsonEmail.port); // 转成整形
let sender = jsonEmail.sender;
let authorizationCode = jsonEmail.authorizationCode;
let mailer;
mailer = SMTP.login({
host: server,
port: port,
username: sender,
password: authorizationCode,
secure: true,
});
mailer.send({
from: pushHeader + "<" + sender + ">",
to: sender,
subject: pushHeader + " - " + data_time,
text: message,
});
// console.log("🍳 已发送邮件至:" + sender);
console.log("🍳 已发送邮件");
sleep(5000);
}
// 邮箱配置
function emailConfig() {
console.log("🍳 开始读取邮箱配置");
let length = jsonPush.length; // 因为此json数据可无序因此需要遍历
let name;
for (let i = 0; i < length; i++) {
name = jsonPush[i].name;
if (name == "email") {
if (jsonPush[i].flag == 1) {
let flag = ActivateSheet(sheetNameEmail); // 激活邮箱表
// 邮箱表存在
// var email = {
// 'email':'', 'port':'', 'sender':'', 'authorizationCode':''
// } // 有效配置
if (flag == 1) {
console.log("🍳 开始读取邮箱表");
for (let i = 2; i <= 2; i++) {
// 从工作表中读取推送数据
jsonEmail.server = Application.Range("A" + i).Text;
jsonEmail.port = Application.Range("B" + i).Text;
jsonEmail.sender = Application.Range("C" + i).Text;
jsonEmail.authorizationCode = Application.Range("D" + i).Text;
if (Application.Range("A" + i).Text == "") {
// 如果为空行,则提前结束读取
break;
}
}
// console.log(jsonEmail)
}
break;
}
}
}
}
// 推送钉钉机器人
function dingtalk(message, key) {
message = messagePushHeader + message // 消息头最前方默认存放【xxxx】
let url = "https://oapi.dingtalk.com/robot/send?access_token=" + key;
let resp = HTTP.post(url, { msgtype: "text", text: { content: message } });
// console.log(resp.text())
sleep(5000);
}
// 推送Discord机器人
function discord(message, key) {
message = messagePushHeader + message // 消息头最前方默认存放【xxxx】
let url = key;
let resp = HTTP.post(url, { content: message });
//console.log(resp.text())
sleep(5000);
}
// =================金山适配结束===================
// =================共用开始===================
// main() // 入口
// function main(){
checkVesion() // 版本检测,以进行不同版本的适配
flagConfig = ActivateSheet(sheetNameConfig); // 激活推送表
// 主配置工作表存在
if (flagConfig == 1) {
console.log("🍳 开始读取主配置表");
let name; // 名称
let onlyError;
let nickname;
for (let i = 2; i <= 100; i++) {
// 从工作表中读取推送数据
name = Application.Range("A" + i).Text;
onlyError = Application.Range("C" + i).Text;
nickname = Application.Range("D" + i).Text;
if (name == "") {
// 如果为空行,则提前结束读取
break; // 提前退出,提高效率
}
if (name == sheetNameSubConfig) {
if (onlyError == "是") {
messageOnlyError = 1;
console.log("🍳 只推送错误消息");
}
if (nickname == "是") {
messageNickname = 1;
console.log("🍳 单元格用昵称替代");
}
break; // 提前退出,提高效率
}
}
}
flagPush = ActivateSheet(sheetNamePush); // 激活推送表
// 推送工作表存在
if (flagPush == 1) {
console.log("🍳 开始读取推送工作表");
let pushName; // 推送类型
let pushKey;
let pushFlag; // 是否推送标志
for (let i = 2; i <= line; i++) {
// 从工作表中读取推送数据
pushName = Application.Range("A" + i).Text;
pushKey = Application.Range("B" + i).Text;
pushFlag = Application.Range("C" + i).Text;
if (pushName == "") {
// 如果为空行,则提前结束读取
break;
}
jsonPushHandle(pushName, pushFlag, pushKey);
}
// console.log(jsonPush)
}
// 邮箱配置函数
emailConfig();
flagSubConfig = ActivateSheet(sheetNameSubConfig); // 激活分配置表
if (flagSubConfig == 1) {
console.log("🍳 开始读取分配置表");
if(qlSwitch != 1){ // 金山文档
for (let i = 2; i <= line; i++) {
var cookie = Application.Range("A" + i).Text;
var exec = Application.Range("B" + i).Text;
if (cookie == "") {
// 如果为空行,则提前结束读取
break;
}
if (exec == "是") {
execHandle(cookie, i);
}
}
message = messageMerge()// 将消息数组融合为一条总消息
push(message); // 推送消息
}else{
for (let i = 2; i <= line; i++) {
var cookie = Application.Range("A" + i).Text;
var exec = Application.Range("B" + i).Text;
if (cookie == "") {
// 如果为空行,则提前结束读取
break;
}
if (exec == "是") {
console.log("🧑 开始执行用户:" + "1" )
execHandle(cookie, i);
break; // 只取一个
}
}
}
}
// }
// 激活工作表函数
function ActivateSheet(sheetName) {
let flag = 0;
try {
// 激活工作表
let sheet = Application.Sheets.Item(sheetName);
sheet.Activate();
console.log("🥚 激活工作表:" + sheet.Name);
flag = 1;
} catch {
flag = 0;
console.log("🍳 无法激活工作表,工作表可能不存在");
}
return flag;
}
// 对推送数据进行处理
function jsonPushHandle(pushName, pushFlag, pushKey) {
let length = jsonPush.length;
for (let i = 0; i < length; i++) {
if (jsonPush[i].name == pushName) {
if (pushFlag == "是") {
jsonPush[i].flag = 1;
jsonPush[i].key = pushKey;
}
}
}
}
// 将消息数组融合为一条总消息
function messageMerge(){
// console.log(messageArray)
let message = ""
for(i=0; i<messageArray.length; i++){
if(messageArray[i] != "" && messageArray[i] != null)
{
message += "\n" + messageHeader[i] + messageArray[i] + ""; // 加上推送头
}
}
if(message != "")
{
console.log("✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨")
console.log(message + "\n") // 打印总消息
console.log("✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨")
}
return message
}
function sleep(d) {
for (var t = Date.now(); Date.now() - t <= d; );
}
// 获取sign返回小写
function getsign(data) {
var sign = Crypto.createHash("md5")
.update(data, "utf8")
.digest("hex")
// .toUpperCase() // 大写
.toString();
return sign;
}
// =================共用结束===================
// 具体的执行函数
function execHandle(cookie, pos) {
let messageSuccess = "";
let messageFail = "";
let messageName = "";
// 推送昵称或单元格,还是不推送位置标识
if (messageNickname == 1) {
// 推送昵称或单元格
messageName = Application.Range("C" + pos).Text;
if(messageName == "")
{
messageName = "单元格A" + pos + "";
}
}
posLabel = pos-2 ; // 存放下标从0开始
messageHeader[posLabel] = "👨‍🚀 " + messageName
try {
let seedId = Application.Range("F" + pos).Text;
let propsId = Application.Range("G" + pos).Text;
// 获取任务taskCode
let taskCode = []
// 领取任务奖励
let userTaskLogId = []
let url = [
'https://sunquan.api.ddxq.mobi/api/v2/user/signin/',// 积分
'https://farm.api.ddxq.mobi/api/v2/task/achieve?api_version=9.1.0&app_client_id=1&station_id=&stationId=&native_version=&app_version=10.15.0&OSVersion=15&CityId=0201&uid=&latitude=40.123389&longitude=116.345477&lat=40.123389&lng=116.345477&device_token=&gameId=1&taskCode=DAILY_SIGN', // 每日
'https://farm.api.ddxq.mobi/api/v2/task/achieve?api_version=9.1.0&app_client_id=1&station_id=&stationId=&native_version=&app_version=10.1.2&OSVersion=15&CityId=0201&uid=&latitude=40.123389&longitude=116.345477&lat=40.123389&lng=116.345477&device_token=&gameId=1&taskCode=CONTINUOUS_SIGN', // 每日2
'https://farm.api.ddxq.mobi/api/v2/props/feed?api_version=9.1.0&app_client_id=1&station_id=&stationId=&native_version&app_version=10.0.1&OSVersion=15&CityId=0201&uid=&latitude=40.123389&longitude=116.345477&lat=40.123389&lng=116.345477&device_token=&gameId=1&propsId=' + propsId + '&seedId=' + seedId + '&cityCode=0201&feedPro=0&triggerMultiFeed=1',// 喂饲料
'https://farm.api.ddxq.mobi/api/v2/task/list?latitude=40.123389&longitude=116.345477&env=PE&station_id=&city_number=0201&api_version=9.44.0&app_client_id=3&native_version=10.15.0&h5_source=&page_type=2&gameId=1', // 获取任务taskCode
'https://farm.api.ddxq.mobi/api/v2/task/achieve?api_version=9.1.0&app_client_id=1&station_id=&stationId=&native_version=&app_version=10.15.0&OSVersion=15&CityId=0201&uid=&latitude=40.123389&longitude=116.345477&lat=40.123389&lng=116.345477&device_token=&gameId=1&taskCode=', // 完成任务
'https://farm.api.ddxq.mobi/api/v2/task/reward?api_version=9.1.0&app_client_id=1&station_id=&stationId=&native_version=&app_version=10.15.1&OSVersion=15&CityId=0201&uid=&latitude=40.123389&longitude=116.345477&lat=40.123389&lng=116.345477&device_token=&userTaskLogId=',// 领取任务奖励
]
headers = {
'Host': 'farm.api.ddxq.mobi',
'Origin': 'https://game.m.ddxq.mobi',
'Cookie': cookie,
'Accept': '*/*',
// 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 xzone/10.0.1 station_id/' + station_id + ' device_id/' + device_id,
'Accept-Language': 'zh-CN,zh-Hans;q=0.9',
'Referer': 'https://game.m.ddxq.mobi/',
};
headerintegral =
{ // 积分
'Host': 'sunquan.api.ddxq.mobi',
'Cookie': cookie,
'Referer': 'https://activity.m.ddxq.mobi/',
'ddmc-city-number': '0201',
'ddmc-api-version': '9.7.3',
'Origin': 'https://activity.m.ddxq.mobi',
'ddmc-build-version': '10.15.0',
'ddmc-longitude': 114.345477,
'ddmc-latitude': 40.123389,
'ddmc-app-client-id': 3,
'Accept-Language': 'zh-CN,zh-Hans;q=0.9',
'ddmc-channel': ' ',
'Accept': '*/*',
'Content-Type': 'application/x-www-form-urlencoded',
'ddmc-station-id': '',
'ddmc-ip': '',
},
dataintegral = {
'api_version':'9.7.3',
'app_client_id':3,
'app_version':'2.14.5',
'app_client_name':'activity',
'station_id':'',
'native_version':'10.15.0',
'city_number':'0201',
'device_token':'',
'device_id':'',
'latitude':'40.123389',
'longitude':'116.345477',
}
// 积分签到
resp = HTTP.fetch(url[0], {
method: "post",
headers: headerintegral,
data : dataintegral
});
if (resp.status == 200) {
resp = resp.json();
console.log(resp);
code = resp["code"];
msg = resp["msg"];
if(code == 0){
content = "🎉 " + "积分签到成功\n"
messageSuccess += content
console.log(content);
}else{
// {"msg":"出了点问题哦,请稍后再试吧","code":119000001,"timestamp":"2023-08-10 21:06:53","success":false,"exec_time":{}}
// content += "帐号:" + messageName + msg + " ";
content += "📢 " + msg + "\n";
messageFail += content;
console.log(content);
}
} else {
console.log(resp.text());
// content = "帐号:" + messageName + "积分签到失败 "
content = "❌ " + "积分签到失败\n"
messageFail += content;
console.log(content);
}
// 领饲料
let flagSign = 0; // 标识是否领取饲料
let tempmessageFail = ""; // 记录临时失败的消息
// resp = HTTP.fetch(url[1], {
// method: "get",
// headers: headers,
// });
resp = HTTP.get(url[1], {headers: headers,});
if (resp.status == 200) {
resp = resp.json();
console.log(resp);
code = resp["code"];
msg = resp["msg"];
if(code == 0){
// messageSuccess += "帐号:" + messageName + "鱼塘签到成功 "
flagSign = 1;
console.log("🍳 帐号:" + messageName + "鱼塘签到成功 ");
}else{
// {"msg":"今日已完成任务,明日再来吧!","code":601,"timestamp":"2023-08-10 21:23:49","success":false,"exec_time":{}}
// {"msg":"出了点问题哦,请稍后再试吧","code":119000001,"timestamp":"2023-08-10 21:06:53","success":false,"exec_time":{}}
// messageFail += "帐号:" + messageName + msg + " ";
console.log("🍳 帐号:" + messageName + msg + " ");
}
} else {
console.log(resp.text());
// messageFail += "帐号:" + messageName + "签到失败 ";
console.log("🍳 帐号:" + messageName + "签到失败 ");
}
// resp = HTTP.fetch(url[2], {
// method: "get",
// headers: headers,
// });
resp = HTTP.get(url[2], {headers: headers,});
if (resp.status == 200) {
resp = resp.json();
console.log(resp);
code = resp["code"];
msg = resp["msg"];
if(code == 0 ){
flagSign = 1;
console.log("🍳 帐号:" + messageName + "鱼塘签到成功 ");
}else{
if(code == 601){
// 此不为错误消息
// {"msg":"今日已完成任务,明日再来吧!","code":601,"timestamp":"2024-06-13 20:30:28","success":false}
flagSign = 1;
console.log("🍳 帐号:" + messageName + msg + " ");
}else{
// content = "帐号:" + messageName + msg + " ";
content = "❌ " + msg + "\n";
tempmessageFail = content;
console.log(content);
}
}
} else {
console.log(resp.text());
// content = "帐号:" + messageName + "签到失败 ";
content = "❌ " + "签到失败\n";
tempmessageFail = content;
console.log(content);
}
if(flagSign == 1){
// content = "帐号:" + messageName + "鱼塘签到成功 "
content = "🎉 " + "鱼塘签到成功\n"
messageSuccess += content;
}else{
messageFail += tempmessageFail;
}
// 获取任务列表
// resp = HTTP.fetch(url[4], {
// method: "get",
// headers: headers,
// });
resp = HTTP.get(url[4], {headers: headers,});
if (resp.status == 200) {
resp = resp.json();
// console.log(resp);
code = resp["code"];
if(code == 0){
console.log("🍳 正在获取taskCode ");
userTasks = resp["data"]["userTasks"];
for (let j = 0; j < userTasks.length; j++) {
taskCode[j] = userTasks[j]["taskCode"]
}
console.log(taskCode)
}else{
console.log("🍳 获取taskCode失败 ");
}
} else {
console.log(resp.text());
console.log("🍳 获取taskCode失败 ");
}
// taskCode = ["ANY_ORDER","BROWSE_GOODS","BUY_GOODS","CONTINUOUS_SIGN","DAILY_SIGN","FIRST_ORDER","HARD_BOX","INVITATION","LOTTERY","LUCK_DRAW","MULTI_ORDER","STEAL_FEED"]
// 完成任务
if(taskCode.length > 0){
console.log("🍳 尝试完成任务...")
for (let j = 0; j < taskCode.length; j++) {
urlTask = url[5] + taskCode[j]
// console.log(urlTask)
try{
// resp = HTTP.fetch(urlTask, {
// method: "get",
// headers: headers,
// });
resp = HTTP.get(urlTask, {headers: headers,});
// console.log(resp.text())
sleep(2000)
}catch{
console.log("🍳 忽略任务:" + taskCode[j])
}
}
}
// 获取奖励id
// resp = HTTP.fetch(url[4], {
// method: "get",
// headers: headers,
// });
resp = HTTP.get(url[4], {headers: headers,});
if (resp.status == 200) {
resp = resp.json();
// console.log(resp);
code = resp["code"];
if(code == 0){
console.log("🍳 正在获取userTaskLogId ");
userTasks = resp["data"]["userTasks"];
let temp
let num = 0
for (let j = 0; j < userTasks.length; j++) {
temp = userTasks[j]["userTaskLogId"]
// console.log(typeof(temp))
// console.log(temp.length) // 长度为18才是id
if(typeof(temp) != "object"){ // || temp != "{}" || temp != "null" || temp != "" || temp != null
userTaskLogId[num] = temp
num += 1
}
}
console.log(userTaskLogId)
}else{
console.log("🍳 获取userTaskLogId失败 ");
}
} else {
console.log(resp.text());
console.log("🍳 获取userTaskLogId失败 ");
}
// 领取任务奖励
if(userTaskLogId.length > 0){
console.log("🍳 尝试领取任务奖励...")
for (let j = 0; j < userTaskLogId.length; j++) {
urlTask = url[6] + userTaskLogId[j]
// console.log(urlTask)
try{
// resp = HTTP.fetch(urlTask, {
// method: "get",
// headers: headers,
// });
resp = HTTP.get(urlTask, {headers: headers,});
// console.log(resp.text())
sleep(2000)
}catch{
console.log("🍳 忽略任务:" + userTaskLogId[j])
}
}
}else{
console.log("🍳 没有可领取的奖励")
}
// 喂饲料
let amount = 10; // 记录剩余数目
let amoutCount = 0; // 已喂饲料次数
let flagAmount = 0; // 标志1为饲料
let countSeedId = 0; // 计算是不是每次浇花的剩余水量都一样如果三次都一样则认为seedid过期
let lastamount = 0; // 记录上一次剩余水量
while(amount >= 10){
// resp = HTTP.fetch(url[3], {
// method: "get",
// headers: headers,
// });
resp = HTTP.get(url[3], {headers: headers,});
if (resp.status == 200) {
resp = resp.json();
// console.log(resp);
code = resp["code"];
msg = resp["msg"];
if(code == 0){
amount = resp["data"]["props"]["amount"];
// 用于判断seedId是否过期也即浇水是否失败
if(lastamount == amount){ // 和上次剩余水量一样,可能没浇水成功
countSeedId += 1; // 记录相同次数
}else{
countSeedId = 0; // 水量不同,浇水成功,置零
}
lastamount = amount; // 记录水量,以便下一次循环使用
if(countSeedId >=3){ // 浇了三次剩余水量都相同则认为浇水失败不再浇水并提醒用户更换新的seedId值
msg = "[❗❗❗提醒]seedId值可能过期请抓包获取最新的值"
messageFail += "[❗❗❗提醒]seedId值可能过期请抓包获取最新的值"
console.log("🍳 提前退出浇水,错误消息为:" + msg)
amoutCount -= 3; // 减去浇水失败的次数
break;
}
flagAmount = 1;
amoutCount += 1;
console.log("🍳 喂饲料中... ,剩余饲料:" + amount)
}else{
console.log(resp);
console.log("🍳 提前退出喂饲料,错误消息为:" + msg)
amount = 0; // 直接置水为0 退出投喂
}
} else {
console.log(resp.text());
console.log("🍳 提前退出喂饲料")
amount = 0; // 直接置水为0 退出投喂
}
sleep(3000)
}
if(flagAmount == 1){
content = "🎉 " + "成功喂饲料" + amoutCount + "次\n"
messageSuccess += content
console.log(content);
}else{
// messageFail += "喂饲料日志:" + msg + " "; // 此错误消息无需推送
console.log("📢 " + "喂饲料日志:" + msg + " ");
}
} catch {
messageFail += "❌ " + messageName + "失败\n";
}
sleep(2000);
if (messageOnlyError == 1) {
messageArray[posLabel] = messageFail;
} else {
if(messageFail != ""){
messageArray[posLabel] = messageFail + " " + messageSuccess;
}else{
messageArray[posLabel] = messageSuccess;
}
}
if(messageArray[posLabel] != "")
{
console.log(messageArray[posLabel]);
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,586 @@
// # Source: https://gitee.com/jdqlscript/toulu/blob/main/%E5%93%81%E8%B5%9E%E4%BB%A3%E7%90%86.js
// # Raw: https://gitee.com/jdqlscript/toulu/raw/main/%E5%93%81%E8%B5%9E%E4%BB%A3%E7%90%86.js
// # Repo: jdqlscript/toulu
// # Path: 品赞代理.js
// # UploadedAt: 2025-06-28T11:18:42+08:00
// # SHA256: 79485dab3ea3a29d4dd5a09f771328d406ba90e352bf93ec3b869eefca72a3bb
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
/**
* 品赞HTTP代理签到v1.1
* const $ = new Env("品赞HTTP代理签到");
* cron 0 0 * * 0 品赞HTTP代理签到.js
* 注册地址https://www.ipzan.com?pid=4k9aetvd
有问题联系3288588344
频道https://pd.qq.com/s/672fku8ge
*
* ========= 青龙--配置文件 ===========
* # 项目名称(两种配置二选一)
* 推荐账号密码token容易过期
* export pzhttp='账号#密码'
* 不推荐
* export pzhttp='你抓包的token'
* 自己抓包协议头上的Authorization
* 多账号换行或&隔开
* 奖励每周签到得3金币大概500个IP可在免费使用代理IP用于其他项目
*
* ====================================
*
*/
const _0xf1ea8 = new _0x299988("品赞HTTP签到");
let _0x34f238 = "pzhttp",
_0x44155b = ["\n", "&"],
_0xa2efe3 = (_0xf1ea8.isNode() ? process.env[_0x34f238] : _0xf1ea8.getdata(_0x34f238)) || "",
_0xd941b5 = [],
_0x8a72a2 = 0;
class _0x138232 {
constructor(_0x61bdcb) {
this.index = ++_0x8a72a2;
this.points = 0;
this.valid = false;
_0x61bdcb?.["includes"]("#") ? [this.account, this.password] = _0x61bdcb?.["split"]("#") : this.activedAuthToken = _0x61bdcb;
}
async ["taskApi"](_0x15938b, _0x2b4597, _0x292c45, _0x4b21ba) {
let _0x17737f = null;
try {
let _0x9d8394 = _0x292c45.replace("//", "/").split("/")[1],
_0x41ba2f = {
"url": _0x292c45,
"headers": {
"Accept": "application/json, text/plain, */*",
"Accept-Language": "zh-CN,zh;q=0.9",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36",
"Host": _0x9d8394,
"Connection": "Keep-Alive",
"Origin": "https://kip.ipzan.com",
"Authorization": "Bearer " + this.activedAuthToken,
"Referer": "https://kip.ipzan.com/",
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
"Content-Type": "application/json"
},
"timeout": 60000
};
_0x4b21ba && (_0x41ba2f.body = _0x4b21ba, _0x41ba2f.headers["Content-Length"] = _0x4b21ba?.["length"]);
await _0x58c2e5(_0x2b4597, _0x41ba2f).then(async _0x1fce27 => {
if (_0x1fce27.resp?.["statusCode"] == 200) _0x1fce27.resp?.["body"] ? _0x17737f = JSON.parse(_0x1fce27.resp.body) : console.log("账号[" + this.index + "]调用" + _0x2b4597 + "[" + _0x15938b + "]出错,返回为空");else {
console.log("账号[" + this.index + "]调用" + _0x2b4597 + "[" + _0x15938b + "]出错,返回状态码[" + (_0x1fce27.resp?.["statusCode"] || "") + "]");
}
});
} catch (_0x2abedd) {
console.log(_0x2abedd);
} finally {
return Promise.resolve(_0x17737f);
}
}
async ["GetUserBalance"]() {
try {
let _0x181f92 = "GetUserBalance",
_0x567f03 = "get",
_0x23d272 = "https://service.ipzan.com/home/userWallet-find",
_0x3f986e = "";
await this.taskApi(_0x181f92, _0x567f03, _0x23d272, _0x3f986e).then(async _0x40fe24 => {
if (_0x40fe24.code === 0) this.valid = true, this.points = _0x40fe24.data.balance, console.log("账号[" + this.index + "] 当前金币: " + this.points);else {
_0xf1ea8.logAndNotify("账号[" + this.index + "]查询金币失败可能Token无效");
}
});
} catch (_0xc67e18) {
console.log(_0xc67e18);
} finally {
return Promise.resolve(1);
}
}
async ["Login"]() {
try {
let _0x1f2260 = "Login",
_0x459f03 = "post",
_0x3d2b06 = "https://service.ipzan.com/users-login",
_0x3e4a5c = JSON.stringify(_0x3771fa(this.account, this.password));
await this.taskApi(_0x1f2260, _0x459f03, _0x3d2b06, _0x3e4a5c).then(async _0x480963 => {
if (_0x480963.code === 0) console.log("账号[" + this.index + "] 登录成功"), this.activedAuthToken = _0x480963?.["data"];else {
console.log("账号[" + this.index + "] 登录失败:" + _0x480963?.["message"]);
}
});
} catch (_0x573284) {
console.log(_0x573284);
} finally {
return Promise.resolve(1);
}
}
async ["SignInDaily"]() {
try {
let _0x28765f = "SignInDaily",
_0x4735c6 = "get",
_0x42ed00 = "https://service.ipzan.com/home/userWallet-receive",
_0x299e34 = "";
await this.taskApi(_0x28765f, _0x4735c6, _0x42ed00, _0x299e34).then(async _0x3f3169 => {
if (_0x3f3169.code === 0) {
console.log("账号[" + this.index + "] 签到成功:", _0x3f3169?.["data"]);
} else console.log("账号[" + this.index + "] 签到失败:" + _0x3f3169?.["message"]);
});
} catch (_0x568f80) {
console.log(_0x568f80);
} finally {
return Promise.resolve(1);
}
}
async ["doTask"]() {
try {
await _0x241982(1000);
console.log("\n============= 账号[" + this.index + "] 开始签到=============");
await this.SignInDaily();
} catch (_0x23c68c) {
console.log(_0x23c68c);
}
}
}
!(async () => {
if (typeof $request !== "undefined") {
await _0x5e22b6();
} else {
if (!(await _0x76f888())) return;
console.log("\n================ 开始执行 ================");
for (let _0x59d06c of _0xd941b5) {
console.log("----------- 执行 第 [" + _0x59d06c.index + "] 个账号 -----------");
!_0x59d06c?.["activedAuthToken"] && (await _0x59d06c?.["Login"]());
await _0x59d06c.GetUserBalance();
}
let _0x3737e6 = _0xd941b5.filter(_0x2aad38 => _0x2aad38.valid);
if (_0x3737e6.length > 0) {
console.log("\n================ 任务队列构建完毕 ================");
for (let _0x434b43 of _0x3737e6) {
console.log("----------- 账号[" + _0x434b43.index + "] -----------");
await _0x434b43.doTask();
}
} else console.log("\n================ 未检测到帐号请先注册https://www.ipzan.com?pid=4k9aetvd ================");
await _0xf1ea8.showmsg();
}
})().catch(_0x4c4062 => console.log(_0x4c4062)).finally(() => _0xf1ea8.done());
function _0x416dc5(_0x3a97a0) {
const _0x414c4d = /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
return _0x414c4d.test(_0x3a97a0);
}
function _0xb417d8(_0x2829c6 = true) {
const _0x2334d0 = _0x2829c6 ? "1.1.1.1" : "0.0.0.0",
_0x44facb = _0x2829c6 ? "223.255.255.255" : "255.255.255.255",
_0xd9f504 = _0x2334d0.split(".").map(Number),
_0x275c26 = _0x44facb.split(".").map(Number),
_0x556be6 = _0xd9f504.map((_0xbf46cc, _0x2a9d1c) => {
const _0x1ab328 = _0x275c26[_0x2a9d1c];
return Math.floor(Math.random() * (_0x1ab328 - _0xbf46cc + 1)) + _0xbf46cc;
});
return _0x556be6.join(".");
}
function _0x157dd3(_0x2d7503, _0x42788a, _0x2e1e85) {
const _0x36ac8a = {};
_0x36ac8a[_0x42788a] = _0x2e1e85;
const _0x1f7e27 = JSON.stringify(_0x36ac8a);
try {
fs.writeFileSync(_0x2d7503 + ".json", _0x1f7e27);
} catch (_0x2fd9c9) {
_0x2fd9c9.code === "ENOENT" ? fs.writeFileSync(_0x2d7503 + ".json", _0x1f7e27) : console.error("保存文件时发生错误:", _0x2fd9c9);
}
}
function _0x35c695(_0x188ff0, _0x1924d1) {
try {
const _0x206e18 = fs.readFileSync(_0x188ff0 + ".json", "utf8"),
_0x4e7920 = JSON.parse(_0x206e18);
return _0x4e7920[_0x1924d1];
} catch (_0x527dd9) {
if (_0x527dd9.code === "ENOENT") return undefined;else {
console.error("读取文件时发生错误:", _0x527dd9);
}
}
}
function _0x3771fa(_0x256ced, _0x59add5) {
var _0x3b0e44 = {
"table": ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "/"],
"UTF16ToUTF8": function (_0x164874) {
for (var _0x22d31c = [], _0x34b5d0 = _0x164874.length, _0x12ffe3 = 0; _0x12ffe3 < _0x34b5d0; _0x12ffe3++) {
var _0x60360,
_0x57e360,
_0x243264 = _0x164874.charCodeAt(_0x12ffe3);
0 < _0x243264 && _0x243264 <= 127 ? _0x22d31c.push(_0x164874.charAt(_0x12ffe3)) : 128 <= _0x243264 && _0x243264 <= 2047 ? (_0x60360 = 192 | _0x243264 >> 6 & 31, _0x57e360 = 128 | 63 & _0x243264, _0x22d31c.push(String.fromCharCode(_0x60360), String.fromCharCode(_0x57e360))) : 2048 <= _0x243264 && _0x243264 <= 65535 && (_0x60360 = 224 | _0x243264 >> 12 & 15, _0x57e360 = 128 | _0x243264 >> 6 & 63, _0x243264 = 128 | 63 & _0x243264, _0x22d31c.push(String.fromCharCode(_0x60360), String.fromCharCode(_0x57e360), String.fromCharCode(_0x243264)));
}
return _0x22d31c.join("");
},
"UTF8ToUTF16": function (_0x2f5e6d) {
for (var _0x2e1ff5 = [], _0x1fe47c = _0x2f5e6d.length, _0x36c899 = 0, _0x36c899 = 0; _0x36c899 < _0x1fe47c; _0x36c899++) {
var _0xddba5e,
_0x1c66d1,
_0x4e11bc = _0x2f5e6d.charCodeAt(_0x36c899);
0 == (_0x4e11bc >> 7 & 255) ? _0x2e1ff5.push(_0x2f5e6d.charAt(_0x36c899)) : 6 == (_0x4e11bc >> 5 & 255) ? (_0x1c66d1 = (31 & _0x4e11bc) << 6 | 63 & (_0xddba5e = _0x2f5e6d.charCodeAt(++_0x36c899)), _0x2e1ff5.push(Sting.fromCharCode(_0x1c66d1))) : 14 == (_0x4e11bc >> 4 & 255) && (_0x1c66d1 = (255 & (_0x4e11bc << 4 | (_0xddba5e = _0x2f5e6d.charCodeAt(++_0x36c899)) >> 2 & 15)) << 8 | ((3 & _0xddba5e) << 6 | 63 & _0x2f5e6d.charCodeAt(++_0x36c899)), _0x2e1ff5.push(String.fromCharCode(_0x1c66d1)));
}
return _0x2e1ff5.join("");
},
"encode": function (_0x4440be) {
if (!_0x4440be) return "";
for (var _0x44c43a = this.UTF16ToUTF8(_0x4440be), _0xa978b5 = 0, _0x4f9c35 = _0x44c43a.length, _0x59ac5c = []; _0xa978b5 < _0x4f9c35;) {
var _0x4a5bc7 = 255 & _0x44c43a.charCodeAt(_0xa978b5++);
if (_0x59ac5c.push(this.table[_0x4a5bc7 >> 2]), _0xa978b5 == _0x4f9c35) {
_0x59ac5c.push(this.table[(3 & _0x4a5bc7) << 4]);
_0x59ac5c.push("==");
break;
}
var _0x77e2fc = _0x44c43a.charCodeAt(_0xa978b5++);
if (_0xa978b5 == _0x4f9c35) {
_0x59ac5c.push(this.table[(3 & _0x4a5bc7) << 4 | _0x77e2fc >> 4 & 15]);
_0x59ac5c.push(this.table[(15 & _0x77e2fc) << 2]);
_0x59ac5c.push("=");
break;
}
var _0xdaed0e = _0x44c43a.charCodeAt(_0xa978b5++);
_0x59ac5c.push(this.table[(3 & _0x4a5bc7) << 4 | _0x77e2fc >> 4 & 15]);
_0x59ac5c.push(this.table[(15 & _0x77e2fc) << 2 | (192 & _0xdaed0e) >> 6]);
_0x59ac5c.push(this.table[63 & _0xdaed0e]);
}
return _0x59ac5c.join("");
},
"decode": function (_0x4de779) {
if (!_0x4de779) return "";
for (var _0x44177d = _0x4de779.length, _0x3286ef = 0, _0x5afdd4 = []; _0x3286ef < _0x44177d;) code1 = this.table.indexOf(_0x4de779.charAt(_0x3286ef++)), code2 = this.table.indexOf(_0x4de779.charAt(_0x3286ef++)), code3 = this.table.indexOf(_0x4de779.charAt(_0x3286ef++)), code4 = this.table.indexOf(_0x4de779.charAt(_0x3286ef++)), c1 = code1 << 2 | code2 >> 4, _0x5afdd4.push(String.fromCharCode(c1)), -1 != code3 && (c2 = (15 & code2) << 4 | code3 >> 2, _0x5afdd4.push(String.fromCharCode(c2))), -1 != code4 && (c3 = (3 & code3) << 6 | code4, _0x5afdd4.push(String.fromCharCode(c3)));
return this.UTF8ToUTF16(_0x5afdd4.join(""));
}
};
function _0x52233c(_0x5136e2, _0xe0d60f) {
for (var _0x2ab4f3 = _0x3b0e44.encode("".concat(_0x5136e2, "QWERIPZAN1290QWER").concat(_0xe0d60f)), _0x4cc15c = "", _0x1675cf = 0; _0x1675cf < 80; _0x1675cf++) _0x4cc15c += Math.random().toString(16).slice(2);
return _0x2ab4f3 = "".concat(_0x4cc15c.slice(0, 100)).concat(_0x2ab4f3.slice(0, 8)).concat(_0x4cc15c.slice(100, 200)).concat(_0x2ab4f3.slice(8, 20)).concat(_0x4cc15c.slice(200, 300)).concat(_0x2ab4f3.slice(20)).concat(_0x4cc15c.slice(300, 400)), _0x2ab4f3;
}
return {
"account": _0x52233c(_0x256ced, _0x59add5),
"source": "ipzan-home-one"
};
}
async function _0x241982(_0x100501 = 3000) {
return console.log("----------- 延迟 " + _0x100501 / 1000 + " s请稍等 -----------"), await new Promise(_0x5783a5 => setTimeout(_0x5783a5, _0x100501));
}
async function _0x5e22b6() {}
async function _0x76f888() {
if (_0xa2efe3) {
let _0x57de73 = _0x44155b[0];
for (let _0x2979c7 of _0x44155b) {
if (_0xa2efe3.indexOf(_0x2979c7) > -1) {
_0x57de73 = _0x2979c7;
break;
}
}
for (let _0xf9d291 of _0xa2efe3.split(_0x57de73)) {
if (_0xf9d291) _0xd941b5.push(new _0x138232(_0xf9d291));
}
userCount = _0xd941b5.length;
} else {
console.log("未找到 配置信息,请检查是否配置 变量:", _0x34f238);
return;
}
return console.log("共找到" + userCount + "个账号"), true;
}
async function _0x58c2e5(_0x542f7d, _0x5679cd) {
return httpErr = null, httpReq = null, httpResp = null, new Promise(_0x2ef8a3 => {
_0xf1ea8.send(_0x542f7d, _0x5679cd, async (_0xb83695, _0x271317, _0x41aed5) => {
httpErr = _0xb83695;
httpReq = _0x271317;
httpResp = _0x41aed5;
_0x2ef8a3({
"err": _0xb83695,
"req": _0x271317,
"resp": _0x41aed5
});
});
});
}
function _0x299988(_0x35c70e, _0xb9b557) {
return "undefined" != typeof process && JSON.stringify(process.env).indexOf("GITHUB") > -1 && process.exit(0), new class {
constructor(_0x26381d, _0x43202e) {
this.name = _0x26381d;
this.notifyStr = "";
this.startTime = new Date().getTime();
Object.assign(this, _0x43202e);
console.log(this.name + " 开始运行:\n");
}
["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;
}
["getdata"](_0x2d117f) {
let _0x30f15c = this.getval(_0x2d117f);
if (/^@/.test(_0x2d117f)) {
const [, _0x1c3665, _0x103309] = /^@(.*?)\.(.*?)$/.exec(_0x2d117f),
_0x2a7cde = _0x1c3665 ? this.getval(_0x1c3665) : "";
if (_0x2a7cde) try {
const _0x594976 = JSON.parse(_0x2a7cde);
_0x30f15c = _0x594976 ? this.lodash_get(_0x594976, _0x103309, "") : _0x30f15c;
} catch (_0x26da6d) {
_0x30f15c = "";
}
}
return _0x30f15c;
}
["setdata"](_0x411712, _0x5b20be) {
let _0x170076 = false;
if (/^@/.test(_0x5b20be)) {
const [, _0x223398, _0x52b97d] = /^@(.*?)\.(.*?)$/.exec(_0x5b20be),
_0x62b663 = this.getval(_0x223398),
_0x57cf24 = _0x223398 ? "null" === _0x62b663 ? null : _0x62b663 || "{}" : "{}";
try {
const _0x1a909a = JSON.parse(_0x57cf24);
this.lodash_set(_0x1a909a, _0x52b97d, _0x411712);
_0x170076 = this.setval(JSON.stringify(_0x1a909a), _0x223398);
} catch (_0x2da117) {
const _0x5c5c9f = {};
this.lodash_set(_0x5c5c9f, _0x52b97d, _0x411712);
_0x170076 = this.setval(JSON.stringify(_0x5c5c9f), _0x223398);
}
} else _0x170076 = this.setval(_0x411712, _0x5b20be);
return _0x170076;
}
["getval"](_0x5f389a) {
return this.isSurge() || this.isLoon() ? $persistentStore.read(_0x5f389a) : this.isQuanX() ? $prefs.valueForKey(_0x5f389a) : this.isNode() ? (this.data = this.loaddata(), this.data[_0x5f389a]) : this.data && this.data[_0x5f389a] || null;
}
["setval"](_0x1b34bf, _0x28cdab) {
return this.isSurge() || this.isLoon() ? $persistentStore.write(_0x1b34bf, _0x28cdab) : this.isQuanX() ? $prefs.setValueForKey(_0x1b34bf, _0x28cdab) : this.isNode() ? (this.data = this.loaddata(), this.data[_0x28cdab] = _0x1b34bf, this.writedata(), !0) : this.data && this.data[_0x28cdab] || null;
}
["send"](_0x38991d, _0x10122b, _0xf72ed5 = () => {}) {
if (_0x38991d != "get" && _0x38991d != "post" && _0x38991d != "put" && _0x38991d != "delete") {
console.log("无效的http方法" + _0x38991d);
return;
}
if (_0x38991d == "get" && _0x10122b.headers) delete _0x10122b.headers["Content-Type"], delete _0x10122b.headers["Content-Length"];else {
if (_0x10122b.body && _0x10122b.headers) {
if (!_0x10122b.headers["Content-Type"]) _0x10122b.headers["Content-Type"] = "application/x-www-form-urlencoded";
}
}
if (this.isSurge() || this.isLoon()) {
this.isSurge() && this.isNeedRewrite && (_0x10122b.headers = _0x10122b.headers || {}, Object.assign(_0x10122b.headers, {
"X-Surge-Skip-Scripting": !1
}));
let _0x2f0893 = {
"method": _0x38991d,
"url": _0x10122b.url,
"headers": _0x10122b.headers,
"timeout": _0x10122b.timeout,
"data": _0x10122b.body
};
if (_0x38991d == "get") delete _0x2f0893.data;
$axios(_0x2f0893).then(_0x39a13c => {
const {
status: _0x53aa82,
request: _0x141a34,
headers: _0x2979d9,
data: _0x2262bf
} = _0x39a13c;
_0xf72ed5(null, _0x141a34, {
"statusCode": _0x53aa82,
"headers": _0x2979d9,
"body": _0x2262bf
});
}).catch(_0x3a5bbb => console.log(_0x3a5bbb));
} else {
if (this.isQuanX()) {
_0x10122b.method = _0x38991d.toUpperCase();
this.isNeedRewrite && (_0x10122b.opts = _0x10122b.opts || {}, Object.assign(_0x10122b.opts, {
"hints": !1
}));
$task.fetch(_0x10122b).then(_0x538157 => {
const {
statusCode: _0x2101fb,
request: _0x186259,
headers: _0x452945,
body: _0x5eb9cc
} = _0x538157;
_0xf72ed5(null, _0x186259, {
"statusCode": _0x2101fb,
"headers": _0x452945,
"body": _0x5eb9cc
});
}, _0x467989 => _0xf72ed5(_0x467989));
} else {
if (this.isNode()) {
this.got = this.got ? this.got : require("got");
const {
url: _0x5ee2a9,
..._0x2ff382
} = _0x10122b;
this.instance = this.got.extend({
"followRedirect": false
});
this.instance[_0x38991d](_0x5ee2a9, _0x2ff382).then(_0x5b094d => {
const {
statusCode: _0x2e12ae,
request: _0x52d154,
headers: _0x3a7327,
body: _0x3cfb53
} = _0x5b094d;
_0xf72ed5(null, _0x52d154, {
"statusCode": _0x2e12ae,
"headers": _0x3a7327,
"body": _0x3cfb53
});
}, _0x596487 => {
const {
message: _0x5e8d76,
request: _0x115f17,
response: _0x3fbe55
} = _0x596487;
_0xf72ed5(_0x5e8d76, _0x115f17, _0x3fbe55);
});
}
}
}
}
["time"](_0x348195, _0x5bc6db = null) {
let _0x4dac7b = _0x5bc6db ? new Date(_0x5bc6db) : new Date(),
_0x587f4c = {
"M+": _0x4dac7b.getMonth() + 1,
"d+": _0x4dac7b.getDate(),
"h+": _0x4dac7b.getHours(),
"m+": _0x4dac7b.getMinutes(),
"s+": _0x4dac7b.getSeconds(),
"q+": Math.floor((_0x4dac7b.getMonth() + 3) / 3),
"S": _0x4dac7b.getMilliseconds()
};
/(y+)/.test(_0x348195) && (_0x348195 = _0x348195.replace(RegExp.$1, (_0x4dac7b.getFullYear() + "").substr(4 - RegExp.$1.length)));
for (let _0x5f41dc in _0x587f4c) new RegExp("(" + _0x5f41dc + ")").test(_0x348195) && (_0x348195 = _0x348195.replace(RegExp.$1, 1 == RegExp.$1.length ? _0x587f4c[_0x5f41dc] : ("00" + _0x587f4c[_0x5f41dc]).substr(("" + _0x587f4c[_0x5f41dc]).length)));
return _0x348195;
}
async ["showmsg"]() {
if (!this.notifyStr) return;
let _0x28fba3 = this.name + " 运行通知\n\n" + this.notifyStr;
if (_0xf1ea8.isNode()) {
var _0x419448 = require("./sendNotify");
console.log("\n============== 推送 ==============");
await _0x419448.sendNotify(this.name, _0x28fba3);
} else this.msg(_0x28fba3);
}
["logAndNotify"](_0x59ff05) {
console.log(_0x59ff05);
this.notifyStr += _0x59ff05;
this.notifyStr += "\n";
}
["logAndNotifyWithTime"](_0x4a4431) {
let _0x16db0f = "[" + this.time("hh:mm:ss.S") + "]" + _0x4a4431;
console.log(_0x16db0f);
this.notifyStr += _0x16db0f;
this.notifyStr += "\n";
}
["logWithTime"](_0x248e8e) {
console.log("[" + this.time("hh:mm:ss.S") + "]" + _0x248e8e);
}
["msg"](_0x5ccbaf = t, _0x5f2ea9 = "", _0x33a21d = "", _0x15d370) {
const _0x26bf99 = _0x479142 => {
if (!_0x479142) return _0x479142;
if ("string" == typeof _0x479142) return this.isLoon() ? _0x479142 : this.isQuanX() ? {
"open-url": _0x479142
} : this.isSurge() ? {
"url": _0x479142
} : void 0;
if ("object" == typeof _0x479142) {
if (this.isLoon()) {
let _0x1298eb = _0x479142.openUrl || _0x479142.url || _0x479142["open-url"],
_0x21c7dc = _0x479142.mediaUrl || _0x479142["media-url"];
return {
"openUrl": _0x1298eb,
"mediaUrl": _0x21c7dc
};
}
if (this.isQuanX()) {
let _0x599a1c = _0x479142["open-url"] || _0x479142.url || _0x479142.openUrl,
_0x11d41a = _0x479142["media-url"] || _0x479142.mediaUrl;
return {
"open-url": _0x599a1c,
"media-url": _0x11d41a
};
}
if (this.isSurge()) {
let _0x526793 = _0x479142.url || _0x479142.openUrl || _0x479142["open-url"];
return {
"url": _0x526793
};
}
}
};
this.isMute || (this.isSurge() || this.isLoon() ? $notification.post(_0x5ccbaf, _0x5f2ea9, _0x33a21d, _0x26bf99(_0x15d370)) : this.isQuanX() && $notify(_0x5ccbaf, _0x5f2ea9, _0x33a21d, _0x26bf99(_0x15d370)));
let _0x5b72bc = ["", "============== 系统通知 =============="];
_0x5b72bc.push(_0x5ccbaf);
_0x5f2ea9 && _0x5b72bc.push(_0x5f2ea9);
_0x33a21d && _0x5b72bc.push(_0x33a21d);
console.log(_0x5b72bc.join("\n"));
}
["getMin"](_0x1e4c28, _0x1b3fed) {
return _0x1e4c28 < _0x1b3fed ? _0x1e4c28 : _0x1b3fed;
}
["getMax"](_0x44257e, _0x5e7519) {
return _0x44257e < _0x5e7519 ? _0x5e7519 : _0x44257e;
}
["padStr"](_0x42eadb, _0x4722e0, _0x520994 = "0") {
let _0x325005 = String(_0x42eadb),
_0x33179d = _0x4722e0 > _0x325005.length ? _0x4722e0 - _0x325005.length : 0,
_0x15c189 = "";
for (let _0xfe43c4 = 0; _0xfe43c4 < _0x33179d; _0xfe43c4++) {
_0x15c189 += _0x520994;
}
return _0x15c189 += _0x325005, _0x15c189;
}
["json2str"](_0x300f3f, _0x2c0636, _0x37b9a0 = false) {
let _0x2f13c4 = [];
for (let _0xd689e of Object.keys(_0x300f3f).sort()) {
let _0x546626 = _0x300f3f[_0xd689e];
if (_0x546626 && _0x37b9a0) _0x546626 = encodeURIComponent(_0x546626);
_0x2f13c4.push(_0xd689e + "=" + _0x546626);
}
return _0x2f13c4.join(_0x2c0636);
}
["str2json"](_0x407b63, _0x270666 = false) {
let _0xd85dc6 = {};
for (let _0x23e13a of _0x407b63.split("&")) {
if (!_0x23e13a) continue;
let _0x2388ac = _0x23e13a.indexOf("=");
if (_0x2388ac == -1) continue;
let _0x189560 = _0x23e13a.substr(0, _0x2388ac),
_0x37af9c = _0x23e13a.substr(_0x2388ac + 1);
if (_0x270666) _0x37af9c = decodeURIComponent(_0x37af9c);
_0xd85dc6[_0x189560] = _0x37af9c;
}
return _0xd85dc6;
}
["randomString"](_0x58daa1, _0x2792a6 = "abcdef0123456789") {
let _0x27ce4a = "";
for (let _0x11c145 = 0; _0x11c145 < _0x58daa1; _0x11c145++) {
_0x27ce4a += _0x2792a6.charAt(Math.floor(Math.random() * _0x2792a6.length));
}
return _0x27ce4a;
}
["randomList"](_0x2b61e8) {
let _0xeea55d = Math.floor(Math.random() * _0x2b61e8.length);
return _0x2b61e8[_0xeea55d];
}
["wait"](_0x2724d1) {
return new Promise(_0x3418cd => setTimeout(_0x3418cd, _0x2724d1));
}
["done"](_0x37d9be = {}) {
const _0x3487fc = new Date().getTime(),
_0x58b1e9 = (_0x3487fc - this.startTime) / 1000;
console.log("\n" + this.name + " 运行结束,共运行了 " + _0x58b1e9 + " 秒!");
if (this.isSurge() || this.isQuanX() || this.isLoon()) $done(_0x37d9be);
}
}(_0x35c70e, _0xb9b557);
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,228 @@
# Source: https://gitee.com/jdqlscript/toulu/blob/main/%E5%A4%A9%E7%BF%BC%E4%BA%91%E7%9B%98.py
# Raw: https://gitee.com/jdqlscript/toulu/raw/main/%E5%A4%A9%E7%BF%BC%E4%BA%91%E7%9B%98.py
# Repo: jdqlscript/toulu
# Path: 天翼云盘.py
# UploadedAt: 2025-06-28T11:18:42+08:00
# SHA256: 3c9fd20b74cc1a446cf8a8a4dc20b345f27ba2f121d6df5f0055e5f5b5bb87de
# Category: web版/账密
# Evidence: web/H5关键词 + username/password/login
#有问题联系3288588344
# cron 30 9 * * *
#频道https://pd.qq.com/s/672fku8ge
#在我写的地方,填上账号密码就行,有问题联系上方
import notify
import time
import re
import json
import base64
import hashlib
import urllib.parse,hmac
import rsa
import requests
import random
BI_RM = list("0123456789abcdefghijklmnopqrstuvwxyz")
B64MAP = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
s = requests.Session()
# 在下面两行的引号内贴上账号(仅支持手机号)和密码
username = "这里填上你的天翼云盘账号"
password = "这里填上你的天翼网盘密码"
_ = """
if(username == "" or password == ""):
username = input("账号:")
password = input("密码:")
# """
assert username and password, "在第23、24行填入有效账号和密码"
def int2char(a):
return BI_RM[a]
def b64tohex(a):
d = ""
e = 0
c = 0
for i in range(len(a)):
if list(a)[i] != "=":
v = B64MAP.index(list(a)[i])
if 0 == e:
e = 1
d += int2char(v >> 2)
c = 3 & v
elif 1 == e:
e = 2
d += int2char(c << 2 | v >> 4)
c = 15 & v
elif 2 == e:
e = 3
d += int2char(c)
d += int2char(v >> 2)
c = 3 & v
else:
e = 0
d += int2char(c << 2 | v >> 4)
d += int2char(15 & v)
if e == 1:
d += int2char(c << 2)
return d
def rsa_encode(j_rsakey, string):
rsa_key = f"-----BEGIN PUBLIC KEY-----\n{j_rsakey}\n-----END PUBLIC KEY-----"
pubkey = rsa.PublicKey.load_pkcs1_openssl_pem(rsa_key.encode())
result = b64tohex((base64.b64encode(rsa.encrypt(f'{string}'.encode(), pubkey))).decode())
return result
def calculate_md5_sign(params):
return hashlib.md5('&'.join(sorted(params.split('&'))).encode('utf-8')).hexdigest()
def login(username, password):
#https://m.cloud.189.cn/login2014.jsp?redirectURL=https://m.cloud.189.cn/zhuanti/2021/shakeLottery/index.html
url=""
urlToken="https://m.cloud.189.cn/udb/udb_login.jsp?pageId=1&pageKey=default&clientType=wap&redirectURL=https://m.cloud.189.cn/zhuanti/2021/shakeLottery/index.html"
s = requests.Session()
r = s.get(urlToken)
pattern = r"https?://[^\s'\"]+" # 匹配以http或https开头的url
match = re.search(pattern, r.text) # 在文本中搜索匹配
if match: # 如果找到匹配
url = match.group() # 获取匹配的字符串
# print(url) # 打印url
else: # 如果没有找到匹配
print("没有找到url")
r = s.get(url)
# print(r.text)
pattern = r"<a id=\"j-tab-login-link\"[^>]*href=\"([^\"]+)\"" # 匹配id为j-tab-login-link的a标签并捕获href引号内的内容
match = re.search(pattern, r.text) # 在文本中搜索匹配
if match: # 如果找到匹配
href = match.group(1) # 获取捕获的内容
# print("href:" + href) # 打印href链接
else: # 如果没有找到匹配
print("没有找到href链接")
r = s.get(href)
captchaToken = re.findall(r"captchaToken' value='(.+?)'", r.text)[0]
lt = re.findall(r'lt = "(.+?)"', r.text)[0]
returnUrl = re.findall(r"returnUrl= '(.+?)'", r.text)[0]
paramId = re.findall(r'paramId = "(.+?)"', r.text)[0]
j_rsakey = re.findall(r'j_rsaKey" value="(\S+)"', r.text, re.M)[0]
s.headers.update({"lt": lt})
username = rsa_encode(j_rsakey, username)
password = rsa_encode(j_rsakey, password)
url = "https://open.e.189.cn/api/logbox/oauth2/loginSubmit.do"
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/76.0',
'Referer': 'https://open.e.189.cn/',
}
data = {
"appKey": "cloud",
"accountType": '01',
"userName": f"{{RSA}}{username}",
"password": f"{{RSA}}{password}",
"validateCode": "",
"captchaToken": captchaToken,
"returnUrl": returnUrl,
"mailSuffix": "@189.cn",
"paramId": paramId
}
r = s.post(url, data=data, headers=headers, timeout=5)
if (r.json()['result'] == 0):
print(r.json()['msg'])
else:
print(r.json()['msg'])
redirect_url = r.json()['toUrl']
r = s.get(redirect_url)
return s
def main():
s=login(username, password)
rand = str(round(time.time() * 1000))
surl = f'https://api.cloud.189.cn/mkt/userSign.action?rand={rand}&clientType=TELEANDROID&version=8.6.3&model=SM-G930K'
url = f'https://m.cloud.189.cn/v2/drawPrizeMarketDetails.action?taskId=TASK_SIGNIN&activityId=ACT_SIGNIN'
url2 = f'https://m.cloud.189.cn/v2/drawPrizeMarketDetails.action?taskId=TASK_SIGNIN_PHOTOS&activityId=ACT_SIGNIN'
url3 = f'https://m.cloud.189.cn/v2/drawPrizeMarketDetails.action?taskId=TASK_2022_FLDFS_KJ&activityId=ACT_SIGNIN'
headers = {
'User-Agent': 'Mozilla/5.0 (Linux; Android 5.1.1; SM-G930K Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36 Ecloud/8.6.3 Android/22 clientId/355325117317828 clientModel/SM-G930K imsi/460071114317824 clientChannelId/qq proVersion/1.0.6',
"Referer": "https://m.cloud.189.cn/zhuanti/2016/sign/index.jsp?albumBackupOpened=1",
"Host": "m.cloud.189.cn",
"Accept-Encoding": "gzip, deflate",
}
response = s.get(surl, headers=headers)
netdiskBonus = response.json()['netdiskBonus']
if (response.json()['isSign'] == "false"):
print(f"未签到,签到获得{netdiskBonus}M空间")
res1 = f"未签到,签到获得{netdiskBonus}M空间"
else:
print(f"已经签到过了,签到获得{netdiskBonus}M空间")
res1 = f"已经签到过了,签到获得{netdiskBonus}M空间"
headers = {
'User-Agent': 'Mozilla/5.0 (Linux; Android 5.1.1; SM-G930K Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36 Ecloud/8.6.3 Android/22 clientId/355325117317828 clientModel/SM-G930K imsi/460071114317824 clientChannelId/qq proVersion/1.0.6',
"Referer": "https://m.cloud.189.cn/zhuanti/2016/sign/index.jsp?albumBackupOpened=1",
"Host": "m.cloud.189.cn",
"Accept-Encoding": "gzip, deflate",
}
response = s.get(url, headers=headers)
if ("errorCode" in response.text):
print(response.text)
res2 = ""
else:
description = response.json()['description']
print(f"抽奖获得{description}")
res2 = f"抽奖获得{description}"
response = s.get(url2, headers=headers)
if ("errorCode" in response.text):
print(response.text)
res3 = ""
else:
description = response.json()['description']
print(f"抽奖获得{description}")
res3 = f"抽奖获得{description}"
response = s.get(url3, headers=headers)
if ("errorCode" in response.text):
print(response.text)
res4 = ""
else:
description = response.json()['description']
print(f"链接3抽奖获得{description}")
res4 = f"链接3抽奖获得{description}"
title = "天翼云签到"
content = f"""
{res1}
{res2}
{res3}
{res4}
"""
notify.send(title, content)
def lambda_handler(event, context): # aws default
main()
def main_handler(event, context): # tencent default
main()
def handler(event, context): # aliyun default
main()
if __name__ == "__main__":
main()
time.sleep(random.randint(5, 30))

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,243 @@
// # Source: https://github.com/smallfawn/QLScriptPublic/blob/main/daily/chery.js
// # Raw: https://raw.githubusercontent.com/smallfawn/QLScriptPublic/main/daily/chery.js
// # Repo: smallfawn/QLScriptPublic
// # Path: daily/chery.js
// # UploadedAt: 2026-05-14T17:47:57+08:00
// # SHA256: 022b783a47c38858a3c9a7afaa031098896163fabfd32345ac93d1c3333c4edb
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
/*
------------------------------------------
@Author: sm
@Date: 2024.06.07 19:15
@Description: 奇瑞汽车
cron: 30 8 * * *
------------------------------------------
#Notice:
APP 抓包的登录接口uaa2c.chery.cn 里面的返回的access_token就是环境变量需要的token多个账号换行或者&
自助获取变量
https://logintools.smallfawn.top/chery.html
⚠️【免责声明】
------------------------------------------
1、此脚本仅用于学习研究不保证其合法性、准确性、有效性请根据情况自行判断本人对此不承担任何保证责任。
2、由于此脚本仅用于学习研究您必须在下载后 24 小时内将所有内容从您的计算机或手机或任何存储设备中完全删除,若违反规定引起任何事件本人对此均不负责。
3、请勿将此脚本用于任何商业或非法目的若违反规定请自行对此负责。
4、此脚本涉及应用与本人无关本人对因此引起的任何隐私泄漏或其他后果不承担任何责任。
5、本人对任何脚本引发的问题概不负责包括但不限于由脚本错误引起的任何损失和损害。
6、如果任何单位或个人认为此脚本可能涉嫌侵犯其权利应及时通知并提供身份证明所有权证明我们将在收到认证文件确认后删除此脚本。
7、所有直接或间接使用、查看此脚本的人均应该仔细阅读此声明。本人保留随时更改或补充此声明的权利。一旦您使用或复制了此脚本即视为您已接受此免责声明。
*/
const { Env } = require("../tools/env")
const $ = new Env("奇瑞汽车");
let ckName = `chery`;
const strSplitor = "#";
const axios = require("axios");
const defaultUserAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.31(0x18001e31) NetType/WIFI Language/zh_CN miniProgram"
const CryptoJS = require("crypto-js");
class Task {
constructor(env) {
this.index = $.userIdx++
this.user = env.split(strSplitor);
this.token = this.user[0];
this.ckStatus = false;
this.articleIdList = []
}
encryptParams(e) {
const t = CryptoJS.enc.Base64.parse("vVfnp9ozfDQyonMKuqgZUWjtdV+7PtBqtMCwJqz2HKQ=")
, n = CryptoJS.lib.WordArray.random(16)
, o = CryptoJS.AES.encrypt(e, t, {
iv: n,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
})
, i = CryptoJS.lib.WordArray.create();
return i.concat(n),
i.concat(o.ciphertext),
CryptoJS.enc.Base64.stringify(i).replace(/\+/g, "-")
}
async run() {
await this.info()
if (this.ckStatus == true) {
await this.signIn()
await this.contentsList()
for (let articleId of this.articleIdList) {
await this.taskShare(articleId)
}
}
}
async signIn() {
let options = {
method: 'POST',
url: `https://mobile-consumer-sapp.chery.cn/web/event/trigger?encryptParam=${encodeURIComponent(this.encryptParams(`access_token=${this.token}&terminal=3`))}`,
headers: {
"user-agent": "Dart/2.19 (dart:io)",
"appversioncode": "26030901",
"accept": "application/json, text/plain, */*",
"appversion": "3.6.9",
"accept-language": "zh-CN,zh;q=0.9",
"accept-encoding": "gzip, deflate",
"host": "mobile-consumer-sapp.chery.cn",
"content-type": "application/json; charset=UTF-8",
"agent": "android",
"encryptflag": "true",
"request-channel": "app"
},
data:
Buffer.from(this.encryptParams(JSON.stringify({ "eventCode": "SJ10002" })), "utf-8"),
transformRequest: [(d, headers) => d]
};
let { data: result } = await axios.request(options);
if (result.status == 200) {
$.log(`✅账号[${this.index}] 【签到】[${result.message}]🎉`);
} else {
$.log(`❌账号[${this.index}] 【签到】[${result.message}]`);
//console.log(result);
}
}
async info() {
let options = {
method: 'GET',
url: `https://mobile-consumer-sapp.chery.cn/web/user/current/details?encryptParam=${encodeURIComponent(this.encryptParams(`access_token=${this.token}&terminal=3`))}`,
headers: {
"user-agent": "Dart/2.19 (dart:io)",
"appversioncode": "26030901",
"accept": "application/json, text/plain, */*",
"appversion": "3.6.9",
"accept-language": "zh-CN,zh;q=0.9",
"accept-encoding": "gzip, deflate",
"host": "mobile-consumer-sapp.chery.cn",
"content-type": "application/json; charset=UTF-8",
"agent": "android",
"encryptflag": "true",
"request-channel": "app"
},
}
let { data: result } = await axios.request(options);
if (result.status == 200) {
$.log(`✅账号[${this.index}] 【昵称】[${result.data.displayName}] 【积分】[${result.data.pointAccount.payableBalance}]🎉`);
this.userName = result.data.displayName
this.userPoint = result.data.pointAccount.payableBalance
this.ckStatus = true;
} else {
$.log(`❌账号[${this.index}] [${result.message}]`);
this.ckStatus = false;
//console.log(result);
}
}
async taskShare(articleId) {
try {
let options = {
method: 'POST',
url: `https://mobile-consumer-sapp.chery.cn/web/community/contents/${articleId}/share?encryptParams=${this.encryptParams(`access_token=${this.token}&terminal=3`)}`,
headers: {
"user-agent": "Dart/2.19 (dart:io)",
"appversioncode": "26030901",
"accept": "application/json, text/plain, */*",
"appversion": "3.6.9",
"accept-language": "zh-CN,zh;q=0.9",
"accept-encoding": "gzip, deflate",
"host": "mobile-consumer-sapp.chery.cn",
"content-type": "application/json; charset=UTF-8",
"agent": "android",
"encryptflag": "true",
"request-channel": "app"
},
data: Buffer.from(this.encryptParams(JSON.stringify({ "contentId": articleId })), "utf-8")
, transformRequest: [(d, headers) => d]
}
let { data: result } = await axios.request(options);
if (result.status == 200) {
$.log(`✅账号[${this.index}] 【分享】[${result.message}]🎉`);
} else {
$.log(`❌账号[${this.index}] 【分享】[${result.message}]`);
//console.log(result);
}
} catch (e) {
console.log(e);
}
}
async contentsList() {
try {
let options = {
method: 'GET',
url: `https://mobile-consumer-sapp.chery.cn/web/community/recommend/contents?encryptParam=${encodeURIComponent(this.encryptParams(`pageNo=1&pageSize=10&access_token=${this.token}&terminal=3`))}`,
headers: {
"user-agent": "Dart/2.19 (dart:io)",
"appversioncode": "26030901",
"accept": "application/json, text/plain, */*",
"appversion": "3.6.9",
"accept-language": "zh-CN,zh;q=0.9",
"accept-encoding": "gzip, deflate",
"host": "mobile-consumer-sapp.chery.cn",
"content-type": "application/json; charset=UTF-8",
"agent": "android",
"encryptflag": "true",
"request-channel": "app"
},
}
let { data: result } = await axios.request(options);
if (result.status == 200) {
$.log(`✅账号[${this.index}] 【获取文章】[${result.message}]🎉`);
this.articleIdList = [result.data.data[0].content.id, result.data.data[1].content.id]
} else {
$.log(`❌账号[${this.index}] 【获取文章】[${result.message}]`);
//console.log(result);
}
} catch (e) {
console.log(e);
}
}
}
!(async () => {
await getNotice()
$.checkEnv(ckName);
for (let user of $.userList) {
await new Task(user).run();
}
})()
.catch((e) => console.log(e))
.finally(() => $.done());
async function getNotice() {
try {
let options = {
url: `https://ghproxy.net/https://raw.githubusercontent.com/smallfawn/Note/refs/heads/main/Notice.json`,
headers: {
"User-Agent": defaultUserAgent,
},
timeout:3000
}
let {
data: res
} = await axios.request(options);
$.log(res)
return res
} catch (e) {}
}

View File

@@ -0,0 +1,304 @@
# Source: https://gitee.com/jdqlscript/toulu/blob/main/%E5%AE%9D%E9%AA%8F%E6%B1%BD%E8%BD%A6%E8%A7%86%E9%A2%91.py
# Raw: https://gitee.com/jdqlscript/toulu/raw/main/%E5%AE%9D%E9%AA%8F%E6%B1%BD%E8%BD%A6%E8%A7%86%E9%A2%91.py
# Repo: jdqlscript/toulu
# Path: 宝骏汽车视频.py
# UploadedAt: 2025-06-28T11:18:42+08:00
# SHA256: 6330e990dc2b7001e0109b13ebcc739afaef1a6a9408b768f0c428e55b2430d4
# Category: web版/账密
# Evidence: web/H5关键词 + username/password/login
"""
TL库:https://github.com/3288588344/toulu.git
tg频道:https://t.me/TLtoulu
QQ频道:https://pd.qq.com/s/672fku8ge
单点登录,会被顶号;体现公众号手动绑定,绑定链接打不开则用浏览器打开绑定即可;提现次日到账
"""
import requests, json, re, os, sys, time, random, datetime, hashlib
response = requests.get("https://github.com/3288588344/toulu/raw/refs/heads/main/tl.txt")
response.encoding = 'utf-8'
txt = response.text
print(txt)
environ = "bjsp"
name = "宝骏༒视频"
session = requests.session()
#---------------------主代码区块---------------------
def lookVideo(accessToken,postid):
timestamp = int(time.time() * 1000)
oauthConsumerKey = "20200113181123916714"
nonce = "4857289347289375"
other = f"{nonce}JNWSY6RXYGXIWR2YCI2HOAGYG9LVQXYZ8d33d72c27994bdc9a9e9fdda2545690"
md5_str = f"{accessToken}{oauthConsumerKey}{timestamp}{other}"
signatrue = hashlib.md5(md5_str.encode('utf-8')).hexdigest()
url = 'https://hapi.baojun.net/base/activity/fission/lookVideo'
header = {
"Host": "hapi.baojun.net",
"Connection": "keep-alive",
"Content-Length": "17",
"accessToken": accessToken,
"nonce": nonce,
"signatrue": signatrue,
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090b13)XWEB/11581",
"oauthConsumerKey": oauthConsumerKey,
"Content-Type": "application/json",
"timestamp": str(timestamp),
"xweb_xhr": "1",
"platformNo": "Wx_mini",
"Accept": "*/*",
"Sec-Fetch-Site": "cross-site",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Dest": "empty",
"Referer": "https://servicewechat.com/wx58774bbe5cd15ebb/409/page-frame.html",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-CN,zh;q=0.9"
}
data = {"postId":postid}
try:
response = session.post(url=url, headers=header, json=data)
except Exception as e:
print(e)
def money(accessToken):
timestamp = int(time.time() * 1000)
oauthConsumerKey = "20200113181123916714"
nonce = "1736572213106_5833612"
other = f"{nonce}JNWSY6RXYGXIWR2YCI2HOAGYG9LVQXYZ8d33d72c27994bdc9a9e9fdda2545690"
md5_str = f"{accessToken}{oauthConsumerKey}{timestamp}{other}"
signatrue = hashlib.md5(md5_str.encode('utf-8')).hexdigest()
url = 'https://hapi.baojun.net/base/account/pocket/money/draw'
header = {
"Host": "hapi.baojun.net",
"Connection": "keep-alive",
"Content-Length": "2",
"sec-ch-ua-platform": "Android",
"timestamp": str(timestamp),
"accessToken": accessToken,
"nonce": nonce,
"signatrue": signatrue,
"sec-ch-ua": 'Chromium";v="130", "Android WebView";v="130", "Not?A_Brand";v="99',
"sec-ch-ua-mobile": "?1",
"platformNo": "Wx_mini",
"deviceType": "html5",
"oauthConsumerKey": oauthConsumerKey,
"Content-Type": "application/json;charset=UTF-8",
"Accept": "application/json, text/plain, */*",
"Accept-Encoding": "gzip, deflate, br, zstd",
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
"Referer": "https://m.baojun.net",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090b13)XWEB/11581",
"Sec-Fetch-Site": "cross-site",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Dest": "empty",
"X-Requested-With": "com.tencent.mm",
}
data = {}
try:
response = session.post(url=url, headers=header, json=data).json()
if "核查" in response["errorMessage"]:
print(f'🌈提现:已提交,待核查后发放')
elif "没有余额" in response["errorMessage"]:
print(f'⭕余额不足,无法提现')
else:
print(f'{response["errorMessage"]}')
except Exception as e:
print(e)
def info(accessToken):
timestamp = int(time.time() * 1000)
nonce = "1736560276274_7143758"
other = f"{nonce}JNWSY6RXYGXIWR2YCI2HOAGYG9LVQXYZ8d33d72c27994bdc9a9e9fdda2545690"
oauthConsumerKey = "20200113181123916714"
md5_str = f"{accessToken}{oauthConsumerKey}{timestamp}{other}"
signatrue = hashlib.md5(md5_str.encode('utf-8')).hexdigest()
url = 'https://hapi.baojun.net/base/account/pocket/draw/info'
header = {
"Accept": "application/json, text/plain, */*",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-CN,zh;q=0.9",
"Host": "hapi.baojun.net",
"deviceType": "html5",
"Connection": "keep-alive",
"accessToken": accessToken,
"nonce": nonce,
"signatrue": signatrue,
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090b13)XWEB/11581",
"oauthConsumerKey": oauthConsumerKey,
"timestamp": str(timestamp),
"platformNo": "Wx_mini",
"Sec-Fetch-Site": "cross-site",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Dest": "empty",
"Referer": "https://m.baojun.net/",
}
try:
response = session.get(url=url, headers=header)
response = json.loads(response.text)
coin = response['data']['noDrawMoney']
timestamp = int(time.time() * 1000)
nonce = "1736638919609_4282954"
other = f"{nonce}JNWSY6RXYGXIWR2YCI2HOAGYG9LVQXYZ8d33d72c27994bdc9a9e9fdda2545690"
oauthConsumerKey = "20200113181123916714"
md5_str = f"{accessToken}{oauthConsumerKey}{timestamp}{other}"
signatrue = hashlib.md5(md5_str.encode('utf-8')).hexdigest()
url = 'https://hapi.baojun.net/base/ucenter/user/wallet/detail/v2?pocketClassType=1&pageNo=1&pageSize=40'
header = {
"Accept": "application/json, text/plain, */*",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-CN,zh;q=0.9",
"Host": "hapi.baojun.net",
"deviceType": "html5",
"Connection": "keep-alive",
"accessToken": accessToken,
"nonce": nonce,
"signatrue": signatrue,
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090b13)XWEB/11581",
"oauthConsumerKey": oauthConsumerKey,
"timestamp": str(timestamp),
"platformNo": "Wx_mini",
"Sec-Fetch-Site": "cross-site",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Dest": "empty",
"Referer": "https://m.baojun.net/",
}
response = session.get(url=url, headers=header)
response = json.loads(response.text)
count = 0
for tc in response['data']:
date_time3 = datetime.datetime.strptime(tc["expireDateStr"], "%Y-%m-%d %H:%M:%S").day
today_date3 = datetime.datetime.now().day - 1
if date_time3 == today_date3:
count = count + 1
timestamp = int(time.time() * 1000)
nonce = "1736566937191_1825450"
other = f"{nonce}JNWSY6RXYGXIWR2YCI2HOAGYG9LVQXYZ8d33d72c27994bdc9a9e9fdda2545690"
oauthConsumerKey = "20200113181123916714"
md5_str = f"{accessToken}{oauthConsumerKey}{timestamp}{other}"
signatrue = hashlib.md5(md5_str.encode('utf-8')).hexdigest()
url = 'https://hapi.baojun.net/base/ucenter/user/wallet/detail/v2?pocketClassType=2&pageNo=2&pageSize=20'
header = {
"Accept": "application/json, text/plain, */*",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-CN,zh;q=0.9",
"Host": "hapi.baojun.net",
"deviceType": "html5",
"Connection": "keep-alive",
"accessToken": accessToken,
"nonce": nonce,
"signatrue": signatrue,
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090b13)XWEB/11581",
"oauthConsumerKey": oauthConsumerKey,
"timestamp": str(timestamp),
"platformNo": "Wx_mini",
"Sec-Fetch-Site": "cross-site",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Dest": "empty",
"Referer": "https://m.baojun.net/",
}
response = session.get(url=url, headers=header)
response = json.loads(response.text)
txall = 0
for t2 in response['data']:
date_time2 = datetime.datetime.strptime(t2["expireDateStr"], "%Y-%m-%d %H:%M:%S").day
today_date2 = datetime.datetime.now().day - 1
if date_time2 == today_date2:
txall = 1
break
return txall, coin, count
except:
e = 2
return e, e, e
def getpostid(accessToken):
txall, coin, count = info(accessToken)
if txall == 2:
print(f"accessToken失效")
return
if txall == 1:
print(f"☁️刷前:提现判定")
elif coin == 0:
print(f"刷前0 元,已刷{count}/30")
else:
print(f"☁️刷前:{coin / 100}元,已刷{count}/30次")
for mm in range(10000):
if count >= 30 or txall == 1:
if txall == 1:
print(f"☁️判定:今日已提现,中止")
else:
print(f"☁️刷后:{coin / 100}元,已刷{count}/30次")
money(accessToken)
break
else:
timestamp = int(time.time() * 1000)
oauthConsumerKey = "20200113181123916714"
nonce = "4857289347289375"
other = f"{nonce}JNWSY6RXYGXIWR2YCI2HOAGYG9LVQXYZ8d33d72c27994bdc9a9e9fdda2545690"
md5_str = f"{accessToken}{oauthConsumerKey}{timestamp}{other}"
signatrue = hashlib.md5(md5_str.encode('utf-8')).hexdigest()
url = f'https://hapi.baojun.net/base/community/post/postList?postTypeId=1&postClassifyId=61&publishSmallProgram=2&pageNo={mm}&pageSize=35 '
header = {
"Host": "hapi.baojun.net",
"Connection": "keep-alive",
"accessToken": accessToken,
"nonce": nonce,
"signatrue": signatrue,
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090b13)XWEB/11581",
"oauthConsumerKey": oauthConsumerKey,
"Content-Type": "application/json",
"timestamp": str(timestamp),
"xweb_xhr": "1",
"platformNo": "Wx_mini",
"Accept": "*/*",
"Sec-Fetch-Site": "cross-site",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Dest": "empty",
"Referer": "https://servicewechat.com/wx58774bbe5cd15ebb/409/page-frame.html",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-CN,zh;q=0.9"
}
try:
response = session.get(url=url, headers=header)
response = json.loads(response.text)
for i in response["data"]:
postid = i["postId"]
postTitle = i["postTitle"]
txall, coin, count = info(accessToken)
if count >= 30 or txall == 1:
break
lookVideo(accessToken, postid)
txallb, coinb, countb = info(accessToken)
if int(coinb)-int(coin)==0:
continue
time.sleep(0.1)
except Exception as e:
print(e)
def main():
if os.environ.get(environ):
ck = os.environ.get(environ)
else:
ck = ""
if ck == "":
print("请设置变量")
sys.exit()
ck_run = ck.split('\n')
ck_run = [item for item in ck_run if item]
print(f"{' ' * 10}꧁༺ {name} ༻꧂\n")
for i, ck_run_n in enumerate(ck_run):
print(f'\n----------- 🍺账号【{i + 1}/{len(ck_run)}】执行🍺 -----------')
try:
id,two = ck_run_n.split('#',2)
#id = id[:3] + "*****" + id[-3:]
print(f"📱:{id}")
getpostid(two)
time.sleep(random.randint(1, 2))
except Exception as e:
print(e)
#notify.send('title', 'message')
print(f'\n----------- 🎊 执 行 结 束 🎊 -----------')
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,645 @@
// # Source: https://github.com/imoki/sign_script/blob/main/polymerization/chinadsl.js
// # Raw: https://raw.githubusercontent.com/imoki/sign_script/main/polymerization/chinadsl.js
// # Repo: imoki/sign_script
// # Path: polymerization/chinadsl.js
// # UploadedAt: 2025-08-25T21:29:14+08:00
// # SHA256: db342b3d6f7631919c5ae6ae460906610890366a47ee9173a951925dad84bc82
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
/*
name: "宽带技术网"
cron: 45 0 9 * * *
脚本兼容: 金山文档1.0金山文档2.0
更新时间20241226
环境变量名:无
环境变量值:无
备注cookie填写宽带技术网网页版中获取的refresh_token。F12 -> NetWork(中文名叫"网络") ->https://www.chinadsl.net -> cookie
宽带技术网网址:https://www.chinadsl.net
*/
var sheetNameSubConfig = "chinadsl"; // 分配置表名称
var pushHeader = "【宽带技术网】";
var sheetNameConfig = "CONFIG"; // 总配置表
var sheetNamePush = "PUSH"; // 推送表名称
var sheetNameEmail = "EMAIL"; // 邮箱表
var flagSubConfig = 0; // 激活分配置工作表标志
var flagConfig = 0; // 激活主配置工作表标志
var flagPush = 0; // 激活推送工作表标志
var line = 21; // 指定读取从第2行到第line行的内容
var message = ""; // 待发送的消息
var messageArray = []; // 待发送的消息数据,每个元素都是某个账号的消息。目的是将不同用户消息分离,方便个性化消息配置
var messageOnlyError = 0; // 0为只推送失败消息1则为推送成功消息。
var messageNickname = 0; // 1为推送位置标识昵称/单元格Ax昵称为空时0为不推送位置标识
var messageHeader = []; // 存放每个消息的头部单元格A3。目的是分离附加消息和执行结果消息
var messagePushHeader = pushHeader; // 存放在总消息的头部默认是pushHeader,如【xxxx】
var version = 1 // 版本类型自动识别并适配。默认为airscript 1.0否则为2.0Beta
var separator = "##########MOKU##########" // 分割符分割消息。可用于PUSH.js灵活推送
var maxMessageLength = 400; // 设置最大长度,超过这个长度则分片发送
var messageDistance = 100; // 消息距离用于匹配100字符内最近的行
var jsonPush = [
{ name: "bark", key: "xxxxxx", flag: "0" },
{ name: "pushplus", key: "xxxxxx", flag: "0" },
{ name: "ServerChan", key: "xxxxxx", flag: "0" },
{ name: "email", key: "xxxxxx", flag: "0" },
{ name: "dingtalk", key: "xxxxxx", flag: "0" },
{ name: "discord", key: "xxxxxx", flag: "0" },
]; // 推送数据flag=1则推送
var jsonEmail = {
server: "",
port: "",
sender: "",
authorizationCode: "",
}; // 有效邮箱配置
// =================青龙适配开始===================
qlSwitch = 0
// =================青龙适配结束===================
// =================金山适配开始===================
// airscript检测版本
function checkVesion(){
try{
let temp = Application.Range("A1").Text;
Application.Range("A1").Value = temp
console.log("😶‍🌫️ 检测到当前airscript版本为1.0进行1.0适配")
}catch{
console.log("😶‍🌫️ 检测到当前airscript版本为2.0进行2.0适配")
version = 2
}
}
// 推送相关
// 获取时间
function getDate(){
let currentDate = new Date();
currentDate = currentDate.getFullYear() + '/' + (currentDate.getMonth() + 1).toString() + '/' + currentDate.getDate().toString();
return currentDate
}
// 将消息写入CONFIG表中作为消息队列之后统一发送
function writeMessageQueue(message){
// 当天时间
let todayDate = getDate()
flagConfig = ActivateSheet(sheetNameConfig); // 激活主配置表
// 主配置工作表存在
if (flagConfig == 1) {
console.log("✨ 开始将结果写入主配置表");
for (let i = 2; i <= 100; i++) {
if(version == 1){
// 找到指定的表行
if(Application.Range("A" + (i + 2)).Value == sheetNameSubConfig){
// 写入更新的时间
Application.Range("F" + (i + 2)).Value = todayDate
// 写入消息
Application.Range("G" + (i + 2)).Value = message
console.log("✨ 写入结果完成");
break;
}
}else{
// 找到指定的表行
if(Application.Range("A" + (i + 2)).Value2 == sheetNameSubConfig){
// 写入更新的时间
Application.Range("F" + (i + 2)).Value2 = todayDate
// 写入消息
Application.Range("G" + (i + 2)).Value2 = message
console.log("✨ 写入结果完成");
break;
}
}
}
}
}
// 总推送
function push(message) {
writeMessageQueue(message) // 将消息写入CONFIG表中
// if (message != "") {
// // message = messagePushHeader + message // 消息头最前方默认存放【xxxx】
// let length = jsonPush.length;
// let name;
// let key;
// for (let i = 0; i < length; i++) {
// if (jsonPush[i].flag == 1) {
// name = jsonPush[i].name;
// key = jsonPush[i].key;
// if (name == "bark") {
// bark(message, key);
// } else if (name == "pushplus") {
// pushplus(message, key);
// } else if (name == "ServerChan") {
// serverchan(message, key);
// } else if (name == "email") {
// email(message);
// } else if (name == "dingtalk") {
// dingtalk(message, key);
// } else if (name == "discord") {
// discord(message, key);
// }
// }
// }
// } else {
// console.log("🍳 消息为空不推送");
// }
}
// 推送bark消息
function bark(message, key) {
if (key != "") {
message = messagePushHeader + message // 消息头最前方默认存放【xxxx】
message = encodeURIComponent(message)
BARK_ICON = "https://s21.ax1x.com/2024/06/23/pkrUkfe.png"
let url = "https://api.day.app/" + key + "/" + message + "/" + "?icon=" + BARK_ICON;
// 若需要修改推送的分组,则将上面一行改为如下的形式
// let url = 'https://api.day.app/' + bark_id + "/" + message + "?group=分组名";
let resp = HTTP.get(url, {
headers: { "Content-Type": "application/x-www-form-urlencoded" },
});
sleep(5000);
}
}
// 推送pushplus消息
function pushplus(message, key) {
if (key != "") {
message = encodeURIComponent(message)
// url = "http://www.pushplus.plus/send?token=" + key + "&content=" + message;
url = "http://www.pushplus.plus/send?token=" + key + "&content=" + message + "&title=" + pushHeader; // 增加标题
let resp = HTTP.fetch(url, {
method: "get",
});
sleep(5000);
}
}
// 推送serverchan消息
function serverchan(message, key) {
if (key != "") {
url =
"https://sctapi.ftqq.com/" +
key +
".send" +
"?title=" + messagePushHeader +
"&desp=" +
message;
let resp = HTTP.fetch(url, {
method: "get",
});
sleep(5000);
}
}
// email邮箱推送
function email(message) {
var myDate = new Date(); // 创建一个表示当前时间的 Date 对象
var data_time = myDate.toLocaleDateString(); // 获取当前日期的字符串表示
let server = jsonEmail.server;
let port = parseInt(jsonEmail.port); // 转成整形
let sender = jsonEmail.sender;
let authorizationCode = jsonEmail.authorizationCode;
let mailer;
mailer = SMTP.login({
host: server,
port: port,
username: sender,
password: authorizationCode,
secure: true,
});
mailer.send({
from: pushHeader + "<" + sender + ">",
to: sender,
subject: pushHeader + " - " + data_time,
text: message,
});
// console.log("🍳 已发送邮件至:" + sender);
console.log("🍳 已发送邮件");
sleep(5000);
}
// 邮箱配置
function emailConfig() {
console.log("🍳 开始读取邮箱配置");
let length = jsonPush.length; // 因为此json数据可无序因此需要遍历
let name;
for (let i = 0; i < length; i++) {
name = jsonPush[i].name;
if (name == "email") {
if (jsonPush[i].flag == 1) {
let flag = ActivateSheet(sheetNameEmail); // 激活邮箱表
// 邮箱表存在
// var email = {
// 'email':'', 'port':'', 'sender':'', 'authorizationCode':''
// } // 有效配置
if (flag == 1) {
console.log("🍳 开始读取邮箱表");
for (let i = 2; i <= 2; i++) {
// 从工作表中读取推送数据
jsonEmail.server = Application.Range("A" + i).Text;
jsonEmail.port = Application.Range("B" + i).Text;
jsonEmail.sender = Application.Range("C" + i).Text;
jsonEmail.authorizationCode = Application.Range("D" + i).Text;
if (Application.Range("A" + i).Text == "") {
// 如果为空行,则提前结束读取
break;
}
}
// console.log(jsonEmail)
}
break;
}
}
}
}
// 推送钉钉机器人
function dingtalk(message, key) {
message = messagePushHeader + message // 消息头最前方默认存放【xxxx】
let url = "https://oapi.dingtalk.com/robot/send?access_token=" + key;
let resp = HTTP.post(url, { msgtype: "text", text: { content: message } });
// console.log(resp.text())
sleep(5000);
}
// 推送Discord机器人
function discord(message, key) {
message = messagePushHeader + message // 消息头最前方默认存放【xxxx】
let url = key;
let resp = HTTP.post(url, { content: message });
//console.log(resp.text())
sleep(5000);
}
// =================金山适配结束===================
// =================共用开始===================
// main() // 入口
// function main(){
checkVesion() // 版本检测,以进行不同版本的适配
flagConfig = ActivateSheet(sheetNameConfig); // 激活推送表
// 主配置工作表存在
if (flagConfig == 1) {
console.log("🍳 开始读取主配置表");
let name; // 名称
let onlyError;
let nickname;
for (let i = 2; i <= 100; i++) {
// 从工作表中读取推送数据
name = Application.Range("A" + i).Text;
onlyError = Application.Range("C" + i).Text;
nickname = Application.Range("D" + i).Text;
if (name == "") {
// 如果为空行,则提前结束读取
break; // 提前退出,提高效率
}
if (name == sheetNameSubConfig) {
if (onlyError == "是") {
messageOnlyError = 1;
console.log("🍳 只推送错误消息");
}
if (nickname == "是") {
messageNickname = 1;
console.log("🍳 单元格用昵称替代");
}
break; // 提前退出,提高效率
}
}
}
flagPush = ActivateSheet(sheetNamePush); // 激活推送表
// 推送工作表存在
if (flagPush == 1) {
console.log("🍳 开始读取推送工作表");
let pushName; // 推送类型
let pushKey;
let pushFlag; // 是否推送标志
for (let i = 2; i <= line; i++) {
// 从工作表中读取推送数据
pushName = Application.Range("A" + i).Text;
pushKey = Application.Range("B" + i).Text;
pushFlag = Application.Range("C" + i).Text;
if (pushName == "") {
// 如果为空行,则提前结束读取
break;
}
jsonPushHandle(pushName, pushFlag, pushKey);
}
// console.log(jsonPush)
}
// 邮箱配置函数
emailConfig();
flagSubConfig = ActivateSheet(sheetNameSubConfig); // 激活分配置表
if (flagSubConfig == 1) {
console.log("🍳 开始读取分配置表");
if(qlSwitch != 1){ // 金山文档
for (let i = 2; i <= line; i++) {
var cookie = Application.Range("A" + i).Text;
var exec = Application.Range("B" + i).Text;
if (cookie == "") {
// 如果为空行,则提前结束读取
break;
}
if (exec == "是") {
execHandle(cookie, i);
}
}
message = messageMerge()// 将消息数组融合为一条总消息
push(message); // 推送消息
}else{
for (let i = 2; i <= line; i++) {
var cookie = Application.Range("A" + i).Text;
var exec = Application.Range("B" + i).Text;
if (cookie == "") {
// 如果为空行,则提前结束读取
break;
}
if (exec == "是") {
console.log("🧑 开始执行用户:" + "1" )
execHandle(cookie, i);
break; // 只取一个
}
}
}
}
// }
// 激活工作表函数
function ActivateSheet(sheetName) {
let flag = 0;
try {
// 激活工作表
let sheet = Application.Sheets.Item(sheetName);
sheet.Activate();
console.log("🥚 激活工作表:" + sheet.Name);
flag = 1;
} catch {
flag = 0;
console.log("🍳 无法激活工作表,工作表可能不存在");
}
return flag;
}
// 对推送数据进行处理
function jsonPushHandle(pushName, pushFlag, pushKey) {
let length = jsonPush.length;
for (let i = 0; i < length; i++) {
if (jsonPush[i].name == pushName) {
if (pushFlag == "是") {
jsonPush[i].flag = 1;
jsonPush[i].key = pushKey;
}
}
}
}
// 将消息数组融合为一条总消息
function messageMerge(){
// console.log(messageArray)
let message = ""
for(i=0; i<messageArray.length; i++){
if(messageArray[i] != "" && messageArray[i] != null)
{
message += "\n" + messageHeader[i] + messageArray[i] + ""; // 加上推送头
}
}
if(message != "")
{
console.log("✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨")
console.log(message + "\n") // 打印总消息
console.log("✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨")
}
return message
}
function sleep(d) {
for (var t = Date.now(); Date.now() - t <= d; );
}
// 获取sign返回小写
function getsign(data) {
var sign = Crypto.createHash("md5")
.update(data, "utf8")
.digest("hex")
// .toUpperCase() // 大写
.toString();
return sign;
}
// =================共用结束===================
// 具体的执行函数
function execHandle(cookie, pos) {
let messageSuccess = "";
let messageFail = "";
let messageName = "";
// 推送昵称或单元格,还是不推送位置标识
if (messageNickname == 1) {
// 推送昵称或单元格
messageName = Application.Range("C" + pos).Text;
if(messageName == "")
{
messageName = "单元格A" + pos + "";
}
}
posLabel = pos-2 ; // 存放下标从0开始
messageHeader[posLabel] = "👨‍🚀 " + messageName
//try {
var url1;
url1 = "https://www.chinadsl.net/"
headers = {
"Cookie":cookie,
"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Core/1.94.225.400 QQBrowser/12.2.5544.400"
}
// 登录
// resp = HTTP.fetch(url1, {
// method: "get",
// headers: headers,
// });
resp = HTTP.get(url1, {headers: headers,});
// 正则匹配
Reg = [
/title="访问我的空间">(.*?)<\/a>/i,
// /showmenu">积分: (.*?)<\/a>/i,
]
valueName = [
"用户", //"当前积分",
]
valueArry = []
html = resp.text();
// console.log(html)
for(i=0; i< Reg.length; i++)
{
flagTrue = Reg[i].test(html); // 判断是否存在字符串
if (flagTrue == true) {
let result = Reg[i].exec(html); // 提取匹配的字符串,["你已经连续签到 1 天,再接再厉!"," 1 "]
// result = result[0];
result = result[1];
valueArry[i] = result
content = valueName[i] + ":" + valueArry[i] + " "
messageSuccess += content;
console.log(content)
} else {
valueArry[i] = "获取失败"
content = "❌ " + valueName[i] + "获取失败\n"
messageFail += content;
}
}
messageSuccess += "🎉 " + "获得登录奖励\n"
sleep(2000)
url = "https://www.chinadsl.net/home.php?mod=task&do=apply&id=1"
// 做任务
// resp = HTTP.fetch(url, {
// method: "get",
// headers: headers,
// });
resp = HTTP.get(url, {headers: headers,});
sleep(2000)
// 领取奖励
url = "https://www.chinadsl.net/home.php?mod=task&do=draw&id=1"
// resp = HTTP.fetch(url, {
// method: "get",
// headers: headers,
// });
resp = HTTP.get(url, {headers: headers,});
sleep(2000)
// 查询奖励积分
url = "https://www.chinadsl.net/home.php?mod=task&item=done"
// resp = HTTP.fetch(url, {
// method: "get",
// headers: headers,
// });
resp = HTTP.get(url, {headers: headers,});
// 积分 猫粮 10 </td>
// 正则匹配
Reg = [
/积分 猫粮 (.*?) <\/td>/i,
]
valueName = [
"做任务获得积分",
]
valueArry = []
html = resp.text();
// console.log(html)
for(i=0; i< Reg.length; i++)
{
flagTrue = Reg[i].test(html); // 判断是否存在字符串
if (flagTrue == true) {
let result = Reg[i].exec(html); // 提取匹配的字符串,["你已经连续签到 1 天,再接再厉!"," 1 "]
// result = result[0];
result = result[1];
valueArry[i] = result
content = "🎉 " + valueName[i] + ":" + valueArry[i] + "\n"
messageSuccess += content;
console.log(content)
} else {
valueArry[i] = "获取失败"
content = "❌ " + valueName[i] + "获取失败\n"
messageFail += content;
}
}
sleep(2000)
// 登录,获取积分
// resp = HTTP.fetch(url1, {
// method: "get",
// headers: headers,
// });
resp = HTTP.get(url1, {headers: headers,});
// 显示积分
// 正则匹配
Reg = [
// /title="访问我的空间">(.*?)<\/a>/i,
/showmenu">积分: (.*?)<\/a>/i,
]
valueName = [
//"用户",
"当前积分",
]
valueArry = []
html = resp.text();
// console.log(html)
for(i=0; i< Reg.length; i++)
{
flagTrue = Reg[i].test(html); // 判断是否存在字符串
if (flagTrue == true) {
let result = Reg[i].exec(html); // 提取匹配的字符串,["你已经连续签到 1 天,再接再厉!"," 1 "]
// result = result[0];
result = result[1];
valueArry[i] = result
content = "🎉 " + valueName[i] + ":" + valueArry[i] + "\n"
messageSuccess += content;
console.log(content)
} else {
valueArry[i] = "获取失败"
content = "❌ " + valueName[i] + "获取失败\n"
messageFail += content;
}
}
// // 将数据写入表格中
// writeColoums = ["D", "E", "F", "G"] // 写入的列
// for(i=0; i<valueName.length;i++){
// if(valueArry[i] != "")
// {
// Application.Range(writeColoums[i] + pos).Value = valueArry[i]
// }
// }
//} catch {
// messageFail += messageName + "失败";
//}
sleep(2000);
if (messageOnlyError == 1) {
messageArray[posLabel] = messageFail;
} else {
if(messageFail != ""){
messageArray[posLabel] = messageFail + " " + messageSuccess;
}else{
messageArray[posLabel] = messageSuccess;
}
}
if(messageArray[posLabel] != "")
{
console.log(messageArray[posLabel]);
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,909 @@
// # Source: https://gitee.com/jdqlscript/toulu/blob/main/%E5%B9%BF%E6%B1%BD%E5%9F%83%E5%AE%89.js
// # Raw: https://gitee.com/jdqlscript/toulu/raw/main/%E5%B9%BF%E6%B1%BD%E5%9F%83%E5%AE%89.js
// # Repo: jdqlscript/toulu
// # Path: 广汽埃安.js
// # UploadedAt: 2025-06-28T11:18:42+08:00
// # SHA256: d765e765b7ca3dc06d021f6976d185f9ff299510be351238783213b618e7399b
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
/*
广汽埃安 v1.02
扫码下载注册: https://raw.githubusercontent.com/leafTheFish/DeathNote/main/gqaa.jpg
每天签到和开连签盲盒, 车主有额外的点赞积分任务
积分可以换充电卡等, 毛不大, 自己决定要不要玩
捉 www.gacne.com.cn 域名请求的Cookie, 把PHPSESSID的值(如PHPSESSID=xxxxxxxx;)填到变量 gqaaCookie 里面
嫌麻烦的也可以把整个cookie扔进去
多账号换行或&或@隔开
export PHPSESSID="xxxxxxxx"
有问题联系3288588344
频道https://pd.qq.com/s/672fku8ge
cron: 51 6,16 * * *
const $ = new Env("广汽埃安");
*/
const _0x57726e = _0xafb67f("广汽埃安"),
_0x157252 = require("got"),
{
CookieJar: _0x39b841
} = require("tough-cookie"),
_0x12a3af = "gqaa",
_0x27935e = /[\n\&\@]/,
_0x570313 = [_0x12a3af + "Cookie"],
_0x1f66ac = 8000,
_0x41a616 = 3;
const _0x620eeb = 1.02,
_0x5cb507 = "gqaa",
_0xd58e67 = "https://leafxcy.coding.net/api/user/leafxcy/project/validcode/shared-depot/validCode/git/blob/master/code.json",
_0x571d42 = "Mozilla/5.0 (iPhone; CPU iPhone OS 16_1_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 StatusHeight/20 BundleId/com.gacne.www Version/3.3.9",
_0x3a15c9 = "https://www.gacne.com.cn",
_0x223773 = "https://www.gacne.com.cn/web/app/sign_in.html",
_0x79e5b9 = 5,
_0x1a60e5 = 13,
_0x149fb5 = 1000,
_0x5a59fa = 3600000,
_0x2aa689 = 0,
_0x327956 = 3,
_0x3dd66a = ["顶一下", "打卡", "每日打打卡", "嘿嘿", "哈哈", "积分积分", "顶顶顶"];
class _0x1e527a {
constructor() {
this.index = _0x57726e.userIdx++;
this.name = "";
this.valid = false;
const _0x627300 = {
limit: 0
};
const _0x2f158b = {
Connection: "keep-alive"
};
const _0x3d9864 = {
retry: _0x627300,
timeout: _0x1f66ac,
followRedirect: false,
headers: _0x2f158b
};
this.got = _0x157252.extend(_0x3d9864);
}
log(_0x4ff667, _0x55786f = {}) {
let _0x1f3278 = "",
_0x49dff4 = _0x57726e.userCount.toString().length;
if (this.index) {
_0x1f3278 += "账号[" + _0x57726e.padStr(this.index, _0x49dff4) + "]";
}
if (this.name) {
_0x1f3278 += "[" + this.name + "]";
}
_0x57726e.log(_0x1f3278 + _0x4ff667, _0x55786f);
}
async request(_0x43dfdb) {
let _0x463e9e = null,
_0x35402b = 0,
_0x44adfc = _0x43dfdb.fn || _0x43dfdb.url;
_0x43dfdb.method = _0x43dfdb?.["method"]?.["toUpperCase"]() || "GET";
while (_0x35402b++ < _0x41a616) {
try {
await this.got(_0x43dfdb).then(_0x4f51f0 => {
_0x463e9e = _0x4f51f0;
}, _0x2322a7 => {
_0x463e9e = _0x2322a7.response;
});
if ((_0x463e9e?.["statusCode"] / 100 | 0) <= 4) {
break;
}
} catch (_0x4633ef) {
_0x4633ef.name == "TimeoutError" ? this.log("[" + _0x44adfc + "]请求超时,重试第" + _0x35402b + "次") : this.log("[" + _0x44adfc + "]请求错误(" + _0x4633ef.message + "),重试第" + _0x35402b + "次");
}
}
const _0x4beaf6 = {
statusCode: -1,
headers: null,
result: null
};
if (_0x463e9e == null) {
return Promise.resolve(_0x4beaf6);
}
let {
statusCode: _0x21acad,
headers: _0x20212f,
body: _0x5aae68
} = _0x463e9e;
if (_0x5aae68) {
try {
_0x5aae68 = JSON.parse(_0x5aae68);
} catch {}
}
const _0x274316 = {
statusCode: _0x21acad,
headers: _0x20212f,
result: _0x5aae68
};
return Promise.resolve(_0x274316);
}
}
let _0x1c4970 = new _0x1e527a();
class _0x61a68c extends _0x1e527a {
constructor(_0x2e700e) {
super();
this.cookieJar = new _0x39b841();
let _0x2753be = _0x2e700e?.["match"](/PHPSESSID=(\w+)/);
this.PHPSESSID = _0x2753be ? _0x2753be[1] : _0x2e700e;
this.set_cookie("PHPSESSID", this.PHPSESSID);
const _0x1937af = {
"User-Agent": _0x571d42,
Origin: _0x3a15c9,
Referer: _0x223773
};
this.got = this.got.extend({
cookieJar: this.cookieJar,
headers: _0x1937af
});
}
set_cookie(_0x280e6f, _0x2a073f, _0x2cf8a7 = {}) {
let _0x33c9fb = _0x2cf8a7.domain || "gacne.com.cn",
_0x980b19 = _0x2cf8a7.url || "https://www.gacne.com.cn";
this.cookieJar.setCookieSync(_0x280e6f + "=" + _0x2a073f + "; Domain=" + _0x33c9fb + ";", "" + _0x980b19);
}
async checkLogin(_0x2e5a5a = {}) {
let _0x2aa514 = false;
try {
const _0x41dd56 = {
fn: "checkLogin",
method: "post",
url: "https://www.gacne.com.cn/index/Madepost/checkLogin"
};
let {
result: _0x5564ff
} = await this.request(_0x57726e.copy(_0x41dd56)),
_0x3adeb3 = _0x57726e.get(_0x5564ff, "code", -1);
if (_0x3adeb3 == 200) {
this.valid = true;
let {
device_id: _0x5e0723,
tel: _0x1d8c34,
token: _0x3df494
} = _0x5564ff?.["data"];
this.deviceId = _0x5e0723;
this.deviceId && this.set_cookie("deviceId", this.deviceId);
this.name = _0x1d8c34;
this.token = _0x3df494;
_0x2aa514 = await this.refresh();
} else {
let _0x4d294d = _0x57726e.get(_0x5564ff, "msg", "");
this.log("登录失败[" + _0x3adeb3 + "]: " + _0x4d294d);
}
} catch (_0x56cd2f) {
console.log(_0x56cd2f);
} finally {
return _0x2aa514;
}
}
async refresh(_0x37f45f = {}) {
let _0x446dd1 = false;
try {
const _0x3c91b7 = {
fn: "refresh",
method: "post",
url: "https://www.gacne.com.cn/newv1/lifemain/insurance-mapi/order/had-insurance-order"
};
let {
result: _0x58b7f2
} = await this.request(_0x57726e.copy(_0x3c91b7)),
_0x5050a9 = _0x57726e.get(_0x58b7f2, "code", -1);
if (_0x5050a9 == "0000") {
_0x446dd1 = true;
} else {
let _0x1222de = _0x57726e.get(_0x58b7f2, "msg", "");
this.log("刷新CK失败[" + _0x5050a9 + "]: " + _0x1222de);
}
} catch (_0xcde42a) {
console.log(_0xcde42a);
} finally {
return _0x446dd1;
}
}
async sign_in(_0x3918cf = {}) {
try {
const _0x4c2257 = {
taskTypeCode: "TASK-INTEGRAL-SIGN-IN"
};
const _0xa4570a = {
fn: "sign_in",
method: "post",
url: "https://www.gacne.com.cn/newv1/lifemain/task-mapi/sign-in",
json: _0x4c2257
};
{
let {
result: _0x2765ad
} = await this.request(_0x57726e.copy(_0xa4570a)),
_0x43ae24 = _0x57726e.get(_0x2765ad, "code", -1);
if (_0x43ae24 == "0000") {
let {
isFirstSign: _0xada6da
} = _0x2765ad?.["data"];
_0xada6da ? this.log("签到成功") : this.log("今天已签到");
} else {
let _0x405d4e = _0x57726e.get(_0x2765ad, "msg", "");
this.log("查询签到失败[" + _0x43ae24 + "]: " + _0x405d4e);
}
}
{
let {
result: _0x436816
} = await this.request(_0x57726e.copy(_0xa4570a)),
_0x2412e4 = _0x57726e.get(_0x436816, "code", -1);
if (_0x2412e4 == "0000") {
let {
days: _0x2cb92f,
nextBoxTotalDay: _0x5644ae,
boxList: _0x249f7a
} = _0x436816?.["data"];
this.log("盲盒进度: " + _0x2cb92f + "/" + _0x5644ae);
for (let _0x14c86c of (_0x249f7a || []).filter(_0x8bef3 => _0x8bef3.status == 1)) {
for (let _0x4b5bcf = 0; _0x4b5bcf < _0x14c86c.openAmount; _0x4b5bcf++) {
await this.box_draw(_0x14c86c);
}
}
} else {
let _0x3639bf = _0x57726e.get(_0x436816, "msg", "");
this.log("查询盲盒进度失败[" + _0x2412e4 + "]: " + _0x3639bf);
}
}
} catch (_0x578aae) {
console.log(_0x578aae);
}
}
async box_draw(_0x3e3b3c, _0x2ca7ed = {}) {
try {
const _0x16465b = {
boxId: _0x3e3b3c.boxId,
type: 0
};
const _0x1f5e4c = {
fn: "box_draw",
method: "post",
url: "https://www.gacne.com.cn/newv1/lifemain/frontend/box/draw",
json: _0x16465b
};
let {
result: _0x2cb490
} = await this.request(_0x57726e.copy(_0x1f5e4c)),
_0x5f56d2 = _0x57726e.get(_0x2cb490, "code", -1);
if (_0x5f56d2 == "0000") {
let {
prizeName: _0x5c4c9d,
boxName: _0x477b46
} = _0x2cb490?.["data"];
const _0x5805b9 = {
notify: true
};
this.log("开启[" + _0x477b46 + "]: " + _0x5c4c9d, _0x5805b9);
} else {
let _0x1aad43 = _0x57726e.get(_0x2cb490, "msg", "");
this.log("开启[" + _0x3e3b3c.boxName + "]失败[" + _0x5f56d2 + "]: " + _0x1aad43);
}
} catch (_0x3a3ced) {
console.log(_0x3a3ced);
}
}
async check_integral(_0x26a1ff = {}) {
try {
const _0x5bb117 = {
fn: "check_integral",
method: "post",
url: "https://www.gacne.com.cn/newv1/lifemain/task-mapi/sign-in",
json: {}
};
_0x5bb117.json.taskTypeCode = "TASK-INTEGRAL-SIGN-IN";
let {
result: _0x15f240
} = await this.request(_0x57726e.copy(_0x5bb117)),
_0x348985 = _0x57726e.get(_0x15f240, "code", -1);
if (_0x348985 == "0000") {
this.integral = _0x15f240?.["data"]?.["totalIntegral"] || 0;
const _0x5967f7 = {
notify: true
};
this.log("积分: " + this.integral, _0x5967f7);
} else {
let _0x4449e3 = _0x57726e.get(_0x15f240, "msg", "");
this.log("查询积分失败[" + _0x348985 + "]: " + _0x4449e3);
}
} catch (_0xb1012) {
console.log(_0xb1012);
}
}
async detail_new(_0x28fa51 = {}) {
try {
const _0x3cf3e2 = {
fn: "detail_new",
method: "post",
url: "https://www.gacne.com.cn/newv1/lifemain/task-mapi/sign-in/detail-new",
json: {}
};
_0x3cf3e2.json.taskTypeCode = "TASK-INTEGRAL-SIGN-IN";
let {
result: _0xfcaa2d
} = await this.request(_0x57726e.copy(_0x3cf3e2)),
_0x5086a5 = _0x57726e.get(_0xfcaa2d, "code", -1);
if (_0x5086a5 == "0000") {
for (let _0x1b6428 of _0xfcaa2d?.["data"]?.["banners"] || []) {
for (let _0x1d600a of _0x1b6428?.["contents"] || []) {
for (let _0x2fb095 of (_0x1d600a?.["tasks"] || []).filter(_0x1aba03 => _0x1aba03.buttonStatus === 0)) {
await this.process_task(_0x2fb095);
}
}
}
} else {
let _0x1e19c9 = _0x57726e.get(_0xfcaa2d, "msg", "");
this.log("查询任务失败[" + _0x5086a5 + "]: " + _0x1e19c9);
}
} catch (_0x37e189) {
console.log(_0x37e189);
}
}
async process_task(_0x2181b7, _0x543497 = {}) {
try {
switch (_0x2181b7.taskId) {
case 62:
{
let _0x2d9cbd = Math.floor(Math.random() * 10000) + 45000;
for (let _0x19f914 = 0; _0x19f914 < 5; _0x19f914++) {
await this.article_like(_0x2d9cbd + _0x19f914);
}
break;
}
}
} catch (_0x4cd91a) {
console.log(_0x4cd91a);
}
}
async comment_add(_0x4bea91, _0x1ef972 = {}) {
try {
let _0x340015 = _0x57726e.randomList(_0x3dd66a),
_0x2b9f20 = {
fn: "comment_add",
method: "post",
url: "https://www.gacne.com.cn/newv1/cms/frontend/comment/add",
json: {
sourceId: _0x4bea91.toString(),
type: "104",
content: _0x340015,
contentExt: _0x340015,
atFriendsList: []
}
},
{
result: _0x24af06
} = await this.request(_0x57726e.copy(_0x2b9f20)),
_0x377dcc = _0x57726e.get(_0x24af06, "code", -1);
if (_0x377dcc == "0000") {
let _0x376cad = _0x24af06?.["data"]?.["id"] || 0;
this.log("评论文章[" + _0x4bea91 + "]成功: 评论id=" + _0x376cad);
_0x376cad && (await this.comment_delete(_0x376cad));
} else {
let _0x4dd834 = _0x57726e.get(_0x24af06, "msg", "");
this.log("评论失败[" + _0x377dcc + "]: " + _0x4dd834);
}
} catch (_0x33db3f) {
console.log(_0x33db3f);
}
}
async comment_delete(_0x2d86d7, _0x3148a6 = {}) {
try {
let _0x1100b5 = {
fn: "comment_add",
method: "post",
url: "https://www.gacne.com.cn/newv1/cms/frontend/comment/delete",
json: {
commentId: _0x2d86d7.toString(),
version: "3.3.9"
}
},
{
result: _0x47dabf
} = await this.request(_0x57726e.copy(_0x1100b5)),
_0x50c004 = _0x57726e.get(_0x47dabf, "code", -1);
if (_0x50c004 == "0000") {
this.log("删除评论[" + _0x2d86d7 + "]成功");
} else {
let _0x1c1b85 = _0x57726e.get(_0x47dabf, "msg", "");
this.log("删除评论[" + _0x2d86d7 + "]失败[" + _0x50c004 + "]: " + _0x1c1b85);
}
} catch (_0x283137) {
console.log(_0x283137);
}
}
async article_like(_0x3f7a7b, _0x5c0c91 = true, _0x468fdd = 0, _0x2f05f6 = {}) {
try {
const _0x2237b0 = {
fn: "comment_add",
method: "post",
url: "https://www.gacne.com.cn/newv1/cms/frontend/like/like",
json: {}
};
_0x2237b0.json.businessType = "104";
_0x2237b0.json.businessId = _0x3f7a7b;
let {
result: _0x89b536
} = await this.request(_0x57726e.copy(_0x2237b0)),
_0x5bff9e = _0x57726e.get(_0x89b536, "code", -1);
if (_0x5bff9e == "0000") {
_0x89b536?.["data"] == true ? (this.log("点赞文章[" + _0x3f7a7b + "]成功"), await this.article_like(_0x3f7a7b, false)) : _0x5c0c91 ? _0x468fdd < _0x327956 ? await this.article_like(_0x3f7a7b, true, _0x468fdd + 1) : this.log("点赞文章[" + _0x3f7a7b + "]失败") : this.log("取消点赞文章[" + _0x3f7a7b + "]成功");
} else {
let _0x2317e8 = _0x57726e.get(_0x89b536, "msg", "");
this.log("点赞文章[" + _0x3f7a7b + "]失败[" + _0x5bff9e + "]: " + _0x2317e8);
}
} catch (_0x423adf) {
console.log(_0x423adf);
}
}
async userTask(_0x332f3a = {}) {
if (!(await this.checkLogin())) {
return;
}
await this.sign_in();
await this.detail_new();
await this.check_integral();
}
}
!(async () => {
//if (!(await _0x54e8ac())) {
// return;
//}
_0x57726e.read_env(_0x61a68c);
for (let _0x1682e4 of _0x57726e.userList) {
await _0x1682e4.userTask();
}
})().catch(_0x30e3bb => _0x57726e.log(_0x30e3bb)).finally(() => _0x57726e.exitNow());
async function _0x54e8ac(_0x24bc02 = 0) {
let _0xbe6122 = false;
try {
const _0x2bdf7d = {
fn: "auth",
method: "get",
url: _0xd58e67,
timeout: 20000
};
let {
statusCode: _0x3b94f2,
result: _0xccbbf5
} = await _0x1c4970.request(_0x2bdf7d);
if (_0x3b94f2 != 200) {
_0x24bc02++ < _0x79e5b9 && (_0xbe6122 = await _0x54e8ac(_0x24bc02));
return _0xbe6122;
}
if (_0xccbbf5?.["code"] == 0) {
_0xccbbf5 = JSON.parse(_0xccbbf5.data.file.data);
if (_0xccbbf5?.["commonNotify"] && _0xccbbf5.commonNotify.length > 0) {
const _0x2920c3 = {
notify: true
};
_0x57726e.log(_0xccbbf5.commonNotify.join("\n") + "\n", _0x2920c3);
}
_0xccbbf5?.["commonMsg"] && _0xccbbf5.commonMsg.length > 0 && _0x57726e.log(_0xccbbf5.commonMsg.join("\n") + "\n");
if (_0xccbbf5[_0x5cb507]) {
let _0x3e76d7 = _0xccbbf5[_0x5cb507];
_0x3e76d7.status == 0 ? _0x620eeb >= _0x3e76d7.version ? (_0xbe6122 = true, _0x57726e.log(_0x3e76d7.msg[_0x3e76d7.status]), _0x57726e.log(_0x3e76d7.updateMsg), _0x57726e.log("现在运行的脚本版本是:" + _0x620eeb + ",最新脚本版本:" + _0x3e76d7.latestVersion)) : _0x57726e.log(_0x3e76d7.versionMsg) : _0x57726e.log(_0x3e76d7.msg[_0x3e76d7.status]);
} else {
_0x57726e.log(_0xccbbf5.errorMsg);
}
} else {
_0x24bc02++ < _0x79e5b9 && (_0xbe6122 = await _0x54e8ac(_0x24bc02));
}
} catch (_0x3351ef) {
_0x57726e.log(_0x3351ef);
} finally {
return _0xbe6122;
}
}
function _0xafb67f(_0x1769fd) {
return new class {
constructor(_0x256e2d) {
this.name = _0x256e2d;
this.startTime = Date.now();
const _0x5c5246 = {
time: true
};
this.log("[" + this.name + "]开始运行\n", _0x5c5246);
this.notifyStr = [];
this.notifyFlag = true;
this.userIdx = 0;
this.userList = [];
this.userCount = 0;
}
log(_0x3a7bbe, _0x5948a5 = {}) {
const _0x5dcf03 = {
console: true
};
Object.assign(_0x5dcf03, _0x5948a5);
if (_0x5dcf03.time) {
let _0x39f680 = _0x5dcf03.fmt || "hh:mm:ss";
_0x3a7bbe = "[" + this.time(_0x39f680) + "]" + _0x3a7bbe;
}
if (_0x5dcf03.notify) {
this.notifyStr.push(_0x3a7bbe);
}
if (_0x5dcf03.console) {
console.log(_0x3a7bbe);
}
}
get(_0x39951a, _0x25a1a2, _0x4d4fc7 = "") {
let _0x4e7345 = _0x4d4fc7;
_0x39951a?.["hasOwnProperty"](_0x25a1a2) && (_0x4e7345 = _0x39951a[_0x25a1a2]);
return _0x4e7345;
}
pop(_0x2e950f, _0x7c0dad, _0x359351 = "") {
let _0x13a1bb = _0x359351;
_0x2e950f?.["hasOwnProperty"](_0x7c0dad) && (_0x13a1bb = _0x2e950f[_0x7c0dad], delete _0x2e950f[_0x7c0dad]);
return _0x13a1bb;
}
copy(_0x49edda) {
return Object.assign({}, _0x49edda);
}
read_env(_0x10092d) {
let _0x51da5d = _0x570313.map(_0x24b37d => process.env[_0x24b37d]);
for (let _0x29db68 of _0x51da5d.filter(_0x5a7143 => !!_0x5a7143)) {
for (let _0x158a73 of _0x29db68.split(_0x27935e).filter(_0x376b1c => !!_0x376b1c)) {
if (this.userList.includes(_0x158a73)) {
continue;
}
this.userList.push(new _0x10092d(_0x158a73));
}
}
this.userCount = this.userList.length;
if (!this.userCount) {
const _0x222b1f = {
notify: true
};
this.log("未找到变量,请检查变量" + _0x570313.map(_0x271334 => "[" + _0x271334 + "]").join("或"), _0x222b1f);
return false;
}
this.log("共找到" + this.userCount + "个账号");
return true;
}
async threads(_0x4949f6, _0x584e43, _0x5a910f = {}) {
while (_0x584e43.idx < _0x57726e.userList.length) {
let _0x2ac950 = _0x57726e.userList[_0x584e43.idx++];
if (!_0x2ac950.valid) {
continue;
}
await _0x2ac950[_0x4949f6](_0x5a910f);
}
}
async threadTask(_0x2dea71, _0xc5fc20) {
let _0x50bab2 = [];
const _0x57c126 = {
idx: 0
};
while (_0xc5fc20--) {
_0x50bab2.push(this.threads(_0x2dea71, _0x57c126));
}
await Promise.all(_0x50bab2);
}
time(_0xd7b6ec, _0x470f66 = null) {
let _0x1f2c33 = _0x470f66 ? new Date(_0x470f66) : new Date(),
_0x5a2523 = {
"M+": _0x1f2c33.getMonth() + 1,
"d+": _0x1f2c33.getDate(),
"h+": _0x1f2c33.getHours(),
"m+": _0x1f2c33.getMinutes(),
"s+": _0x1f2c33.getSeconds(),
"q+": Math.floor((_0x1f2c33.getMonth() + 3) / 3),
S: this.padStr(_0x1f2c33.getMilliseconds(), 3)
};
/(y+)/.test(_0xd7b6ec) && (_0xd7b6ec = _0xd7b6ec.replace(RegExp.$1, (_0x1f2c33.getFullYear() + "").substr(4 - RegExp.$1.length)));
for (let _0x28cc52 in _0x5a2523) new RegExp("(" + _0x28cc52 + ")").test(_0xd7b6ec) && (_0xd7b6ec = _0xd7b6ec.replace(RegExp.$1, 1 == RegExp.$1.length ? _0x5a2523[_0x28cc52] : ("00" + _0x5a2523[_0x28cc52]).substr(("" + _0x5a2523[_0x28cc52]).length)));
return _0xd7b6ec;
}
async showmsg() {
if (!this.notifyFlag) {
return;
}
if (!this.notifyStr.length) {
return;
}
let _0x1d4fbc = require("./sendNotify");
this.log("\n============== 推送 ==============");
await _0x1d4fbc.sendNotify(this.name, this.notifyStr.join("\n"));
}
padStr(_0x3ad858, _0x529cdd, _0x52f10e = {}) {
let _0x430a77 = _0x52f10e.padding || "0",
_0x2f3ffe = _0x52f10e.mode || "l",
_0x20e6f5 = String(_0x3ad858),
_0x35ef26 = _0x529cdd > _0x20e6f5.length ? _0x529cdd - _0x20e6f5.length : 0,
_0x28c19f = "";
for (let _0x178519 = 0; _0x178519 < _0x35ef26; _0x178519++) {
_0x28c19f += _0x430a77;
}
_0x2f3ffe == "r" ? _0x20e6f5 = _0x20e6f5 + _0x28c19f : _0x20e6f5 = _0x28c19f + _0x20e6f5;
return _0x20e6f5;
}
json2str(_0x359dfc, _0x55e160, _0xe089a1 = false) {
let _0x209a05 = [];
for (let _0x25a87e of Object.keys(_0x359dfc).sort()) {
let _0x490db8 = _0x359dfc[_0x25a87e];
if (_0x490db8 && _0xe089a1) {
_0x490db8 = encodeURIComponent(_0x490db8);
}
_0x209a05.push(_0x25a87e + "=" + _0x490db8);
}
return _0x209a05.join(_0x55e160);
}
str2json(_0x17b2a4, _0x272cec = false) {
let _0x162d31 = {};
for (let _0x3c5246 of _0x17b2a4.split("&")) {
if (!_0x3c5246) {
continue;
}
let _0x2f91c5 = _0x3c5246.indexOf("=");
if (_0x2f91c5 == -1) {
continue;
}
let _0x1ab288 = _0x3c5246.substr(0, _0x2f91c5),
_0x162db1 = _0x3c5246.substr(_0x2f91c5 + 1);
if (_0x272cec) {
_0x162db1 = decodeURIComponent(_0x162db1);
}
_0x162d31[_0x1ab288] = _0x162db1;
}
return _0x162d31;
}
randomPattern(_0x5f3c83, _0x19f9c5 = "abcdef0123456789") {
let _0x4fa6d4 = "";
for (let _0x348d6c of _0x5f3c83) {
if (_0x348d6c == "x") {
_0x4fa6d4 += _0x19f9c5.charAt(Math.floor(Math.random() * _0x19f9c5.length));
} else {
_0x348d6c == "X" ? _0x4fa6d4 += _0x19f9c5.charAt(Math.floor(Math.random() * _0x19f9c5.length)).toUpperCase() : _0x4fa6d4 += _0x348d6c;
}
}
return _0x4fa6d4;
}
randomUuid() {
return this.randomPattern("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx");
}
randomString(_0x343b03, _0x324233 = "abcdef0123456789") {
let _0x30330 = "";
for (let _0x4135c1 = 0; _0x4135c1 < _0x343b03; _0x4135c1++) {
_0x30330 += _0x324233.charAt(Math.floor(Math.random() * _0x324233.length));
}
return _0x30330;
}
randomList(_0x13e9bb) {
let _0x110f62 = Math.floor(Math.random() * _0x13e9bb.length);
return _0x13e9bb[_0x110f62];
}
wait(_0x24952c) {
return new Promise(_0x34f73f => setTimeout(_0x34f73f, _0x24952c));
}
async exitNow() {
await this.showmsg();
let _0x2d8959 = Date.now(),
_0x46c8c7 = (_0x2d8959 - this.startTime) / 1000;
this.log("");
const _0x4e1a23 = {
time: true
};
this.log("[" + this.name + "]运行结束,共运行了" + _0x46c8c7 + "秒", _0x4e1a23);
process.exit(0);
}
normalize_time(_0x53b538, _0x1faa00 = {}) {
let _0x37b02e = _0x1faa00.len || _0x1a60e5;
_0x53b538 = _0x53b538.toString();
let _0x166c58 = _0x53b538.length;
while (_0x166c58 < _0x37b02e) {
_0x53b538 += "0";
}
_0x166c58 > _0x37b02e && (_0x53b538 = _0x53b538.slice(0, 13));
return parseInt(_0x53b538);
}
async wait_until(_0x218619, _0x55d35f = {}) {
let _0x52ea23 = _0x55d35f.logger || this,
_0x40b0a3 = _0x55d35f.interval || _0x149fb5,
_0x321fe6 = _0x55d35f.limit || _0x5a59fa,
_0x43d134 = _0x55d35f.ahead || _0x2aa689;
if (typeof _0x218619 == "string" && _0x218619.includes(":")) {
if (_0x218619.includes("-")) {
_0x218619 = new Date(_0x218619).getTime();
} else {
let _0x4570db = this.time("yyyy-MM-dd ");
_0x218619 = new Date(_0x4570db + _0x218619).getTime();
}
}
let _0x213726 = this.normalize_time(_0x218619) - _0x43d134,
_0x15f711 = this.time("hh:mm:ss.S", _0x213726),
_0x64038d = Date.now();
_0x64038d > _0x213726 && (_0x213726 += 86400000);
let _0x2300fa = _0x213726 - _0x64038d;
if (_0x2300fa > _0x321fe6) {
const _0x472762 = {
time: true
};
_0x52ea23.log("离目标时间[" + _0x15f711 + "]大于" + _0x321fe6 / 1000 + "秒,不等待", _0x472762);
} else {
const _0x51bb43 = {
time: true
};
_0x52ea23.log("离目标时间[" + _0x15f711 + "]还有" + _0x2300fa / 1000 + "秒,开始等待", _0x51bb43);
while (_0x2300fa > 0) {
let _0x35d2f8 = Math.min(_0x2300fa, _0x40b0a3);
await this.wait(_0x35d2f8);
_0x64038d = Date.now();
_0x2300fa = _0x213726 - _0x64038d;
}
const _0x50a2dc = {
time: true
};
_0x52ea23.log("已完成等待", _0x50a2dc);
}
}
async wait_gap_interval(_0x4b224a, _0x63b7f5) {
let _0x33918a = Date.now() - _0x4b224a;
_0x33918a < _0x63b7f5 && (await this.wait(_0x63b7f5 - _0x33918a));
}
}(_0x1769fd);
}

Some files were not shown because too many files have changed in this diff Show More