I'm new in Discord bot coding and I want to create a command where the bot only replies if the message sender has a specific role.
According to the discord.js documentation I have to use GuildMemberRoleManager.cache. Sadly, it isn't working.
The whole command looks like this:
client.on('messageCreate', (message) => {
if (
message.content.toLowerCase() === prefix + 'test' &&
GuildMemberRoleManager.cache.has(AdminRole)
)
message.reply('test');
});
You should get the author's roles. Only members have roles, so you will need to get the author as a member using message.member. message.member returns a GuildMember and GuildMembers have a roles property that returns a GuildMemberRoleManager (the one you mentioned in your original post).
Its cache property is a collection of the roles of this member, so you can use its has() method to check if the user has the admin role:
client.on('messageCreate', (message) => {
let adminRole = 'ADMIN_ROLE';
let isAdmin = message.member.roles.cache.has(adminRole);
if (message.content.toLowerCase() === prefix + 'test' && isAdmin)
message.reply('test');
});
Define the variables which will make you easy to understand as you are new
const guild = message.guild.id;
const role = guild.roles.cache.get("role id");
const cmduser = message.author;
const member = await guild.members.fetch(cmduser.id);
and make if statement like
if(member.roles.cache.has(role.id)) {
return message.channel.send("test")
}
if you want bot to check if user have administrator perm than
message.member.hasPermission('ADMINISTRATOR')
Check all perm flags on Discord Perm Flags
So according to your code it will be
const guild = message.guild.id;
const role = guild.roles.cache.get("role id");
const cmduser = message.author;
const member = await guild.members.fetch(cmduser.id);
client.on("messageCreate",(message) => {
if(message.content.toLowerCase() === prefix + "test" && member.roles.cache.has(role.id))
message.reply("test")
})
Related
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 2 years ago.
Improve this question
I have some code that detects when someone enters the command role and gives them the role with the name of the first argument passed to the command (args[0]). For example, the bot would try to detect something like !role nameOfTheRole, which would give the user the role with the name nameOfTheRole.
However, the code is not working and I'm not sure why. Here is what I have mnaged to get so far:
var cmdmap = {
role: gimmerole
}
function gimmerole(member, args, message) {
var memb = message.member() //<------- ERROR
const role = memb.guild.roles.find(r => r.name == args[0])
memb.roles.add(role)
}
client.on('message', (msg) => {
var cont = msg.content,
author = msg.member,
chan = msg.channel,
guild = msg.guild
if (author.id != client.user.id && cont.startsWith(config.prefix)) {
var invoke = cont.split(' ')[0].substr(config.prefix.length),
args = cont.split(' ').slice(1)
console.log(invoke, args)
if (invoke in cmdmap) {
cmdmap[invoke](msg, args)
}
}
})
I have made a few modifications to your code:
I changed the line function gimmerole(member, args, message) { to function gimmerole(message, args) {, as in the line cmdmap[invoke](msg, args);, you are calling it with the message object and the arguments, so the message was getting assigned to member instead and message would have been undefined.
I changed message.member() to message.member, as member is a property of message, not a method.
I also changed the code that parses the message and splits it into a command and arguments so that it's a lot cleaner.
Added a sanity check (if (!role) return console.log(`The role "${args[0]}" does not exist`);) to make the bot log to the console if the role does not exist.
Changed args[0] to args.join(' ') to enable roles with spaces to be specified.
var cmdmap = {
role: gimmerole
};
function gimmerole(message, args) {
const member = message.member;
const role = message.guild.roles.cache.find(r => r.name === args.join(' '));
if (!role) return console.log(`The role "${args.join(' ')}" does not exist`);
member.roles.add(role);
}
client.on('message', (msg) => {
var cont = msg.content,
author = msg.member,
chan = msg.channel,
guild = msg.guild;
if (author.id !== client.user.id && cont.startsWith(config.prefix)) {
const [invoke, ...args] = cont.slice(config.prefix.length).trim().split(' ');
console.log(invoke, args);
if (invoke in cmdmap) {
cmdmap[invoke](msg, args);
}
}
})
There is the Discord.js Guide that you can use if you want something to follow along with. It is really helpful and detailed.
I have noticed you're improperly trying to find a role. In order to get a full roles collection, you will need to use the cache method of message.guild.roles, resulting in the line:
const roleObject = memb.guild.roles.cache.find(...);
var cmdmap = {
role: gimmerole
};
function gimmerole(message, args) {
const member = message.member;
const role = message.guild.roles.cache.find(r => r.name === args.join(' '));
if (!role) return console.log(`The role "${args.join(' ')}" does not exist`);
member.roles.add(role);
}
client.on('message', (msg) => {
var cont = msg.content,
author = msg.member,
chan = msg.channel,
guild = msg.guild;
if (author.id !== client.user.id && cont.startsWith(config.prefix)) {
const [invoke, ...args] = cont.slice(config.prefix.length).trim().split(' ');
console.log(invoke, args);
if (invoke in cmdmap) {
cmdmap[invoke](msg, args);
}
}
}
Credits to Deamon Beast
My command: it does what it has to do. I can mention a user or use his id
let args = message.content.split(' ');
if (args.length > 2) return message.channel.send('Only mention one user!');
if (!args[1]) return message.channel.send('Mention someone!');
if (args[1]) {
let member = message.guild.member(
message.mentions.members.first() || message.guild.members.cache.get(args[1])
);
let roles = member.roles.cache
.filter((r) => r.name !== '#everyone')
.map((role) => role.name)
.join('\n');
if (roles.length === 0) roles = '-';
if (member) {
let embed = new Discord.MessageEmbed()
.setColor(tesseract.Constants.COLORS.TEAL)
.setTitle('User Info')
.setThumbnail(member.user.displayAvatarURL())
.setAuthor(
`${member.user.tag} (${member.id})`,
member.user.displayAvatarURL()
)
.addField('**Username:**', `${member.user.username}`, true)
.addField('**Discriminator:**', `${member.user.discriminator}`, true)
.addField('**ID:**', `${member.user.id}`, true)
.addField('**Status:**', `${member.user.presence.status}`, true)
.addField('**Joined On:**', `${member.joinedAt.toLocaleString()}`, true)
.addField(
'**Created On:**',
`${member.user.createdAt.toLocaleString()}`,
true
)
.setDescription(roles)
.setFooter(
`© ${message.guild.me.displayName}`,
this.client.user.displayAvatarURL()
);
message.channel.send(embed);
} else {
message.channel.send(`Could not find that member`);
}
}
Now i want to add that i can search for a user outside the discord. (Bot is added to 2 discords) So i want to do the user command on the second discord and search for a user from the first discord. i get this done with client.users.cache.get('user id') but due to the roles function i get a TypeError: Cannot read property 'roles' of null. If i remove the role funcion it works fine..
How can I ignore the role function when its searching for client.users.cache.get('user id')
The error is telling you that member is null. This happens when args[1] is not a valid ID or the user is not in the guild.
Check that a valid member was supplied before getting the member's roles:
// You don't need to wrap this in a message.guild.member()
let member = message.mentions.members.first() || message.guild.members.cache.get(args[1]);
if (member) {
let roles = member.roles.cache
.filter((r) => r.name !== '#everyone')
.map((role) => role.name)
.join('\n');
// rest of code...
}
I have a json file (localJSON.json) with Discord usernames (i.e. JohnDoe#1234) and need to get the User IDs from these usernames in order to have a role added. Every place I have looked online has resulted with either an 'undefined' or 'null' value for rMember. Verified that the code to add a role works when given a User ID as a string, but can't find how to get a User ID from a username.
How do I get a user's ID from their Username using Discord.js?
localJSON.json
[
{
"discordName": "JohnDoe#1234"
},
{
"discordName": "MarySue#5678"
}
]
function addRole(discordUsername, gameName, message){
var roleName = "";
//Switch statement to assign roleName to a valid guild role based on argument
var userID = discordUsername.id; //Pseudo code, Need to accomplish this
var rMember = message.guild.members.get(userID); //Needs UserID as string
var gRole = message.guild.roles.find((role) => role.name == roleName);
if (!rMember) { //if member not in server
message.channel.send(rMember + " is not in the server!");
} else { //assign role
rMember.addRole(gRole);
}
}
async run(message, args){
...
for (var i = 0; i < localJSON.length; i++) {
var currentEntry = localJSON[i];
var currrentUserName = currentEntry.discordName;
addRole(currrentUserName, args, message); //addRole(discordUsername, gameName, message);
}
}
You'll want to do
client.users.cache.find(u => u.tag === 'Someone#1234').id
Discord.js v12 uses .cache now, so you have to run find on the cache, and v12 also removes Collection#find(key, value) in favor of Collection#find(data => data.key === value).
I am trying to make a bot for a game of tag. I am making it so you can mention a user and it adds the 'IT' role to them, but when they don't mention a member, it's added to them. My code is here:
const args = message.content.slice(prefix.length).trim().split(/ +/g);
if (message.content.startsWith(`${prefix}tag`)) {
if (!message.mentions.users.size) {
let roleenter = message.guild.roles.get("555947490315075600");
let member = message.member;
member.addRole(roleenter).catch(console.error);
message.reply("you are now it!")
client.channels.get("555943069271457792").send(member + " is now in!")
await message.guild.fetchMembers();
const role = message.guild.roles.get("555947490315075600");
for (const member of role.members.array()) {
await member.removeRole(role);
}} else {
let member = message.mentions.users.first();
let roleenter = message.guild.roles.get("555947490315075600");
member.addRole(roleenter).catch(console.error);
message.reply("you are now it!")
client.channels.get("555943069271457792").send(member + " is now in!")
await message.guild.fetchMembers();
const role = message.guild.roles.get("555947490315075600");
for (const member of role.members.array()) {
await member.removeRole(role);
Whenever I try #tag #user, it says member.addRole is not a function when I use it earlier on and it works.
Change this line:
let member = message.mentions.users.first();
To this line:
let member = message.mentions.members.first();
You used the user Object of the mentioned user, but you have to use the guildMember Object because you can‘t assign a role to an user.
Users are still getting the public role regardless of the role they have
I'm sorry if the answer here is fairly obvious but I'm learning javascript as I write this bot. I'm aiming for users to be able to do !name and gain a role called "public" as long as they don't have a role listed in the code (General, Captain, etc.).
client.on('message', async message => {
if (message.channel.id === '535226845654810624'); {
if(message.content.startsWith('!name')) {
if (message.member.roles.some(role => role.name === 'General', 'Captain', 'Lieutenant', 'Sergeant', 'Corporal', 'Recruit'));
const newname = message.content.split(' ').slice(1).join(' ');
message.member.setNickname(newname);
}
else {(message.content.startsWith('!name'));} {
if(message.channel.id === '535226845654810624') {
const newname = message.content.split(' ').slice(1).join(' ');
message.member.setNickname(newname);
const newrole = message.guild.roles.find(x => x.name === 'Public');
message.member.addRole(newrole);
message.delete();
}
}
I'm sure the code is completely ugly. I'm still learning. Right now regardless of if they have the Gen/Capt/Lieutenant/etc roles they still gain the public role.
client.on('message', async message => {
if(message.channel.id === '535226845654810624') {
if (message.content.startsWith('!name')) {
const newname = message.content.split(' ').slice(1).join(' ');
message.member.setNickname(newname);
const newrole = message.guild.roles.find(x => x.name === 'Public');
message.member.addRole(newrole);
message.delete();
}
}
This is the code I had before adding in the attempt to ignore the role add if they have the other roles. I'm not sure how to change this to what I'm looking for.
Take a look at the below code, give it a try and let me know what the result is. There were several errors with your code which I'm quite surprised your editor didn't pick up (or atleast didn't error out the code), such as having a semicolon right after defining an if statement, the extra curly brackets after your else statement, etc.
Anyway, the code below checks if the command entered is !name and if so, it assigns the new nickname to the user. After that it checks if the user has any of the specified roles, and if he does not, he gets a new role 'Public'.
client.on('message', async message => {
if (message.channel.id === '535226845654810624') {
if(message.content.startsWith('!name')) {
// Users are allowed to change their nicknames no matter their roles
const newname = message.content.split(' ').slice(1).join(' ');
message.member.setNickname(newname);
// Define the roles which need to be checked
const roleNames = ['General', 'Captain', 'Lieutenant', 'Sergeant', 'Corporal', 'Recruit'];
// If the user does not have any of the roles above, assign them the role 'Public'
if (!message.member.roles.some(role => roleNames.includes(role.name))) {
const newrole = message.guild.roles.find(x => x.name === 'Public');
message.member.addRole(newrole);
message.delete();
}
}
}
});