Reaperxxxx commited on
Commit
5a87bc6
Β·
verified Β·
1 Parent(s): b873bc6

Update app.js

Browse files
Files changed (1) hide show
  1. app.js +236 -13
app.js CHANGED
@@ -1,5 +1,6 @@
1
  const puppeteer = require('puppeteer-extra');
2
  const StealthPlugin = require('puppeteer-extra-plugin-stealth');
 
3
  const FormData = require('form-data');
4
  const fs = require('fs');
5
  const path = require('path');
@@ -7,12 +8,28 @@ const path = require('path');
7
  // Use stealth plugin to avoid detection
8
  puppeteer.use(StealthPlugin());
9
 
 
 
 
 
 
 
 
 
10
  // Helper function to wait
11
  const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));
12
 
13
  // Random delay to appear more human-like
14
  const randomWait = (min, max) => wait(Math.floor(Math.random() * (max - min + 1)) + min);
15
 
 
 
 
 
 
 
 
 
16
  // Function to upload image to uploadnx.zone.id
17
  async function uploadToServer(filePath) {
18
  return new Promise((resolve, reject) => {
@@ -89,7 +106,7 @@ function loadCookies(cookieFilePath) {
89
  }
90
 
91
  const browser = await puppeteer.launch({
92
- headless: true,
93
  args: [
94
  '--no-sandbox',
95
  '--disable-setuid-sandbox',
@@ -122,17 +139,38 @@ function loadCookies(cookieFilePath) {
122
  '--disable-sync',
123
  '--disable-client-side-phishing-detection',
124
  '--disable-features=site-per-process',
125
- '--enable-features=NetworkServiceInProcess'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  ],
127
  ignoreHTTPSErrors: true,
128
  defaultViewport: null,
129
- ignoreDefaultArgs: ['--enable-automation']
130
  });
131
 
132
  const page = await browser.newPage();
133
 
134
  // EXTREME: Additional page configurations
135
  await page.setBypassCSP(true);
 
 
 
 
 
 
 
136
 
137
  try {
138
  // Enable JavaScript
@@ -191,13 +229,16 @@ function loadCookies(cookieFilePath) {
191
  if (cookieData && cookieData.cookies) {
192
  console.log('\nπŸͺ Pre-loading cookies...');
193
 
194
- // Strategy 1: Navigate to base domain first with minimal load
195
  try {
196
  await page.goto('https://m.betking.com/', {
197
  waitUntil: 'domcontentloaded',
198
  timeout: 15000
199
  });
200
  console.log('βœ“ Base domain loaded');
 
 
 
201
  } catch (baseError) {
202
  console.log('⚠️ Base domain load issue, trying alternative...');
203
  // Try setting domain manually
@@ -383,6 +424,53 @@ function loadCookies(cookieFilePath) {
383
  delete window.cdc_adoQpoasnfa76pfcZLmcfl_Array;
384
  delete window.cdc_adoQpoasnfa76pfcZLmcfl_Promise;
385
  delete window.cdc_adoQpoasnfa76pfcZLmcfl_Symbol;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
386
  });
387
 
388
  console.log('\n🌐 Navigating to the page...');
@@ -406,16 +494,151 @@ function loadCookies(cookieFilePath) {
406
 
407
  if (statusCode === 403) {
408
  console.log('⚠️ Received 403 Forbidden error.');
409
- console.log('Trying alternative approaches...');
410
-
411
- // Wait and try reloading
412
- await wait(2000);
413
 
414
- try {
415
- await page.reload({ waitUntil: ['domcontentloaded', 'networkidle2'], timeout: 30000 });
416
- console.log('βœ“ Page reloaded with cookies');
417
- } catch (reloadError) {
418
- console.log('Reload had issues, but continuing...');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
419
  }
420
  } else if (statusCode >= 400) {
421
  console.log(`⚠️ Received error status: ${statusCode}`);
 
1
  const puppeteer = require('puppeteer-extra');
2
  const StealthPlugin = require('puppeteer-extra-plugin-stealth');
3
+ const RecaptchaPlugin = require('puppeteer-extra-plugin-recaptcha');
4
  const FormData = require('form-data');
5
  const fs = require('fs');
6
  const path = require('path');
 
8
  // Use stealth plugin to avoid detection
9
  puppeteer.use(StealthPlugin());
10
 
11
+ // Add recaptcha plugin (requires 2captcha API key for actual solving, but helps with detection)
12
+ puppeteer.use(
13
+ RecaptchaPlugin({
14
+ visualFeedback: true, // Show when solving captcha
15
+ throwOnError: false // Don't throw errors, just try to continue
16
+ })
17
+ );
18
+
19
  // Helper function to wait
20
  const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));
21
 
22
  // Random delay to appear more human-like
23
  const randomWait = (min, max) => wait(Math.floor(Math.random() * (max - min + 1)) + min);
24
 
25
+ // Check if we should wait for manual Cloudflare solving
26
+ const MANUAL_CLOUDFLARE = process.env.MANUAL_CLOUDFLARE === 'true';
27
+ const CLOUDFLARE_WAIT = parseInt(process.env.CLOUDFLARE_WAIT || '30000');
28
+
29
+ if (MANUAL_CLOUDFLARE) {
30
+ console.log('⚠️ MANUAL_CLOUDFLARE mode enabled - will wait up to', CLOUDFLARE_WAIT / 1000, 'seconds for manual solving');
31
+ }
32
+
33
  // Function to upload image to uploadnx.zone.id
34
  async function uploadToServer(filePath) {
35
  return new Promise((resolve, reject) => {
 
106
  }
107
 
108
  const browser = await puppeteer.launch({
109
+ headless: false,
110
  args: [
111
  '--no-sandbox',
112
  '--disable-setuid-sandbox',
 
139
  '--disable-sync',
140
  '--disable-client-side-phishing-detection',
141
  '--disable-features=site-per-process',
142
+ '--enable-features=NetworkServiceInProcess',
143
+ // Additional anti-Cloudflare flags
144
+ '--disable-features=IsolateOrigins,site-per-process,SitePerProcess',
145
+ '--disable-web-security',
146
+ '--allow-running-insecure-content',
147
+ '--disable-features=VizDisplayCompositor',
148
+ '--disable-ipc-flooding-protection',
149
+ '--disable-hang-monitor',
150
+ '--disable-prompt-on-repost',
151
+ '--disable-background-timer-throttling',
152
+ '--disable-backgrounding-occluded-windows',
153
+ '--disable-renderer-backgrounding',
154
+ '--force-color-profile=srgb',
155
+ '--disable-features=TranslateUI',
156
+ '--disable-features=Translate'
157
  ],
158
  ignoreHTTPSErrors: true,
159
  defaultViewport: null,
160
+ ignoreDefaultArgs: ['--enable-automation', '--enable-blink-features=IdleDetection']
161
  });
162
 
163
  const page = await browser.newPage();
164
 
165
  // EXTREME: Additional page configurations
166
  await page.setBypassCSP(true);
167
+
168
+ // Set extra permissions to look more like real browser
169
+ const context = browser.defaultBrowserContext();
170
+ await context.overridePermissions('https://m.betking.com', [
171
+ 'geolocation',
172
+ 'notifications'
173
+ ]);
174
 
175
  try {
176
  // Enable JavaScript
 
229
  if (cookieData && cookieData.cookies) {
230
  console.log('\nπŸͺ Pre-loading cookies...');
231
 
232
+ // First, navigate to the domain to establish context
233
  try {
234
  await page.goto('https://m.betking.com/', {
235
  waitUntil: 'domcontentloaded',
236
  timeout: 15000
237
  });
238
  console.log('βœ“ Base domain loaded');
239
+
240
+ // Wait a bit for any Cloudflare JS to run
241
+ await wait(3000);
242
  } catch (baseError) {
243
  console.log('⚠️ Base domain load issue, trying alternative...');
244
  // Try setting domain manually
 
424
  delete window.cdc_adoQpoasnfa76pfcZLmcfl_Array;
425
  delete window.cdc_adoQpoasnfa76pfcZLmcfl_Promise;
426
  delete window.cdc_adoQpoasnfa76pfcZLmcfl_Symbol;
427
+
428
+ // Override Performance API to prevent timing attacks
429
+ const originalGetEntries = Performance.prototype.getEntries;
430
+ Performance.prototype.getEntries = function() {
431
+ const entries = originalGetEntries.call(this);
432
+ return entries.filter(entry => !entry.name.includes('devtools'));
433
+ };
434
+
435
+ // Override Date to add small random variations
436
+ const originalDate = Date;
437
+ Date = class extends originalDate {
438
+ constructor(...args) {
439
+ if (args.length === 0) {
440
+ super();
441
+ const offset = Math.floor(Math.random() * 10);
442
+ return new originalDate(this.getTime() + offset);
443
+ }
444
+ return new originalDate(...args);
445
+ }
446
+ };
447
+ Date.prototype = originalDate.prototype;
448
+ Date.now = function() {
449
+ return originalDate.now() + Math.floor(Math.random() * 10);
450
+ };
451
+
452
+ // Spoof notification permission
453
+ Object.defineProperty(Notification, 'permission', {
454
+ get: () => 'default'
455
+ });
456
+
457
+ // Mock realistic connection
458
+ Object.defineProperty(navigator, 'connection', {
459
+ get: () => ({
460
+ effectiveType: '4g',
461
+ rtt: 50,
462
+ downlink: 10,
463
+ saveData: false
464
+ })
465
+ });
466
+
467
+ // Override outerHeight/Width to match viewport
468
+ Object.defineProperty(window, 'outerWidth', {
469
+ get: () => 390
470
+ });
471
+ Object.defineProperty(window, 'outerHeight', {
472
+ get: () => 844
473
+ });
474
  });
475
 
476
  console.log('\n🌐 Navigating to the page...');
 
494
 
495
  if (statusCode === 403) {
496
  console.log('⚠️ Received 403 Forbidden error.');
497
+ console.log('Checking for Cloudflare challenge...');
 
 
 
498
 
499
+ // Check if it's a Cloudflare challenge page
500
+ const isCloudflare = await page.evaluate(() => {
501
+ const body = document.body.innerText;
502
+ const title = document.title;
503
+ return (
504
+ body.includes('Cloudflare') ||
505
+ body.includes('Just a moment') ||
506
+ body.includes('Checking your browser') ||
507
+ title.includes('Just a moment') ||
508
+ document.querySelector('#challenge-form') !== null ||
509
+ document.querySelector('.cf-browser-verification') !== null
510
+ );
511
+ });
512
+
513
+ if (isCloudflare) {
514
+ console.log('πŸ” Cloudflare challenge detected!');
515
+ console.log('⏳ Attempting to solve automatically...');
516
+
517
+ // Try to click the Cloudflare Turnstile checkbox
518
+ try {
519
+ // Wait for checkbox to be clickable
520
+ await page.waitForSelector('input[type="checkbox"]', { timeout: 5000, visible: true })
521
+ .catch(() => console.log('No visible checkbox found, trying iframe...'));
522
+
523
+ // Check for iframe (Cloudflare Turnstile uses iframe)
524
+ const frames = page.frames();
525
+ console.log(`Found ${frames.length} frames, checking for Cloudflare challenge...`);
526
+
527
+ let clicked = false;
528
+ for (const frame of frames) {
529
+ try {
530
+ // Try to find and click checkbox in iframe
531
+ const checkbox = await frame.$('input[type="checkbox"]');
532
+ if (checkbox) {
533
+ console.log('βœ“ Found checkbox in iframe, clicking...');
534
+ await checkbox.click();
535
+ clicked = true;
536
+ console.log('βœ“ Checkbox clicked!');
537
+ break;
538
+ }
539
+
540
+ // Try Turnstile specific selector
541
+ const turnstile = await frame.$('.cf-turnstile');
542
+ if (turnstile) {
543
+ console.log('βœ“ Found Turnstile widget, clicking...');
544
+ await turnstile.click();
545
+ clicked = true;
546
+ console.log('βœ“ Turnstile clicked!');
547
+ break;
548
+ }
549
+
550
+ // Try clicking the challenge box area
551
+ const challengeBox = await frame.$('#challenge-stage');
552
+ if (challengeBox) {
553
+ console.log('βœ“ Found challenge box, clicking...');
554
+ await challengeBox.click();
555
+ clicked = true;
556
+ console.log('βœ“ Challenge box clicked!');
557
+ break;
558
+ }
559
+ } catch (frameError) {
560
+ // Continue to next frame
561
+ }
562
+ }
563
+
564
+ if (!clicked) {
565
+ console.log('⚠️ Could not find clickable element, trying main page...');
566
+ // Try clicking on main page
567
+ const mainCheckbox = await page.$('input[type="checkbox"]').catch(() => null);
568
+ if (mainCheckbox) {
569
+ await mainCheckbox.click();
570
+ console.log('βœ“ Main page checkbox clicked!');
571
+ }
572
+ }
573
+
574
+ } catch (clickError) {
575
+ console.log('⚠️ Auto-click failed:', clickError.message);
576
+ }
577
+
578
+ // Simulate human-like mouse movements
579
+ try {
580
+ await wait(500);
581
+ await page.mouse.move(100, 100);
582
+ await wait(100);
583
+ await page.mouse.move(200, 200);
584
+ await wait(150);
585
+ await page.mouse.move(150, 300);
586
+ console.log('βœ“ Mouse movements simulated');
587
+ } catch (mouseError) {
588
+ console.log('Mouse simulation skipped');
589
+ }
590
+
591
+ const waitSeconds = CLOUDFLARE_WAIT / 1000;
592
+ console.log(`⏳ Waiting for Cloudflare to verify (up to ${waitSeconds} seconds)...`);
593
+ if (MANUAL_CLOUDFLARE) {
594
+ console.log('πŸ’‘ You can manually solve the challenge in the browser window!');
595
+ }
596
+
597
+ // Wait for Cloudflare challenge to complete
598
+ try {
599
+ await page.waitForFunction(
600
+ () => {
601
+ // Check if we've passed the challenge
602
+ const body = document.body.innerText;
603
+ const title = document.title;
604
+ return (
605
+ !body.includes('Just a moment') &&
606
+ !body.includes('Checking your browser') &&
607
+ !body.includes('Verify you are human') &&
608
+ !title.includes('Just a moment') &&
609
+ document.querySelector('#challenge-form') === null &&
610
+ document.querySelector('.cf-browser-verification') === null
611
+ );
612
+ },
613
+ { timeout: CLOUDFLARE_WAIT, polling: 500 }
614
+ );
615
+ console.log('βœ“ Cloudflare challenge passed!');
616
+
617
+ // Take screenshot after passing challenge
618
+ await wait(2000);
619
+ await page.screenshot({ path: './after-cloudflare.png', fullPage: true });
620
+ console.log('Screenshot after Cloudflare: after-cloudflare.png');
621
+ } catch (cfError) {
622
+ console.log('⚠️ Cloudflare challenge timeout - may need manual intervention');
623
+ console.log('Taking screenshot of challenge page...');
624
+ await page.screenshot({ path: './cloudflare-challenge.png', fullPage: true });
625
+ console.log('Screenshot saved to cloudflare-challenge.png');
626
+
627
+ // Try to continue anyway
628
+ console.log('Attempting to continue despite challenge...');
629
+ }
630
+ } else {
631
+ console.log('Trying alternative approaches...');
632
+
633
+ // Wait and try reloading
634
+ await wait(2000);
635
+
636
+ try {
637
+ await page.reload({ waitUntil: ['domcontentloaded', 'networkidle2'], timeout: 30000 });
638
+ console.log('βœ“ Page reloaded with cookies');
639
+ } catch (reloadError) {
640
+ console.log('Reload had issues, but continuing...');
641
+ }
642
  }
643
  } else if (statusCode >= 400) {
644
  console.log(`⚠️ Received error status: ${statusCode}`);