const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
const path = require('path');
const fs = require('fs');
// ⚠️ REPLACE WITH YOUR API KEY
const CAPTCHA_API_KEY = 'f1fc51f083043b2c22c7835ffe7a8721';
// Configuration
const CONFIG = {
// --- SCHEDULED REFRESH SETTINGS ---
REFRESH_MINUTE: 10, // Refresh at X:10 every hour
CHAT_SELECTOR: '.chat-toggle-shadow',
CHAT_SIDEBAR_ID: '11m', // The ID from the div structure
ENABLE_CAPTCHA_SOLVER: false,
CAPTCHA_SERVICE: '2captcha',
USE_PROXY: true,
PROXY_SERVER: 'http://geo.g-w.info:10080',
PROXY_USERNAME: 'user-FUBJvHtbDOaVNm3M-type-mobile-country-FR',
PROXY_PASSWORD: '1PRX9EnYq8WtCFy0',
EXTENSION_1_PATH: path.join(process.env.HOME, 'Downloads', 'csgoroll-auto-claim'),
EXTENSION_2_PATH: path.join(process.env.HOME, 'Downloads', 'capmonster'),
USE_USER_DATA_DIR: false,
USER_DATA_DIR: path.resolve(__dirname, 'chrome-profile'),
TARGET_URL: 'https://www.csgoroll.com/',
CHECK_INTERVAL: 7000,
SOLVE_INVISIBLE: false,
MAX_SOLVE_ATTEMPTS: 60,
POLL_DELAY: 3000,
DISCORD_WEBHOOK_URL: 'https://discordapp.com/api/webhooks/1443661462219395125/kGkJBIz885Poa0N-cZTk8j2JciH7u0usEPkpGQgL2f14sXdDKibuRoPrpIZEe1PbmrbU',
ENABLE_MEMORY_MONITOR: true,
MEMORY_CHECK_INTERVAL: 5000,
CHECK_ERROR_PAGES: true,
AUTO_RETRY_ON_ERROR: true,
RETRY_DELAY: 5000,
MAX_RETRY_ATTEMPTS: 10,
ENABLE_CAPTCHA_ERROR_HANDLER: true,
CAPTCHA_ERROR_RETRY_DELAY: 2000,
};
puppeteer.use(StealthPlugin());
// ==================== ERROR RECOVERY LOGIC ====================
/**
* Checks if the page is currently showing a Chrome error page (like ERR_CONNECTION_CLOSED)
* and reloads if necessary.
*/
async function recoverFromErrorPage(page) {
try {
const isErrorPage = await page.evaluate(() => {
const title = document.title.toLowerCase();
const bodyText = document.body.innerText.toLowerCase();
return (
title.includes('not available') ||
title.includes('can\'t be reached') ||
bodyText.includes('err_connection_closed') ||
bodyText.includes('unexpectedly closed the connection') ||
bodyText.includes('err_proxy_connection_failed') ||
bodyText.includes('err_tunnel_connection_failed')
);
});
if (isErrorPage) {
console.log('⚠️ Proxy/Connection error detected. Retrying in 5s...');
await new Promise(r => setTimeout(r, CONFIG.RETRY_DELAY));
await page.reload({ waitUntil: 'networkidle2' });
}
} catch (e) {
// Evaluation might fail if the page is completely unresponsive
}
}
/**
* Robust navigation that retries multiple times if the connection fails initially.
*/
async function safeNavigate(page, url) {
let attempts = 0;
while (attempts < CONFIG.MAX_RETRY_ATTEMPTS) {
try {
console.log(`🌐 Navigating to ${url} (Attempt ${attempts + 1})...`);
await page.goto(url, { waitUntil: 'networkidle2', timeout: 60000 });
// Check for hidden error pages
await recoverFromErrorPage(page);
return;
} catch (e) {
attempts++;
console.error(`❌ Navigation failed (likely proxy issue): ${e.message}. Retrying...`);
await new Promise(r => setTimeout(r, CONFIG.RETRY_DELAY));
}
}
console.error('🛑 Max navigation retries reached. Check if your proxy credentials or IP are valid.');
}
// ==================== CHAT & REFRESH LOGIC ====================
async function ensureChatVisible(page) {
try {
await page.evaluate((selector, sidebarId) => {
const sidebar = document.querySelector(`div[q\\:id="${sidebarId}"]`);
const chatBtn = document.querySelector(selector);
if (!sidebar || !chatBtn) {
console.log('Sidebar or Toggle Button not found in DOM.');
return;
}
const style = window.getComputedStyle(sidebar);
const isHidden = sidebar.classList.contains('-translate-x-full') ||
style.transform.includes('-100%') ||
(style.transform === 'none' && sidebar.offsetWidth === 0);
if (isHidden) {
console.log('Chat is closed. Opening now via shadow toggle...');
chatBtn.dispatchEvent(new MouseEvent('click', { bubbles: true }));
} else {
console.log('Chat is already visible. Skipping click.');
}
}, CONFIG.CHAT_SELECTOR, CONFIG.CHAT_SIDEBAR_ID);
} catch (e) {
console.error('❌ Failed to check/open chat:', e.message);
}
}
function startScheduledRefresh(page) {
console.log(`⏰ Scheduler active: Refreshing every hour at minute :${CONFIG.REFRESH_MINUTE}`);
let hasRefreshedThisMinute = false;
setInterval(async () => {
const now = new Date();
const currentMinute = now.getMinutes();
if (currentMinute === CONFIG.REFRESH_MINUTE) {
if (!hasRefreshedThisMinute) {
console.log(`🔄 Hourly trigger reached (${now.getHours()}:${currentMinute}). Refreshing page...`);
hasRefreshedThisMinute = true;
try {
await page.reload({ waitUntil: 'networkidle2' });
await new Promise(r => setTimeout(r, 5000));
await recoverFromErrorPage(page);
await ensureChatVisible(page);
} catch (e) {
console.error('❌ Reload failed:', e.message);
}
}
} else {
hasRefreshedThisMinute = false;
}
await recoverFromErrorPage(page);
}, 15000);
}
// ==================== MAIN APP ====================
function formatBytes(bytes) {
if (bytes === 0) return '0 B';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
async function startApp() {
const browser = await puppeteer.launch({
headless: false,
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--ignore-certificate-errors', // Helps with proxy SSL issues
'--disable-web-security',
`--disable-extensions-except=${CONFIG.EXTENSION_1_PATH},${CONFIG.EXTENSION_2_PATH}`,
`--load-extension=${CONFIG.EXTENSION_1_PATH},${CONFIG.EXTENSION_2_PATH}`,
CONFIG.USE_PROXY ? `--proxy-server=${CONFIG.PROXY_SERVER}` : ''
].filter(Boolean)
});
const page = await browser.newPage();
if (CONFIG.USE_PROXY) {
await page.authenticate({
username: CONFIG.PROXY_USERNAME,
password: CONFIG.PROXY_PASSWORD
});
}
await safeNavigate(page, CONFIG.TARGET_URL);
await new Promise(r => setTimeout(r, 5000));
await ensureChatVisible(page);
startScheduledRefresh(page);
if (CONFIG.ENABLE_MEMORY_MONITOR) {
setInterval(() => {
const usage = process.memoryUsage();
console.log(`[Memory] RSS: ${formatBytes(usage.rss)} | Heap: ${formatBytes(usage.heapUsed)}`);
}, CONFIG.MEMORY_CHECK_INTERVAL);
}
console.log('🚀 System initialized and monitoring.');
}
startApp().catch(console.error);