My bot can issue roles by mention, but I want it to be given by name (so that there's no need to ping the entire role. This is the syntax of the command: !role <#user> <role name>
I'm using discord.js#v12
const Discord = require("discord.js");
module.exports.run = async(bot, message, args) => {
if (!message.member.roles.cache.has('706754890294099990')) return message.channel.send(`${message.author}, roles can only be assigned by admins`).then(msg => {
setTimeout(() => {
msg.delete()
}, 5000);
})
let rMember = message.mentions.members.first()
if (!rMember) return message.reply(`You didn't mention any user`).then(msg => {
setTimeout(() => {
msg.delete()
}, 5000);
})
let role = message.guild.roles.cache.find(role => role.name. == args[1]) || message.mentions.roles.first()
if (!role) return message.channel.send(`${message.author}, You haven't written any role name`).then(msg => {
setTimeout(() => {
msg.delete()
}, 5000);
})
if (rMember.roles.cache.has(role.id)) return message.reply(`This member already has this role!`).then(msg => {
setTimeout(() => {
msg.delete()
}, 5000);
})
if (rMember.roles.cache.has(role.id)) {
} else {
await (rMember.roles.add(role.id));
message.channel.send(`${message.author} Added __${role.name}__ to ${rMember}`);
}
}
module.exports.help = {
name: "role"
}
If your role has spaces in its name that means that your args will be something like this: ['#user', 'Name', 'in', 'parts']
To get the full name you need to join together all the arguments except for the first one, which is the user. To do that, you can use Array.slice() and Array.join(); here's an example:
let roleName = args
.slice(1) // Take every element from index 1 to the end
.join(' ') // Join them back with spaces
let role = message.guild.roles.cache.find(r => r.name == roleName) || message.mentions.roles.first()
Related
I want to make a command that tags a user when there name got mentoined. But now the bot only tags the username and not a nickname the person has in the server
client.on("message", message => {
if(message.content === 'test'){
message.channel.send("works")
console.log("logged the message")
}
})
client.on("message", message => {
const list = message.guild;
list.members.cache.each(member => {
pinging = member.user.id
console.log(member.user.username)
if(message.content.includes(member.user.username)){
message.channel.send(`<#${pinging}>`)
}
})
})
can anyone help?
First thing, you only want to have one listener for the message event, so try this code:
client.on("message", message => {
if (message.content === 'test'){
message.channel.send("works")
console.log("logged the message")
}
// insert choices from below here
})
If you want it to listen for a member being tagged
const mentionedMember = message.mentions.members.first()
if (mentionedMember){
message.channel.send(`${mentionedMember}`)
}
Now if you want it to listen for username instead of #username
const args = message.content.slice().trim().split(' ')
const guild = message.guild
args.forEach(arg => {
const member = guild.members.cache.find(member => member.user.username.toLowerCase() === arg.toLowerCase())
if (member) {
message.channel.send(`${member}`)
} else {
return
}
})
To listen for displayName
const args = message.content.slice().trim().split(' ')
const guild = message.guild
args.forEach(arg => {
const member = guild.members.cache.find(member => member.displayName.toLowerCase() === arg.toLowerCase())
if (member) {
message.channel.send(`${member}`)
} else {
return
}
})
I'm working on this mute code:
if (cmd === "mute") {
if (
message.member.permissions.has(
"ADMINISTRATOR",
"KICK_MEMBERS",
"BAN_MEMBERS",
"MANAGE_ROLES"
)
) {
const target = message.mentions.members.first();
if (target) {
let mainRole = message.guild.roles.cache.find(
(role) => role.name === "{🍁}Scouts (VERIFIED)"
);
let muteRole = message.guild.roles.cache.find(
(role) => role.name === "Muted"
);
let memberTarget = message.guild.members.cache.get(target.id);
// timer mute
if (!args[1]) {
memberTarget.roles.remove(mainRole.id);
memberTarget.roles.add(muteRole.id);
message.channel.send(`<#${memberTarget.user.id}> has been muted`);
return;
}
// manually mute
memberTarget.roles.remove(mainRole.id);
memberTarget.roles.add(muteRole.id);
message.channel.send(
`<#${memberTarget.user.id}> has been muted for ${ms(ms(args[1]))}`
);
setTimeout(function () {
memberTarget.roles.remove(muteRole.id);
memberTarget.roles.add(mainRole.id);
}, ms(args[1]));
} else {
message.channel.send(" I can't mute this member !");
}
} else {
message.channel.send("You can't mute members !");
}
}
I'm trying to make it so that I won't have to keep changing
let mainRole = message.guild.roles.cache.find( (role) => role.name === "{🍁}Scouts (VERIFIED)" )"
instead, I'm trying to make this work on multiple servers/guilds without having to change it. How can I achieve that?
You may check if the role exists in that guild if it doesn't create one!
if(!muteRole) {
const muteRole =
message.guild.roles.create({
data: {
name: "Muted",
},
reason: 'Creating Mute role',
});
message.guild.channels.cache.forEach(async (channel, id) => {
await channel.createOverwrite(muteRole, {
SEND_MESSAGES: false,
MANAGE_MESSAGES: false,
READ_MESSAGES: false,
ADD_REACTIONS: false
});
});
memberTarget.roles.set([]); // removed all roles
memberTarget.roles.add(muteRole.id);
return message.channel.send("Mute role not found! Created Muted Role and muted user ");
}
This would allow your bot to create a role if none is present in that guild and the GuildMemberRolesManager#set([]) would remove all the roles from the user so you don't have to remove "specific" roles each time!
So I made this poll command that people without admin could make polls. To prevent spam, there is a verify step for everyone without admin. But when you react to the poll to verify it, it only works for the person making the poll. And not the admin that's supposed to check if it's not spam.
So when the admin reacts nothing happens but when the person that made the poll reacts to it, it verifies the poll and sends it to the main channel.
Code is down below is someone could help! 'Appreciate it!
const {Client, Collection, GuildMember, User, MessageEmbed, Message} = require("discord.js");
const ms = require("ms");
const delay = (msec) => new Promise((resolve) => setTimeout(resolve, msec));
module.exports.run = async(client, message, args, user, reaction) => {
var woord = '!poll'
var question = args.slice(0).join(' ')
var poll = new MessageEmbed()
.setTitle(`${message.author.username} wil een poll maken.`)
.setDescription(question)
.setColor('#eb8dd8')
.setFooter(`Poll gemaakt door: `+ message.author.username)
var success = new MessageEmbed()
.setDescription(question)
.setColor('#eb8dd8')
.setFooter("Poll started door: "+ message.author.username)
if(message.content.includes(woord)) {
message.delete({timeout:0})
}
if(!message.member.roles.cache.some(r => r.name === 'Barman')) {
if(message.channel.name.includes("🙇-poll")) {
if(args[0]) {
message.delete()
message.guild.channels.create(message.author.username, { permissionOverwrites:[
{
deny: 'VIEW_CHANNEL',
id: message.guild.id
},
{
allow: 'VIEW_CHANNEL',
id: message.author.id
},
],
}).then(channel => {
channel.send(poll).then(poll => {
poll.react('✅')
.then(() => poll.react('❌'));
})
})
} else {
message.delete()
}
}
} else {
var pollChannel = client.channels.cache.get('876531134702448701')
pollChannel.send(success).then(success => {
success.react('✅')
.then(() => success.react('❌'))
})
}
client.on('messageReactionAdd', (reaction, user) => {
const deleteChannel = message.guild.channels.cache.find(channel => channel.name.toLowerCase() === user.username);
var pollChannel = client.channels.cache.get('876531134702448701')
if(reaction.emoji.name === '✅') {
if(message.guild.channels.cache.find(channel => channel.name.toLowerCase() === user.username)) {
deleteChannel.delete()
.then(channel => {
pollChannel.send(success).then(success =>{
success.react('✅')
.then(() => success.react('❌'))
})
})
}
} if(reaction.emoji.name === '❌') {
if(message.guild.channels.cache.find(channel => channel.name.toLowerCase() === user.username)) {
deleteChannel.delete()
}
}
})
}
module.exports.help = {
name: "poll"
}
At the start of your function you can do this:
const questions = new Collection();
questions.set("What is the color of healthy grass?", "green");
questions.set("How many vowels are there in these letters: apple", "2");
const chosen = questions.randomKey()
await message.channel.send(`Please answer the question. This is to prevent spam. Make sure your spelling is correct. You have 30 seconds —> ${chosen}`)
try {
await message.channel.awaitMessages((m) => m.author.id === message.author.id && m.content.toLowerCase() === questions.get(chosen), {
time: 30000,
max: 1
})
} catch(err) {
return message.channel.send("You ran out of time to answer correctly!")
}
//code to make poll
Your awaitMessages syntax may be different on v13. You can also replace my questions, and add as many as you want!
Trying to make a bot that when the users click on the reaction there discord id goes into an embed Field and if they un click or click another emoji they end up in the field. This is gonna be used for a voting bot that once a certain number of users click yes or no a decision will be made to accept a user or deny a user. Any help?
exports.run = async (client, message, args) => {
message.delete({ timeout: 100 });
if (!args[0]) return message.reply('You need to supply the question');
let embed = new Discord.MessageEmbed()
.setTitle(args.join(' '))
.setDescription('Poll created by ' + message.author.tag)
.addField('Status', 'Voting is currently open.')
.setColor('#ffd700')
.attachFiles(new Discord.MessageAttachment('https://i.imgur.com/QUmbq9o.png', 'thumbnail.png'))
.setThumbnail('attachment://thumbnail.png')
.setFooter('Bot created by James (Rock)₇₇₇');
message.channel.send(embed).then(async msg => {
await msg.react('👍');
await msg.react('👎');
await msg.react('🤷');
await msg.react('🗑️');
const threshold = 6;
async function stop(result) {
collector.stop();
const newEmbed = new Discord.MessageEmbed(msg.embeds[0]);
newEmbed.title = newEmbed.title + ' [CLOSED]';
newEmbed.fields[0] = { name: 'Status', value: 'Voting is now closed.\n' + result };
newEmbed.setThumbnail('attachment://thumbnail.png');
await msg.edit(newEmbed);
msg.reactions.removeAll();
}
async function update() {
const newEmbed = new Discord.MessageEmbed(embed);
const userYes = (votes['👍'].size === 0)? '-' : [...votes['👍']];
const userNo = (votes['👎'].size === 0)? '-' : [...votes['👎']];
const userUnsure = (votes['🤷'].size === 0)? '-' : [...votes['🤷']];
newEmbed.addFields(
{ name: `User Yes (${votes['👍'].size}/${threshold})`, value: userYes, inline: true },
{ name: `User No (${votes['👎'].size}/${threshold})`, value: userNo, inline: true },
{ name: 'User Unsure', value: userUnsure, inline: true }
);
await msg.edit(newEmbed);
if (votes['👍'].size >= threshold) {
await stop('This answer is good enough to get accepted and an upvote.');
// do something
} else if (votes['👎'].size >= threshold) {
await stop('This answer is not good enough to get accepted and an upvote.');
// do something
}
}
const votes = {
'👍': new Set(),
'👎': new Set(),
'🤷': new Set(),
'🗑️': new Set()
};
update();
const collector = msg.createReactionCollector((reaction, user) => !user.bot , { dispose: true });
collector.on('collect', async (reaction, user) => {
if (['👍', '👎', '🤷', '🗑️'].includes(reaction.emoji.name)) {
const userReactions = msg.reactions.cache.filter(reaction => reaction.users.cache.has(user.id));
for (const userReaction of userReactions.values()) {
if (userReaction.emoji.name !== reaction.emoji.name || reaction.emoji.name === '🗑️') {
userReaction.users.remove(user.id);
votes[userReaction.emoji.name].delete(user);
}
}
votes[reaction.emoji.name].add(user);
} else {
reaction.remove();
}
update();
});
collector.on('remove', (reaction, user) => {
votes[reaction.emoji.name].delete(user);
update();
});
});
};
module.exports.help = {
name: "poll"
}
You can read this page from the discord.js guide about reaction collectors, it tells you everything you need to know. You can read this for more info about the .createReactionCollector() method.
There are multiple ways to acheive what you want once you make the reaction collector but I beleive the easiest would look something like this:
message.channel.send('your_message_here')
.then(async function(message) {
await message.react('👍');
await message.react('👎');
await message.react('🤷');
const filter = (reaction, user) => {
return ['👍', '👎', '🤷'].includes(reaction.emoji.name) && user.id === ogauthor
}
const collector = message.createReactionCollector(filter)
collector.on('collect', (reaction, user) => {
async function collect() {
if (!user.bot) {
if (reaction.emoji.name === '👍') {
//code here
}
//repeat this for the rest of your reactions
reaction.users.remove(user.id) //you can remove the reaction once they react to it and their name is added.
}
}
collect()
});
})
One problem is that this will run forever so you should add a timer to it.
You can use Reaction Collectors for this case to listen to reactions and list them depending on it.
I've made the code below, it works as expected:
message.delete({ timeout: 100 });
if (!args[0]) return message.reply('You need to supply the question');
let embed = new Discord.MessageEmbed()
.setTitle(args.join(' '))
.setDescription('Poll created by ' + message.author.tag)
.setColor('#ffd700')
.setThumbnail("https://i.imgur.com/QUmbq9o.png")
.addFields({name: "User Yes", value: 'None'}, {name: "User No", value: 'None'}, {name: "User Hum", value: 'None'})
.setFooter("Bot created by James (Rock)₇₇₇");
message.channel.send(embed).then(async msg => {
await msg.react('👍');
await msg.react('👎');
await msg.react('🤷');
const filter = (reaction, user) => {
return ["👍", "👎", "🤷"].includes(reaction.emoji.name);
};
const collector = await msg.createReactionCollector(filter);
collector.on('collect', (reaction, user) => {
const reactionsList = ["👍", "👎", "🤷"];
const fieldTitle = ["User Yes", "User No", "User Hum"];
var reactions = reaction.message.reactions.cache.array();
for(var reactionID in reactions) {
for (var i = 0; i < reactionsList.length; i++) {
if(reactionsList[i] === reaction.emoji.name){
let fieldDescription = user.id + "\n";
var users = reactions[reactionID].users.cache.array();
for(var userID in users){
if(users[userID].id === client.user.id || users[userID].id === user.id) continue;
fieldDescription += users[userID].id + "\n";
}
embed.spliceFields(i, 1, {name: fieldTitle[i], value: fieldDescription})
}
}
}
msg.edit(embed);
});
})
I have slightly modified your code and added code to track votes, edit the embed and check when the votes reach the threshold.
Demonstration
Code
message.delete({ timeout: 100 });
if (!args[0]) return message.reply('You need to supply the question');
let embed = new Discord.MessageEmbed()
.setTitle(args.join(' '))
.setDescription('Poll created by ' + message.author.tag)
.addField('Status', 'Voting is currently open.')
.setColor('#ffd700')
.attachFiles(new Discord.MessageAttachment('https://i.imgur.com/QUmbq9o.png', 'thumbnail.png'))
.setThumbnail('attachment://thumbnail.png')
.setFooter('Bot created by James (Rock)₇₇₇');
message.channel.send(embed).then(async msg => {
await msg.react('👍');
await msg.react('👎');
await msg.react('🤷');
await msg.react('🗑️');
const threshold = 1;
async function stop(result) {
collector.stop();
const newEmbed = new Discord.MessageEmbed(msg.embeds[0]);
newEmbed.title = newEmbed.title + ' [CLOSED]';
newEmbed.fields[0] = { name: 'Status', value: 'Voting is now closed.\n' + result };
newEmbed.setThumbnail('attachment://thumbnail.png');
await msg.edit(newEmbed);
msg.reactions.removeAll();
}
async function update() {
const newEmbed = new Discord.MessageEmbed(embed);
const userYes = (votes['👍'].size === 0)? '-' : [...votes['👍']];
const userNo = (votes['👎'].size === 0)? '-' : [...votes['👎']];
const userUnsure = (votes['🤷'].size === 0)? '-' : [...votes['🤷']];
newEmbed.addFields(
{ name: `User Yes (${votes['👍'].size}/${threshold})`, value: userYes, inline: true },
{ name: `User No (${votes['👎'].size}/${threshold})`, value: userNo, inline: true },
{ name: 'User Unsure', value: userUnsure, inline: true }
);
await msg.edit(newEmbed);
if (votes['👍'].size >= threshold) {
await stop('This answer is good enough to get accepted and an upvote.');
// do something
} else if (votes['👎'].size >= threshold) {
await stop('This answer is not good enough to get accepted and an upvote.');
// do something
}
}
const votes = {
'👍': new Set(),
'👎': new Set(),
'🤷': new Set(),
'🗑️': new Set()
};
update();
const collector = msg.createReactionCollector((reaction, user) => !user.bot , { dispose: true });
collector.on('collect', async (reaction, user) => {
if (['👍', '👎', '🤷', '🗑️'].includes(reaction.emoji.name)) {
const userReactions = msg.reactions.cache.filter(reaction => reaction.users.cache.has(user.id));
for (const userReaction of userReactions.values()) {
if (userReaction.emoji.name !== reaction.emoji.name || reaction.emoji.name === '🗑️') {
userReaction.users.remove(user.id);
votes[userReaction.emoji.name].delete(user);
}
}
votes[reaction.emoji.name].add(user);
} else {
reaction.remove();
}
update();
});
collector.on('remove', (reaction, user) => {
votes[reaction.emoji.name].delete(user);
update();
});
});
I have a code. this code replaces the letter "x" in the members' name with "y". but it sends the message I set for each user. that is, if there are 15 users, it sends the message "I changed the name of the x person" 15 times. I want to make this a single message then I want the bot to edit the message according to the user.
like this;
"I changed the name of member person" then "I changed the name of member2 person. (edited)"?
exports.run =async (bot, message, args) => {
let tokaci = message.guild.members.filter(membersx => {
return membersx.roles.some(r=>["639572199409319994"].includes(r.id));
});
let tokacis = message.guild.members.filter(membersx => {
return membersx.roles.some(r=>["tokuchi"].includes(r.name));
}).size;
tokaci.forEach(member => {
if(!member.displayName.includes(`✯`)) return message.channel.send(`<:reds:669706016375701574> **Belirtilen role sahip kişilerin isminde değiştirilmesi gereken harfi bulamadım.**`)
if(member.manageable) {
let newNickName = member.displayName.replace(`✯`, '⛥');
member.setNickname(newNickName)
.catch(console.error)
message.channel.send(`***<:onays:669706016354729984> Belirtilen role sahip olan kişilerin ismindeki harfi değiştiriyorum. ${member}***`)
}
});
}
You can use another function to edit message or use message.edit. Method channel.send() return a promise with sended message.
exports.run =async (bot, message, args) => {
let tokaci = message.guild.members.filter(membersx => {
return membersx.roles.some(r=>["639572199409319994"].includes(r.id));
});
let tokacis = message.guild.members.filter(membersx => {
return membersx.roles.some(r=>["tokuchi"].includes(r.name));
}).size;
message.channel.send('Start edit nicknemes').then(msg => {
tokaci.forEach(member => {
if(!member.displayName.includes(`✯`)) return message.channel.send(`<:reds:669706016375701574> **Belirtilen role sahip kişilerin isminde değiştirilmesi gereken harfi bulamadım.**`)
if(member.manageable) {
let newNickName = member.displayName.replace(`✯`, '⛥');
member.setNickname(newNickName)
.catch(console.error)
let text = `***<:onays:669706016354729984> Belirtilen role sahip olan kişilerin ismindeki harfi değiştiriyorum. ${member}***`
editMsg(msg,text)
}
});
})
}
function editMsg(message, text) {
message.edit(text)
}
V2
exports.run =async (bot, message, args) => {
let tokaci = message.guild.members.filter(membersx => {
return membersx.roles.some(r=>["639572199409319994"].includes(r.id));
});
let tokacis = message.guild.members.filter(membersx => {
return membersx.roles.some(r=>["tokuchi"].includes(r.name));
}).size;
message.channel.send('Start edit nicknemes').then(msg => {
tokaci.forEach(member => {
if(!member.displayName.includes(`✯`)) {
editMsg(msg,`***<:onays:669706016354729984> Belirtilen role sahip olan kişilerin ismindeki harfi değiştiriyorum. ${member}***`)
}
if(member.manageable) {
let newNickName = member.displayName.replace(`✯`, '⛥');
member.setNickname(newNickName)
.catch(console.error)
let text = `***<:onays:669706016354729984> Belirtilen role sahip olan kişilerin ismindeki harfi değiştiriyorum. ${member}***`
editMsg(msg,text)
}
});
})
}
function editMsg(message, text) {
message.edit(text)
}