/** * 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);