feat(xuequ): 添加携趣白名单切换脚本
- 新增 switch.js 脚本,用于自动切换携趣代理的白名单IP - 支持多账户和多IP配置,通过环境变量 XQ_ACCOUNTS 和 XQ_WHITELIST 设置 - 实现获取当前白名单、删除所有白名单、选择剩余次数最多的账户并添加新白名单的功能 - 集成定时任务,可通过 cron 表达式设置执行时间 - 添加详细的日志输出和错误处理机制
This commit is contained in:
96
.gitignore
vendored
Normal file
96
.gitignore
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node_modules
|
||||
node_modules/
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
.env.test
|
||||
.env.local
|
||||
.env.production
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# next.js build output
|
||||
.next
|
||||
|
||||
# nuxt.js build output
|
||||
.nuxt
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
|
||||
.claude/
|
||||
60
README.md
Normal file
60
README.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# 青龙面板脚本库
|
||||
|
||||
这是一个专为青龙面板设计的脚本库,包含各种自动化脚本和工具。
|
||||
|
||||
## 简介
|
||||
|
||||
青龙面板是一个支持 Python3、JavaScript、Shell、Typescript 的定时任务管理平台。本仓库提供了一系列实用的脚本,帮助用户更好地使用青龙面板进行自动化任务管理。
|
||||
|
||||
## 功能特性
|
||||
|
||||
- 📦 丰富的脚本库
|
||||
- 🔧 易于配置和使用
|
||||
- 📝 详细的文档说明
|
||||
- 🚀 持续更新维护
|
||||
|
||||
## 安装使用
|
||||
|
||||
### 环境要求
|
||||
|
||||
- Node.js >= 14.0.0
|
||||
- 青龙面板 >= 2.10.0
|
||||
|
||||
### 快速开始
|
||||
|
||||
1. 克隆仓库
|
||||
```bash
|
||||
git clone https://github.com/your-username/ql-scripts.git
|
||||
cd ql-scripts
|
||||
```
|
||||
|
||||
2. 安装依赖
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
3. 配置环境变量
|
||||
```bash
|
||||
cp .env.local .env
|
||||
# 编辑 .env 文件,填入必要的配置信息
|
||||
```
|
||||
|
||||
## 脚本说明
|
||||
|
||||
### 使用方法
|
||||
|
||||
每个脚本都有详细的使用说明,请查看对应的文档或脚本内的注释。
|
||||
|
||||
## 注意事项
|
||||
|
||||
- 请确保脚本符合青龙面板的规范
|
||||
- 使用前请仔细阅读脚本说明
|
||||
- 定期更新脚本以获得最新功能
|
||||
|
||||
## 免责声明
|
||||
|
||||
本项目仅供学习交流使用,请勿用于非法用途。使用本项目所产生的一切后果由使用者自行承担。
|
||||
|
||||
---
|
||||
|
||||
⭐ 如果这个项目对你有帮助,请给个 Star 支持一下!
|
||||
157
package-lock.json
generated
Normal file
157
package-lock.json
generated
Normal file
@@ -0,0 +1,157 @@
|
||||
{
|
||||
"name": "ql-scripts",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "ql-scripts",
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"node-fetch": "^2.7.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"env-cmd": "^11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@commander-js/extra-typings": {
|
||||
"version": "13.1.0",
|
||||
"resolved": "https://mirrors.cloud.tencent.com/npm/@commander-js/extra-typings/-/extra-typings-13.1.0.tgz",
|
||||
"integrity": "sha512-q5P52BYb1hwVWE6dtID7VvuJWrlfbCv4klj7BjUUOqMz4jbSZD4C9fJ9lRjL2jnBGTg+gDDlaXN51rkWcLk4fg==",
|
||||
"dev": true,
|
||||
"peerDependencies": {
|
||||
"commander": "~13.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "13.1.0",
|
||||
"resolved": "https://mirrors.cloud.tencent.com/npm/commander/-/commander-13.1.0.tgz",
|
||||
"integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://mirrors.cloud.tencent.com/npm/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"path-key": "^3.1.0",
|
||||
"shebang-command": "^2.0.0",
|
||||
"which": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/env-cmd": {
|
||||
"version": "11.0.0",
|
||||
"resolved": "https://mirrors.cloud.tencent.com/npm/env-cmd/-/env-cmd-11.0.0.tgz",
|
||||
"integrity": "sha512-gnG7H1PlwPqsGhFJNTv68lsDGyQdK+U9DwLVitcj1+wGq7LeOBgUzZd2puZ710bHcH9NfNeGWe2sbw7pdvAqDw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@commander-js/extra-typings": "^13.1.0",
|
||||
"commander": "^13.1.0",
|
||||
"cross-spawn": "^7.0.6"
|
||||
},
|
||||
"bin": {
|
||||
"env-cmd": "bin/env-cmd.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://mirrors.cloud.tencent.com/npm/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://mirrors.cloud.tencent.com/npm/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/path-key": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://mirrors.cloud.tencent.com/npm/path-key/-/path-key-3.1.1.tgz",
|
||||
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/shebang-command": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://mirrors.cloud.tencent.com/npm/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"shebang-regex": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/shebang-regex": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://mirrors.cloud.tencent.com/npm/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
||||
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://mirrors.cloud.tencent.com/npm/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://mirrors.cloud.tencent.com/npm/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||
},
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://mirrors.cloud.tencent.com/npm/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||
"dependencies": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://mirrors.cloud.tencent.com/npm/which/-/which-2.0.2.tgz",
|
||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"isexe": "^2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"node-which": "bin/node-which"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
33
package.json
Normal file
33
package.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "ql-scripts",
|
||||
"version": "1.0.0",
|
||||
"description": "青龙面板脚本库 - 自动化任务脚本集合",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "node index.js",
|
||||
"dev": "npx env-cmd -f .env.local node ./xuequ/switch.js",
|
||||
"test": "jest",
|
||||
"lint": "eslint .",
|
||||
"lint:fix": "eslint . --fix",
|
||||
"format": "prettier --write ."
|
||||
},
|
||||
"keywords": [
|
||||
"青龙面板",
|
||||
"qinglong",
|
||||
"scripts",
|
||||
"automation",
|
||||
"cron",
|
||||
"task"
|
||||
],
|
||||
"author": "@ZhuHJay",
|
||||
"license": "MIT",
|
||||
"volta": {
|
||||
"node": "18.20.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"node-fetch": "^2.7.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"env-cmd": "^11.0.0"
|
||||
}
|
||||
}
|
||||
1437
sendNotify.js
Normal file
1437
sendNotify.js
Normal file
File diff suppressed because one or more lines are too long
82
xuequ/switch.js
Normal file
82
xuequ/switch.js
Normal file
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* cron: 0 12 * * *
|
||||
*
|
||||
* 携趣白名单切换(多个携趣,多个IP,多个IP选中一个合适的携趣进行切换)
|
||||
*/
|
||||
const { Env } = require('../common');
|
||||
const $ = new Env('携趣小助手-白名单切换');
|
||||
const fetch = require('node-fetch');
|
||||
|
||||
/** 环境变量
|
||||
* XQ_ACCOUNTS: uid1;ukey1@备注 -》 多个则使用 & 分隔
|
||||
* XQ_WHITELIST: ip1 -》 多个则使用 & 分隔
|
||||
*/
|
||||
const accounts = process.env['XQ_ACCOUNTS'];
|
||||
const whitelist = process.env['XQ_WHITELIST'];
|
||||
|
||||
const apiTpl = {
|
||||
// 查看当前哪些 IP 在白名单中
|
||||
get: info => `http://op.xiequ.cn/IpWhiteList.aspx?uid=${info.uid}&ukey=${info.ukey}&act=get`,
|
||||
add: (info, ip) => `http://op.xiequ.cn/IpWhiteList.aspx?uid=${info.uid}&ukey=${info.ukey}&act=add&ip=${ip}`,
|
||||
delOne: (info, ip) => `http://op.xiequ.cn/IpWhiteList.aspx?uid=${info.uid}&ukey=${info.ukey}&act=del&ip=${ip}`,
|
||||
delAll: info => `http://op.xiequ.cn/IpWhiteList.aspx?uid=${info.uid}&ukey=${info.ukey}&act=del&ip=all`,
|
||||
// 获取 API 使用情况
|
||||
apiUse: info => `http://op.xiequ.cn/ApiUser.aspx?act=suitdt&uid=${info.uid}&ukey=${info.ukey}`
|
||||
}
|
||||
|
||||
!(async () => {
|
||||
if (!accounts || !whitelist) {
|
||||
$.log('请填写环境变量 XQ_ACCOUNTS & XQ_WHITELIST');
|
||||
return;
|
||||
}
|
||||
let tmp = [];
|
||||
let accs = accounts.split('&');
|
||||
let ips = whitelist.split('&');
|
||||
|
||||
// 解析参数 & 获取信息
|
||||
for (let content of accs) {
|
||||
let [acc, comment] = content.split('@');
|
||||
let [uid, ukey] = acc.split(';');
|
||||
if (!uid || !ukey) {
|
||||
$.log('请填写正确的环境变量 XQ_ACCOUNTS');
|
||||
return;
|
||||
}
|
||||
let info = { uid: uid.trim(), ukey: ukey.trim(), comment: comment || `[uid:${uid}]` };
|
||||
let item = {
|
||||
info: info,
|
||||
res: await (await fetch(apiTpl.get(info))).text(),
|
||||
count: await (async function () {
|
||||
let { data } = await (await fetch(apiTpl.apiUse(info))).json();
|
||||
return +data[0].num - +data[0].use;
|
||||
}())
|
||||
};
|
||||
tmp.push(item)
|
||||
$.log(`[INFO] ${item.info.comment} 剩余数: ${item.count}`);
|
||||
}
|
||||
|
||||
// 删除所有白名单
|
||||
$.log('\n--- 删除白名单 --- \n');
|
||||
for (let tmpElement of tmp) {
|
||||
if (tmpElement?.res) {
|
||||
await fetch(apiTpl.delAll(tmpElement.info));
|
||||
$.log(`删除 name: ${tmpElement.info.comment} 下的所有白名单 -> `, tmpElement.res);
|
||||
}
|
||||
}
|
||||
|
||||
await $.wait(520);
|
||||
// 选中一个数量最多的 API
|
||||
let change = tmp.sort((a, b) => b.count - a.count)[0];
|
||||
$.log('\n--- 切换白名单 --- \n');
|
||||
if (change) {
|
||||
for (const ip of ips) {
|
||||
await fetch(apiTpl.add(change.info, ip));
|
||||
$.log(`添加 name: ${change.info.comment} 白名单`);
|
||||
}
|
||||
}
|
||||
})()
|
||||
.catch((e) => {
|
||||
$.logErr(e);
|
||||
})
|
||||
.finally(() => {
|
||||
$.done();
|
||||
});
|
||||
Reference in New Issue
Block a user