Puppeteer: How to bypass FUNCAPTCHA without submit button


New member
I'm going to get right to the point. I'm trying to bypass Twitch's login funcaptcha using 2captcha's API. Everything works well: My bot communicates with 2captcha fast enough where the captcha won't timeout and my bot receives the token needed to authenticate the captcha and login, except there is no submit button to actually go through with the login. To the best of my knowledge, I've looked through every Github post, every stackoverflow post regarding this issue, and the best solution I could find was to look through the Google Network tab in the devtools to look for a function to call manually which would simulate a button and get you through the captcha. With my limited coding ability, I was able to find a function which references ArkoseEnforcement & the word "callback" which I believe is what I'm trying to find. After attempting to scavenge the sources tab and network tab the best I could find was this:
I've been trying to implement this function for an hour with no success and I also tried looking at "callback" and "ArkoseEnforment.funcaptcha_events" etc. etc.
I seriously have no idea how to implement them into my code and I would appreciate any help on where to start.
//require packages
require('dotenv').config(); const fs = require('fs'); const puppeteer = require('puppeteer'); const https = require('https');

//define varibles
var usernames = []; var pkValue; var surl = process.env.SURL ; var pk = process.env.PUBLICKEY ; var api = process.env.APIKEY;
const readFile = fs.readFileSync("accounts.txt").toString().split("\n");

//read accounts
console.log(`Reading ${readFile.length} lines.`);
for(i in readFile) {
    (readFile[i].toLowerCase().startsWith("u") ? usernames.push(readFile[i].slice(10).replace("\r", "")) : null);

//get captcha

//retreive stream keys
async function getKey(username) {

    const browser = await puppeteer.launch({headless:false}); const page = await browser.newPage(); const navigationPromise = page.waitForNavigation()

    //get captcha
    function getCaptcha(captchaID) {
        https.get(`https://2captcha.com/res.php?key=${api}&action=get&id=${captchaID.slice(3)}`, (response) => {
            var dataRes = '';
            response.on('data', (chunk) => {
            dataRes += chunk;
            response.on('end', () => {
                if (dataRes.toLowerCase()==="capcha_not_ready") {
                    setTimeout(() => {getCaptcha(captchaID)}, 5000)
                else {
                    pkValue = dataRes.slice(3)
                    page.evaluate((pkValue) => {
                        //add token to val
                        document.querySelector('#FunCaptcha-Token').value = pkValue;
                        //submit form
                        //somehow need to submit the form here.
                    }, pkValue)

    await page.goto(`https://dashboard.twitch.tv/u/${username}/settings/stream`, { waitUntil: ['networkidle2'] })
    await page.setViewport({ width: 1920, height: 880 })
    await page.waitForSelector('.sc-AxjAm #login-username')
    await page.click('.sc-AxjAm #login-username')
    await page.type('.sc-AxjAm #login-username', username)
    await page.waitForSelector('.sc-AxjAm #password-input')
    await page.click('.sc-AxjAm #password-input')
    await page.type('.sc-AxjAm #password-input', process.env.PASSWORD)
    await page.waitForSelector('.sc-AxjAm > .sc-AxjAm:nth-child(3) > .ScCoreButton-sc-1qn4ixc-0 > .ScCoreButtonLabel-lh1yxp-0 > .sc-AxjAm', {visible:true})
    await page.click('.sc-AxjAm > .sc-AxjAm:nth-child(3) > .ScCoreButton-sc-1qn4ixc-0 > .ScCoreButtonLabel-lh1yxp-0 > .sc-AxjAm')

    await page.waitForSelector('#FunCaptcha-Token')

    //request 2captcha funcaptcha
    await https.get(`https://2captcha.com/in.php?key=${api}&method=funcaptcha&publickey=${pk}&surl=${surl}&pageurl=https://dashboard.twitch.tv/u/${username}/settings/stream`, (response) => {
        var data = '';
        response.on('data', (chunk) => {
            data += chunk;

        response.on('end', () => {
            setTimeout(() => {getCaptcha(data)}, 20000)
    .on('error', (e) => {

    await page.waitForSelector('.sc-AxjAm:nth-child(2) > .sc-AxjAm > .ScCoreButton-sc-1qn4ixc-0 > .ScCoreButtonLabel-lh1yxp-0 > .sc-AxjAm', {visible:true,timeout:0})
    var streamkey = await page.evaluate(() => document.querySelector('.sc-AxjAm:nth-child(2) > .sc-AxjAm > .ScCoreButton-sc-1qn4ixc-0 > .ScCoreButtonLabel-lh1yxp-0 > .sc-AxjAm').innerHTML);
    await navigationPromise

    await fs.appendFile('userkeys.txt', `${username}:${streamkey}`, e => console.log(`error: ${e}`))

console.log(`Getting keys.`);

(async () => {
    for(i in usernames) {
        await getKey(usernames[i]);

//https://dashboard.twitch.tv/u/stokeshester/settings/stream trying to login as soon as I enter this link

Here is an example of my code logging the "tc-token" value for the funcaptcha:
Here is what the captcha interface looks like (no button):


New member
I'm looking for it too.
Anyone can help us?

Edit: i added some source codes from twitch, and the game.js from arkose (fun captcha).
But i cant find a callback.
: /

Edit²: after typing "ArkoseEnforcement" on console, we got a function, maybe callback is here?


  • twitch.zip
    318.8 KB · Views: 19
Last edited:


New member
I have the same issue that hcaptha dont have a button the press like continue or somethinf like that. i try to use it on discord.com/register i also get the solved captchakey and im able to inject it into the code however after its injected it does not continue means i cant press on any button because there is none. i use capmonster.cloud as solvingsite. probably someone can help me here

I also found a code that set a callback function but im nto sure how to use it. im psuing selenium on python with the execute_script function so im not sure how to set the responsecode stored ito a pythonvar into the code. here is the site where i found the code:

Its russian but there are some deepl translate plugins:


New member
string token = "";//paste your token here (can use https://anycaptcha.com or https://2captcha.com)

chromeDriver.ExecuteScript("parent.postMessage(JSON.stringify({eventId: \"challenge-complete\",payload: {sessionToken: \"" + token + "\"}}), \"*\")");

Use this script to callback submit button and done!
This script using C#. you can convert it to python.