Commands not running with no error message - discord.js

im trying to run multiple commands for my discord bot, bot for some reason one singular command is not running. This is the code in my main.js file:
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 === 'petfeed') {
client.commands.get('petfeed').execute(message, args, Discord);
}else if(command === 'petwater') {
client.commands.get('petwater').execute(message, args, Discord);
//this is one of the commands that runs perfectly fine. The command has virtually identical code to the petfeed command in its file but with a few small changes
});
Here is the command that i am trying to run:
const db = require('quick.db')
module.exports = {
name: 'petfeed',
description: 'feeds your pet',
execute: async (message, args, Discord) => {
let user = message.author
let fullness = await db.fetch(`fullness_${user.id}`)
let food = await db.fetch(`food_${user.id}`)
if(fullness === null) fullness = 0;
if(food === null) food = 0;
if(fullness < 3 && food >= 1) {
db.add(`fullness_${user.id}`, 1)
db.subtract(`food_${user.id}`, 1)
}
}
}
I have other very similar commands that run perfectly fine, but this command does nothing when i try to run it, and it doesn't give back any errors.

Somehow changing the name to petfood in both the main.js file and the command file fixed the issue. If i change it back to petfeed it stops working again.

Related

Can someone help me find what is wrong with my code?

Im trying to make a stopwatch command that when you say !duty on and then !duty off it will calculate the time took to stop it. It works like a regular stopwatch but it is for discord. I have been trying to fix the err for a week but i cant understand why it doesnt work pls help me. The err is in line 10 id where it says message.guild.id
the code:
const Discord = require('discord.js');
const StopWatch = require("timer-stopwatch-dev");
const moment = require('moment');
module.exports = {
name: 'duty',
description: "This is a stopwatch command",
async execute(client, message, args, CurrentTimers) {
try {
let guildTimers = CurrentTimers.get(message.guild.id);
let guildTimersUser = guildTimers.get(message.author.id);
if(!guildTimersUser){ guildTimers.set(message.author.id, new StopWatch()); guildTimersUser = guildTimers.get(message.author.id); };
if(!args[0] || args[0] === 'on'){
if(guildTimersUser.isRunning()) return message.channel.send('You need to stop your shift first!')
guildTimersUser.start();
message.channel.send('You have started your shift')
} else if(args[0] === 'off'){
if(!guildTimersUser.isRunning()) return message.channel.send('You need to start the Stopwatch first!')
guildTimersUser.stop();
message.channel.send(new Discord.RichEmbed().setTitle('You have stopped the Stopwatch!').setDescription('Total Time: ' + dhm(guildTimersUser.ms)).setTimestamp());
}
}
catch(err) {
console.log(err)
}
function dhm(ms){
days = Math.floor(ms / (24*60*60*1000));
daysms=ms % (24*60*60*1000);
hours = Math.floor((daysms)/(60*60*1000));
hoursms=ms % (60*60*1000);
minutes = Math.floor((hoursms)/(60*1000));
minutesms=ms % (60*1000);
sec = Math.floor((minutesms)/(1000));
return days+" days, "+hours+" hours, "+minutes+" minutes, "+sec+" seconds.";
}
}
}
my main:
require('dotenv').config();
//create cooldowns map
const cooldowns = new Map();
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){
//If cooldowns map doesn't have a command.name key then create one.
if(!cooldowns.has(command.name)){
cooldowns.set(command.name, new Discord.Collection());
}
const current_time = Date.now();
const time_stamps = cooldowns.get(command.name);
const cooldown_amount = (command.cooldown) * 1000;
//If time_stamps has a key with the author's id then check the expiration time to send a message to a user.
if(time_stamps.has(message.author.id)){
const expiration_time = time_stamps.get(message.author.id) + cooldown_amount;
if(current_time < expiration_time){
const time_left = (expiration_time - current_time) / 1000;
return message.reply(`Please wait ${time_left.toFixed(1)} more seconds before using ${command.name}`);
}
}
//If the author's id is not in time_stamps then add them with the current time.
time_stamps.set(message.author.id, current_time);
//Delete the user's id once the cooldown is over.
setTimeout(() => time_stamps.delete(message.author.id), cooldown_amount);
}
try{
command.execute(message,args, cmd, client, Discord, CurrentTimers);
} catch (err){
message.reply("There was an error trying to execute this command!");
console.log(err);
}
}
You didn’t show the actual error but I suspect that it is something like Cannot read property 'id' of undefined. The way to fix this is to make sure of 2 things:
Make sure the message is not in DM
Make sure your execution parameters are passed in correctly.
command.execute(client, message, args, CurrentTimers)
//these may not be the same variable names, but make sure the values are correct

how to make command that lists all of the servers the bot is in

I try making a command that I can use to show me the servers the bot is in, but when I start making the command it doesn't work in every way I try it and always tells me that one of the things was not defined or cannot read property mostly it tells me that bot or guilds is not defined or cannot read properly.
I want to make a command that only I can use in discord to see all the servers that my bot is in.
I use command handler that means that every single command is in separate js file.
My discord client variable is set to "bot" (as shown in the code).
This is the command (servers.js):
module.exports = {
name: 'servers',
execute(bot, message, args) {
bot.guilds.cache.forEach(guild => {
message.channel.send(`Servers: ${guild.name}`);
})
}
}
This is the command handler/the main file (index.js):
const Discord = require('discord.js');
const bot = new Discord.Client();
const fs = require('fs');
const { prefix, token } = require('./config.json');
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}`);
bot.commands.set(command.name, command);
}
const cooldowns = new Discord.Collection();
bot.once('ready', () => {
console.log('Online!');
});
bot.on('message', message => {
if (!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).trim().split(/ +/);
const commandName = args.shift().toLowerCase();
if (!bot.commands.has(commandName)) return;
const command = bot.commands.get(commandName);
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}\``;
}
return message.channel.send(reply);
}
try {
command.execute(message, args);
}
catch (error) {
console.error(error);
message.reply('there was an error trying to execute that command!').then(msg => {
msg.delete({timeout:6000});
});
}
});
And there is the error:
TypeError: Cannot read property 'cache' of undefined
at Object.execute (D:\Users\USER\Desktop\Bot\commands\serversinfo.js:4:20)
at Client.<anonymous> (D:\Users\USER\Desktop\Bot\index.js:64:21)
at Client.emit (node:events:376:20)
at MessageCreateAction.handle (D:\Users\USER\Desktop\Bot\node_modules\discord.js\src\client\actions\MessageCreate.js:31:14)
at Object.module.exports [as MESSAGE_CREATE] (D:\Users\USER\Desktop\Bot\node_modules\discord.js\src\client\websocket\handlers\MESSAGE_CREATE.js:4:32)
Your execute function takes 3 arguments execute(bot, message, args), but you are only giving it 2 arguments when you use it in the main file: command.execute(message, args);
Adding that missing argument should fix that:
command.execute(bot, message, args)
The easiest way to list all the servers the bot is in is by mapping all the servers like this:
message.channel.send(client.guilds.cache.map(s => s.name))
Then you can put it in to your command however needed - Feel free to reply to this if you have any questions or it doesn't work.
module.exports = {
name: 'servers',
execute(bot, message, args) {
message.channel.send(client.guilds.cache.map(s => s.name))
}
Please feel free to reply to me if this doesn't work or you have any other questions!

Read message sent after command start

I am trying to make a sort of trivia bot but the problem is that I can't get it working. I have it so that when you type "-quiz" it sends a embed with a random question. Now you might say that I need to make a separate JSON file and put the questions and answers there, the problem is, is that I need variables in those strings and when I tried it, it wouldn't work because the order or something like that. I tried to fix that but it seems like a bad solution anyway. I set it up so it looks for a message after the initial commands, problem is that it reads it's own embed and I honestly don't know how to make it skip bot messages
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 === 'quiz'){
var TypeID = (Math.floor(Math.random() * 11))
var toLog = (Math.floor(Math.random() * 2))
{ //there is something here that is used for the variables above but it is super long
}
var question = [`Question one`, `Question two`]
var answers = [[Answer1_1, Answer1_2],[Answer1_1]]
if(toLog === 0){
const quizEmbed1 = new Discord.MessageEmbed()
.setColor('#0099ff')
.setTitle('quiz')
.setDescription(`${question[0]}`)
message.channel.send(quizEmbed1)
if(!message.content || message.author.bot) return;
if(message.content === [answers[0], answers[1], answers[2], answers[3], answers[4], answers[5]]){
message.channel.send('Good Job! That is right!')
}else{
message.channel.send('Oops! that is wrong.')
}
}else if(toLog == 1){
const quizEmbed2 = new Discord.MessageEmbed()
.setColor('#0099ff')
.setTitle('quiz')
.setDescription(`${question[1]}`)
message.channel.send(quizEmbed2)
if(!message.content || message.author.bot) return;
if(message.content === [answers[6]]){
message.channel.send('Good Job! That is right!')
}else{
message.channel.send('Oops! That is wrong.')
}
}
}
});
if something it wrong it is most likely because I changed it to make it smaller, I am fairly newer to coding in JavaScript
Try using a MessageCollector. There is a good guide on the discord.js guide
Or using awaitMessages. Again there is a guide on the discord.js guide
Here is the example using awaitMessages
const filter = response => {
return item.answers.some(answer => answer.toLowerCase() === response.content.toLowerCase());
};
message.channel.send(item.question).then(() => {
message.channel.awaitMessages(filter, { max: 1, time: 30000, errors: ['time'] })
.then(collected => {
message.channel.send(`${collected.first().author} got the correct answer!`);
})
.catch(collected => {
message.channel.send('Looks like nobody got the answer this time.');
});
});

Trying to do a single Discord.js command without a prefix

I am attempting to make a command like dank memer has, when someone says F or f, the bot replies with F. My problem is that it will not work without the prefix, but I would like to be able to do it without the prefix.
Here is my code. I use a command handler.
//THIS IS THE INDEX.JS FILE
const Discord = require('discord.js');
const { default_prefix, token_bot } = require('./config.json');
const client = new Discord.Client();
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('Ready Player One!');
});
client.on('message', message => {
if (!message.content.startsWith(default_prefix) || message.author.bot) return;
const args = message.content.slice(default_prefix.length).trim().split(/ +/);
const command = args.shift().toLowerCase();
if (command === 'f'){
client.commands.get('f').execute(message, args);
}
And this one is the f.js command that it calls on.
module.exports = {
name: 'f',
description: "This is an f command",
execute(message, args){
message.channel.send('F');
},
};
This is not all of my index.js file, it is too long.
The solution to this is very simple. All commands have prefixes, so I would not consider what you are trying to create as a command, I would say it is technically more of an auto-response. Therefore, you should not be using the code of your args or command variables to check if "F" has been sent, you should instead directly check the message's content.
client.on('message', message => {
if (!message.content.startsWith(default_prefix) || message.author.bot) return;
const args = message.content.slice(default_prefix.length).trim().split(/ +/);
const command = args.shift().toLowerCase();
if (message.content.toLowerCase() == 'f'){
client.commands.get('f').execute(message, args);
}
});
I would advise looking into the args and command variables and learning how their values are being retrieved. Your code, as it is, seems to heavily rely on a simple template, but you cannot entirely depend on this template if you want to fully customize how your bot/commands will look and function.

Arguments for Discord.js

how do I read args in discord.js? I am trying to create a support bot and I want to have an !help {topic} command. how do I do that?
my current code is very basic
const Discord = require('discord.js');
const client = new Discord.Client();
const prefix = ("!")
const token = ("removed")
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
});
client.on('message', msg => {
if (msg.content === 'ping') {
msg.reply('pong');
}
if (msg.content === 'help') {
msg.reply('type -new to create a support ticket');
}
});
client.login(token);
You can make use of a prefix and arguments like so...
const prefix = '!'; // just an example, change to whatever you want
client.on('message', message => {
if (!message.content.startsWith(prefix)) return;
const args = message.content.trim().split(/ +/g);
const cmd = args[0].slice(prefix.length).toLowerCase(); // case INsensitive, without prefix
if (cmd === 'ping') message.reply('pong');
if (cmd === 'help') {
if (!args[1]) return message.reply('Please specify a topic.');
if (args[2]) return message.reply('Too many arguments.');
// command code
}
});
you can use Switch statement instead of
if (command == 'help') {} else if (command == 'ping') {}
client.on ('message', async message => {
var prefix = "!";
var command = message.content.slice (prefix.length).split (" ")[0],
topic = message.content.split (" ")[1];
switch (command) {
case "help":
if (!topic) return message.channel.send ('no topic bro');
break;
case "ping":
message.channel.send ('pong!');
break;
}
});
let args = msg.content.split(' ');
let command = args.shift().toLowerCase();
this is the simplified answer from #slothiful.
usage
if(command == 'example'){
if(args[0] == '1'){
console.log('1');
} else {
console.log('2');
You can create a simple command/arguments thing (I don't know how to word it correctly)
client.on("message", message => {
let msgArray = message.content.split(" "); // Splits the message content with space as a delimiter
let prefix = "your prefix here";
let command = msgArray[0].replace(prefix, ""); // Gets the first element of msgArray and removes the prefix
let args = msgArray.slice(1); // Remove the first element of msgArray/command and this basically returns the arguments
// Now here is where you can create your commands
if(command === "help") {
if(!args[0]) return message.channel.send("Please specify a topic.");
if(args[1]) return message.channel.send("Too many arguments.");
// do your other help command stuff...
}
});
You can do
const args =
message.content.slice(prefix.length).trim().split(' ');
const cmd = args.shift().toLocaleLowerCase();
Word of advice, use a command handler and slash commands - this will solve both the need for a help command and reading arguments. Also helps with readability.
Anyways...
message.content.split(' '): This will split your string into an array of sub-strings, then return a new array.
.shift(): This will remove the first index in the array.
Combining this will get you your arguments: const args = message.content.split(' ').shift()

Resources