myssh / login.js
epii-1
修改结构
c5f59bc
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}`);
})();