Guide to Scripting Bots | Javascript Tutorial | FunCaptcha and New Host Info

IMPORTANT UPDATE

Roblox has recently changed the way they handled the logins, so what you find in this guide is currently still usable but you have to change how you use the login function. Cookies are now required for the logins and you will need to get it yourself to work.

We reccomend you no longer use roblox-js and just use noblox-js which has better support for the new login. This guide currently does not go over using noblox but it’s basically a maintained version of roblox-js.

If you’re looking to get into bot scripting you should at least have previous experience with programming languages mainly in Javascript before you try to make this guide your first project.

He currently has a written example of how to use his cookie login, you should go read it. If you continue on with this tutorial you can just install noblox.js instead of roblox-js and still follow along but keep in mind the changes.

Where is your cookie?

NEW HOST SUGGESTIONS

The cookie bypass may not work on Heroku, so I prefer you guys use something else if you don’t know how to setup a database with SQL or NoSQL (MongoDB).

Suggestions:

ABOUT

Before you begin reading this tutorial please know that it is unfinished and I only added as much as I did so far to get feedback on if I should build on it with things such as Google Spreadsheet and Twitter support.

If this tutorial has a demand for it to be built on I will certainly post updates such as more commands and more framework scripting.

If you have trouble with this tutorial or would like to learn more you can contact me on Discord (TechSpectrum#2620) and I’ll do what I can to help you or answer any questions.


DISCLAIMER

This tutorial is in no shape or form intended to be malicious to ROBLOX in any way. It is simply something for people interested in expanding their scripting abilities to look into. It will not include botting or anything as such for gaining an advantage on ROBLOX. It is only going to focus on the development side such as for clans to manage their members or for users to have a better discord experience with their community.

GUIDE

RESOURCES

discord.js
Home · sentanos/roblox-js Wiki · GitHub
Discord Developer Portal
Discord Permissions Calculator

Part I. Setting up your first bot in Discord

DISCORD BOT

GETTING STARTED

Installation

Node.js Framework: Node.js
IDE: Download - Sublime Text
CMD: http://cmder.net

CMD Installation: Cmder: Super Command Line Tool Windows - YouTube

Please visit the Discord.js server for additional support!

Create a new Project

1. Start by creating a new folder, you can name this anything you want, we'll call ours "MyBot"

2. Access your Command Prompt, I use Cmder so I'll be accessing mine through here.

3. Type into your Commander Prompt "npm init" this is used to create our package.json fille we'll be using for all our dependencies such as Discord.js, Roblox-js, etc. Enter the name in lower case and you can just click through everything, when it's finished type yes and press enter.

4. Type into your Command Prompt "npm install Discord.js " and you will then see your package is downloading and installing. ng and installing. "

5. Your folder should now look like this, if it's not - make sure you completed the steps.

image

6. Create a text file and change the file type to .js which stands for Javascript, assuming you have Sublime 3 installed or any IDE that supports it the file will change to that programs icon.

imageimage

7. How to restart the Command Prompt/Program in Cmder - You will do this quite frequently when re-running your bot after making saved changes.

image

UPDATE
Please install the following:

npm install nodemon

This library is used to auto-restart your application once you click save.
When you run your program type it in like the following:

nodemon bot.js

Some of my pictures have me typing in “node bot.js” and while you still can you just have to close and re-open or restart the command prompt to run the changes.


DISCORD

Create a new Bot Account

If you have have an account you can access the Discord Developers page here:

This is your workstation for managing all your bots, you can create as many as you want (as far as I’m aware).

1. Click the + button.

image

2. Give your bot a unique name, image, and description. Once that's that, hit the Submit button.

3. You'll now see you have a button to turn this account into a bot, click it and agree to change.

image

4. Go to the Discord Permissions Calculator listed at the top of this thread and enter your permissions. If you want all the permissions to become allows you must enable 2 Step Verification on your account.

image

5. Select the server for your bot to be added to and continue with the Captca.

image

image
image

Getting your bot Online

var discord = require('discord.js');
var client = new discord.Client();
var token = "TOKEN_HERE_FROM_THE_BOT_PAGE"
client.login(token)

This code here is all you need to login, just make sure you get your token off the web page you were on earlier to create the bot. Now if we save this to something like “Bot” the script file, we can head over to our command prompt and run the bot right now.

imageimage


Events

So now that we now know how to bring our bot online we want to start figuring out how to start making it check for messages, when people join or leave our server, come online and more. I’m going to list out all of these below so you can see what we are going to go over.

var discord = require('discord.js');
var client = new discord.Client();
var token = "TOKEN_HERE"
client.login(token)

client.on("ready", () => {
  client.user.setGame(`Making HL3`);
  console.log(`Ready to serve on ${client.guilds.size} servers, for ${client.users.size} users.`);
});

client.on('guildMemberAdd', member => {
  let guild = member.guild;
  let user = member.user
  console.log(`${user.tag} joined ${guild}`)
});

client.on('guildMemberRemove', member => {
  let guild = member.guild;
  let user = member.user
  console.log(`${user.tag} left ${guild}`)
});

client.on('message', (message) => {
	console.log(`${message.author} said ${message.content}`)
});

Results:
image
image
image
image

Explanation

So lets go over what we just wrote for a second, you may want to refer to the Discord.js documentation’s class page for this. Once we login we then have the ready event that goes off once our bot is online. When this goes off you can tell it what you want it to do, and for us our client’s user as the method setGame which allows us to enter what we want. You can use this to display the server count, and it does not have to be fired within ready because this is a part of the client, so feel free to use the guildMemberAdd event to display the current servers size with client.guilds.size if you wanted to show off.

Now you are probably wondering what a guild so if you haven’t figured it out already, it’s a server. Discord’s term for servers are guilds and all casses related to it can be found on the discord.js documentation page. Which brings us to guildMemberAdd where got member which is a property belonging to a guild. Remember that a member is not a user reference so you have to do that yourself and refer to your server just like the following code example. guildMemberRemove is the when the server member leaves but returns the same member object as well.

Next we have message which is the most important part of our bot. A message is more than just context, it’s an object returning data such as author which is a drect “@” reference to the user, and content which is the true text of your message. We will be taking a message and breaking it down to create our first commands.

Creating a Command

var prefix = '!';

function isCommand(command, message){
	var command = command.toLowerCase();
	var content = message.content.toLowerCase();
	return content.startsWith(prefix + command);
}

client.on('message', (message) => {
	if (message.author.bot) return; // Dont answer yourself.
    var args = message.content.split(/[ ]+/)
    
    if(isCommand('Ping', message)){
    	message.reply('Pong');
    }
});

image

In this code I wrote the function isCommand to make it easier on you for checking for a command. It turns our command (“Ping”) and message content and turns it into lower case. This is so even if we say Ping or ping it would still work. Now in order to know if this was a command we added our own prefix which will be looked at the beginning of the message content for.

Essentially this function is looking for “n!ping” to be the beginning of the message entered. Which will return true if it is. When it does return true we tell the bot to reply with “Pong” using message.reply which is a function that will result in the @ response as shown.

Now sometimes you may have a command and the bot will reply to itself, we don’t want this so we added the message.author.bot check to make sure the bot will never reply to its own messages.

Last we are going to be working on a command to promote a user on ROBLOX but in order to do that we must first make a way to get a name to work with. So we have a args variable that is now an array.

If your message was:

“n!promote TechSpectrum”

This is now turned into:

args[0] = “n!promote”
args[1] = “TechSpectrum”

If you have no experience in JavaScript and only Lua you should know that arrays always start with 0 unlike Lua Tables so don’t get confused and mix them up.


client.on('message', (message) => {
	if (message.author.bot) return; // Dont answer yourself.
    var args = message.content.split(/[ ]+/)
    
    if(isCommand('Promote', message)){
    	var username = args[1];
    	if (username){
    		message.channel.send(`Checking ROBLOX for ${username}`)
    	} else {
    		message.channel.send("Please enter a username.")
    	}
    	return;
    }
});

image

So what we did here was take our array args and just as I mentioned before took the index 1 for the first name we should expect to search for. Sometimes though someone may not enter the rest of the command and we will get an error. In order to prevent this we checked for username (args[1]) if it existed, otherwise we will reply with a message asking them to enter the correct arguement.

You may have noticed I said message.channel.send instead of message.reply and either you use it just fine. However message.channel will refer to the current channel the message is in, and channels have a send function we can use to post a new message with the @.

Now we just have to install Roblox-js

Part II. Writing a Promotion Command for Discord

ROBLOX-JS

npm install roblox-js

Run this line into your command prompt after you restart the window, after a few seconds you should see it begin to download.

var roblox = require(‘roblox-js’);

If you remember we did a require earlier for discord.js, you will put this line underneath it at the top so we can begin to use the library, you may find this familiar just like Lua Modules in ROBLOX.

Login

Now we need to login to a ROBLOX account, you should probably create something with a unique password that is not the same as your regular account.

roblox.login({username: "Username_Here", password: "Password_Here"}).then((success) => {

}).catch(() => {console.log("Failed to login.");});

As you can see this is the main thing we have to do first before we can work with ROBLOX, just like Discord. However if you notice we have a catch and this is because a promise which is what Roblox-js relies heavily on to work. A promise the best way I can describe it is similar to pcall() which will return a result of success or error, this is great to avoid breaking your bot.

Now lets head back over to our command.

Promotion Function in Roblox-js

var prefix = '!';
var groupId = 2750654;
var maximumRank = 20;

function isCommand(command, message){
	var command = command.toLowerCase();
	var content = message.content.toLowerCase();
	return content.startsWith(prefix + command);
}

client.on('message', (message) => {
	if (message.author.bot) return; // Dont answer yourself.
    var args = message.content.split(/[ ]+/)
    
    if(isCommand('Promote', message)){
    	var username = args[1]
    	if (username){
    		message.channel.send(`Checking ROBLOX for ${username}`)
    		roblox.getIdFromUsername(username)
			.then(function(id){
				roblox.getRankInGroup(groupId, id)
				.then(function(rank){
					if(maximumRank <= rank){
						message.channel.send(`${id} is rank ${rank} and not promotable.`)
					} else {
						message.channel.send(`${id} is rank ${rank} and promotable.`)
						roblox.promote(groupId, id)
						.then(function(roles){
							message.channel.send(`Promoted from ${roles.oldRole.Name} to ${roles.newRole.Name}`)
						}).catch(function(err){
							message.channel.send("Failed to promote.")
						});
					}
				}).catch(function(err){
					message.channel.send("Couldn't get him in the group.")
				});
			}).catch(function(err){ 
				message.channel.send(`Sorry, but ${username} doesn't exist on ROBLOX.`)
			});
    	} else {
    		message.channel.send("Please enter a username.")
    	}
    	return;
    }
});

image

Now you might be a little confused unless you read this carefully, we simply used some of the group functions found here: Group Functions · sentanos/roblox-js Wiki · GitHub

The documentation is pretty great so if you want to find out what a function does it tells you what you need to give it and what it returns.

Now in order for us to first promote the username we gave we have to find it, you can use getIdFromUsername in order to return a users Id, and using the catch tell the user if this player doesn’t actually exist.

From there we took the Id of the user and used getRankInGroup to find out what this user is in the group, if they are 0 they are a guest and if they are 255 they are the owner. We can promote a user by knowing this and setting a maximum promotion rank limit.

Now that we got the Id and rank we made sure that we were not at the maximum promotable rank, and if we weren’t we could use promote which brings the user to the next rank in the group such as 23 to 24 or 14 to 17 if that is the next rank from the current one.

Promote also returns to us an object called roles which contains 2 more objects, oldRole, and newRole that we then use to tell the server what we did.


Full Script so Far

var discord = require('discord.js');
var roblox = require('roblox-js');
var client = new discord.Client();
var token = "TOKEN_HERE"
client.login(token)

roblox.login({username: "Username_Here", password: "Password_Here"}).then((success) => {

}).catch(() => {console.log("Sorry, it failed.");});


client.on("ready", () => {
  client.user.setGame(`Making HL3`);
  console.log(`Ready to serve on ${client.guilds.size} servers, for ${client.users.size} users.`);
});

client.on('guildMemberAdd', member => {
  let guild = member.guild;
  let user = member.user
  console.log(`${user.tag} joined ${guild}`)
});

client.on('guildMemberRemove', member => {
  let guild = member.guild;
  let user = member.user
  console.log(`${user.tag} left ${guild}`)
});

var prefix = '!';
var groupId = 2750654;
var maximumRank = 20;

function isCommand(command, message){
	var command = command.toLowerCase();
	var content = message.content.toLowerCase();
	return content.startsWith(prefix + command);
}

client.on('message', (message) => {
	if (message.author.bot) return; // Dont answer yourself.
    var args = message.content.split(/[ ]+/)
    
    if(isCommand('Promote', message)){
    	var username = args[1]
    	if (username){
    		message.channel.send(`Checking ROBLOX for ${username}`)
    		roblox.getIdFromUsername(username)
			.then(function(id){
				roblox.getRankInGroup(groupId, id)
				.then(function(rank){
					if(maximumRank <= rank){
						message.channel.send(`${id} is rank ${rank} and not promotable.`)
					} else {
						message.channel.send(`${id} is rank ${rank} and promotable.`)
						roblox.promote(groupId, id)
						.then(function(roles){
							message.channel.send(`Promoted from ${roles.oldRole.Name} to ${roles.newRole.Name}`)
						}).catch(function(err){
							message.channel.send("Failed to promote.")
						});
					}
				}).catch(function(err){
					message.channel.send("Couldn't get him in the group.")
				});
			}).catch(function(err){ 
				message.channel.send(`Sorry, but ${username} doesn't exist on ROBLOX.`)
			});
    	} else {
    		message.channel.send("Please enter a username.")
    	}
    	return;
    }
});
Part III. Game Server Bot (Free Hosting)

So this time around we want to be doing things like promotions on our games, perhaps things like commands. Thanks to sentanos we can do this with the server sided version of his roblox-js library which requires absolutely no hosting on your end.

First of all you want to go here: GitHub - sentanos/roblox-js-server: (THIS SERVER IS UNSECURE - USE AT YOUR OWN RISK) Example server using roblox-js module
Download Scripts: https://github.com/sentanos/roblox-js-server/archive/master.zip
Sign Up: https://heroku.com/
Download the CLI for Heroku: The Heroku CLI | Heroku Dev Center

Make sure your have the following contents you download from GitHub:
image

Be sure you extra everything from the ZIP files, we want to focus on 3 things.

Settings
image

Just like your bot for Discord this also requires a ROBLOX accounts Username and Password to login, and now we 2 other settings to work with.

Key is something we make up ourselves, such as “thisismysecretpassword” or “jKKlkis9929Nnxnwi” but write this down somewhere because you will need it for your ROBLOX Server script.

The maximum rank setting is there to protect certain ranks from being changed such as your officers, so if your highest Low Rank or Medium rank is 15 and the next rank is an officer at 17 you want to want to make Maximum Rank 15.

Preparing to Host

Make sure you have Git installed! Git - Downloads

Once you do, you can go to the folder where you put your exported files from roblox-js server and enter your Command Prompt for that folder.

First login.

heroku login

It will ask you to type in your heroku account credentials, Email and Password.

Next

git init

This is going to initialize our git depository to push.

Once it’s finished we now need to push all our files since it’s empty.

git add --all

Give it time to add all your content it will let you know when it’s finished, depending on the speed of your computer this could take some time.

When it’s finished enter the following:

git commit -am “Initial”

By commiting this allows us to prepare to push the code to our web ap on heroku, but before we can do that we have to make one first, give the commit time to finish then move on with the following:

heroku create my-roblox-bot

You can name this whatever you like, this new web app will show up on your heroku account now such as this:

https://dashboard.heroku.com/apps

Finally, we can send our code to the web app like this:

git push heroku master

Once everything is finished being pushed it should tell you that it ran successfully to verify there was no errors.

You may now take this file: image

And copy/paste the script inside of it into ROBLOX as a module.

You can:

  1. promote
  2. demote
  3. setRank
  4. shout
  5. post
  6. handleJoinRequest
  7. forumPostNew
  8. forumPostReply
  9. message

Script Example:

local server = require(script.Parent.Server)
local domain = 'rbx-js.herokuapp.com' -- Make sure there is no http:// in here!
local key = '/UAO9lTOYapr8ecV8cs/t3cP9c7na6rKHfRn7M6GDct+PdJyQJ40Jebe+CKZDgKV8TRLtbBqfhJc/eHNC7RHA8BCKkrFOkaIKC9/ripy34QzLq3m2qqy/GdyCg/5KHFUPbsuRNetr52ZP+6E2puKWrR9XvuAMG9bq+X02luwmID6aU7YBpq7sALl21Pv0OB4wy43VhuI3esN8w/Rl0ZC3LiJWwMv8PnwCKqgmq9L9UXLVBEPNJ9Plcv73+QqArHqiZ/qtrJO88='
local groupId = 18
local userId = game:GetService'Players':GetUserIdFromNameAsync'Shedletsky'
local api = server(domain, key, groupId)
print(api.promote(userId).message)
print(api.message(userId, 'Subject', 'Body').message)
print(api.getBlurb(1).data.blurb)

Let me know what you think so far, I hope I explained myself well.

EXTRA CODE

Check Speakers Role
function pluck(array){
    return array.map(function(item) { return item['name']; })
}

function hasRole(members, role){
    if(pluck(members.roles).includes(role)){
        return true;
    } else {
        return false;
    }
}

function isAdmin(message){
	if(
		hasRole(message.member,"Commander") || 
		hasRole(message.member,"Arch Admiral") || 
		hasRole(message.member,"Viceroy") || 
		hasRole(message.member,"Colonel") || 
		hasRole(message.member,"Admiral") || 
		hasRole(message.member,"Captain") 
		){

		return true;
	} else {
		return false;
	}
}
client.on('message', (message) => {

if (isAdmin(message)){
console.log('Is an admin!')
}

})

SURVEY

  • Yes this was clear to follow,
  • I found this difficult to follow

0 voters

  • Expand on Discord.js
  • Expand on Roblox-js
  • Add Spreadsheet Tutorial
  • Add Twitter Tutorial
  • Add another library (Read Post Below)

0 voters

Help Resource:
https://forum.codingwithstorm.com/index.php?topic=82.0

223 Likes

Awesome tutorial!

This is great for people who don’t really know how a lot of clan and discord bots work.

13 Likes

I always love what you do, Tech! <3 Keep it coming.

9 Likes

Woooooo, yeah! TechSpectrum, you da man!

10 Likes

NodeJS is the only real dev language.
(I hope people get the joke)

Good tutorial.

17 Likes

I agree. I use it for GalacticBot and all my websites now.

11 Likes

Ok so im going to be adding the following later

Player and Group Blacklist (Google Spreadsheet)
Twitter feed channel
ROBLOX Forum feed channel
View a group members status and rank

5 Likes

Open source project if you’re interested in more intensive ways of doing this

11 Likes

Really detailed tutorial, very nice stuff.

5 Likes

Awesome!

I’m facepalming rn seeing some of those functions I didn’t use in my bot.
cough string.split cough

7 Likes

Hahaha, man it made a world of difference, I don’t event think to much of using commando cause its easier this way.

4 Likes

Update

How to host a Bot for a ROBLOX Server!

5 Likes

Very nice tutorial.

On a side note, there is also a library for coding Discord Bots with Lua called Discordia.

Link: GitHub - SinisterRectus/Discordia: Discord API library written in Lua for the Luvit runtime environment

9 Likes

I noticed for the message it responded with a message of “Error: Captcha”

3 Likes

Probably because I tried to authorize special permissions that required double authentication when I didn’t have it turned on. It will do that if you try.

5 Likes

So that will be done with the new update?

3 Likes

in jan?

3 Likes

Near the end of January after this week once I finish my exam Ill post some updates.

7 Likes

This is due to Roblox adding Captcha to a lot of APIs in order to prevent bots. Specifically for the message and join group APIs to my knowledge. Login APIs will also give captcha if too many people are logging in from one IP.

4 Likes

I don’t know if it’ll be of any use to anyone, but afaik sentanos doesn’t plan on maintaining the roblox-js library; however, there is a fork of the repo available that consists of more functionality, such as avatar and chat APIs: https://github.com/Neztore/roblox-js

5 Likes