Command permissions - discord.js

I am looking to develop a personal network bot, I am in need of a simple "mod", "admin", and other moderation commands. I have the commands complete, I just need to figure out how to send an error & have the command not execute when the member does not have the "admin", "mod", or other moderation roles. Here is what I have so far:
if (!message.member.roles.some(r=>[Tester].includes(r.name)) )
return message.channel.send("error_here").catch(console.error);
I would like the code to include an error message:
message.channel.send(message.author + " you do not have permission to use this command!")
I would also like the command to not execute when the member does not have the "admin", "mod", or other moderation roles.

I think you're on the right track, just add a little code for extra validation. This code checks if the user has any moderation roles, and if so, the command gets executed.
// Just some test role names
let modRoles = ['admin', 'moderator', 'helper'];
if (command === '<Some mod/admin command here>') {
if (!message.member.roles.some(r=>modRoles.includes(r.name))) {
// User does not have any moderation roles. User is not allowed to execute command
return message.channel.send(message.author + ' you do not have permission to execute this command!');
.catch(console.error);
}
// User does have a moderation role. User can execute command
// Write code here for the command
}

Related

Lock command for discord.js

I need to make a lock command for a bot I'm making with discord.js but I don't know how. I need it to lock the channel when I do ".lock" by changing "Send messages" setting for the "Community" role to false, and set it back to True when I do ".unlock".
Does anyone know how to do this?
Here are the steps:
Get the "community" role's id. Store it in some variable (I'm calling it communityRoleId in this example).
Call <Message>.channel.permissionOverwrites.edit(communityRoleId, { SEND_MESSAGES: false }) when someone calls the lock command. This creates a permission overwrite for the community role saying that that role can't send messages in the channel.
For the unlock command, you can either delete the permission overwrite you made with the lock command or edit it so the community role can send messages again. To delete it, you can just <Message>.channel.permissionOverwrites.delete(communityRoleId), and to edit it, you can <Message>.channel.permissionOverwrites.edit(communityRoleId, { SEND_MESSAGES: true })
Edit: Be sure to also run checks to see if the person using the command has an "admin" role or sufficient permissions or something like that, you don't want random people being able to lock channels!

Get the role(s) of a member in discord.py

I am trying to make a command that shows the roles of the mentions user.
This command is a test command which I am going to implement into my mute command. (the command will remove the member's current role and add the mute role)
This is what I have:
#client.command()
async def roles(ctx, member: discord.Member):
roles = member.roles
role_names = [role.name for role in roles]
await ctx.send(role_names)
The command works fine, but the output isn't quite what I expected.
Output:
['#everyone', 'Member']
It correctly displays the 2 roles mentioned by the user, but it isn't formatted in the specific way I want.
I want the output to simply be "Member" or whatever other roles the mentioned member has besides #everyone. basically, I want to remove the square brackets and "#everyone" from the output, leaving only the role name.
Hopefully, somebody can help me with this.
Thanks!
To fix your problem you just have to format the information from role_names in string form and remove the '#everyone'. You can use a list comprehension and the join() method .
Here would be the amended code:
#client.command()
async def roles(ctx, member: discord.Member):
roles = member.roles
role_names = ' '.join([role.name for role in roles if role.name != '#everyone'])
await ctx.send(role_names)

Trying to implement Patreon-only commands/functions on my discord bot, how would I accomplish this?

My discord bot gives the role of 'Patreon' to my patreon supporters. This role is given on my main discord bot server. So right now I'm trying to write some commands that would be only available to users who have the role 'Patreon' in the BOTS discord server, how can I accomplish this?
Like is there a way I can be like -
message.member.has('Patreon Role').in('My Discord Server)?
Let's go over the tasks you need to accomplish this.
Get the "home guild" with your users and corresponding Patreon role.
See Client.guilds and Map.get().
Find the user in the guild.
See Guild.member().
Check whether or not the user has the Patreon role.
See GuildMember.roles and Collection.find().
You can define a function to help you out with this, export it and require it where you need it (or define it within relevant scope), and then call it to check if a user is one of your Patreon supporters.
Here's what this function would look like...
// Assuming 'client' is the instance of your Discord Client.
function isSupporter(user) {
const homeGuild = client.guilds.get('idHere');
if (!homeGuild) return console.error('Couldn\'t find the bots guild!');
const member = homeGuild.member(user);
if (!member) return false;
const role = member.roles.find(role => role.name === 'Patreon');
if (!role) return false;
return true;
}
Then, as an example, using this function in a command...
// Assuming 'message' is a Message.
if (!isSupporter(message.author)) {
return message.channel.send(':x: This command is restricted to Patreon supporters.')
.catch(console.error);
}
message.member.roles.find('name', 'Patreon Role');//this returns either undefined or a role
What that does is it searches the users collection to see if the have "Patreon Role"
If the message is on the same server, otherwise you could do
client.guild.find('name','My Discord Server').member(message.author).roles.find('name', 'Patreon Role'); //this also returns undefined or a role
Clearly that second option is long, but what is basically does is searches the servers the bot is in for a server called 'My Discord Server' then it finds the GuildMember form of the message.author user resolvable, then it searches their roles for the role 'Patreon Role'
There is a chance it will crash though if they aren't on the server(the documentation doesn't say if it returns and error or undefined for some reason) so if it does crash you could instead do
client.guild.find('name','My Discord Server').members.find('id', message.author.id).roles.find('name', 'Patreon Role'); //this also returns undefined or a role
You can read more here: https://discord.js.org/#/docs/main/stable/class/User
and here
https://discord.js.org/#/docs/main/stable/class/Client
and here
https://discord.js.org/#/docs/main/stable/class/Guild
To try and give a full example, assuming this is in your message event
if (message.member.roles.find(r => r.name === 'Patreon') == undefined &&
commandIsExclusive || message.guild.id !== 'this-id-for-BOTS-server') {
// Don't allow them in here
}
Essentially, to run a command they must be a supporter, in a specific server and if it is exclusive and the other criteria aren't met, they are denied

Privilege too low, setNickname()

if (message.content.startsWith(prefix + "nickname ")) {
var nick = message.content.replace(prefix + "nickname ", "");
message.member.setNickname("nick");
message.channel.send('You have *changed* your **nickname** to "' + nick + '" **!**');
}
I am trying to make a command to change the authors nickname through text. Unfortunately it throws an error of "Privilege too low..." even though my bot has the Manage Nicknames permission, Administrators and is even at the top of the list of roles in server settings. Anyone have any ideas?
EDIT: According to the answer, the bot of the server is not allowed to modify the nickname of the server superior, despite having the highest role. I ran the code on an alternate account and it ran flawlessly. I just don't get the privilege of nicknaming myself (which can essentially be done via the /nick command that discord implemented)
Discord.js implements changing nicknames by getting the GuildMember from the message, and using the GuildMember#setNickname method. Here's a simple example of setting the nickname of the user who ran the message:
if (message.content.includes('changeName')) {
if (!message.guild.me.hasPermission('MANAGE_NICKNAMES')) return message.channel.send('I don/'t have permission to change your nickname!');
message.member.setNickname(message.content.replace('changeName ', ''));
}

Using emotes to give roles Discord.js

In my discord server, as a verification method, I want my bot to have all users react to the message and then get given the verified role, and remove the old role. The current code I have doesn't grant or remove roles, but doesn't error.
client.on("messageReactionAdd", function(users) {
users.addRole(users.guild.roles.find("name", setup.verify));
users.removeRole(users.guild.roles.find("name", setup.default));
});
There is a problem in the current code. The messageReactionAdd event returns a User object, which does not contain the property .guilds which you attempt to access: users.guilds.r- .
Instead of this perhaps you should the id of the User object and plug that into message.guild.members.get("id here"). Then use the returned Member object with your current code. That should work!
References:
Guild Member
, Message Reaction Event, User Object
Would something like this work?
I'm not sure it will I haven't tested it. This should add the role if the message they reacted to consists of the word "role1" and if they react to a different message it will remove the role. I don't know if this is what you're going for but in theory this should work.
client.on("MessageReactionAdd", function(users) {
if (message.content === "role1") {
users.addRole(users.guild.roles.find("name", setup.verify))
} else if (!message.content === "role1") {
user.removeRole(users.guild.role.find("name", setup.default))
}
});
Are the names of the roles; setup.verify & setup.default?
If not, that's why it is not working.
Try:
client.on("messageReactionAdd", function(users) {
users.addRole(users.guild.roles.find("id", ROLEIDHERE));
users.removeRole(users.guild.roles.find("id", ROLEIDHERE));
});
where ROLEIDHERE put the role id to find the role id just tag the role and before you hit send put \ before the tag and it will supply the id

Resources