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());
// ==================== CHAT & REFRESH LOGIC ====================
/**
* Ensures the chat is visible by checking current state first.
* It only dispatches the click event if the chat is detected as closed.
*/
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;
}
// Detect if hidden: checking for the translate-x-full class or computed offsetWidth
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);
}
}
/**
* Monitors the clock and refreshes the page at the specified minute
*/
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();
// Check if we hit the target minute
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' });
console.log('✅ Page reloaded. Ensuring chat is open...');
await new Promise(r => setTimeout(r, 5000)); // Increased wait for UI to initialize
await ensureChatVisible(page);
} catch (e) {
console.error('❌ Reload failed:', e.message);
}
}
} else {
// Reset flag when we move past the target minute
hasRefreshedThisMinute = false;
}
}, 10000); // Check every 10 seconds
}
// ==================== REST OF YOUR UTILITIES ====================
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',
`--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 page.goto(CONFIG.TARGET_URL, { waitUntil: 'networkidle2' });
// Initialize schedule and UI helpers
await new Promise(r => setTimeout(r, 5000)); // Wait for page to fully load elements
await ensureChatVisible(page);
startScheduledRefresh(page);
// Start your existing monitors
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);
}
// Keep the logic running...
console.log('🚀 System initialized and monitoring.');
}
startApp().catch(console.error);