Command handler loading the files however not running them - discord.js

Hi (no expert by all means)
Working with discord.js setting up a command handler, I know the files are being loaded however when I am running them they don't work (run).
Start of my index file
const { prefix, token } = require("./settings/config.json");
const Discord = require("discord.js");
const fs = require("fs");
const bot = new Discord.Client();
bot.commands = new Discord.Collection();
const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js'));
for (const file of commandFiles) {
const command = require(`./commands/${file}`);
commandFiles.run(bot, message, args);
console.log(`${file} loaded!`);
bot.commands.set(command.name, command);
}
One of the files in the commands folder (which is loads but doesn't run):
const Discord = require("discord.js");
const client = new Discord.Client();
let servericon = ('https://i.imgur.com/foKcByT.png');
module.exports.run = async (bot, message, args) => {
// No Perms Embed
const noPermsErrEmbed = new Discord.MessageEmbed()
.setColor('FF6961')
.setTitle("**error!**")
.setDescription("This command can only be used by staff!")
.setTimestamp()
.setFooter(message.author.tag + " | Peace Keeper", message.author.displayAvatarURL({dynamic: true, size: 1024}))
if(!message.member.hasPermission("MANAGE_MESSAGES")) return message.reply(noPermsErrEmbed).then(msg => msg.delete(5000));
let ancArgs = args.slice(0).join(" ").split('|');
if (args.length >= 3) {
message.delete().then(() => {
const ancEmbed = new Discord.MessageEmbed()
.setColor('#ABDFF2')
.setTitle("** " + ancArgs[0] + " **")
.setDescription(ancArgs[1])
.setTimestamp()
.setThumbnail(servericon)
.setFooter(message.author.tag + " | Peace Keeper", message.author.displayAvatarURL({dynamic: true, size: 1024}))
message.channel.send(ancEmbed);
})
} else {
message.delete().catch();
const ancErrEmbed = new Discord.MessageEmbed()
.setColor('FF6961')
.setTitle("**error!**")
.setDescription("use the correct format: !special-anc <title> | <message>")
.setTimestamp()
.setFooter(message.author.tag + " | Peace Keeper", message.author.displayAvatarURL({dynamic: true, size: 1024}))
message.reply(ancErrEmbed).then(msg => msg.delete({timeout: 10000}));
}
}
module.exports.help = {
name: "special-anc"
}

It won't run the commands because you used the wrong variable to call the run part:
commandFiles.run(bot, message, args);
It should be:
command.run(bot, message, args);
commandFiles is just a list of files so it has nothing to do directly with your commands.
However, there's something wrong with your code.
This is your module.exports object (inside the command variable):
{
run: [AsyncFunction],
help: { name: String }
}
When you use this line bot.commands.set(command.name, command);, it won't work because there's no name property, it should be help.name.

Related

discord.js { split: true } will not split

I try to split more than 2000 chars from a file, but the
{ split: true }
seem not to work, any here know what I'm doing wrong.. here my full code:
const Discord = require("discord.js");
const fs = require('fs');
const date = require('date-and-time');
const readLastLines = require('read-last-lines');
const bot = new Discord.Client({ intents: ["GUILDS", "GUILD_MESSAGES"] });
const now = new Date();
var settings = require("./settings.js");
var channel = require("./settings.js");
var playlist = "text.txt"
bot.on("ready", function () {
console.log("ready");
// console.log("Stream ready - Starting live Playlist...." + date.format(now, 'DD/MM/YYYY'));
// bot.channels.cache.get(settings.discord_channel).send("Stream ready - Starting live Playlist...." + date.format(now, 'DD/MM/YYYY'));
});
fs.watchFile(playlist, (eventType, filename) => {
readLastLines.read(playlist, 255)
.then((lines) => bot.channels.cache.get(settings.discord_channel).send(lines, { split: true }));
});
bot.login(settings.bot_token);
The split option for MessageOptions was removed in v13. You now have to import the Util class and use it's splitMessage() method.
You'll need to split the message into chunks and then asynchronously loop through each chunk, awaiting the sending of each.
const { Util } = require('discord.js');
// Your code
readLastLines.read(playlist, 255)
.then(async lines => {
const channel = bot.channels.cache.get(settings.discord_channel);
// Splitting and sending
const messageChunks = Util.splitMessage(lines, {
maxLength: 2000,
char: ' '
});
messageChunks.forEach(async chunk => {
await channel.send(chunk);
});
});

client.commands.get('kickembed').execute //cannot read property 'execute' is undefined//

I can actually run the bot, it will let mi interact with the other 3 commands, but when trying to do the "kickembed" it will fail and give me the error "client.commands.get('kickembed').execute(message,args,Discord)"
^
Cannot read property of 'execute' of undefined
tbh, i tried everithing, my little brain cant work this out, tysm for your time!
const client = new Discord.Client();
const prefix = ('^');
const fs = require('fs');
client.commands = new Discord.Collection();
const commandFiles = fs.readdirSync('./commands/').filter(file => file.endsWith('.js'));
for(const file of commandFiles){
const command = require(`./commands/${file}`);
client.commands.set(command.name, command);
}
client.once('ready', () =>{
console.log('Cataclysm is online, beep bop')
});
client.on('message', message =>{
if(!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).split(/ +/);
const command = args.shift().toLowerCase();
if(command === 'ping'){
message.channel.send('pong!');
} else if (command === 'welcome'){
client.commands.get('welcome').execute(message, args);
} else if (command === 'ban'){
client.commands.get('Ban').execute(message, args);
} else if (command === 'kick'){
client.commands.get('kick').execute(message, args);
} else if (command === 'kickembed'){
client.commands.get('kickembed').execute(message, args, Discord);
}
}); ~~~
and this is "kickembed"(where i have the problem i think)
~~~ const name = 'kick';
const description = "This command kicks a member!";
function execute(message, args, Discord) {
const banembed = new Discord.MessageEmbed()
.setColor('#ff3838')
.setTitle('A user has been kicked')
.setDescription('player (fix this plis) has been kicked by etc');
message.channel.send(banembed);~~~
your kickembed files have wrong name it is kick
So it should be like:
const name = 'kickembed';
const description = "This command kicks a member!";
function execute(message, args, Discord) {
const banembed = new Discord.MessageEmbed()
.setColor('#ff3838')
.setTitle('A user has been kicked')
.setDescription('player (fix this plis) has been kicked by etc');
message.channel.send(banembed);

discord.js suggestions - Cannot read property 'channels' of undefined

I've been making a suggestion command and I don't know what the current problem is, please help.
module.exports = {
name: 'suggestions',
aliases: ['suggest', 'suggestion'],
permissions: [],
description: 'creates a suggestions!',
execute(message, args, cmd, client, discord){
const channel = message.guild.channels.cache.find(c => c.name === 'suggestions');
if(!channel) return message.channel.send('suggestions channel does not exist!');
}
}
Here's the error message:
TypeError: Cannot read property 'channels' of undefined
at Object.execute (C:\Users\MyName\Desktop\DiscordBots\commands\suggestions.js:7:39)
Here's my main file:
const Discord = require('discord.js');
const client = new Discord.Client({ partials: ["MESSAGE", "CHANNEL", "REACTION"]});
client.commands = new Discord.Collection();
client.events = new Discord.Collection();
['command_handler', 'event_handler'].forEach(handler =>{
require(`./handlers/${handler}`)(client, Discord);
})
client.login('MYTOKEN');
Here's where I run execute() i think:
module.exports = (Discord, client, message) => {
const prefix = '-';
if(!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).split(/ +/);
const cmd = args.shift().toLowerCase();
const command = client.commands.get(cmd) || client.commands.find(a => a.aliases && a.aliases.includes(cmd));
if(command) command.execute(client, message, args, Discord);
}
Please try to define channel and then send message
client.channels.cache.get("CHANNELID").send(`TEST`);
this may be work;
module.exports = {
name: 'suggestions',
aliases: ['suggest', 'suggestion'],
permissions: [],
description: 'creates a suggestions!',
execute(client, message, args, Discord){ // CHANGED
const channel = message.guild.channels.cache.find(c => c.name === 'suggestions');
if(!channel) return message.channel.send('suggestions channel does not exist!');
}
}

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