Permissions in Discord.js API? - javascript

I'm coding a Discord bot with discord.js/node (I'm fairly new).
I tried to setup a permissions system where you would need a specific role to make an if statement return true and allow the user to use a command or something else. I tried (this is just part of it):
if(message.author.roles.includes('role_id') {
COMMANDS
}
But it just gives me errors in the console (obviously)
If any of you know how to properly set a permissions system up in a efficient way, that would be appreciated!

To achieve this using an if conditional: if(message.member.roles.has([role_id]))
where [role_id] is a string (otherwise it will always return false)

There is an hasRole method on users: http://discordjs.readthedocs.io/en/8.2.0/docs_user.html
hasRole(role)
Shortcut of client.memberHasRole(member, role)
See client.memberHasRole
Which link to this: http://discordjs.readthedocs.io/en/8.2.0/docs_client.html#memberhasrole-member-role
memberHasRole(member, role)
Returns if a user has a role

Did you try doing something like this?
if (!message.member.roles.some(r=>["role_name"].includes(r.name)) )
return;
This will prevent all users from using that specific command unless they have the specified role.

Related

Disconnect users from a voice channel for being defeaned for 10 minutes

So my problem is I want to create a bot that disconnects people from a VC on Discord server if they are being defeaned for 10 minutes.
I know a thing or two about programming because I learnt it in school, but I never used python.
I have a working music bot, with index.js and everything. So I was wondering if you could help me write a code for that I can paste into it so it'll work?
Thanks in advance!
I found this code:
client.on('voiceStateUpdate', (oldState, newState) => {
if (newState.deafened && newState.member.manageable) {
newState.kick();
}
});
But it didn't work for some reason, and it wouldn't even let me set user afk time.
You don't have to fix this, you can write a new code instead for the whole concept :)
First of all, VoiceState doesn't have a property called 'deafened'. You can use VoiceState.selfDeaf instead, which returns a boolean.
Second of all, VoiceState.kick() wont do anything, as it's not a method of VoiceState. Assuming you want to kick the member from the vc, you can use VoiceState.disconnect().
You can read the VoiceState documentation here

List all users with a specific role with DiscordJS

I already checked here but this unfortunately doesn't seem to help in my case. I am trying to list all members in a server that have the role with id 'roleID'. I get that role like so:
const guild = await client.guilds.fetch(guildID);
const role = await guild.roles.fetch(roleID);
However, whenever I try to print the roles.member property, I get an empty collection, and trying to map it out returns an empty array
console.log(role.members);
>>Collection(0) [Map] {}
console.log(role.members.map(users => users.user.tag));
>>[]
And I am absolutely stumped as to why. I know the ID is definitely correct since printing out the role lists all the correct information, and I used roleID to successfully assign the role to a few users in the server.
And yes, I triple checked, there are definitely users in the server that have the role
Weirdly enough what seems to fix this issue on my side is not adding the GuildMembers intent, but adding the GuildPresences intent.
I don't know why that happens since this intent is unrelated, but you could try it as a solution to your problem.
You also need to make sure that you enabled this intent at https://discord.com/developers/applications -> Bot -> Enable Presence Intent
Image for reference: https://i.imgur.com/oepA04b.png

Discord.js - Get Message from Interaction

client.ws.on('INTERACTION_CREATE', async (interaction) => {}
The interaction class has lots of properties like channel, member and id but it doesn't have a message property.
Is there a way to get the message from an interaction or will I have to use a event listener on message? And if so, how would I use this with slash commands?
You can get the user input by just using the base class interaction. However, the content is not visible, but you can view it by passing it through an api endpoint or something similar, its kind of weird for me but i'm sure there is an explanation for that.
The best way is to use interaction.options, so you'll need to add at least one option in your application command.
For example
// /test as your Application command
client.on('interactionCreate', async interaction => {
if (interaction.commandName === 'test') {
const message = interaction.options.data
console.log(message)
})
}
Slash commands have their own type of message. I don’t believe they have an id, delete button, edit button or lots of things most messages do. This means you will not be able to get the "message" from a slash command. From buttons however, they do emit INTERACTION_CREATE but has a little more info. I don’t remember for sure, but I think you can use something like interaction.components. I am not completely sure, but if you want, click a button and log the interaction into your console to see the unique button info like this
client.ws.on('INTERACTION_CREATE', async (interaction) => {
{
console.log(interaction) //will be long!
//…
})

I cant get an item from an array for my Discord bot to use to take action

I am trying to program a bot for a server, and I am currently working on making a 'Mute' command. My idea was to make it so when the command is called, the bot must first check if the person has the role which allows them to mute other members, if that condition is met, then the bot would take the second argument, aka the Discord id of the member which must be muted, and give them a role which inhibits them from speaking in the server.
For some reason when I was testing the code, I wasn't able to get past the bot checking whether the second argument was a valid ID for a member of the server.
Here is the mute command code:
if (message.member.roles.cache.has('765334017011613717')) {
console.log('Oh oh');
const person = message.guild.member(
message.mentions.users.first() || message.guild.members.get(args[1])
);
if (!person) {
console.log('Oh oh 2');
}
} else message.channel.send('You do not have permission to use this command.');
Note: The console.log() functions were added so I could see where the problem was happening when running the code.
There are two things that you might do in order to make this work with the first being more of a suggestion.
First, ideally you always want to check if the role exists and return if it doesn't. This prevents you from having to put your entire logic to mute the person into the if statement. You do that like this:
if (!message.member.roles.cache.has('your role ID')) {
return message.channel.send('You do not have permission to use this command.');
}
The actual problem in your code stems from your way of finding the member. The right way to do that is, either checking the first mention of a member or taking a provided ID from your first argument. Your first argument being not args[1] but args[0]. If the ID is being used you need to use the cache property. Source
let muteMember = message.mentions.members.first() || message.guild.members.cache.get(args[0]);
You should then check if a member has actually been found and return if not.
if (!muteMember) {
return message.channel.send("That member doesn't exist!")
}
Note: You already have this in your code but I wanted to include it for completeness.
After that you can continue with your code to mute someone.

How do I make my Discord.JS bot react to it's own Direct Message?

When I'm making my bot, I want to make it so that when you type afv!support it will send a DM like this:
DM example
Thanks for contacting AFV support. Please react below for which problem you have.
:one: Ban Appeal
:two: Bug Report
:three: Report Staff/User
This command will expire in two minutes.
and then react with :one:, :two:, and :three:. I've looked around but haven't found the answer.
Thanks for the help!
Elitezen's answer is correct, I just wanted to elaborate on their use of <emote>.
If you replace the first usage of <emote> with :one:, for example, it will not work correctly. You will have to enter the physical unicode emoji, or emoji ID if it's a custom emoji.
For example:
message.member.send(<theMessage>).then(msg => {
await msg.react('1️⃣') // instead of :one:
await msg.react('2️⃣') // instead of :two:
msg.react('3️⃣') // instead of :three:
})
Read this discord.js guide on reactions for more information
Send a message to your target, pass the message into a .then(), Where the bot will react to the message
message.member.send(<theMessage>).then(msg => {
msg.react('<emoji>')
msg.react('<emoji>')
msg.react('<emoji>')
})

Categories

Resources