/**
* Peekabo Networks 自动续费监控脚本
* 每天 00:05 检测账单,有账单自动用余额续费
* 续费失败通知 Telegram
*/
const https = require('https');
// ========== 配置 ==========
const ACCOUNTS = [
{ email: 'mail@mailpre.com', password: 'hawvys-Vitcy7-kyxzuf' },
{ email: 'mf0@msn.com', password: '@a110110' },
{ email: 'yxvmhk@qq.com', password: '@a110110' }
];
const TG_BOT_TOKEN = '8300905342:AAH3Q78FuR5Exrw2zWYJHFRyVeLlws3xnww';
const TG_CHAT_ID = '165067365';
const BASE_URL = 'gigo.peekabo.io';
// ========== Telegram 通知 ==========
async function sendTG(message) {
const data = JSON.stringify({ chat_id: TG_CHAT_ID, text: message, parse_mode: 'HTML' });
return new Promise((resolve) => {
const req = https.request({
hostname: 'api.telegram.org',
path: `/bot${TG_BOT_TOKEN}/sendMessage`,
method: 'POST',
headers: { 'Content-Type': 'application/json' }
}, res => { let b = ''; res.on('data', c => b += c); res.on('end', () => resolve(b)); });
req.write(data);
req.end();
});
}
// ========== HTTP 请求 ==========
function request(options, postData = null) {
return new Promise((resolve, reject) => {
const req = https.request(options, res => {
let body = '';
res.on('data', c => body += c);
res.on('end', () => resolve({
status: res.statusCode,
headers: res.headers,
body,
cookies: res.headers['set-cookie'] || []
}));
});
req.on('error', reject);
if (postData) req.write(postData);
req.end();
});
}
// ========== 检测单个账户 ==========
async function checkAccount(account) {
const result = { email: account.email, invoices: [], paid: [], failed: [], error: null };
let cookies = '';
try {
// 1. 获取登录页面拿 token
const loginPage = await request({
hostname: BASE_URL,
path: '/index.php?rp=/login',
method: 'GET'
});
const tokenMatch = loginPage.body.match(/name="token" value="([^"]+)"/);
if (!tokenMatch) { result.error = '获取token失败'; return result; }
cookies = loginPage.cookies.map(c => c.split(';')[0]).join('; ');
// 2. 登录
const loginData = `token=${tokenMatch[1]}&username=${encodeURIComponent(account.email)}&password=${encodeURIComponent(account.password)}`;
const loginRes = await request({
hostname: BASE_URL,
path: '/index.php?rp=/login',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Cookie': cookies
}
}, loginData);
// 更新 cookies
if (loginRes.cookies.length) {
cookies = loginRes.cookies.map(c => c.split(';')[0]).join('; ');
}
// 3. 检查是否登录成功 - 访问客户区
const dashboard = await request({
hostname: BASE_URL,
path: '/clientarea.php',
method: 'GET',
headers: { 'Cookie': cookies }
});
if (!dashboard.body.includes('My Dashboard') && !dashboard.body.includes('Logout')) {
result.error = '登录失败';
return result;
}
// 4. 获取未付账单
const invoicesPage = await request({
hostname: BASE_URL,
path: '/clientarea.php?action=invoices',
method: 'GET',
headers: { 'Cookie': cookies }
});
// 匹配未付账单
const unpaidRegex = /viewinvoice\.php\?id=(\d+)[^>]*>.*?#\d+.*?<\/a>.*?\$([0-9.]+).*?Unpaid/gs;
let match;
while ((match = unpaidRegex.exec(invoicesPage.body)) !== null) {
result.invoices.push({ id: match[1], amount: parseFloat(match[2]) });
}
// 5. 如果有未付账单,尝试用余额支付
for (const inv of result.invoices) {
const payRes = await request({
hostname: BASE_URL,
path: `/viewinvoice.php?id=${inv.id}`,
method: 'GET',
headers: { 'Cookie': cookies }
});
// 检查是否有 Apply Credit 按钮
if (payRes.body.includes('applycredit')) {
const creditRes = await request({
hostname: BASE_URL,
path: `/viewinvoice.php?id=${inv.id}&applycredit=true`,
method: 'GET',
headers: { 'Cookie': cookies }
});
if (creditRes.body.includes('Paid') || creditRes.status === 302) {
result.paid.push(inv);
} else {
result.failed.push({ ...inv, reason: '支付失败' });
}
} else {
result.failed.push({ ...inv, reason: '无法使用余额' });
}
}
} catch (err) {
result.error = err.message;
}
return result;
}
// ========== 主函数 ==========
async function main() {
console.log(`[${new Date().toISOString()}] 开始检测...`);
let msg = '🔔 Peekabo 账单检测\n\n';
let needNotify = false;
for (const acc of ACCOUNTS) {
const r = await checkAccount(acc);
msg += `📧 ${r.email}\n`;
if (r.error) {
msg += `❌ ${r.error}\n`;
needNotify = true;
} else if (r.invoices.length === 0) {
msg += `✅ 无待付账单\n`;
} else {
if (r.paid.length) msg += `✅ 已付: ${r.paid.map(i => '$' + i.amount).join(', ')}\n`;
if (r.failed.length) {
msg += `❌ 失败: ${r.failed.map(i => '$' + i.amount).join(', ')}\n`;
needNotify = true;
}
}
msg += '\n';
}
if (needNotify) {
await sendTG(msg);
console.log('已通知');
} else {
console.log('全部正常');
}
}
main().catch(console.error);