As you read by the title I'm trying to make a clear command for my Discord bot, but I can't get it to work.
Here's a snippet:
client.on('message', message => {
if (message.content = "clear") {
let args = message.content.substring(prefix.length).split(" ");
var deleteCount = message.guild.members.cache.get(args[1]);
if (message.member.hasPermission("MANAGE_MESSAGES")) {
const deleteCount = args[2];
const fetched = ({
limit: deleteCount
});
message.delete(fetched)
try {
} catch (error) {
}(error => message.reply(`Couldn't delete messages because of: ${error}`));
if (!deleteCount || deleteCount < 2 || deleteCount > 100)
return message.reply("Please provide a number between 2 and 100 for the number of messages to delete");
message.channel.send('Successfully deleted ' + `${deleteCount}` + 'messages!');
}
}
});
Also, don't ask me what I'm doing and why I copied some stuff from other people trying to make it but the code was outdated.
Can someone help me?
client.on("message", message => {
if (message.content.indexOf(prefix) !== 0) {return false};
const arguments = message.content.slice(prefix.length).trim().split(/ +/g);
const command = arguments.shift().toLowerCase();
if (command == "clear") {
if (!message.member.hasPermission("MANAGE_MESSAGES")) return message.channel.send("You are not allowed to use this command.");
if (!arguments[0]) return message.channel.send("Please provide a number between 2 and 100.")
if (arguments[0] < 2 || arguments[0] > 100) return message.channel.send("Please provide a number between 2 and 100.")
message.channel.bulkDelete(arguments[0]).then(messages => {
message.channel.send(`Deleted ${messages.size} messages.`);
}).catch(e => console.log(e));
};
});
Related
I am trying to make a Discord.js giveaway command that send an embed, save it to the variable embedSent then collect the reactions after the TimeOut with the reactions.get() method, but I keep getting the error TypeError: embedSent.reactions.get is not a function Here is the part of my code :
var embed = new Discord.MessageEmbed();
embed.setColor(0x3333ff);
embed.setTitle("Nouveau Giveaway !");
embed.setDescription("**" + item + "**");
embed.addField(`DurΓ©e : `, ms(ms(time), {
long: true
}), true);
embed.setFooter("RΓ©agissez Γ ce message avec π pour participer !");
var embedSent = await message.channel.send(embed);
embedSent.react("π");
setTimeout(function () {
var peopleReacted = embedSent.reactions.get("π").users.filter(user => user.id !== client.user.id).array()
}, time);
Ok, after almost 2 months, I finally figured it out. The full, working command (DiscordJS v12) :
if (command == "giveaway") {
// !giveaway {time s/m/d} {item}
const messageArray = message.content.split(" ");
if (!message.member.hasPermission(["ADMINISTRATOR"])) return message.channel.send("You don't have enough permissions to start a giveaway !")
var item = "";
var time;
var winnerCount;
for (var i = 1; i < args.length; i++) {
item += (args[i] + " ");
}
time = args[0];
if (!time) {
return message.channel.send(`Invalid duration provided`);
}
if (!item) {
item = "No title"
}
var embed = new Discord.MessageEmbed();
embed.setColor(0x3333ff);
embed.setTitle("New Giveaway !");
embed.setDescription("**" + item + "**");
embed.addField(`Duration : `, ms(ms(time), {
long: true
}), true);
embed.setFooter("React to this message with π to participate !");
var embedSent = await message.channel.send(embed);
embedSent.react("π");
setTimeout(async () => {
try{
const peopleReactedBot = await embedSent.reactions.cache.get("π").users.fetch();
var peopleReacted = peopleReactedBot.array().filter(u => u.id !== client.user.id);
}catch(e){
return message.channel.send(`An unknown error happened during the draw of the giveaway **${item}** : `+"`"+e+"`")
}
var winner;
if (peopleReacted.length <= 0) {
return message.channel.send(`Not enough participants to execute the draw of the giveaway **${item}** :(`);
} else {
var index = Math.floor(Math.random() * peopleReacted.length);
winner = peopleReacted[index];
}
if (!winner) {
message.channel.send(`An unknown error happened during the draw of the giveaway **${item}**`);
} else {
console.log(`Giveaway ${item} won by ${winner.toString()}`)
message.channel.send(`π **${winner.toString()}** has won the giveaway **${item}** ! Congratulations ! π`);
}
}, ms(time));
}
Hope it helped some !
I guess this giveaway command works for me - Discord.js V13
don't forget to have npm i ms installed if you haven't already
const { Client, Intents, CommandInteraction, ReactionUserManager } = require('discord.js');
const INTENTS = new Intents(32767); // 32767 == full intents, calculated from intent calculator
const client = new Client({
intents: INTENTS
});
const Discord = require('discord.js');
const ms = require('ms') // make sure package ms is downloaded in console, to do this, simply type: npm i ms in your terminal
// https://www.npmjs.com/package/ms
client.once("ready" , () => {
console.log("I am online!")
});
client.on('messageCreate', async message => {
const prefix = "!" // this can be any prefix you want
let args = message.content.substring(prefix.length).split(" ")
// COMMAND FORMAT: !startgiveaway {duration} {winners} {#channel} {prize}
// E.g. !startgiveaway 24h 3w #giveaways Free Discord Nitro
if ((message.content.startsWith(`${prefix}startgiveaway`))) { // this condition can be changed to any command you'd like, e.g. `${prefix}gstart`
if (message.member.roles.cache.some(role => (role.name === 'Giveaway') )) { // user must have a role named Giveaway to start giveaway
let duration = args[1];
let winnerCount = args[2];
if (!duration)
return message.channel.send('Please provide a duration for the giveaway!\nThe abbreviations for units of time are: `d (days), h (hours), m (minutes), s (seconds)`');
if (
!args[1].endsWith("d") &&
!args[1].endsWith("h") &&
!args[1].endsWith("m") &&
!args[1].endsWith("s")
)
return message.channel.send('Please provide a duration for the giveaway!\nThe abbreviations for units of time are: `d (days), h (hours), m (minutes), s (seconds)`');
if (!winnerCount) return message.channel.send('Please provide the number of winners for the giveaway! E.g. `1w`')
if (isNaN(args[2].toString().slice(0, -1)) || !args[2].endsWith("w")) // if args[2]/winnerCount is not a number (even after removing end 'w') or args[2] does not end with 'w', condition returns:
return message.channel.send('Please provide the number of winners for the giveaway! E.g. `3w`');
if ((args[2].toString().slice(0, -1)) <= 0)
return message.channel.send('The number of winners cannot be less than 1!');
let giveawayChannel = message.mentions.channels.first();
if (!giveawayChannel || !args[3]) return message.channel.send("Please provide a valid channel to start the giveaway!")
let prize = args.slice(4).join(" ");
if (!prize) return message.channel.send('Please provide a prize to start the giveaway!');
let startGiveawayEmbed = new Discord.MessageEmbed()
.setTitle("π GIVEAWAY π")
.setDescription(`${prize}\n\nReact with π to participate in the giveaway!\nWinners: **${winnerCount.toString().slice(0, -1)}**\nTime Remaining: **${duration}**\nHosted By: **${message.author}**`)
.setColor('#FFFFFF')
.setTimestamp(Date.now() + ms(args[1])) // Displays time at which the giveaway will end
.setFooter("Giveaway ends");
let embedGiveawayHandle = await giveawayChannel.send({embeds: [startGiveawayEmbed]})
embedGiveawayHandle.react("π").catch(console.error);
setTimeout(() => {
if (embedGiveawayHandle.reactions.cache.get("π").count <= 1) {
return giveawayChannel.send("Nobody joined the giveaway :(")
}
if (embedGiveawayHandle.reactions.cache.get("π").count <= winnerCount.toString().slice(0, -1)) { // this if-statement can be removed
return giveawayChannel.send("There's not enough people in the giveaway to satisfy the number of winners!")
}
let winner = embedGiveawayHandle.reactions.cache.get("π").users.cache.filter((users) => !users.bot).random(winnerCount.toString().slice(0, -1));
const endedEmbedGiveaway = new Discord.MessageEmbed()
.setTitle("π GIVEAWAY π")
.setDescription(`${prize}\n\nWinner(s): ${winner}\nHosted By: **${message.author}**\nWinners: **${winnerCount.toString().slice(0, -1)}**\nParticipants: **${embedGiveawayHandle.reactions.cache.get("π").count - 1}**\nDuration: **${duration}**`)
.setColor('#FFFFFF')
.setTimestamp(Date.now() + ms(args[1])) // Displays time at which the giveaway ended
.setFooter("Giveaway ended");
embedGiveawayHandle.edit({embeds:[endedEmbedGiveaway]}); // edits original giveaway message to show that the giveaway ended successfully
const congratsEmbedGiveaway = new Discord.MessageEmbed()
.setDescription(`π₯³ Congratulations ${winner}! You just won **${prize}**!`)
.setColor('#FFFFFF')
giveawayChannel.send({embeds: [congratsEmbedGiveaway]}).catch(console.error);
}, ms(args[1]));
} // end "Giveaway" role condition
}
})
client.login('INSERT YOUR BOT TOKEN HERE');
So im trying to make a sort of pokemon catching bot just for fun and to test my skill, I've invited my friend to help me. We're trying to make a random spawn and a catching mechanism. The catching mechaninism didn't really work well since it detect the user input before the embed not after the embed which is impossible to catch. Any help will be much appreciate.
bot.on("message", async message => {
const args = message.content
.slice(prefix.length)
.trim()
.split(/ +/g);
let r = message.content.slice(bot.prefix.length+6)
let dex = Math.floor((Math.random() * 921) + 1);
let random = Math.floor((Math.random() * 5) + 1);
if (message.author.bot) return;
if (!message.content.startsWith(prefix)) {
if(random===5){
const options = {
url: `https://pokeapi.co/api/v2/pokemon/${dex}`,
json: true
}
get(options).then(body => {
let Embed = new MessageEmbed()
.setTitle("A Wild pokemon has appeared")
.setDescription(`Quick, catch that pokemon!`)
.setThumbnail(body.sprites.front_default)
.setFooter(body.name)
.setColor("#00eaff")
message.channel.send(Embed);
})
get(options).then(body => {
if(message.content==(body.name)){
message.reply("You just caught a " + body.name);
}
else {
message.reply("Not that one!");
}
})
}
}
It is not impossible to catch. You can easily achieve this by using awaitMessages()
bot.on("message", async message => {
const args = message.content
.slice(prefix.length)
.trim()
.split(/ +/g);
let r = message.content.slice(bot.prefix.length + 6)
let dex = Math.floor((Math.random() * 921) + 1);
let random = Math.floor((Math.random() * 5) + 1);
if (message.author.bot) return;
if (!message.content.startsWith(prefix)) {
if (random === 5) {
const options = {
url: `https://pokeapi.co/api/v2/pokemon/${dex}`,
json: true
}
get(options).then(async body => {
let Embed = new MessageEmbed()
.setTitle("A Wild pokemon has appeared")
.setDescription(`Quick, catch that pokemon!`)
.setThumbnail(body.sprites.front_default)
.setFooter(body.name)
.setColor("#00eaff")
const msg = await message.channel.send(Embed);
const filter = m => m.author.id === message.author.id
msg.channel.awaitMessages(filter, { max: 1, time: 60000, errors: ['time'] }) // 1 minute timer & max of 1 attempt at answering
.then(collected => {
get(options).then(body => {
if (collected.first().content == (body.name)) {
message.reply("You just caught a " + body.name);
}
else {
message.reply("Not that one!");
}
})
})
.catch(() => message.reply('you did not guess in time!'));
})
}
}
So I'm currently making a discord bot so whenever someone types !true #USER [Location] it will DM the #USER a message, add a role and then nickname the user to [Location] with the following code :
const mention = message.mentions.members.first();
msg = message.content.toLowerCase();
if (msg.startsWith(prefix)){
if(message.channel.id === '12345'){
if (msg.startsWith (prefix + "true")){
if(!message.member.hasPermission("MANAGE_NICKNAMES")) return message.reply("You have no permission!");
if (mention == null) { return; }
let args = message.content.split(" ").slice(2);
if ((mention.displayName + " " + args.join(" ")).length > 32) return message.channel.send("The nickname exceeds 32 characters")
if(mention.roles.cache.has('1234567890')){
message.reply("User is already accepted.")
} else {
mention.roles.add('1234567890').then(() => mention.setNickname(mention.displayName+" "+args.join(' ')))
.catch((e) => {
console.log('handle error here: ', e.message)
})
}
}}}
However, most of the time it will return with Cannot read property 'first' of null and it won't change the user's nickname (only roles and DM). Is there anything wrong with my code? Thanks.
const mention = message.mentions.members.first();
In the above code, message.mentions.members is null so you can't access a property (here first) in a null object.
The culprit is probably somewhere you set members property, not the code you provided here. do some debugging and console.log and you'll fix the issue.
You got error because you can`t get first of null. Better check mention in a command, like this.
if (msg.startsWith(prefix)) {
if (message.channel.id === '12345') {
if (msg.startsWith(prefix + 'true')) {
if (args.length < 0) return message.reply('PLS mention a member or write his ID');
const mention = message.mentions.members.first() || message.guild.members.cache.get(args[0]);
if (!mention) return message.reply('Can`t find a member');
msg = message.content.toLowerCase();
if (!message.member.hasPermission('MANAGE_NICKNAMES')) return message.reply('You have no permission!');
if (mention == null) {
return;
}
let args = message.content.split(' ').slice(2);
if ((mention.displayName + ' ' + args.join(' ')).length > 32) return message.channel.send('The nickname exceeds 32 characters');
if (mention.roles.cache.has('1234567890')) {
message.reply('User is already accepted.');
} else {
mention.roles
.add('1234567890')
.then(() => mention.setNickname(mention.displayName + ' ' + args.join(' ')))
.catch(e => {
console.log('handle error here: ', e.message);
});
}
}
}
}
Actually, i try to create a bot with discord.js and i try to do a help command.
i don't understand why my loop do this (i know it's not a good way for this)
let i = 0;
const embed = new RichEmbed();
if (args.length < 1) {
embed.setColor('#5B4DCA');
while (i < list_groups.length) {
let x = 0;
embed.setTitle(`${list_groups[i]}`)
while (x < groups.length) {
if (groups[x] === list_groups[i]) {
embed.addField('test1', 'test2')
}
x++;
}
message.channel.send(embed)
i++;
}
}
"ModΓ©rations" is supposed to display one command, "level & rank" too, "Outils" 4 command and "Sondage" too
enter image description here
I think you solutuion its not right way. If you will have more then 10 groups bot will spam commands list. The 1 way to do it its display all categories list if args.length===0, if args !==0 you try to find all commands in this category. To discord embed you can add only 18 fields, so if you have more then 18 command in categroy you will get api error. So you need spliced commands to pages.
This code will display all categories if args.length === 0, or command groups not fined.
If group fined bot send embed message with command in group (max 10), and react message if pages more then 1, so user can change page with reaction.
const {Discord,RichEmbed} = require('discord.js');
const {prefix,token,classic_roles} = require('../config.json');
const logs = require('../logs/logs');
module.exports.run = async (bot, message, args) => {
if(args.length === 0) {
//Show user all allowed groups commands
let commandCategories = bot.commands.map(command => `!help ${command.help.groups}`).filter(onlyUnique).join('\n') //find all categories and get onlyUnique
let helpMessage = `**The list of command groups:**\n\n ${commandCategories}`
let Embed = new Discord.RichEmbed()
.setAuthor(message.author.tag, message.author.displayAvatarUrl)
.setDescription(helpMessage)
.setColor('#e0c40b')
message.channel.send(Embed)
} else {
//try find required group
let commandsInCategory = bot.commands.filter(command => command.help.groups === args.join(' ').toLowerCase())
if(commandsInCategory.size === 0) {
// if no group find, then display user list of groups
let commandCategories = bot.commands.map(command => `!help ${command.help.groups}`).filter(onlyUnique).join('\n')
let helpMessage = `**For get command list use**\n\n ${commandCategories}`
let Embed = new Discord.RichEmbed()
.setAuthor(message.author.tag, message.author.displayAvatarUrl)
.setDescription(helpMessage)
.setColor('#e0c40b')
message.channel.send(Embed)
return
}
let counter = 0
let allCommands = []
commandsInCategory.map(command => {
allCommands.push({
name: command.help.name,
description: command.help.description
})
})
allCommands = generateHelpArray(allCommands)
//for better display, we will display only 10 in page
let Embed = new Discord.RichEmbed()
Embed.setAuthor(message.author.tag, message.author.displayAvatarUrl)
Embed.setDescription(`The list command of group : **${args.join(' ')}**`)
allCommands[counter].map(command => {
Embed.addField(`**${command.name}**`,`${command.description}`,false)
})
Embed.setColor('#E8DB0E')
Embed.setFooter(`Page ${counter+1} of ${allCommands.length}`)
message.channel.send(Embed).then(msg => {
if(allCommands.length < 2) return
// To change page we will use react emoji
msg.react(`βοΈ`).then(() => msg.react('βΆοΈ'))
const filter = (reaction, user) => {
return [`βοΈ`, 'βΆοΈ'].includes(reaction.emoji.name) && user.id === message.author.id;
};
const collector = msg.createReactionCollector(filter, { max:50, time: 60000 });
collector.on('collect', (reaction, reactionCollector) => {
if (reaction.emoji.name === `βοΈ`) {
//Change counter, remove user reaction and call change embed function
reaction.remove(message.author.id)
counter-=1
if(counter < 0) counter = 0
editEmbed(message, msg, counter, args.join(' '), allCommands)
} else if (reaction.emoji.name === `βΆοΈ`) {
//Change counter, remove user reaction and call change embed function
reaction.remove(message.author.id)
counter+=1
if(counter >= allCommands.length) counter = allCommands.length -1
editEmbed(message, msg, counter, args.join(' '), allCommands)
}
});
collector.on('end', (reaction, reactionCollector) => {
msg.clearReactions()
})
})
}
}
module.exports.help = {
name: "help",
description: "Vous permet d'obtenir toutes les commandes accessibles pour vos rΓ΄les.",
access: "Public",
groups: "Outils"
}
const onlyUnique = (value, index, self) => {
return self.indexOf(value) === index;
}
const editEmbed = (message, msg, counter, category, allCommands) => {
let Embed = new Discord.RichEmbed()
Embed.setAuthor(message.author.tag, message.author.displayAvatarURL)
Embed.setDescription(`The list command of group : **${category}**`)
Embed.setColor('#E8DB0E')
allCommands[counter].map(command => {
Embed.addField(`**${command.name}**`,`${command.description}`,false)
})
Embed.setFooter(`Page ${counter+1} of ${allCommands.length}`)
msg.edit(Embed)
}
const generateHelpArray = (arr) => {
let newArray = [];
for (let i = 0; i < arr.length; i+=10) {
newArray.push(arr.slice(i,i+10))
}
return newArray
}
how to make sure that the role when pressing the bell is give only in a certain channel? The code is below. Can also make that only administrators have the right to issue reactions with a bell that will issue a role. Help, pls.
var emojiname = ["π"];
var rolename=["π Notifications"];
client.on('message', msg => {
if(msg.content.startsWith("reaction" && message.channel.name.toLowerCase() === 'information')){
if(!msg.channel.guild) return;
for(let n in emojiname){
var emoji =[msg.guild.emojis.find(r => r.name == emojiname[n])];
for(let i in emoji){
msg.react(emoji[i]);
}
}
}
});
client.on("messageReactionAdd",(reaction,user)=>{
if(!user) return;
if(user.bot)return;
if(!reaction.message.channel.guild) return;
for(let n in emojiname){
if(reaction.emoji.name == emojiname[n]){
let role = reaction.message.guild.roles.find(r => r.name == rolename[n]);
reaction.message.guild.member(user).addRole(role).catch(console.error);
}
}
});
client.on("messageReactionRemove",(reaction,user)=>{
if(!user) return;
if(user.bot)return;
if(!reaction.message.channel.guild) return;
for(let n in emojiname){
if(reaction.emoji.name == emojiname[n]){
let role = reaction.message.guild.roles.find(r => r.name == rolename[n]);
reaction.message.guild.member(user).removeRole(role).catch(console.error);
}
}
});
Here it is.
First, be aware that there is 2 types of discord emojis. The unicode one, common emoji, like β‘. And the guild emoji, that you add to a server.
The first one are represented only by the unicode name, while the second have an id and others difference (see Emoji and Message Reaction)
That being said, I used the name of the emoji in the emojiname array. I then changed a little bit the code to accept both unicode and guild emojis.
The rest of the code was good. Just be sure to use === instead of == except if you realy want to accept "falsy" term.
demo gif
// β‘ is an ascii emoji
// lina is a guild emoji
var emojiname = ['β‘', 'lina'];
var rolename=["β‘ Notifications", "lina supporter"];
client.on('message', msg => {
if(msg.content.startsWith('reaction') && (msg.channel.name.toLowerCase() === 'information')) {
for (let n in emojiname){
let emoji = msg.guild.emojis.find(r => r.name === emojiname[n]);
if (emoji === null) {
emoji = emojiname[n];
}
msg.react(emoji);
}
}
});
client.on("messageReactionAdd",(reaction,user)=>{
if (!user) { return; }
if (user.bot) { return; }
if (reaction.message.channel.name.toLowerCase() !== 'information') { return; }
for(let n in emojiname){
if(reaction.emoji.name === emojiname[n]){
let role = reaction.message.guild.roles.find(r => r.name === rolename[n]);
reaction.message.guild.member(user).addRole(role).catch(console.error);
}
}
});
client.on("messageReactionRemove",(reaction,user)=>{
if(!user) { return; }
if(user.bot) { return; }
if (reaction.message.channel.name.toLowerCase() !== 'information') { return; }
for(let n in emojiname){
if(reaction.emoji.name === emojiname[n]){
let role = reaction.message.guild.roles.find(r => r.name == rolename[n]);
reaction.message.guild.member(user).removeRole(role).catch(console.error);
}
}
});