Skip to content

Tutorial: Your First Bot

Ethan Snow edited this page Nov 23, 2020 · 10 revisions

My First Bot

In this article I'm going to show the basics of using Neos.js to build a bot account.

We will learn how to:

  • Authenticate the Bot
  • Set up Friend Request Handling
  • Set up Command Handling using the CommandExtended Plugin
  • Set up Error Handling
  • Build a Basic Bot

This tutorial will assume you know the Very Basics of node, If you are brand new to Node I recommend this video.

Installing and Setup

Setup for Neos.js is quite simple, The package including many beta builds are available on NPM.

Run npm install @bombitmanbomb/neosjs to add the library to your workspace. For pre-release builds append @version to neosjs

Next, We require the Contructor like so

const Neosjs = require("@bombitmanbomb/neosjs");

This constructor will let us create a New Neos Client, along with pass in Startup Variables (See New Neos)

const Neos = new Neosjs({OnlineState:"Online"}) //Optional Param

Now we have a new instance of the Client ready to use. Now we need to tell it What to do. Neos.js is an Asynchronous Library, meaning Most functions will return a Promise of information from the server. Most functions data must be accessed via await or .then().

Handling Friend Requests

In neos, accounts can only send messages to users they are Friends with. Neosjs has a whole list of events that fire when things happen.

When the bot receives a Friend Request, this will fire the friendAdded with the Friend object. This will also fire on login when the bot fetches friends, so we also need to check if its a request, or existing friend

With Neos.js we use .AddFriend to accept or send a request.

Neos.on("friendAdded", (request)=>{
 if (request.friendStatus === "Requested") { // check if request
  Neos.AddFriend(request.FriendUserId)
 }
})

Your bot will now accept All incoming Friend Requests!

Handling Messages with CommandExtended

For Handling messages we will be using CommandHandler developed with @RoxxyBoxy and CommandExtended to do anything we could possibly want by sending the bot a message.

Before we define commands we need to import both libraries. As of 1.7.x these plugins ship natively with Neos.js and are available via a deep require!

const CommandHandler = require("@bombitmanbomb/neosjs/Plugins/CommandHandler")
const CommandExtended = require("@bombitmanbomb/neosjs/Plugins/CommandExtended")

As of 1.7.6 no docs exist for Plugins. If you use an editor like VSCode they are set up with proper IntelliSense

Initialize CommandExtended like so:

const Command = new CommandExtended(new CommandHandler(Neos))

This will set internal values so the modules can communicate.

CommandExtended has many features but we will primarily be using only Add and Run.

Writing a Ping command with Contexts

This is one of the most straightforward commands we can write with Neos.js

We will also be defining Indexes for the /help and /usage commands natively implemented by CommandExtended

Command.Add("ping", (Handler)=>{ //es6 arrow syntax
 Handler.Reply("pong!");
}, {
 index:"Test Response Time", // Define Help Context
 usage:"/ping" // Define Usage Context
});

This code adds /ping. /help ping, and /usage ping

Now that we have the command set up, we need the bot to know to run commands when it receives a message. This uses Command.Run

Neos.on("messageReceived", Command.Run)

And that's it! Neos.js will now parse all incoming messages to the Commands.

Let's add something a little more complex, a Relay command.

Adding a Relay command

For this command we will be using the Handler, Arguments, and Neos.js to fetch user info. First we build the command function.

This function will require 2 arguments, a User, and a Message. This will also be an Asynchronous function, as we will be dealing with Networked data.

async function Relay(Handler, SenderId, Args){
 if (Args.length!==2) return Handler.Usage() // this will respond with the Usage Context if there are not the right number of arguments.
 var UserId //Define a variable for UserId to send to.
 if (Args[0].startsWith("U-")){
  UserId = Args[0] // Argument is a UserId
 } else {
 //Username passed, Fetch a user using this name
 let user = await Neos.GetUserByName(Args[0]);
 if (user.Id == null) return Handler.Reply("Invalid User \""+ Args[0]+"\"") // User passed is not a valid username
 UserId = user.Id
 }

//Now we have the User ID, Relay the message.
let Sender = await Neos.GetUser(SenderId)
Neos.SendTextMessage(UserId, Sender.Username + ":" + Args[1]).then(()=>{
 Handler.Reply("Sent!")
})
}

Quite a bit more complex! But there are barely any limits on what you can do! Now like before we plug the command into the Command module.

Command.Add("relay", Relay, {
 index:"Relay a message to another user.",
 usage:'/relay "User" "Message"'
})

The command is now set up!

But we still cant use any of this, we need to Turn On the client. There are 2 steps to this.

Turning On Neos.js

Error Handling

No errors are explicitly handled in neos.js unless they would absolutely break everything, for safety we will add a general error handler.

Neos.on("error", (err)=>console.trace(err))

Running Code before Logged In

Another thing to keep in mind is that running any code that would require authentication before logging in a user will result in an error. For this we have an event that runs After the user is logged in, this is similar to Discord.js's on ready.

Neos.on("login", ()=>{
// Code goes here
})

Logging In

You need to use your Credentials for this, So it's reccomend to create an account specifically for your bot. I will be using Fake Credentials in this to show how to define.

Neos.Login("TotallyRealEmail@google.com","Password", /*If we had a session token we could use it here*/ null, "aUniqueIdentifierTokenForYourBot")

If the given credentials are valid your bot is now Live!

Full Code

const Neosjs = require("@bombitmanbomb/neosjs");
const CommandHandler = require("@bombitmanbomb/neosjs/Plugins/CommandHandler");
const CommandExtended = require("@bombitmanbomb/neosjs/Plugins/CommandExtended");

const Neos = new Neosjs({ OnlineState: "Online" }); //Optional Param
const Command = new CommandExtended(new CommandHandler(Neos));

Neos.on("messageReceived", Command.Run);
Neos.on("error", (err) => console.trace(err));
Neos.on("friendAdded", (request) => {
	if (request.friendStatus === "Requested") {
		// check if request
		Neos.AddFriend(request.FriendUserId);
	}
});
Neos.on("login", () => {
	console.log(Neos.CurrentUser.Username + " Logged in");
});
//Commands
Command.Add(
	"ping",
	(Handler) => {
		//es6 arrow syntax
		Handler.Reply("pong!");
	},
	{
		index: "Test Response Time", // Define Help Context
		usage: "/ping", // Define Usage Context
	}
);

async function Relay(Handler, SenderId, Args) {
	if (Args.length !== 2) return Handler.Usage(); // this will respond with the Usage Context if there are not the right number of arguments.
	var UserId; //Define a variable for UserId to send to.
	if (Args[0].startsWith("U-")) {
		UserId = Args[0]; // Argument is a UserId
	} else {
		//Username passed, Fetch a user using this name
		let user = await Neos.GetUserByName(Args[0]);
		if (user.Id == null) return Handler.Reply("Invalid User \"" + Args[0] + "\""); // User passed is not a valid username
		UserId = user.Id;
	}

	//Now we have the User ID, Relay the message.
	let Sender = await Neos.GetUser(SenderId);
	Neos.SendTextMessage(UserId, Sender.Username + ":" + Args[1]).then(() => {
		Handler.Reply("Sent!");
	});
}

Command.Add("relay", Relay, {
	index: "Relay a message to another user.",
	usage: "/relay \"User\" \"Message\"",
});

Neos.Login(
	"TotallyRealEmail@google.com",
	"Password",
	/*If we had a session token we could use it here*/ null,
	"aUniqueIdentifierTokenForYourBot"
);