How to join a group through the roblox api (javascript)

I have been working on a new discord bot and I want users to basically be able to integrate an automated roblox account to their group so they can run actions like paying users out, exiling, etc through discord commands. However I never thought that dealing with roblox captchas would be a nightmare. I have some code, and it basically sends a link, the user goes to the link and solves the captcha, and they press a discord button which sends a request to the roblox group with the captcha id basically stating the captcha is solved. This is not working however, and keeps saying the captcha test has to be solved.

Code (i marked what most of the things do):

const noblox = require("noblox.js")
let readline = require("readline")
let fs = require("fs")
const fun = require("funcaptcha")
const {
    Message,
    Client,
    MessageEmbed
} = require("discord.js");
const Discord = require('discord.js');
const fetch = require('node-fetch')
module.exports = {
        name: "groupJoin",
        /**
         *
         * @param {Client} client
         * @param {Message} message
         * @param {String[]} args
         */
        run: async (client, message, args) => {
          
            let msg;
            let answer;
            let token = await noblox.getGeneralToken() //gets x-csrf token
            let blo;  //dx blob
            let id;   //unified id
          
          //response to group i want the bot to join (https://groups.roblox.com/docs#!/Membership/post_v1_groups_groupId_users)
            let response = await fetch(`https://groups.roblox.com/v1/groups/9651507/users`, {
                method: 'POST',
                headers: {
                    Cookie: ".ROBLOSECURITY=_|WARNING:-DO-NOT-SHARE-THIS.--Sharing-this-will-allow-someone-to-log-in-as-you-and-to-steal-your-ROBUX-and-items.|",
                    ["X-CSRF-TOKEN"]: `${token}`,
                    ["Content-Type"]: "application/json"
                },
                body: {
                    "sessionId": "string", //null value
                    "redemptionToken": "string", //null value
                    "captchaId": "string", //null value
                    "captchaToken": "63E4117F-E727-42B4-6DAA-C8448E9B137F", //online captcha token for group join
                    "captchaProvider": "PROVIDER_ARKOSE_LABS" //online captcha provider
                }

            })
            
            
            let _data = await response.json();

            if (_data.errors[0].fieldData) {
                blo = JSON.parse(_data.errors.map(x => x.fieldData)).dxBlob
                id = JSON.parse(_data.errors.map(x => x.fieldData)).unifiedCaptchaId
            } else {
                return console.log('no dx blob');
            }
           
          //using a package to make the requests from arkose labs to roblox easier
            fun.getToken({
                pkey: "63E4117F-E727-42B4-6DAA-C8448E9B137F", 
                surl: "https://roblox-api.arkoselabs.com",
                data: {
                    blob: blo  //blob (extra data)
                },
            }).then(async token => {
                    let session = new fun.Session(token)
           
                    let challenge = await session.getChallenge() //gets the challenge (the captcha)
                  
                    
						//some discord stuff for the bot
                        const row = new Discord.MessageActionRow()
                            .addComponents(
                                new Discord.MessageButton()
                                .setCustomId('primary')
                                .setLabel('Validate Captcha')
                                .setStyle('SUCCESS'),

                                new Discord.MessageButton()
                                .setCustomId('primary2')
                                .setLabel('Cancel')
                                .setStyle('DANGER'),


                            );
                        await message.channel.send({
                            content: `game varient: ${challenge.data.game_data.game_variant}` //sending game varient
                        })
                       
                        msg = await message.channel.send({
                            content: `${session.getEmbedUrl()}`, //sending the url to the captcha for user to complete
                            components: [row]
                        })
                        
              //more discord stuff
                    const filterd = (m) => m.user.id === message.author.id
                    const collector = msg.channel.createMessageComponentCollector({
                        filterd,
                        time: 30000,
                    })
                    const embed2 = new Discord.MessageEmbed()
                        .setDescription(`Prompt Cancelled.`)
                        .setColor('RED')


                    collector.on('collect', async (i) => { //collecter
                            if (i.customId === 'primary2') {
                                return await msg.edit({
                                    embeds: [embed2],
                                    components: []
                                })
                            } else if (i.customId === 'primary') {
                              //when validate captcha button is pressed (meaning that user is done with captcha)
                              
                              //renewing x-csrf token 
                                let token2 = await noblox.getGeneralToken()

                                console.log('interaction success')
                               
                              
								//send the actual request to the roblox api with captcha id so it knows it's finished
                                let reqq = await fetch(`https://groups.roblox.com/v1/groups/9651507/users`, {
                                    method: 'POST',
                                    headers: {
                                        Cookie: ".ROBLOSECURITY=_|WARNING:-DO-NOT-SHARE-THIS.--Sharing-this-will-allow-someone-to-log-in-as-you-and-to-steal-your-ROBUX-and-items.|_",
                                        ["X-CSRF-TOKEN"]: `${token2}`,
                                        ["Content-Type"]: "application/json"
                                    },
                                    body: {
                                        "sessionId": "",
                                        "redemptionToken": "",
                                        "captchaId": `${id}`,
                                        "captchaToken": "63E4117F-E727-42B4-6DAA-C8448E9B137F",
                                        "captchaProvider": "PROVIDER_ARKOSE_LABS"
                                    }

                                })
                                

                                let reqqData = await reqq.json()
                                console.log(reqqData) //logs that the captcha hasnt been solved (problem)

                           


                            }


                        )


                    })

            },
        };

The api endpoint: Groups Api

Any help would be appreciated, thanks!

1 Like

link to funcaptcha package: GitHub - noahcoolboy/funcaptcha: A library used to interact with funcaptchas.

Pretty sure this would be against the TOS. The whole point of their captchas is to prevent automation of joining groups and bots from joining a group.

1 Like

The user still has to manually complete the captcha so it’s not against TOS.

2 Likes

is there any solution to this? Thanks!

We’re you ever able to solve this?