const puppeteer = require('puppeteer'); const axios = require('axios'); // Telegram 配置 let telegramConfig; try { telegramConfig = JSON.parse(process.env.TELEGRAM_JSON || '{}'); } catch (error) { console.error('Error parsing TELEGRAM_JSON:', error); } function formatToISO(date) { return date.toISOString().replace('T', ' ').replace('Z', '').replace(/\.\d{3}Z/, ''); } async function delayTime(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function sendTelegramMessage(message) { if (!telegramConfig || !telegramConfig.cloudflareWorkerUrl || !telegramConfig.telegramBotToken || !telegramConfig.telegramBotUserId || !telegramConfig.customAuthKey) { console.log('Telegram configuration not set or incomplete, skipping notification'); return; } console.log('Attempting to send Telegram message...'); const url = `${telegramConfig.cloudflareWorkerUrl}/${telegramConfig.telegramBotToken}/sendMessage`; try { const response = await axios.post(url, { "chat_id": telegramConfig.telegramBotUserId, "text": message }, { headers: { 'X-Custom-Auth': telegramConfig.customAuthKey } }); console.log('Telegram notification sent successfully'); } catch (error) { console.error('Error sending Telegram notification:', error.response ? error.response.data : error.message); } } async function loginAccount(account, browser) { const { username, password, panelnum, type } = account; const page = await browser.newPage(); let url = type === 'ct8' ? 'https://panel.ct8.pl/login/?next=/' : `https://panel${panelnum}.serv00.com/login/?next=/`; try { // 设置自定义 headers 来绕过 Cloudflare await page.setExtraHTTPHeaders({ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate, br', 'Connection': 'keep-alive', 'Upgrade-Insecure-Requests': '1', 'Sec-Fetch-Dest': 'document', 'Sec-Fetch-Mode': 'navigate', 'Sec-Fetch-Site': 'none', 'Sec-Fetch-User': '?1', 'Cache-Control': 'max-age=0', }); await page.goto(url, { waitUntil: 'networkidle0' }); const usernameInput = await page.$('#id_username'); if (usernameInput) { await usernameInput.click({ clickCount: 3 }); await usernameInput.press('Backspace'); } await page.type('#id_username', username); await page.type('#id_password', password); const loginButton = await page.$('#submit'); if (loginButton) { await loginButton.click(); } else { throw new Error('无法找到登录按钮'); } await page.waitForNavigation({ timeout: 30000 }); const isLoggedIn = await page.evaluate(() => { const logoutButton = document.querySelector('a[href="/logout/"]'); return logoutButton !== null; }); const nowUtc = formatToISO(new Date()); const nowBeijing = formatToISO(new Date(new Date().getTime() + 8 * 60 * 60 * 1000)); if (isLoggedIn) { const message = `账号 ${username} (${type}) 于北京时间 ${nowBeijing}(UTC时间 ${nowUtc})登录成功!`; console.log(message); await sendTelegramMessage(`${type}, [${nowBeijing.split(' ')[1].split('.')[0]}]\n${message}`); return { success: true, message }; } else { const message = `账号 ${username} (${type}) 登录失败,请检查账号和密码是否正确。`; console.error(message); await sendTelegramMessage(`${type}, [${nowBeijing.split(' ')[1].split('.')[0]}]\n${message}`); return { success: false, message }; } } catch (error) { const message = `账号 ${username} (${type}) 登录时出现错误: ${error}`; console.error(message); await sendTelegramMessage(`${type}, [${formatToISO(new Date()).split(' ')[1].split('.')[0]}]\n${message}`); return { success: false, message }; } finally { await page.close(); } } (async () => { const accountsJson = process.env.ACCOUNTS_JSON; const accounts = JSON.parse(accountsJson); const browser = await puppeteer.launch({ headless: true, args: ['--no-sandbox', '--disable-setuid-sandbox'], executablePath: '/usr/bin/google-chrome-stable' }); const results = []; for (const account of accounts) { const result = await loginAccount(account, browser); results.push({ ...account, ...result }); const delay = Math.floor(Math.random() * 8000) + 1000; await delayTime(delay); } await browser.close(); const successfulLogins = results.filter(r => r.success); const failedLogins = results.filter(r => !r.success); // 生成表格形式的输出 console.log('\n登录结果汇总:'); console.log('| 账号 | 类型 | 状态 | 消息 |'); console.log('|------|------|------|------|'); results.forEach(({ username, type, success, message }) => { console.log(`| ${username} | ${type} | ${success ? '成功' : '失败'} | ${message} |`); }); let summaryMessage = '\n登录结果统计:\n'; summaryMessage += `成功登录的账号:${successfulLogins.length}\n`; summaryMessage += `登录失败的账号:${failedLogins.length}\n`; if (failedLogins.length > 0) { summaryMessage += '\n登录失败的账号列表:\n'; failedLogins.forEach(({ username, type }) => { summaryMessage += `- ${username} (${type})\n`; }); } console.log(summaryMessage); await sendTelegramMessage(`${accounts[0].type}, [${formatToISO(new Date()).split(' ')[1].split('.')[0]}]\n${summaryMessage}`); })();