HidenCloud 全自动续期 & 账单自动支付脚本 (青龙面板版)
HidenCloud 全自动续期 & 账单自动支付脚本 (青龙面板版)
这是一个用于 HidenCloud 免费服务器自动续期和自动支付账单的青龙面板脚本。
原帖:https://linux.do/t/topic/1393805
感谢 Y 佬的教程
HidenCloud 的免费机器虽然好用,但机制比较繁琐,本脚本实现了全流程自动化,自动续期 + 支付 + 自动读写 cookie。
建议手动续期 84 天后,每 7 天执行一次,避免错过续期窗口
功能特点
- 全流程自动化:自动识别账号下的所有服务 → 自动提交续期请求 → 自动跳转账单页 → 自动完成 0 元支付。
- 智能支付逻辑:
- 脚本会自动解析账单页面 HTML。
- 动态提取隐藏的支付参数。
- Cookie 自动续命 (持久化):
- 脚本运行期间会自动捕获服务器返回的新 Cookie。
- 将最新 Cookie 保存到本地
hiden_cookies.json文件。 - 优势:只要脚本每天运行,理论上无需再手动更新环境变量中的 Cookie。
- 多账号支持:支持无限个账号,通过换行或
&符号分隔。 - 防检测机制:
- 内置随机延迟(3-8 秒),模拟真人操作。
- 伪装完整的 Chrome 浏览器 Headers,降低被 Cloudflare 拦截的风险。
- 消息推送:对接青龙面板的通知系统,任务完成后发送续期结果。
使用方法
1. 准备工作
确保你的青龙面板已安装以下 Node.js 依赖(在 依赖管理 → NodeJs 中添加):
axioscheerio
2. 添加脚本
在青龙面板 脚本管理 中新建脚本,名称随意(例如 hiden_renew.js),将代码完全粘贴进去。
自定义续期天数:脚本第 23 行,将数字 10 修改为你想要的天数即可。
const RENEW_DAYS = 10;
青龙脚本 hiden_renew.js
/*
new Env('HidenCloud 自动续期-毕业版');
cron: 0 0 10 * * ?
checks: 自动续期、自动支付、Cookie自动持久化、消息推送
*/
const axios = require('axios');
const cheerio = require('cheerio');
const fs = require('fs');
const path = require('path');
// 尝试加载 notify,如果没有也不影响运行
let sendNotify = () => {};
try {
const notify = require('./sendNotify');
sendNotify = notify.sendNotify;
} catch (e) {
console.log('未找到 sendNotify,跳过推送');
}
// 环境变量
const HIDEN_COOKIES_ENV = process.env.HIDEN_COOKIE ? process.env.HIDEN_COOKIE.split(/[&\n]/) : [];
const RENEW_DAYS = 10;
const CACHE_FILE = path.join(__dirname, 'hiden_cookies.json');
// 汇总消息
let summaryMsg = '';
const sleep = (min = 3000, max = 8000) => {
const delay = Math.floor(Math.random() * (max - min + 1)) + min;
return new Promise(resolve => setTimeout(resolve, delay));
};
// 本地缓存管理
const CacheManager = {
load() {
if (fs.existsSync(CACHE_FILE)) {
try {
return JSON.parse(fs.readFileSync(CACHE_FILE, 'utf8'));
} catch (e) {
console.log('读取缓存文件失败,将重新创建');
}
}
return {};
},
save(data) {
fs.writeFileSync(CACHE_FILE, JSON.stringify(data, null, 2));
},
get(index) {
const data = this.load();
return data[index] || null;
},
update(index, cookieStr) {
const data = this.load();
data[index] = cookieStr;
this.save(data);
console.log(`💾 [账号 ${index + 1}] 最新 Cookie 已保存到本地缓存`);
}
};
class HidenCloudBot {
constructor(envCookie, index) {
this.index = index + 1;
this.envCookie = envCookie;
this.cookieData = {};
this.logMsg = []; // 存储该账号的日志用于推送
// 优先尝试读取缓存
const cachedCookie = CacheManager.get(this.index - 1);
if (cachedCookie) {
console.log(`[账号 ${this.index}] 发现本地缓存 Cookie,优先使用...`);
this.parseCookieStr(cachedCookie);
} else {
console.log(`[账号 ${this.index}] 使用环境变量 Cookie...`);
this.parseCookieStr(envCookie);
}
this.commonHeaders = {
'Host': 'dash.hidencloud.com',
'Connection': 'keep-alive',
'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
'sec-ch-ua-mobile': '?0',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
'Referer': 'https://dash.hidencloud.com/',
};
this.client = axios.create({
baseURL: 'https://dash.hidencloud.com',
maxRedirects: 0,
validateStatus: status => status >= 200 && status < 500,
timeout: 30000
});
this.services = [];
this.csrfToken = '';
}
log(msg) {
console.log(`[账号 ${this.index}] ${msg}`);
this.logMsg.push(msg);
}
parseCookieStr(str) {
if (!str) return;
str.split(';').forEach(pair => {
const idx = pair.indexOf('=');
if (idx > 0) {
const key = pair.substring(0, idx).trim();
const val = pair.substring(idx + 1).trim();
if (!['path', 'domain', 'expires', 'httponly', 'secure', 'samesite'].includes(key.toLowerCase())) {
this.cookieData[key] = val;
}
}
});
}
updateCookiesFromResponse(headers) {
const setCookie = headers['set-cookie'];
if (setCookie) {
setCookie.forEach(sc => {
const firstPart = sc.split(';')[0];
const idx = firstPart.indexOf('=');
if (idx > 0) {
const key = firstPart.substring(0, idx).trim();
const val = firstPart.substring(idx + 1).trim();
this.cookieData[key] = val;
}
});
// 每次更新 Cookie 都保存到本地
CacheManager.update(this.index - 1, this.getCookieStr());
}
}
getCookieStr() {
return Object.keys(this.cookieData).map(k => `${k}=${this.cookieData[k]}`).join('; ');
}
async request(method, url, data = null, extraHeaders = {}) {
let currentUrl = url;
let methodToUse = method;
let finalResponse = null;
const requestHeaders = {
...this.commonHeaders,
...extraHeaders,
'Cookie': this.getCookieStr()
};
if (methodToUse === 'POST' && !requestHeaders['Content-Type']) {
requestHeaders['Content-Type'] = 'application/x-www-form-urlencoded';
}
try {
const res = await this.client({
method: methodToUse,
url: currentUrl,
headers: requestHeaders,
data: data
});
this.updateCookiesFromResponse(res.headers);
res.finalUrl = currentUrl;
finalResponse = res;
if (res.status === 301 || res.status === 302) {
const location = res.headers['location'];
if (location) {
this.log(`🔄 重定向 -> ${location}`);
currentUrl = location.startsWith('http') ? location : `https://dash.hidencloud.com${location.startsWith('/') ? '' : '/'}${location}`;
return this.request('GET', currentUrl);
}
}
finalResponse.finalUrl = currentUrl;
return finalResponse;
} catch (err) {
throw err;
}
}
extractTokens($) {
const metaToken = $('meta[name="csrf-token"]').attr('content');
if (metaToken) this.csrfToken = metaToken;
}
async init() {
this.log('正在验证登录状态...');
try {
const res = await this.request('GET', '/dashboard');
// 检查失效
if (res.headers.location && res.headers.location.includes('/login')) {
this.log('❌ 当前 Cookie 已失效');
return false;
}
const $ = cheerio.load(res.data);
this.extractTokens($);
// 解析服务列表
$('a[href*="/service/"]').each((i, el) => {
const href = $(el).attr('href');
const match = href.match(/\/service\/(\d+)\/manage/);
if (match) {
this.services.push({ id: match[1], url: href });
}
});
this.services = this.services.filter((v, i, a) => a.findIndex(t => t.id === v.id) === i);
this.log(`✅ 登录成功,发现 ${this.services.length} 个服务。`);
return true;
} catch (e) {
this.log(`❌ 初始化异常: ${e.message}`);
return false;
}
}
// 重置为环境变量 Cookie (用于缓存失效时重试)
resetToEnv() {
this.cookieData = {};
this.parseCookieStr(this.envCookie);
console.log(`[账号 ${this.index}] 切换回环境变量原始 Cookie 重试...`);
}
async processService(service) {
await sleep(2000, 4000);
this.log(`>>> 处理服务 ID: ${service.id}`);
try {
const manageRes = await this.request('GET', `/service/${service.id}/manage`);
const $ = cheerio.load(manageRes.data);
const formToken = $('input[name="_token"]').val();
this.log(`提交续期 (${RENEW_DAYS}天)...`);
await sleep(1000, 2000);
const params = new URLSearchParams();
params.append('_token', formToken);
params.append('days', RENEW_DAYS);
const res = await this.request('POST', `/service/${service.id}/renew`, params, {
'X-CSRF-TOKEN': this.csrfToken,
'Referer': `https://dash.hidencloud.com/service/${service.id}/manage`
});
if (res.finalUrl && res.finalUrl.includes('/invoice/')) {
this.log(`⚡️ 续期成功,前往支付`);
await this.performPayFromHtml(res.data, res.finalUrl);
} else {
this.log('⚠️ 续期后未跳转,检查列表...');
await this.checkAndPayInvoices(service.id);
}
} catch (e) {
this.log(`处理异常: ${e.message}`);
}
}
async checkAndPayInvoices(serviceId) {
await sleep(2000, 3000);
try {
const res = await this.request('GET', `/service/${serviceId}/invoices?where=unpaid`);
const $ = cheerio.load(res.data);
const invoiceLinks = [];
$('a[href*="/invoice/"]').each((i, el) => {
const href = $(el).attr('href');
if (href && !href.includes('download')) invoiceLinks.push(href);
});
const uniqueInvoices = [...new Set(invoiceLinks)];
if (uniqueInvoices.length === 0) {
this.log(`✅ 无未支付账单`);
return;
}
for (const url of uniqueInvoices) {
await this.paySingleInvoice(url);
await sleep(3000, 5000);
}
} catch (e) {
this.log(`查账单出错: ${e.message}`);
}
}
async paySingleInvoice(url) {
try {
this.log(`📄 打开账单: ${url}`);
const res = await this.request('GET', url);
await this.performPayFromHtml(res.data, url);
} catch (e) {
this.log(`访问失败: ${e.message}`);
}
}
async performPayFromHtml(html, currentUrl) {
const $ = cheerio.load(html);
let targetForm = null;
let targetAction = '';
$('form').each((i, form) => {
const btnText = $(form).find('button').text().trim().toLowerCase();
const action = $(form).attr('action');
if (btnText.includes('pay') && action && !action.includes('balance/add')) {
targetForm = $(form);
targetAction = action;
return false;
}
});
if (!targetForm) {
this.log(`⚪ 页面未找到支付表单 (可能已支付)。`);
return;
}
const payParams = new URLSearchParams();
targetForm.find('input').each((i, el) => {
const name = $(el).attr('name');
const value = $(el).val();
if (name) payParams.append(name, value || '');
});
this.log(`👉 提交支付...`);
try {
const payRes = await this.request('POST', targetAction, payParams, {
'X-CSRF-TOKEN': this.csrfToken,
'Referer': currentUrl
});
if (payRes.status === 200) {
this.log(`✅ 支付成功!`);
} else {
this.log(`⚠️ 支付响应: ${payRes.status}`);
}
} catch (e) {
this.log(`❌ 支付失败: ${e.message}`);
}
}
}
(async () => {
if (HIDEN_COOKIES_ENV.length === 0) {
console.log('❌ 未配置环境变量 HIDEN_COOKIE');
return;
}
console.log(`=== HidenCloud 续期脚本启动 (账号数: ${HIDEN_COOKIES_ENV.length}) ===\n`);
for (let i = 0; i < HIDEN_COOKIES_ENV.length; i++) {
const bot = new HidenCloudBot(HIDEN_COOKIES_ENV[i], i);
// 第一次尝试(可能用的是缓存)
let success = await bot.init();
// 如果失败,且当前用的是缓存,则回退到环境变量重试
if (!success && CacheManager.get(i)) {
bot.resetToEnv();
success = await bot.init();
}
if (success) {
for (const svc of bot.services) {
await bot.processService(svc);
}
summaryMsg += `账号 ${i + 1}: 成功续期 ${bot.services.length} 个服务\n`;
} else {
summaryMsg += `账号 ${i + 1}: 登录失败,请更新 Cookie\n`;
}
console.log('\n----------------------------------------\n');
if (i < HIDEN_COOKIES_ENV.length - 1) await sleep(5000, 10000);
}
// 发送推送
if (summaryMsg) {
await sendNotify('HidenCloud 续期报告', summaryMsg);
}
})();
3. 设置环境变量
在 环境变量 中添加变量:
| 变量名 | 必填 | 说明 |
|---|---|---|
HIDEN_COOKIE | 你的 HidenCloud 面板 Cookie |
如何获取 Cookie:
- 浏览器打开并登录 HidenCloud Dashboard。
- 按
F12打开开发者工具,点击 网络 (Network) 标签。 - 刷新页面,点击第一个请求(
dashboard或manage)。 - 在右侧 请求头 (Request Headers) 中找到
Cookie,复制后面的一长串内容。
多账号设置:
如果有多个账号,直接新建多个同名变量 HIDEN_COOKIE,或者在一个变量值里用 & 或换行符分隔。
4. 设置定时任务
建议手动续期 84 天后,每 7 天执行一次,避免错过续期窗口。
Cron 表达式示例:0 10 */7 * * (每 7 天上午 10 点执行)
消息推送配置说明
本脚本已深度集成青龙面板自带的通知系统 (sendNotify.js)。你只需要在青龙面板配置好推送方式,脚本运行结束后就会自动发送报告。
支持的推送渠道
微信 (Server 酱 / 企业微信)、Telegram、钉钉、飞书、Bark、PushPlus 等青龙支持的所有渠道。
配置步骤
- 打开青龙面板 → 系统设置 → 通知设置。
- 选择你喜欢的推送方式(例如 PushPlus 或 Telegram)。
- 填入相应的 Token 或 Key,点击保存并测试。
- 无需修改脚本代码。脚本会自动检测青龙的通知配置。
推送效果预览
任务完成后,你会收到类似如下的通知:
HidenCloud 续期报告
账号 1: 成功续期 2 个服务
账号 2: 成功续期 1 个服务
账号 3: 登录失败,请更新 Cookie
脚本逻辑说明
- 初始化:脚本启动时,优先读取本地缓存文件
hiden_cookies.json中的 Cookie。如果缓存不存在或失效,则回退使用环境变量HIDEN_COOKIE。 - 检测:登录 Dashboard,自动扫描账号下所有活跃的服务 ID。
- 续期:进入管理页面,获取 CSRF Token,提交续期 10 天的请求。
- 支付:
- 续期成功后,脚本会自动检测是否跳转到了 Invoice 页面。
- 如果是,直接在当前页面提取表单参数并提交支付。
- 如果未跳转,脚本会额外检查 “未支付账单” 列表,确保没有漏网之鱼。
- 保存:运行结束时,将最新的有效 Cookie 写入本地缓存,供下次使用。
常见问题
Q: 提示 403 Forbidden / Cloudflare 拦截?
A: 这通常是因为你的青龙面板服务器 IP (如阿里云、腾讯云数据中心 IP) 被 Cloudflare 拉黑了。
- 解决方法:尝试在本地电脑(家庭宽带)运行脚本,或者给青龙面板配置代理。
Q: 为什么日志显示 “支付成功” 但网页看还是未支付?
A: HidenCloud 后端偶尔有延迟。只要日志显示 Status 200 或 支付成功,通常稍等几分钟刷新网页即可变更为 Paid。
Q: 必须要手动抓包 Cookie 吗?
A: 第一次必须手动抓取。之后脚本会自动维护 Cookie,除非服务器强制登出所有会话,否则不需要频繁更新。
免责声明
本脚本仅供学习交流使用,请勿用于非法用途。使用本脚本产生的任何后果由使用者自行承担。