Making a Discord bot: Roles 101

Roles are an essential part of Discord – from managing permissions to colors on top of your username to public and private channels, roles help shape every server and are a necessity. So it’s no surprise that discord.js has a wide variety of ways to find, edit and work with roles from your bot. This guide will teach you how to work with roles in discord.js and do common functions such as creating roles, deleting roles, editing permissions, and checking roles and permissions. For this guide, we’re going to make an example bot that can change roles at will – but only for members with certain permission or role. Make sure that you have a basic understanding of javascript and discord.js so that you’re able to follow along. We’re going to have to set up the bot first, with a basic single-file command handler:
const Discord = require("discord.js");
const client = new Discord.Client();

client.on("message", async message => {
     const prefix = ".";
     const content = message.content.toLowerCase().trim();
     if (message.author.bot) return;
     if (!content.startsWith(prefix)) return;
     const args = content.slice(prefix.length).split(/ +/g);
     const command = args.shift();
});

client.login("BOT TOKEN");
We’re not going to go into the command handler since this is a guide for roles. You also may have bot instead of client or msg instead of message. That’s our base bot. Now the first thing we have to do is create a role command. Each server and the member has a RoleManager, which is a manager that lets you… well, manage, a member’s or server’s roles. To access the RoleManager, just get the roles property of the server or member. Note that a member’s RoleManager is different than a server’s one. So we have our bot that’s ready to manage our roles!
The first command we’re going to add is going to create a role and give it to the member that used the command. We’re going to have to use both types of RoleManagers – the server one to create the role, and the member one to add the role.
// Make sure to put this in your message event
if (command == "gimmerole") {
     let role = await message.guild.roles.create({
          data: {
               name: "Cool Role",
               color: "GREEN"
          }
     }); // Creates a green role named "Cool Role"
     message.channel.send("Made the role!");
}
You can put any other role property inside the data argument, such as name, color, whether it should be hoisted, and permissions. We’ll get back to permissions later, though. After doing the command, sure enough, the role was created!
But there’s one problem – the member that did the command doesn’t have the role! To do this, we’re going to have to access the member’s RoleManager. While inside the server’s manager we’re able to create and delete roles, inside the member’s we’re able to add and remove roles.
if (command == "gimmerole") {
     let role = await message.guild.roles.create({
          data: {
               name: "Cool Role",
               color: "GREEN"
          }
     });

     message.member.roles.add(role); // Adds the role to the member that did the command

     message.channel.send("Made the role!");
}
You can also supply a role ID or an array of roles to add a role to a member. Sure enough, the role was added!
That’s a good start, but not very useful. What would be useful is if we could mention a user and it would add the role to them – and luckily, we can! We can find the member RoleManager in ANY member in ANY server! We can access the first-mentioned member using message.mentions.members.first().
if (command == "gimmerole") {
     let role = await message.guild.roles.create({
          data: {
               name: "Cool Role",
               color: "GREEN"
          }
     });


     let member = message.mentions.members.first();
     if (!member) return message.channel.send("Please mention a member to add the role to!");
     member.roles.add(role).catch(err => {return message.channel.send("Couldn't add the role")}); 
     // Adds the role to the mentioned member

     message.channel.send("Made the role!");
}
Now the mentioned member will get the role! We can take it a step further by adding a role specified to the member instead of creating a new one. To do this, we have to access the role cache of the server and member. The RoleManager’s cache property is a role cache, and it’s a Collection of roles that the server or member has.
const roleByID = message.guild.roles.cache.get("ROLE ID"); // Get a role by it's ID

const roleByName = message.guild.roles.cache.find(r => r.name == "ROLE NAME"); // Get a role by it's name
You can use these methods for any server or member. In this case, we want to get the name of the role that the user using the command specifies. Like this: “.gimmerole @user Role Name” To do that, we have to: 1. Slice the arguments from 1 to the end so we allow role names with spaces 2. Get the role by its name 3. Give the role to the member mentioned
if (command == "gimmerole") {
     let roleName = args.slice(1).join(" "); // 1

     let role = await message.guild.roles.cache.find(r => r.name.toLowerCase() == roleName); // 2
     if (!role) return message.channel.send("That's not an existing role!");


     let member = message.mentions.members.first();
     if (!member) return message.channel.send("Please mention a member to add the role to!");
     member.roles.add(role).catch(err => {return message.channel.send("Couldn't add the role")}); // 3

     message.channel.send(`Gave the role to ${member.user.tag}!`);
}
Our first full command is done, and it works!
Now, what if we wanted to remove a role from a user? It’s just as easy! The RoleManager of a member has add, set, and remove methods. We can just use our code for the add role command and change the add to remove!
// Make sure to put this under your gimmerole command
if (command == "takerole") {
     let roleName = args.slice(1).join(" ");

     let role = await message.guild.roles.cache.find(r => r.name.toLowerCase() == roleName);
     if (!role) return message.channel.send("That's not an existing role!");


     let member = message.mentions.members.first();
     if (!member) return message.channel.send("Please mention a member to remove the role from!");
     member.roles.remove(role).catch(err => {return message.channel.send("Couldn't remove the role")});

     message.channel.send(`Took the role from ${member.user.tag}!`);
}
This command works as well.
And our 2 role commands are complete. But we don’t want just anyone to add and remove roles from members! We need to check if a member has a certain role or permission. It’s easier and better to check for a permission than a role, but let’s use a role just to show how you can:
// Make sure to put this below your command variable and above your commands
let role = await message.guild.roles.cache.find(r => r.name == "Moderator");
if (!message.member.roles.cache.has(role.id)) return message.channel.send("Only moderators can use this command!");
This isn’t a very good method because the server may not have a moderator role, or it could be called something else. A much better way of doing this is checking a member’s permissions. In this case, let’s make them have the Manage Roles permission. We can check if a member has a permission (from any of their roles) just from message.member.hasPermission!
// Make sure to put this below your command variable and above your commands
if (!message.member.hasPermission("MANAGE_ROLES")) return message.channel.send("Only members with the Manage Roles permission can use this command!");
If you wanted to, you could use a database and let admins choose a specific role that can use the commands, but we’ll just use permissions for now. What about role permissions? We can change them pretty easily with the setPermissions method. Let’s make a command that sets one permission to a role:
// Make sure to put this below the other commands
if (command == "setpermission") {
     let roleName = args.slice(1).join(" ");
     let role = await message.guild.roles.cache.find(r => r.name.toLowerCase() == roleName);
     
     await role.setPermissions([args[0].toUpperCase()]).catch(err => {return message.channel.send("Couldn't set the permission")});
     
     message.channel.send(`Set the **${args[0].toUpperCase()}** permission to the role!`);
}
You can supply more than one permission in the array to set more, like this:
role.setPermissions(["MANAGE_MESSAGES", "EMBED_LINKS", "ATTACH_FILES"]);
Our bot is almost done, and now all we need is to make sure that the bot has the Manage Roles permission before any command is used:
// Make sure to put this below the permission check, and above the commands
if (!message.guild.me.hasPermission("MANAGE_ROLES")) return message.channel.send("I need the Manage Roles permission to work! (look at my name)");
And we’re done! Hopefully, you learned a bit about roles in discord.js from this guide, and are ready to start creating and editing roles in your bots! Useful Resources: Guild RoleManager: https://discord.js.org/#/docs/main/stable/class/RoleManager Member RoleManager: https://discord.js.org/#/docs/main/stable/class/GuildMemberRoleManager Role constructor: https://discord.js.org/#/docs/main/stable/class/Role Learn More: Multi-file command handler: https://codinghelp.site/knowledgebase/discord-bot/command-handler-full-index-js-file-decoded/ Create a Discord bot as a beginner: https://codinghelp.site/knowledgebase/discord-bot/setup/

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.