I'm trying to make a clear command with role permissions for my Discord bot. (Discord.js) - discord

I have some code already, but how would I implement some other code to make the command only accessible by users with the MANAGE_MESSAGES permission?
My attempt at doing it myself:
else if (message.content.startsWith(`${prefix}clear`)) {
const amount = parseInt(args[0]);;
if (isNaN(amount)) {
return message.reply('that doesn\'t seem to be a valid number.');
} else if (amount <= 0 || amount > 100) {
return message.reply('you need to input a number between 1 and 100.');
}
message.channel.bulkDelete(amount, true).catch(err => {
console.error(err);
message.channel.send('Uh oh! Something went wrong!');
}).catch(() => {
if (!message.member.hasPermission(['MANAGE_MESSAGES'])) {
message.reply("you do not have permission to use this command!");
}
});
}
Without the extra bit at the end:
else if (message.content.startsWith(`${prefix}clear`)) {
const amount = parseInt(args[0]);;
if (isNaN(amount)) {
return message.reply('that doesn\'t seem to be a valid number.');
} else if (amount <= 0 || amount > 100) {
return message.reply('you need to input a number between 1 and 100.');
}
message.channel.bulkDelete(amount, true).catch(err => {
console.error(err);
message.channel.send('Uh oh! Something went wrong!');
});
}

Try this:
else if (message.content.startsWith(`${prefix}clear`)) {
// put this at the very top
if (!message.member.hasPermission("MANAGE_MESSAGES")) {
return message.reply("you do not have permission to use this command!");
const amount = parseInt(args[0]);
if (isNaN(amount))
return message.reply("that doesn't seem to be a valid number.");
if (amount <= 0 || amount > 100)
return message.reply("you need to input a number between 1 and 100.");
message.channel
.bulkDelete(amount, true)
.catch((err) => {
console.error(err);
message.channel.send("Uh oh! Something went wrong!");
})
.catch((err) => console.log(err));
}
}
I think the problem is that you were not returning if the member did not have the required permissions, so your code was just continuing on normally.

Related

Discord.js V.13 collect once with Collector

I'm making a suggest system for my bot which starts of with the user pressing a button in a channel which then prompts them to say what they want to suggest and then their suggestion gets sent to a different channel where others can vote on it. So what I want to make it do is I want it to create a createMessageComponentCollector and then register all the good/bad votes under a a period of 24h, if the suggestion got 10 good votes it's approved, otherwise it's not. Here is my code for it so far but what I'm having issue with is to start the ComponentCollector one time and then make it register the votes for each suggestion. this is the part of my code that I'm having trouble with
client.channels.cache.get("909420357285474334").send({ embeds:[embed], components:[row] })
const filter1 = m => m.customId === "Yes" && i.messageId === interaction.messageId
collector1 = interaction.channel.createMessageComponentCollector({filter: filter1, time: 86400000});
const filter2 = m => m.customId === "No" && i.messageId === interaction.messageId
collector2 = interaction.channel.createMessageComponentCollector({filter: filter2, time: 86400000});
if (interaction.customId === "Yes") {
collector1.on('collect', async i => {
client.logger("collector1 collected")
});
collector1.on('end', collected => {
client.logger(collected.size)
// if (collected.size < 10) {
// }
});
}
if (interaction.customId === "No") {
collector2.on('collect', async i => {
client.logger("collector2 collected")
});
collector2.on('end', collected => {
client.logger(collected.size)
// if (collected.size < 10) {
// }
});
}
your question is a little bit unclear but I think I get what your looking for, if you want to check if a user already has pressed a button you could add them to a Set() constructor, now you need to set a new Set() which you can define in your startup file like this:
client.alreadyPressed = new Set()
and when you've done that one possible way to do it in your suggestion code could be like this:
collector1.on('collect', async i => {
client.logger("collector1 collected")
if (client.alreadyPressed.has(interaction.user.id)) {
i.reply({ content: `You've already voted ${i.user.username}!`, ephemeral: true })
return;
} else {
i.reply({ content: `Thank you for your vote ${i.user.username}!`, ephemeral: true });
}
client.alreadyPressed.add(i.user.id)
});
collector1.on('end', collected => {
client.logger(collected.size)
// if (collected.size < 10) {
// }
});
collector2.on('collect', async i => {
client.logger("collector2 collected")
if (client.alreadyPressed.has(interaction.user.id)) {
i.reply({ content: `You've already voted ${i.user.username}!`, ephemeral: true })
return;
} else {
i.reply({ content: `Thank you for your vote ${i.user.username}!`, ephemeral: true });
}
client.alreadyPressed.add(i.user.id)
});
collector2.on('end', collected => {
client.logger(collected.size)
// if (collected.size < 10) {
// }
});
one problem with this is that they only can vote once in the whole channel which im not sure if that's what you wanted

Discord.js - Command that after 10 seconds if you not typing something it will tell you you run of time

I'm trying to do bot in js that when users do the command: !mugg #someone //someone is another user mention.
it will say: The Mugger is approaching ${user}, and then after 10 seconds if the user that got mugged won't type !killmugger he will get the message The Mugger mugged ${user} but if he does he will get the message: The mugger didn't mug ${user}.
This is what i tried to do: (I tried to play with if and roles)
bot.on("message", (message) => {
let args = message.content.substring(PREFIX.length).split(" ");
bot.user.setActivity("!mugg #someone");
switch (args[0]) {
case "mug":
const user = message.mentions.members.first();
let Role = message.guild.roles.cache.get("772195872133742634");
if (user) {
const member = message.guild.member(user);
if (member) {
message.reply(`The Mugger is approaching ${user}`);
user.roles.add("Role");
} else {
message.reply("That user isn't in this server.");
}
} else {
message.reply("You need to mention a user");
}
setTimeout(function () {
if (!message.mentions.roles.has("772195872133742634")) {
message.channel.send(`The Mugger mugged ${user}`);
user.roles.remove(Role);
}
}, 10000);
break;
case "killmugger":
const user1 = message.mentions.members.first();
let Role1 = message.guild.roles.cache.get("772195872133742634");
if (!message.mentions.roles.has("772195872133742634")) {
message.channel.send(`The Mugger not mugged ${user1}`);
user1.roles.remove(Role1);
}
}
});
Welcome,
Like #Saddy mentioned you can use awaitMessages, in the following way you don't need to verify if the user has the needed roles.
message.channel.send(`The Mugger mugged ${user}`);
//filter where m is message and the author needs to be the user you mentioned and the content needs to be equal to killmugger or you can change it to !killmugger
const filter = m => m.author.id == user!.id && m.content.toLowerCase() == "killmugger"
//awaitMessage function max: maximum messages, time: in milliseconds and the errors in this case we just need time to make sure that after
//10s it will return the message if he doesn't write killmuger in time
message.channel.awaitMessages(filter, { max: 1, time: 10000, errors: ['time'] }).then(m => {
return console.log("He got it in time")
}).catch(() => {
return message.channel.send(`The Mugger not mugged ${user1}`);
})

Declaration or statement expected. ts(1128) (11, 1)

Im quite new to coding and ive come across an issue which I'm not really sure what the issue is.
Ive been making my discord bot kick/ban command and its giving me the error "Declaration or statement expected. ts(1128) (11, 1)"
Here is my code helps appreciated.
CODE:
member.kick().then((member) => {
message.channel.send(`:wave: ${member.displayName} has been kicked`);
}).catch(() => {
if (!message.member.hasPermission(['KICK_MEMBERS', 'ADMINISTRATOR'])) {
message.reply("You cannot kick members");
} else if (member.hasPermission(['KICK_MEMBERS', 'BAN_MEMBERS', 'ADMINISTRATOR'])) {
message.reply("You cannont kick this member");
}
})
}
if (message.content.startsWith(`${prefix}ban`)) {
let member = message.mentions.members.first();
member.ban().then((member) => {
message.channel.send(`:wave: ${member.displayName} has been kicked`);
}).catch(() => {
if (!message.member.hasPermission(['BAN_MEMBERS', 'ADMINISTRATOR'])) {
message.reply("You cannot ban members");
} else if (member.hasPermission(['KICK_MEMBERS', 'BAN_MEMBERS', 'ADMINISTRATOR'])) {
message.reply("You cannont ban this member");
}
})
}
The reason why the code is throwing an error is because you can't check for permissions in a .catch block because catch blocks handle errors thrown by code. Instead, you should check for permissions before the command is executed. Additionally, you are checking that the user has all three permissions. You can use the JavaScript OR (||) to check that they have any of the permissions and the Administrator permission has ALL PERMISSIONS, eliminating the need to add it to the list. I've rewritten the code below
// You never need to check for ADMINISTRATOR, because it has all permissions
if (!message.member.hasPermission('KICK_MEMBERS')) {
message.reply("you cannot kick members");
} else if (member.hasPermission('KICK_MEMBERS' || 'BAN_MEMBERS')) {
message.reply("you cannot kick this member");
}
member.kick()
.then(member => message.channel.send(`:wave: ${member.displayName} has been kicked`))
.catch(e => console.log(e));
}
if (message.content.startsWith(`${prefix}ban`)) {
let member = message.mentions.members.first();
if (!message.member.hasPermission('BAN_MEMBERS')) {
message.reply("You cannot ban members")
} else if (member.hasPermission('KICK_MEMBERS' || 'BAN_MEMBERS')) {
message.reply("You cannont ban this member")
}
member.ban()
.then(member => message.channel.send(`:wave: ${member.displayName} has been banned`)
.catch(e => console.log(e));
}

Discord await messages timing out | Discord V12

I am stuck on a problem. When "Player 2" (player[1]) types !yes in the channel then reason it times out. I'm not sure what I am doing wrong. player[1] is defined as msg.mentions.members.first();
let answer = true;
if (players[1].user.bot) {
return;
} else {
answer = await msg.channel.awaitMessages((msg) => {
console.log(msg.author.id === players[1].id && msg.content === `!yes`) // returns true
if (msg.author.id === players[1].id && msg.content === `!yes`) {
console.log("Player has accepted") // The console does print "Player has accepted"
return true;
}
return false;
}, {maxMatches: 1, time: 30000, errors: ['time']})
.catch(() => {
console.log("Timed out!") // The console does print "Timed Out as well"
return false;
});
}
// if user refuses to play
if (!answer) {
return channel.send(`${players[1]} preferred to run away.`);
}
You have incorrect syntax for awaitMessages() - the first argument should be a CollectorFilter (see here), not a callback.
Consider using createMessageCollector() instead. It reads much more nicely than awaitMessages() and makes more sense than forcing async/await into a collector. Should look something like this:
const filter = m => (m.author.id===players[1].id && m.content==="!yes");
const collector = msg.channel.createMessageCollector(filter, {max: 1, time: 30000});
collector.on("collect", (m) => {
// Player has accepted... do whatever
});
collector.on("end", (reason) => {
if(reason === "time") {
// Ran out of time
}
});

(Discord.js) Bot does not respond

I've made a bot, and I have this purge function, it worked before i added the if that checked for the user's role. It gives me no errors and doesnt reply at all, no matter if i have the roles or not.
Code:
client.on("message", message => {
if (message.content.startsWith(prefix("purge"))) {
if (!message.guild.member.roles.cache.get('703727486009213048') || !message.guild.member.roles.cache.get('702847833241550859') || !message.guild.member.roles.cache.get('703727579328151562')) {
console.log('ssadd')
return message.reply('you can\'t use that command!')
};
const args = message.content.slice(prefix.length).split(" ");
const amount = args[1];
if (!amount) {
return message.reply("please specify the number of messages to purge!");
}
if (isNaN(amount * 1)) {
return message.reply(
"you'll need to specify a number, not whatever \"" +
`${amount}` +
'" is.'
);
}
message.delete();
message.channel.bulkDelete(amount * 1 + 1);
};
});
client.login(process.env.token);```
If it never replied to anything that either means the bot didn't log in or it never passed the first if condition. To check if the bot logged in, just do client.on("ready", () => console.log("ready"))
But I think it's more likely it just failed the first condition, is prefix a function?
prefix("purge") should be prefix + "purge".
There are some other flaws in your code too. Heres just the redo, if you need me to explain anything just lmk.
client.on("message", msg => {
if (msg.author.bot || !msg.content.startsWith(prefix)) return;
const args = msg.content.slice(1).split(" ");
//later on you should move to modules but for now this is fine ig
if (args[0] === "purge") {
//other flags here https://discord.js.org/#/docs/main/stable/class/Permissions?scrollTo=s-FLAGS
if (!msg.member.hasPermission("ADMINISTRATOR")) {
return msg.reply("you can't use that command!")
}
const amount = args[1] && parseInt(args[1]);
if (!amount) {
return msg.reply("please specify an integer of messages to purge!");
}
msg.delete();
msg.channel.bulkDelete(amount);
};
});
client.login(process.env.token);

Resources