hitz / app.js
Reaperxxxx's picture
Update app.js
123cb63 verified
Raw
History Blame
14.3 kB
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
const FormData = require('form-data');
const fs = require('fs');
const path = require('path');
// Use stealth plugin to avoid detection
puppeteer.use(StealthPlugin());
// Helper function to wait
const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));
// Random delay to appear more human-like
const randomWait = (min, max) => wait(Math.floor(Math.random() * (max - min + 1)) + min);
// Function to upload image to catbox.moe
async function uploadToCatbox(filePath) {
return new Promise((resolve, reject) => {
const form = new FormData();
form.append('reqtype', 'fileupload');
form.append('fileToUpload', fs.createReadStream(filePath));
form.submit('https://catbox.moe/user/api.php', (err, res) => {
if (err) {
reject(err);
return;
}
let data = '';
res.on('data', chunk => {
data += chunk;
});
res.on('end', () => {
if (res.statusCode === 200) {
resolve(data.trim());
} else {
reject(new Error(`Upload failed with status code: ${res.statusCode}`));
}
});
res.on('error', reject);
});
});
}
// Load cookies from JSON file
function loadCookies(cookieFilePath) {
try {
if (fs.existsSync(cookieFilePath)) {
const cookieData = JSON.parse(fs.readFileSync(cookieFilePath, 'utf8'));
console.log(`βœ“ Loaded cookies from: ${cookieFilePath}`);
console.log(` - ${cookieData.cookies.length} cookies found`);
console.log(` - ${Object.keys(cookieData.localStorage || {}).length} localStorage items`);
console.log(` - ${Object.keys(cookieData.sessionStorage || {}).length} sessionStorage items`);
return cookieData;
} else {
console.log(`⚠️ Cookie file not found: ${cookieFilePath}`);
console.log(' Running without cookies...');
return null;
}
} catch (error) {
console.error(`❌ Error loading cookies: ${error.message}`);
return null;
}
}
(async () => {
// Look for cookie file in multiple locations
const possibleCookieFiles = [
path.join(__dirname, 'cookies.json'),
path.join(__dirname, 'betking-cookies.json'),
'/mnt/user-data/uploads/cookies.json'
];
let cookieData = null;
for (const cookieFile of possibleCookieFiles) {
cookieData = loadCookies(cookieFile);
if (cookieData) break;
}
const browser = await puppeteer.launch({
headless: false,
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-blink-features=AutomationControlled',
'--disable-web-security',
'--disable-features=IsolateOrigins,site-per-process',
'--disable-dev-shm-usage',
'--disable-accelerated-2d-canvas',
'--no-first-run',
'--no-zygote',
'--disable-gpu',
'--disable-notifications',
'--disable-popup-blocking'
],
ignoreHTTPSErrors: true,
defaultViewport: null
});
const page = await browser.newPage();
try {
// Enable JavaScript
await page.setJavaScriptEnabled(true);
// Use user agent from cookie file if available
const userAgent = cookieData?.userAgent || 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1';
await page.setUserAgent(userAgent);
console.log(`βœ“ Using User Agent: ${userAgent}`);
// Set realistic mobile viewport to match cookies
await page.setViewport({
width: 390,
height: 844,
isMobile: true,
hasTouch: true,
deviceScaleFactor: 3
});
// Set additional headers
const headers = {
'Accept-Language': 'en-US,en;q=0.9,en-NG;q=0.8',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
'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.setExtraHTTPHeaders(headers);
// CRITICAL: Set cookies BEFORE navigating
if (cookieData && cookieData.cookies) {
console.log('\nπŸͺ Setting cookies BEFORE navigation...');
// First, navigate to the domain to establish context
await page.goto('https://m.betking.com/', {
waitUntil: 'domcontentloaded',
timeout: 10000
}).catch(() => {
console.log('Initial navigation for cookie context...');
});
// Now set all cookies
for (const cookie of cookieData.cookies) {
try {
await page.setCookie(cookie);
} catch (error) {
console.log(` ⚠️ Could not set cookie: ${cookie.name} - ${error.message}`);
}
}
console.log('βœ“ Cookies set successfully');
}
// Override WebDriver and other bot detection properties
await page.evaluateOnNewDocument(() => {
// Remove webdriver property
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
});
// Override permissions
const originalQuery = window.navigator.permissions.query;
window.navigator.permissions.query = (parameters) => (
parameters.name === 'notifications' ?
Promise.resolve({ state: Notification.permission }) :
originalQuery(parameters)
);
// Add Chrome object
window.chrome = { runtime: {} };
// Override plugins
Object.defineProperty(navigator, 'plugins', {
get: () => [1, 2, 3, 4, 5]
});
// Override languages
Object.defineProperty(navigator, 'languages', {
get: () => ['en-US', 'en']
});
// Remove automation indicators
delete navigator.__proto__.webdriver;
// Override toString to avoid detection
const originalToString = Function.prototype.toString;
Function.prototype.toString = function() {
if (this === navigator.permissions.query) {
return 'function query() { [native code] }';
}
return originalToString.call(this);
};
});
console.log('\n🌐 Navigating to the page...');
await randomWait(500, 1500);
// Navigate to the actual target URL
const response = await page.goto('https://m.betking.com/en-ng?', {
waitUntil: ['networkidle0', 'domcontentloaded'],
timeout: 45000
});
const statusCode = response.status();
console.log(`Response status: ${statusCode}`);
if (statusCode === 403) {
console.log('⚠️ Received 403 Forbidden error.');
console.log('Trying alternative approach...');
// Try reloading with cookies already set
await wait(2000);
await page.reload({ waitUntil: ['networkidle0', 'domcontentloaded'] });
console.log('Page reloaded with cookies');
} else if (statusCode >= 400) {
console.log(`⚠️ Received error status: ${statusCode}`);
} else {
console.log('βœ“ Page loaded successfully');
}
// Set localStorage and sessionStorage if available
if (cookieData) {
if (cookieData.localStorage && Object.keys(cookieData.localStorage).length > 0) {
console.log('\nπŸ’Ύ Setting localStorage...');
await page.evaluate((storage) => {
for (const [key, value] of Object.entries(storage)) {
try {
localStorage.setItem(key, value);
} catch (e) {
console.log('Could not set localStorage item:', key);
}
}
}, cookieData.localStorage);
console.log('βœ“ localStorage set successfully');
}
if (cookieData.sessionStorage && Object.keys(cookieData.sessionStorage).length > 0) {
console.log('\nπŸ’Ύ Setting sessionStorage...');
await page.evaluate((storage) => {
for (const [key, value] of Object.entries(storage)) {
try {
sessionStorage.setItem(key, value);
} catch (e) {
console.log('Could not set sessionStorage item:', key);
}
}
}, cookieData.sessionStorage);
console.log('βœ“ sessionStorage set successfully');
}
// One more reload to ensure everything is applied
console.log('\nπŸ”„ Final reload to apply all data...');
await page.reload({ waitUntil: ['networkidle0', 'domcontentloaded'] });
console.log('βœ“ Page reloaded');
}
console.log('\n⏳ Waiting 3 seconds...');
await wait(3000);
// Take initial screenshot
console.log('\nπŸ“Έ Taking initial screenshot...');
await page.screenshot({
path: './betking-initial.png',
fullPage: true
});
console.log('\nπŸ” Looking for the Sign In button...');
const buttonSelectors = [
'button[data-testid="signInButton"]',
'button#signInButton',
'button.pill.pill-text.pill-text--inherit.pill--medium.button',
'button:has-text("Login")',
'button:has-text("Sign In")'
];
let buttonFound = false;
let buttonSelector = null;
for (const selector of buttonSelectors) {
try {
const button = await page.$(selector);
if (button) {
buttonFound = true;
buttonSelector = selector;
console.log(`βœ“ Button found using selector: ${selector}`);
const isVisible = await button.isIntersectingViewport();
console.log(`Button is visible: ${isVisible}`);
if (isVisible) {
console.log('πŸ‘† Clicking the button...');
await randomWait(200, 800);
await button.click();
console.log('βœ“ Button clicked successfully!');
} else {
console.log('Button exists but is not visible, scrolling into view...');
await page.evaluate((sel) => {
document.querySelector(sel).scrollIntoView({ behavior: 'smooth', block: 'center' });
}, selector);
await wait(500);
await randomWait(200, 800);
await button.click();
console.log('βœ“ Button clicked after scrolling!');
}
await wait(1500);
break;
}
} catch (error) {
console.log(`Selector ${selector} failed: ${error.message}`);
}
}
if (!buttonFound) {
console.log('⚠️ Button not found with any selector.');
console.log('This might mean you\'re already logged in or the page structure changed.');
const allButtons = await page.evaluate(() => {
return Array.from(document.querySelectorAll('button')).slice(0, 20).map(btn => ({
id: btn.id,
class: btn.className,
text: btn.innerText?.substring(0, 50),
testId: btn.getAttribute('data-testid')
}));
});
console.log('\nπŸ“‹ Available buttons on page (first 20):');
console.log(JSON.stringify(allButtons, null, 2));
}
console.log('\nπŸ“Έ Taking final screenshot...');
await page.screenshot({
path: './betking-final.png',
fullPage: true
});
console.log('βœ“ Screenshot saved to betking-final.png');
// Upload screenshot to catbox
console.log('\nπŸ“€ Uploading screenshot to Catbox...');
try {
const catboxUrl = await uploadToCatbox('./betking-final.png');
console.log('βœ“ Upload successful!');
console.log('\nπŸ”— Download link:');
console.log(catboxUrl);
console.log('\nπŸ“‹ Direct link (copy this):');
console.log(catboxUrl);
} catch (uploadError) {
console.error('❌ Failed to upload to Catbox:', uploadError.message);
console.log('Screenshot is still saved locally at: ./betking-final.png');
}
} catch (error) {
console.error('\n❌ Error occurred:', error.message);
console.error('Stack trace:', error.stack);
try {
await page.screenshot({
path: './betking-error.png',
fullPage: true
});
console.log('Error screenshot saved to betking-error.png');
} catch (screenshotError) {
console.error('Could not take error screenshot:', screenshotError.message);
}
} finally {
await browser.close();
console.log('\nβœ… Browser closed');
}
})();