Logo of «2Captcha»To home page
Captcha bypass tutorials

Was this helpful?

How to bypass the captcha on the Discord

Gregory Fisher
Gregory Fisher

Technical engineer

Introduction

When automating registration or working with Discord accounts, developers often run into visual captchas. Unlike standard text challenges, this captcha requires the user to click on specific objects in an image or select the right pictures.

Automating this type of protection with standard text recognition methods won't work. We need to get the exact coordinates of the objects and click on them. In this article, we will break down a practical approach to solving the Discord click captcha using SeleniumBase for browser automation and the 2Captcha API to get the coordinates.

What you will need

To run the script, you will need the following libraries:

  • seleniumbase (with UC mode support to bypass basic detections)
  • 2captcha-python (the official library for working with the API)

You can install them with a single command:

bash Copy
pip install seleniumbase 2captcha-python

You will also need an API key from 2Captcha and a working residential proxy, as Discord strictly blocks datacenter IP addresses.

Solving logic

The process of solving a click captcha involves several steps:

  1. Find the captcha image element and take a screenshot.
  2. Send the screenshot to 2Captcha using the coordinates method.
  3. Get the response as a list of coordinates (for example, x=123,y=456).
  4. Adjust the coordinates by adding the element's offset on the page.
  5. Click on the resulting points using ActionChains.
  6. Click the confirmation button in the bottom right corner of the image.

The main challenge here is adjusting the coordinates. The API returns coordinates relative to the image itself, while Selenium clicks relative to the entire browser window. If you don't add the offset (the element's location), the clicks will hit empty space.

Code breakdown

Browser setup

We use SeleniumBase in UC mode (undetected chromedriver). It is crucial to fix the window size so the coordinates are always predictable, and we pass the User-Agent and proxy.

python Copy
from seleniumbase import SB

proxy = "your_residential_proxy:port"
agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"

with SB(uc=True, headless=False, proxy=proxy, locale_code='en', agent=agent) as sb:
    sb.set_window_size(1282, 842)
    sb.open("https://discord.com/register")

Form filling and captcha trigger

After opening the page, we fill in the registration fields and switch to the captcha iframe to click the checkbox.

python Copy
sb.type('input[name="email"]', "some_post2020_AA@gmail.com")
sb.type('input[name="global_name"]', "Jason_doorilo")
sb.type('input[name="username"]', "Adminbest3030")
sb.type('input[name="password"]', "Adm4512365874512547")

# Fill in the date of birth
sb.driver.find_element(By.ID, "react-select-2-input").send_keys("10", Keys.ENTER)
sb.find_element(By.ID, "react-select-3-input").send_keys("11", Keys.ENTER)
sb.find_element(By.ID, "react-select-4-input").send_keys("2000", Keys.ENTER)

sb.sleep(7)

# Switch to the iframe and click the checkbox
sb.switch_to_frame('iframe[title="Widget containing checkbox for security challenge"]')
sb.click("#checkbox")
sb.reconnect(15)
sb.switch_to_default_content()

Captcha solving function

The most important part of the script is the function that takes the screenshot, sends it to the API, and clicks the coordinates.

python Copy
import base64
import os
from io import BytesIO
from selenium.webdriver.common.action_chains import ActionChains
from twocaptcha import TwoCaptcha

def search_and_solve(sb, my_img):
    solver = TwoCaptcha(os.environ["APIKEY"])
    
    # Take a screenshot and convert to Base64
    screenshot = my_img.screenshot_as_png
    screenshot_bytes = BytesIO(screenshot)
    base64_screenshot = base64.b64encode(screenshot_bytes.getvalue()).decode('utf-8')
    
    # Get the position and size of the element
    element_position = my_img.location
    size = my_img.size
    
    try:
        print("Solve captcha...")
        # Send the image to 2Captcha
        result = solver.coordinates(base64_screenshot, lang='en')
    except Exception as e:
        print(e)
        return
        
    print("Captcha solved!")
    
    # Parse the API response
    coords_string = result['code'].split(':')[1].split(';')
    coordinates = [[int(val.split('=')[1]) for val in coord.split(',')] for coord in coords_string]
    
    # Adjust coordinates based on the element's position on the page
    for coord in coordinates:
        coord[0] = coord[0] + element_position['x']
        coord[1] = coord[1] + element_position['y']
        
    # Add the coordinate for the confirmation button (bottom right corner)
    button_coord = [
        element_position['x'] + size['width'] - 30, 
        element_position['y'] + size['height'] - 15
    ]
    coordinates.append(button_coord)
    
    # Click the coordinates
    actions = ActionChains(sb.driver)
    print("Coordinates received:", coordinates)
    
    for coord in coordinates:
        actions.move_by_offset(coord[0], coord[1]).click().perform()
        sb.sleep(1) # Pause between clicks
        actions.reset_actions() # Reset accumulated actions
        
    sb.sleep(5)

Waiting loop

After clicking the checkbox, the captcha might not appear immediately. We use an infinite loop that looks for the captcha image and tries to solve it until it disappears.

python Copy
while True:
    try:
        sb.sleep(1)
        # Look for the iframe with the captcha image itself
        my_img = sb.find_element("body > div:nth-child(14) > div:nth-child(1) > iframe")
        print("CAPTCHA VISIBLE!!")
        search_and_solve(sb, my_img)
    except:
        print("CAPTCHA PASSED!!!!")
        break

sb.sleep(2)
# Further registration code...

Important nuances

Fixed window size

The code uses sb.set_window_size(1282, 842). This is critical. If the window size changes, the element's offset (location) will also change, and the adjusted coordinates will be incorrect.

Resetting ActionChains

The click loop must use actions.reset_actions(). If you don't do this, Selenium will accumulate offsets, and each subsequent click will drift further and further from the target point.

Pauses between actions

The Discord click captcha analyzes mouse behavior. Instant clicks without delays look like a bot. A 1-second pause between clicks and 5 seconds before checking the result significantly increase the chances of a successful pass.

Captcha type

This method perfectly solves standard click captchas (selecting objects in a picture). However, it is not suitable for "hold and drag" captchas, as they require a completely different interaction mechanic.

Solution reports

If the captcha fails despite correct coordinates, it makes sense to send a reportIncorrect to the 2Captcha API. This will help the service improve its recognition algorithms for your future requests.

Conclusion

Passing visual captchas on Discord requires precise work with coordinates and correctly accounting for element offsets on the page. Using the coordinates method from 2Captcha in combination with SeleniumBase and ActionChains allows you to fully automate this process. The main thing is not to forget to fix the window size, use high-quality proxies, and add human-like delays between clicks.