Skip to content

trying to solve hcaptcha for discord #20

Description

@dsadcsadsa

const puppeteer = require('puppeteer-extra');
const fs = require('fs');
const path = require('path');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
const { Solver } = require('2captcha-ts');

puppeteer.use(StealthPlugin());

// Configuration
const TWOCAPTCHA_API_KEY = process.env.API_KEY || '7fa47ec2ef5ad5ffafa832362323a955';
const CAPTCHA_OPERATION_TIMEOUT = 240000;
const MAX_ATTEMPTS = 1000;
const DELAY_BETWEEN_ATTEMPTS = { min: 120000, max: 240000 };
const DELAY_AFTER_SUCCESS = { min: 180000, max: 300000 };

const solver = new Solver(TWOCAPTCHA_API_KEY);

function generateRandomName() {
const adjectives = ['Swift', 'Cool', 'Wise', 'Brave', 'Bright', 'Clever', 'Silent', 'Shadow', 'Quick', 'Ghost', 'Aqua', 'Solar', 'Red', 'Blue', 'Green', 'Dark'];
const animals = ['Fox', 'Eagle', 'Shark', 'Tiger', 'Wolf', 'Panther', 'Dragon', 'Griffin', 'Serpent', 'Lion', 'Hawk', 'Bear', 'Viper', 'Cobra', 'Raven'];
const randomAdjective = adjectives[Math.floor(Math.random() * adjectives.length)];
const randomAnimal = animals[Math.floor(Math.random() * animals.length)];
const randomNumber = Math.floor(Math.random() * 1000);
return ${randomAdjective}${randomAnimal}${randomNumber};
}

async function randomMouseMovement(page) {
try {
const viewport = await page.viewport();
if (!viewport) return;
const points = [];
for (let i = 0; i < 5; i++) {
points.push({
x: Math.random() * (viewport.width * 0.8) + (viewport.width * 0.1),
y: Math.random() * (viewport.height * 0.8) + (viewport.height * 0.1)
});
}
for (let i = 0; i < points.length; i++) {
await page.mouse.move(points[i].x, points[i].y, {
steps: Math.floor(Math.random() * 30) + 10
});
await waitFor(Math.random() * 300 + 100);
}
} catch (e) {
console.warn("Mouse movement error:", e.message);
}
}

async function waitFor(delay) {
return new Promise((resolve) => setTimeout(resolve, delay));
}

async function slowType(page, selector, text, minDelay = 150, maxDelay = 450) {
await page.waitForSelector(selector, { visible: true, timeout: 15000 });
await page.click(selector);
await waitFor(Math.random() * 200 + 150);
for (const char of text) {
await page.keyboard.type(char, { delay: Math.floor(Math.random() * (maxDelay - minDelay + 1) + minDelay )});
}
}

async function solveCaptchaWithLibrary(page) {
console.log('Attempting to solve hCaptcha with 2captcha-ts library...');
const originalUrl = page.url();

// Extract sitekey from the page
const sitekey = await page.evaluate(() => {
const hcaptchaDiv = document.querySelector('.h-captcha[data-sitekey]');
if (hcaptchaDiv) return hcaptchaDiv.getAttribute('data-sitekey');
const iframes = document.querySelectorAll('iframe[src*="hcaptcha.com"]');
for (const iframe of iframes) {
const src = iframe.src;
const sitekeyMatch = src.match(/[?&]sitekey=([^&]+)/);
if (sitekeyMatch) return sitekeyMatch[1];
}
return null;
});

if (!sitekey) {
console.error('Could not find hCaptcha sitekey on page:', originalUrl);
await page.screenshot({ path: path.join(__dirname, error_sitekey_not_found_${Date.now()}.png), fullPage: true });
throw new Error('Could not find hCaptcha sitekey');
}

console.log(Solving hCaptcha with sitekey: ${sitekey} on URL: ${originalUrl});

try {
// Submit CAPTCHA to 2captcha API
const res = await solver.hcaptcha({
pageurl: originalUrl,
sitekey: sitekey,
});

if (!res || !res.data) {
  throw new Error('Invalid or empty response from 2Captcha service.');
}

const captchaAnswer = res.data;
const captchaID = res.id;
console.log('Received hCaptcha token:', captchaAnswer.substring(0, 30) + '...');

// Apply the solution to the page
await page.evaluate((captchaAnswer) => {
  // Make the response textarea visible if hidden
  const textarea = document.querySelector("textarea[name='h-captcha-response']");
  if (textarea) {
    textarea.style.display = "block";
    textarea.value = captchaAnswer;
  }
  
  // Create hidden input if textarea doesn't exist
  if (!textarea) {
    const hiddenInput = document.createElement('input');
    hiddenInput.type = 'hidden';
    hiddenInput.name = 'h-captcha-response';
    hiddenInput.value = captchaAnswer;
    document.querySelector('form')?.appendChild(hiddenInput) || document.body.appendChild(hiddenInput);
  }
  
  // Dispatch input and change events
  const inputEvent = new Event('input', { bubbles: true });
  const changeEvent = new Event('change', { bubbles: true });
  const targetElement = textarea || document.querySelector("input[name='h-captcha-response']");
  if (targetElement) {
    targetElement.dispatchEvent(inputEvent);
    targetElement.dispatchEvent(changeEvent);
  }
  
  // Try to find and trigger callback if exists
  const hcaptchaWidget = document.querySelector('.h-captcha');
  if (hcaptchaWidget) {
    const callbackName = hcaptchaWidget.getAttribute('data-callback');
    if (callbackName && window[callbackName]) {
      window[callbackName](captchaAnswer);
    }
  }

  // Try to call hcaptcha.submit if available
  if (typeof window.hcaptcha !== 'undefined' && typeof window.hcaptcha.submit === 'function') {
    window.hcaptcha.submit();
  }
}, captchaAnswer);

// Wait a bit for the CAPTCHA to process
await waitFor(3000);

// Try to find and click the submit button with multiple attempts
let submitSuccess = false;
const submitButtonSelectors = [
  'button[type="submit"]',
  'button[class*="submit"]',
  'button[class*="continue"]',
  'button[class*="verify"]',
  'button[class*="join"]',
  'button[class*="accept"]',
  '//button[contains(., "Submit")]',
  '//button[contains(., "Continue")]',
  '//button[contains(., "Verify")]',
  '//button[contains(., "Join")]',
  '//button[contains(., "Accept")]'
];

for (let attempt = 1; attempt <= 3; attempt++) {
  for (const selector of submitButtonSelectors) {
    try {
      const elements = selector.startsWith('//') 
        ? await page.$x(selector)
        : await page.$$(selector);
      
      for (const element of elements) {
        if (await element.isIntersectingViewport()) {
          await element.click({ delay: Math.random() * 100 + 50 });
          console.log(`Clicked button with selector: ${selector} (attempt ${attempt})`);
          submitSuccess = true;
          await waitFor(2000);
          break;
        }
      }
      if (submitSuccess) break;
    } catch (e) {
      console.log(`Failed to click button with selector ${selector}:`, e.message);
    }
  }
  if (submitSuccess) break;
  if (!submitSuccess) await waitFor(2000);
}

if (!submitSuccess) {
  console.log('No submit button found, trying to press Enter');
  await page.keyboard.press('Enter');
  await waitFor(2000);
}

// Wait for navigation or CAPTCHA verification
await waitFor(8000);

// Check if we're still on a CAPTCHA page
const newUrl = page.url();
const stillOnCaptcha = await page.evaluate(() => {
  return document.querySelector('.h-captcha') !== null || 
         document.querySelector('iframe[src*="hcaptcha.com"]') !== null;
});

if (stillOnCaptcha || newUrl.includes('challenge') || newUrl.includes('verify')) {
  // CAPTCHA still present, report as bad
  await solver.badReport(captchaID);
  throw new Error('Still on CAPTCHA page after solving attempt');
}

// Report good if we got past the CAPTCHA
await solver.goodReport(captchaID);
console.log('CAPTCHA solved successfully!');
return true;

} catch (error) {
console.error('CAPTCHA solving error:', error.message);
await page.screenshot({ path: path.join(__dirname, error_captcha_solving_${Date.now()}.png), fullPage: true });
throw error;
}
}

async function checkForCaptcha(page) {
console.log('Checking for CAPTCHA presence...');
const captchaCheckTimeout = 25000;
try {
await page.waitForFunction(() => {
const selectors = [
'iframe[src*="hcaptcha.com"]', 'iframe[data-hcaptcha-widget-id]',
'iframe[title*="hCaptcha"]', 'iframe[title*="challenge"]',
'.h-captcha[data-sitekey]', 'div[data-hcaptcha-widget-id]',
'[data-hcaptcha-response]'
];
for (const selector of selectors) {
const elem = document.querySelector(selector);
if (elem && (elem.offsetWidth > 0 || elem.offsetHeight > 0 || (elem.getClientRects && elem.getClientRects().length > 0))) {
return true;
}
}
return false;
}, { timeout: captchaCheckTimeout });
return true;
} catch (e) {
return false;
}
}

async function processDiscordJoin(attemptNum) {
const launchArgs = [
'--no-sandbox', '--disable-setuid-sandbox', '--disable-infobars',
'--window-position=0,0', '--disable-dev-shm-usage', '--disable-accelerated-2d-canvas',
'--no-zygote', '--window-size=1366,768',
'--disable-web-security',
'--disable-features=IsolateOrigins,site-per-process',
--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${Math.floor(Math.random() * 20) + 95}.0.${Math.floor(Math.random() * 5000) + 1000}.${Math.floor(Math.random() * 200)} Safari/537.36
];

let browser = null;
let page = null;

try {
browser = await puppeteer.launch({
headless: false,
args: launchArgs,
ignoreDefaultArgs: ['--enable-automation'],
defaultViewport: null,
executablePath: puppeteer.executablePath(),
ignoreHTTPSErrors: true
});

page = await browser.newPage();
await page.setViewport({ width: 1366, height: 768 });
await page.bringToFront();

// Anti-detection measures
await page.evaluateOnNewDocument(() => {
  Object.defineProperty(navigator, 'webdriver', { get: () => false });
  Object.defineProperty(navigator, 'plugins', {
    get: () => [
      { name: "Chrome PDF Plugin", filename: "internal-pdf-viewer", description: "Portable Document Format", mimeTypes: [{type: "application/pdf", suffixes: "pdf"}] },
      { name: "Chrome PDF Viewer", filename: "mhjfbmdgcfjbbpaeojofohoefgiehjai", description: "", mimeTypes: [{type: "application/pdf", suffixes: "pdf"}] },
      { name: "Native Client", filename: "internal-nacl-plugin", description: "", mimeTypes: [{type: "application/x-nacl", suffixes: "nexe"}]}
    ],
  });
  Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'], });
});

console.log('Navigating to Discord invite...');
await page.goto('https://discord.gg/UX3ApyDHCd', {
  waitUntil: 'networkidle0',
  timeout: 90000
});
console.log('Navigation complete. Current URL:', page.url());
await waitFor(3000 + Math.random() * 2000);

// Handle username input
const usernameSelectors = [
  'input[placeholder="Enter a username"]', 'input[name="username"]',
  'input[type="text"][class*="inputDefault"]', 'input[class*="username"]'
];

let usernameInputFound = false;
for (const selector of usernameSelectors) {
  try {
    await page.waitForSelector(selector, { visible: true, timeout: 10000 });
    const randomName = generateRandomName();
    console.log('Using the name:', randomName);
    await randomMouseMovement(page);
    await slowType(page, selector, randomName, 180, 480);
    usernameInputFound = true;
    break;
  } catch (e) { /* continue */ }
}

if (!usernameInputFound) {
  await page.screenshot({ path: path.join(__dirname, `error_username_input_not_found_${attemptNum}_${Date.now()}.png`), fullPage: true });
  throw new Error("Username input field not found");
}

await randomMouseMovement(page);
await waitFor(500 + Math.random() * 500);

// Handle initial continue button
const continueButtonSelectors = [
  'button[type="submit"]',
  'button[class*="submit"]',
  '//button[contains(., "Continue")]',
  '//button[contains(., "Accept Invite")]',
  'button[class*="continueButton"]',
  'button[class*="joinButton"]'
];

let initialContinueClicked = false;
for (const selector of continueButtonSelectors) {
  try {
    if (selector.startsWith('//')) {
      const [button] = await page.$x(selector);
      if (button) {
        await button.click({ delay: Math.random() * 200 + 150 });
        initialContinueClicked = true;
        break;
      }
    } else {
      const button = await page.$(selector);
      if (button) {
        await button.click({ delay: Math.random() * 200 + 150 });
        initialContinueClicked = true;
        break;
      }
    }
  } catch (e) { /* continue */ }
}

if (!initialContinueClicked) {
  console.log("Trying Enter key as fallback");
  await page.keyboard.press('Enter');
}

await waitFor(8000 + Math.random() * 4000);

// Handle CAPTCHA if present
const captchaDetected = await checkForCaptcha(page);
if (captchaDetected) {
  console.log('CAPTCHA detected, attempting to solve...');
  await randomMouseMovement(page);
  const captchaSolved = await solveCaptchaWithLibrary(page);
  
  if (!captchaSolved) {
    throw new Error('Failed to solve CAPTCHA');
  }
  
  await waitFor(5000 + Math.random() * 3000);
}

// Wait for Discord app to load
console.log('Waiting for Discord app to load...');
try {
  await page.waitForFunction(() => {
    return document.querySelector('nav[aria-label*="Servers"]') || 
           document.querySelector('div[class*="guildsWrapper"]') ||
           document.querySelector('div[class*="chatContent"]') ||
           document.querySelector('main[class*="chatContent"]') ||
           window.location.href.includes('channels/@me');
  }, { timeout: 60000 });

  console.log('Discord app loaded successfully');
} catch (e) {
  console.error('Failed to load Discord app:', e.message);
  await page.screenshot({ path: path.join(__dirname, `error_app_not_loaded_${attemptNum}_${Date.now()}.png`), fullPage: true });
  throw new Error("Discord app did not load after CAPTCHA");
}

// Get token from localStorage
console.log('Attempting to retrieve token...');
let token = null;
const tokenStartTime = Date.now();
while (Date.now() - tokenStartTime < 30000 && !token) {
  token = await page.evaluate(() => {
    try {
      return localStorage.getItem('token');
    } catch (e) {
      console.error('Error accessing localStorage:', e);
      return null;
    }
  });
  if (!token) await waitFor(2000);
}

if (token) {
  const cleanedToken = token.replace(/"/g, '');
  const tokenFilePath = path.join(__dirname, 'tokens.txt');
  fs.appendFileSync(tokenFilePath, cleanedToken + '\n');
  console.log(`Token saved successfully! Token: ...${cleanedToken.slice(-10)}`);
  return true;
} else {
  throw new Error("Token not found in localStorage");
}

} catch (error) {
console.error(Error during attempt ${attemptNum}:, error.message);
if (page) {
await page.screenshot({ path: path.join(__dirname, error_attempt_${attemptNum}_${Date.now()}.png), fullPage: true });
}
return false;
} finally {
if (browser) {
try {
await browser.close();
} catch (closeError) {
console.error("Error closing browser:", closeError);
}
}
}
}

async function startProcessWithRetries() {
let attempts = 0;
let successCount = 0;

while (attempts < MAX_ATTEMPTS) {
attempts++;
console.log(\n--- Attempt #${attempts} of ${MAX_ATTEMPTS} ---);

const success = await processDiscordJoin(attempts);

if (success) {
  successCount++;
  console.log(`--- ✔️ Success! Total successful joins: ${successCount}/${attempts} ---`);
  const delay = Math.floor(Math.random() * (DELAY_AFTER_SUCCESS.max - DELAY_AFTER_SUCCESS.min + 1)) + DELAY_AFTER_SUCCESS.min;
  console.log(`Waiting ${Math.round(delay/1000/60)} minutes before next attempt...`);
  await waitFor(delay);
} else {
  console.log(`--- ❌ Failed attempt ${attempts}. ---`);
  const delay = Math.floor(Math.random() * (DELAY_BETWEEN_ATTEMPTS.max - DELAY_BETWEEN_ATTEMPTS.min + 1)) + DELAY_BETWEEN_ATTEMPTS.min;
  console.log(`Retrying in ${Math.round(delay/1000/60)} minutes...`);
  await waitFor(delay);
}

}

console.log(Max attempts (${MAX_ATTEMPTS}) reached. Total successes: ${successCount}. Exiting.);
}

// Main execution
(async () => {
if (!TWOCAPTCHA_API_KEY || TWOCAPTCHA_API_KEY === 'YOUR_2CAPTCHA_API_KEY_HERE' || TWOCAPTCHA_API_KEY.length < 20) {
console.error("ERROR: Invalid or placeholder 2Captcha API key. Please provide a valid key in the script.");
console.error("Current key:", TWOCAPTCHA_API_KEY);
} else {
console.log("2Captcha API key seems to be set.");
await startProcessWithRetries();
}
})();

this is my code and this error occur

Checking for CAPTCHA presence...
CAPTCHA detected, attempting to solve...
Attempting to solve hCaptcha with 2captcha-ts library...
Solving hCaptcha with sitekey: a9b5fb07-92ff-493f-86fe-352a2803b3df on URL: https://discord.com/invite/UX3ApyDHCd
CAPTCHA solving error: Your captcha was unable to be solved after 3 attempts. You haven't been charged for this request.
Error during attempt 1: Your captcha was unable to be solved after 3 attempts. You haven't been charged for this request.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions