Discord.js command handler problems - discord.js

I've been trying to fix a command handler for 3 hours now, but anytime I try to add a custom command nothing happens. It loads the command, but when the command is run it does nothing. Here's some code:
index.js:
const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js'));
for (const file of commandFiles) {
const command = require(`./commands/${file}`);
console.log(`[LOG] Loaded command ${file}`);
client.commands.set(command.name, command);
}
commands/kick.js:
const fs = require('fs');
var moment = require('moment');
var logger = fs.createWriteStream(`./logs/${moment().format('MM-DD-YYYY')}.log`, {
flags: 'a'
});
module.exports = {
name: "kick",
category: "moderation",
description: "Kicks the mentioned user.",
usage: "<imputs>",
run: (client, message, args) => {
let reason = args.slice(1).join(' ');
let user = message.mentions.users.first();
if (message.mentions.users.size < 1) return message.reply('You must mention someone to kick them.').then(msg => { msg.delete(10000) }).catch(console.error);
if (user.id === message.author.id) return message.reply("You cannot kick yourself.").then(msg => { msg.delete(10000) });
if (user.id === client.user.id) return message.reply("You cannot kick me.").then(msg => { msg.delete(10000) });
if (!message.member.hasPermission("KICK_MEMBERS")) return message.reply("You don't have the **Kick Members** permission!").then(msg => { msg.delete(10000) });
if (reason.length < 1) reason = 'No reason supplied';
if (!message.guild.member(user).kickable) return message.reply('I could not kick that member').then(msg => { msg.delete(10000) });
message.delete();
message.guild.member(user).kick();
const embed = new Discord.RichEmbed()
.setColor(0x0000FF)
.setTimestamp()
.addField('Action:', 'Kick')
.addField('User:', `${user.username}#${user.discriminator} (${user.id})`)
.addField('Moderator:', `${message.author.username}#${message.author.discriminator}`)
.addField('Reason', reason)
.setFooter(`© NetSync by Towncraft Developers`);
let logchannel = message.guild.channels.find('name', 'logs');
if (!logchannel){
message.channel.send(`Successfully kicked ${user.username}#${user.discriminator}.`).then(msg => { msg.delete(10000) });
logger.log(`[LOG] [KICK] ${user.username}#${user.discriminator} (${user.id}) was kicked by ${message.author.username}#${message.author.discriminator}.`);
}else{
message.channel.send(`Successfully kicked ${user.username}#${user.discriminator}. I\'ve also logged the kick in <#${logchannel.id}>.`).then(msg => { msg.delete(10000) });
client.channels.get(logchannel.id).send({embed});
}
if(user.bot) return;
return message.mentions.users.first().send({embed}).catch(e =>{
if(e) return
});
}
}
Like I said, been trying to do this for 3 hours now, and I'm stumped. If someone could tell me what I did wrong that'd be awesome, thanks.

You need execute command in you main.js file on bot.on('message' block.
Like this:
client.on('message', message => {
if (message.channel.type === "dm") return;
let prefix = '!'
let messageArray = message.content.split(" ");
let cmd = messageArray[0];
let args = messageArray.slice(1);
if (!message.content.startsWith(prefix)) return;
let commandfile = client.commands.get(cmd.slice(prefix.length));
if (commandfile) commandfile.run(client, message, args, botconfig);
})

Related

How do give only person that write i an specific discord channel xp

Here is the Code. I only want to give members xp when they write in a specific discord channel. How can i do that?
client.on('messageCreate', async message => {
if (!message.guild) return;
if (message.author.bot) return;
const prefix = '?'
const args = message.content.slice(prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
const user = await Levels.fetch(message.author.id, message.guild.id);
if (!message.guild) return;
if (message.author.bot) return;
const randomAmountOfXp = Math.floor(Math.random() * 29) + 1; // Min 1, Max 30
const hasLeveledUp = await Levels.appendXp(message.author.id, message.guild.id, randomAmountOfXp);
if (hasLeveledUp) {
const user = await Levels.fetch(message.author.id, message.guild.id);
message.channel.send({ content: `${message.author}, congratulations! You have leveled up to **${user.level}**. :tada:` });
}
if (user.level === 5) {
message.member.roles.add("1022876270754791445");
} else if (user.level === 10) {
message.member.roles.add("1022876505132499054");
}else if (user.level === 10) {
message.member.roles.remove("1022876270754791445");
}
});
You can check message's channel id when event triggered.
if (message.channel.id !== "CHANNEL_ID") return;

Making only admins execute commands

The problem is that I couldn't figure out a way to make this command only accessible by admins. I've tried using if statements, however, I failed. message. I am not sure if member. roles. cache. has( ' 732524984777572363 ' ) would allow members with the role ID 732524984777572363 to execute it since there's already an if statement.
const Discord = require('discord.js');
const fs = require('fs');
const cooldown = new Set();
module.exports.run = async (client, msg, args, config) => {
if(cooldown.has(msg.author.id)) {
msg.reply(`You need to wait ${config.COOLDOWN} minutes to use this command again!`)
.then((m) => {
msg.delete();
setTimeout(() => {
m.delete();
}, 5000);
});
} else {
fs.readFile('./accounts/crunchy.txt', 'utf8', function(err, data) {
if (err) throw err;
data = data + '';
var lines = data.split('\n');
let account = lines[Math.floor(Math.random() * 1)];
fs.writeFile('./accounts/crunchy.txt', lines.slice(1).join('\n'), function(err) {
if(err) throw err;
});
let embed = new Discord.RichEmbed()
.addField('Rate Us Here | قيمنا هنا ', `<#915***********80>`)
.addField('CrunchyRoll Account',`\n**${account}**`)
.setThumbnail('**************************')
.setColor("#363940")
.setFooter('Bot made by ******')
.setTimestamp();
msg.author.send(embed);
msg.reply('I\'ve sent you the account! Please check your DM!')
.then(m => {
setTimeout(() => {
m.delete();
}, 900000);
});
cooldown.add(msg.author.id);
setTimeout(() => {
cooldown.delete(msg.author.id);
}, config.COOLDOWN * 60 * 1000);
});
}
};
module.exports.help = {
name: `CrunchyRoll`,
description: `Sends you a CrunchyRoll account!`
};```
Simply adding a role check and a server check will prevent any issues!
The first line would be:
if(!msg.guild) return;
This line makes sure the user is running the command in a server(guild), this prevents a member role from being undefined or null.
The second line would be:
if(!msg.author.roles.cache.has('ROLE_ID_HERE')) return;
This prevents a user from running a command if they do not have a specific role.
The final code would be:
if(!msg.guild) return;
if(!msg.author.roles.cache.has('ROLE_ID_HERE')) return;
You will need to add this to the top of your code in order for it to work as you'd like.
const Discord = require('discord.js');
const fs = require('fs');
const cooldown = new Set();
module.exports.run = async (client, msg, args, config) => {
if(!msg.guild) return;
if(!msg.member.roles.cache.has('ROLE_ID_HERE')) return;
if(cooldown.has(msg.author.id)) {
msg.reply(`You need to wait ${config.COOLDOWN} minutes to use this command again!`)
.then((m) => {
msg.delete();
setTimeout(() => {
m.delete();
}, 5000);
});
} else {
fs.readFile('./accounts/crunchy.txt', 'utf8', function(err, data) {
if (err) throw err;
data = data + '';
var lines = data.split('\n');
let account = lines[Math.floor(Math.random() * 1)];
fs.writeFile('./accounts/crunchy.txt', lines.slice(1).join('\n'), function(err) {
if(err) throw err;
});
let embed = new Discord.RichEmbed()
.addField('Rate Us Here | قيمنا هنا ', `<#915***********80>`)
.addField('CrunchyRoll Account',`\n**${account}**`)
.setThumbnail('**************************')
.setColor("#363940")
.setFooter('Bot made by ******')
.setTimestamp();
msg.author.send(embed);
msg.reply('I\'ve sent you the account! Please check your DM!')
.then(m => {
setTimeout(() => {
m.delete();
}, 900000);
});
cooldown.add(msg.author.id);
setTimeout(() => {
cooldown.delete(msg.author.id);
}, config.COOLDOWN * 60 * 1000);
});
}
};
module.exports.help = {
name: `CrunchyRoll`,
description: `Sends you a CrunchyRoll account!`
};

TypeError: Cannot read property 'toLowerCase' of undefined discord.js

I'm developing a discord.js moderation bot, but when I run it I get this error.
Here is the code:
var Discord = require('discord.js')
const fs = require("fs")
const { PREFIX } = require("../../config")
const db = require('quick.db')
const { stripIndents } = require("common-tags");
module.exports = {
config: {
name: "help",
description: "Help Menu",
usage: "1) m/help \n2) m/help [module name]\n3) m/help [command (name or alias)]",
example: "1) m/help\n2) m/help utility\n3) m/help ban",
aliases: ['h']
},
run: async (bot, message, args) => {
let prefix;
if (message.author.bot || message.channel.type === "dm") return;
try {
let fetched = await db.fetch(`prefix_${message.guild.id}`);
if (fetched == null) {
prefix = PREFIX
} else {
prefix = fetched
}
} catch (e) {
console.log(e)
};
if(message.content.toLowerCase() === `${prefix}help`){
var log = new Discord.MessageEmbed()
.setTitle("**Help Menu: Main**")
.setColor(`#d9d9d9`)
.addField(`**👑Moderation**`, `[ \`${prefix}help mod\` ]`, true)
.addField(`**⚙️Utility**`, `[ \`${prefix}help utility\` ]`, true)
message.channel.send(log);
}
else if(args[0].toLowerCase() === "mod") {
var commandArray = "1) Ban \n2) Kick\n3) Whois\n4) Unban\n5) Warn\n6) Mute\n7) Purge\n8) Slowmode \n9) Nick \n10) Roleinfo"
var commandA2 = "11) Rolememberinfo\n12) Setmodlog\n13) Disablemodlog\n14) Lock (Lock the channel)\n15) Unlock (Unlock the channel)\n16) Lockdown (Fully Lock the whole server. [FOR EMRGENCIES ONLY]) \n17) Hackban\\forceban <id>"
pageN1 = "**\n💠Commands: **\n`\`\`js\n" + commandArray + "\`\`\`";
pageN2 = "**\n💠Commands: **\n`\`\`js\n" + commandA2 + "\`\`\`";
let pages = [pageN1, pageN2]
let page = 1
var embed = new Discord.MessageEmbed()
.setTitle('**Help Menu: [Moderation]👑**')
.setColor("#d9d9d9") // Set the color
.setFooter(`Page ${page} of ${pages.length}`, bot.user.displayAvatarURL())
.setDescription(pages[page-1])
message.channel.send({embed}).then(msg => {
msg.react('⬅').then( r => {
msg.react('➡')
// Filters
const backwardsFilter = (reaction, user) => reaction.emoji.name === '⬅' && user.id === message.author.id
const forwardsFilter = (reaction, user) => reaction.emoji.name === '➡' && user.id === message.author.id
const backwards = msg.createReactionCollector(backwardsFilter, {timer: 6000})
const forwards = msg.createReactionCollector(forwardsFilter, {timer: 6000})
backwards.on('collect', (r, u) => {
if (page === 1) return r.users.remove(r.users.cache.filter(u => u === message.author).first())
page--
embed.setDescription(pages[page-1])
embed.setFooter(`Page ${page} of ${pages.length}`, bot.user.displayAvatarURL())
msg.edit(embed)
r.users.remove(r.users.cache.filter(u => u === message.author).first())
})
forwards.on('collect', (r, u) => {
if (page === pages.length) return r.users.remove(r.users.cache.filter(u => u === message.author).first())
page++
embed.setDescription(pages[page-1])
embed.setFooter(`Page ${page} of ${pages.length}`, bot.user.displayAvatarURL())
msg.edit(embed)
r.users.remove(r.users.cache.filter(u => u === message.author).first())
})
})
})
}
else if(args[0].toLowerCase() === "util") {
var embed = new Discord.MessageEmbed()
.setTitle('**Help Menu: [Utility]**')
.setColor("#d9d9d9") // Set the color
.setDescription("```js" + `1) Prefix [${prefix}help prefix for more info]\n 2) Help [${prefix}help for more info]` + "```")
} else {
const embed = new Discord.MessageEmbed()
.setColor("#d9d9d9")
.setAuthor(`${message.guild.me.displayName} Help`, message.guild.iconURL())
.setThumbnail(bot.user.displayAvatarURL())
let command = bot.commands.get(bot.aliases.get(args[0].toLowerCase()) || args[0].toLowerCase())
if (!command) return message.channel.send(embed.setTitle("**Invalid Command!**").setDescription(`**Do \`${prefix}help\` For the List Of the Commands!**`))
command = command.config
embed.setDescription(stripIndents`
** Command -** [ \`${command.name.slice(0, 1).toUpperCase() + command.name.slice(1)}\` ]\n
** Description -** [ \`${command.description || "No Description provided."}\` ]\n
** Usage -** [ \`${command.usage ? `\`${command.usage}\`` : "No Usage"}\` ]\n
** Examples -** [ \`${command.example ? `\`${command.example}\`` : "No Examples Found"}\` ]\n
** Aliases -** [ \`${command.aliases ? command.aliases.join(" , ") : "None."}\` ]`)
embed.setFooter(message.guild.name, message.guild.iconURL())
return message.channel.send(embed)
}
}
}
If someone could help with this issue it would be great because I don't know what to do. I already searched on internet but I still don't know what I need to do to solve this error. All this code is for help function, when someone calls -pks help the bot should show embed telling all his functions
Here is my index.js file:
const { Client, Collection } = require('discord.js');
const { PREFIX, TOKEN } = require('./config');
const bot = new Client({ disableMentions: 'everyone' });
const fs = require("fs");
const db = require('quick.db');
bot.commands = new Collection();
bot.aliases = new Collection();
["aliases", "commands"].forEach(x => bot[x] = new Collection());
["console", "command", "event"].forEach(x => require(`./handler/${x}`)(bot));
bot.categories = fs.readdirSync("./commands/");
["command"].forEach(handler => {
require(`./handler/${handler}`)(bot);
});
bot.on('message', async message => {
let prefix;
try {
let fetched = await db.fetch(`prefix_${message.guild.id}`);
if (fetched == null) {
prefix = PREFIX
} else {
prefix = fetched
}
} catch {
prefix = PREFIX
};
try {
if (message.mentions.has(bot.user.id) && !message.content.includes("#everyone") && !message.content.includes("#here")) {
message.channel.send(`\nMy prefix for \`${message.guild.name}\` is \`${prefix}\` Type \`${prefix}help\` for help`);
}
} catch {
return;
};
});
bot.login(TOKEN);

Random Meme Command (discord.js v12)

I'm trying to make a 'random meme' command for my Discord Bot. I'm new to working with APIs, but I've tried my best.
The problem is, when I type the command, nothing happens. There are no errors, but the bot doesn't send anything in discord.
This is my code:
if (command === "meme")
async (client, message, args) => {
const subReddits = ["dankmeme", "meme", "me_irl"];
const random = subReddits[Math.floor(Math.random() * subReddits.length)];
const img = await randomPuppy(random);
const embed = new Discord.MessageEmbed()
.setColor(16776960)
.setFooter("test")
.setImage(img)
.setTitle(`Random Meme requested by <#${message.author.tag}>`)
.setURL(`https://reddit.com/r/${random}`)
message.channel.send(embed);
}
Here Is One That Will Show Info About The Meme
if(command === "meme") {
const subReddits = ["dankmeme", "meme", "me_irl"];
const random = subReddits[Math.floor(Math.random() * subReddits.length)];
try {
const { body } = await snekfetch
.get('https://www.reddit.com/r/${random}.json?sort=top&t=week')
.query({ limit: 800 });
const allowed = message.channel.nsfw ? body.data.children : body.data.children.filter(post => !post.data.over_18);
if (!allowed.length) return message.channel.send('It seems we are out of memes');
const randomnumber = Math.floor(Math.random() * allowed.length)
const embed = new Discord.RichEmbed()
.setColor(0x00A2E8)
.setTitle(allowed[randomnumber].data.title)
.setDescription("Posted by: " + allowed[randomnumber].data.author)
.setImage(allowed[randomnumber].data.url)
.addField("Other info:", "Up votes: " + allowed[randomnumber].data.ups + " / Comments: " + allowed[randomnumber].data.num_comments)
.setFooter("r/" + random)
message.channel.send(embed)
} catch (err) {
return console.log(err);
}
}
Let Me Know If It Don't Work, But I Should
client.on('message', message => {
if (!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).trim().split(/ +/);
const command = args.shift().toLowerCase();
if (command === "meme") {
async (client, message, args) =>
const subReddits = ["dankmeme", "meme", "me_irl"];
const random = subReddits[Math.floor(Math.random() * subReddits.length)];
const img = await randomPuppy(random);
const embed = new Discord.MessageEmbed()
.setColor(16776960)
.setFooter("test")
.setImage(img)
.setTitle(`Random Meme requested by <#${message.author.tag}>`)
.setURL(`https://reddit.com/r/${random}`)
message.channel.send(embed);
}
});
This should work, not quite sure, haven't tested it. (You can put in a command handler your self)
if (command === "meme")
async (client, message, args) => {
const fetch = require('node-fetch');
let userAvatar = message.author.avatarURL({ format: "png", dynamic: true, size: 2048 }); // this is just the users icon, u can remove it if you want.
fetch(`https://meme-api.herokuapp.com/gimme`)
.then(res => res.json())
.then(async json => {
const embed = new MessageEmbed()
.setAuthor(`${json.title}`, `${userAvatar + "?size=2048"}`, `${json.postLink}`)
.setImage(`${json.url}`)
.setFooter(`👍${json.ups} | ${json.subreddit}`)
.setColor("RANDOM")
message.channel.send(embed).catch((error) => {
console.log("An error has occured on the \"meme\" command\n", error)
})
}
Here you go! I've tested this on my own command handler.

Prefix is changing

So in my config.json file I had put my prefix as "!". I was testing the bot in my friends server and the prefix was clashing with other bots. I changed it to ";". But now both the prefixs are functioning "!" and";". I saved all my files and restarted node too, but the commands are still responding to "!". Am I missing something?
The structure of my file system is -
1. index.js
2. config.json
3. commands folder (command files)
index.js
const Discord = require('discord.js');
const fs = require('fs');
const { prefix, token } = require('./config.json');
const profanity = require('profanities')
//console.log(profanity);
const client = new Discord.Client();
const cooldowns = new Discord.Collection();
client.commands = new Discord.Collection();
const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js')); //returns an array of all file anmes in a dir ['ping.js', beep.js, ....]; the filter is used to get only .js files.
const commandFiles_mod = fs.readdirSync('./commands/mod').filter(file => file.endsWith('.js')); //mod folder
const commandFiles_info = fs.readdirSync('./commands/info').filter(file => file.endsWith('.js')); //info folder
const commandFiles_extras = fs.readdirSync('./commands/extras').filter(file => file.endsWith('.js')); //
//file system
for (const file of commandFiles) {
const command = require(`./commands/${file}`);
// set a new item in the Collection
// with the key as the command name and the value as the exported module
client.commands.set(command.name, command); //set takes the file name and the path to the file. //command is the path to file and command.name is the name of the file
}
for (const file of commandFiles_info) {
const command1 = require(`./commands/info/${file}`);
client.commands.set(command1.name, command1);
}
for (const file of commandFiles_mod) {
const command2 = require(`./commands/mod/${file}`);
client.commands.set(command2.name, command2);
}
for (const file of commandFiles_extras) {
const command3 = require(`./commands/extras/${file}`);
client.commands.set(command3.name, command3);
}
client.once('ready', () => {
client.user.setActivity(`${prefix}help`)
console.log(`Hello! ${client.user.username}-bot is now online!`)
});
client.on('message', message => {
//command handling
if (message.content === 'galaxy-prefix') {
const prefix_embed = new Discord.MessageEmbed()
.setTitle('Prefix')
.setDescription(`Use this ahead of comamnds for usage: **${prefix}**`)
.setColor('RANDOM')
.setTimestamp()
message.channel.send(prefix_embed);
}
if (message.content.startsWith(prefix) || !message.author.bot || !message.channel.type === 'dm') { //edit here
const args = message.content.slice(prefix.length).split(/ +/); //caveats
//console.log(args);
const messageArray = message.content.split(/ +/);
//console.log(messageArray);
const cmd = args[1];
//console.log(cmd);
const commandName = args.shift().toLowerCase();
//console.log(commandName);
/*if (!message.content.startsWith(prefix) && !message.author.bot) {
const messageArray = message.content.split(" ");
console.log(messageArray);
}*/
/*for (i=0; i < profanity.length; i++) {
if (messageArray.includes(profanity[i])) {
message.delete();
break;
}
}*/
const command = client.commands.get(commandName) || client.commands.find(cmd => cmd.aliases && cmd.aliases.includes(commandName)); //aliases
if (!command) return;
if (command.guildOnly && message.channel.type !== 'text') {
return message.reply('I can\'t execute that command inside DMs!'); //cannot dm this command
}
if (command.args && !args.length) {
let reply = `You didn't provide any arguments, ${message.author}!`;
if (command.usage) {
reply += `\nThe proper usage would be: \`${prefix}${command.name} ${command.usage}\``; //usage check, in file as usage: '<...>'
}
return message.channel.send(reply);
}
if (!cooldowns.has(command.name)) { //cooldown
cooldowns.set(command.name, new Discord.Collection());
}
const now = Date.now();
//console.log(now);
const timestamps = cooldowns.get(command.name); // gets the collection for the triggered command
const cooldownAmount = (command.cooldown || 3) * 1000; //3 is default cooldown time, if cooldown isnt set in command files.
if (timestamps.has(message.author.id)) {
if (timestamps.has(message.author.id)) {
const expirationTime = timestamps.get(message.author.id) + cooldownAmount;
if (now < expirationTime) {
const timeLeft = (expirationTime - now) / 1000;
return message.reply(`please wait ${timeLeft.toFixed(1)} more second(s) before reusing the \`${command.name}\` command.`);
}
}
}
timestamps.set(message.author.id, now);
setTimeout(() => timestamps.delete(message.author.id), cooldownAmount);
try {
command.execute(client, message, args);
} catch (error) {
console.error(error);
message.reply('there was an error trying to execute that command!');
}
}
});
client.on('shardError', error => {
console.error('A websocket connection encountered an error:', error);
});
process.on('unhandledRejection', error => {
console.error('Unhandled promise rejection:', error);
});
client.login(token);
config.json
{
"token": " ................. ",
"prefix": ";"
}
Your bot will respond to anything actually...
if (message.content.startsWith(prefix) || !message.author.bot || !message.channel.type === 'dm')
This means your bot will run if the message starts with the prefix OR the sender is not a bot OR the channel type is DM. You should try using ? - .... They will probs work too.
To use an and you use && instead of ||

Resources