I've never had a problem with the say command until I start using modules and cleaned up my code but since I have few my commands have bugged. I'm trying to figure out why it is saying the command.
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);
}
bot.on("message", async message => {
if (!message.content.startsWith(PREFIX)) return;
let args = message.content.substring(PREFIX.length).split(" ");
switch (args[0]) {
case "say":
bot.commands.get("say").execute(message, args);
break;
const Discord = require("discord.js");
module.exports = {
name: "say",
description: "Show's avatar",
async execute(message, args){
const sayMessage = args.join(" ");
message.delete().catch(O_o => {});
message.channel.send(`${sayMessage} - ${message.author}`);
}
}
Thanks in advance!
The code is doing exactly what you programmed it to, be it not intended.
let args = message.content.substring(PREFIX.length).split(" "); // args = ['say', 'Hello', 'World']
bot.commands.get("say").execute(message, args); // Passing in the entire args array
const sayMessage = args.join(" "); // sayMessage = 'say Hello World'
One solution of many:
let args = message.content.substring(PREFIX.length).split(" ");
const command = args.splice(0, 1); // args now only contains the arguments
switch (command) {
...
}
Here you go this is using the anidiots guidebot boiler plate i highly recommend using it to help you better understand incorporating a command handler into your discord bot.
your going to want to download the repo from here https://github.com/AnIdiotsGuide/guidebot/
extract it
run npm install
in the commands folder add say.js using the code below this is how to properly execute what your trying todo
by default the prefix is ~ to change it in discord chat run ~conf edit prefix Example: ~conf edit prefix !
run !say hello world
exports.run = async (client, message, args) => {
const sayMessage = args.join(" ");
message.delete();
message.channel.send(sayMessage + ' - ' + message.author)
};
exports.conf = {
enabled: true,
guildOnly: false,
aliases: [],
permLevel: "User"
};
exports.help = {
name: "say",
category: "Miscelaneous",
description: "say command",
usage: "say"
};```
Related
const config = require(`${process.cwd()}/botconfig/config.json`)
var ee = require(`${process.cwd()}/botconfig/embed.json`)
const fetch = require("node-fetch");
const { MessageEmbed } = require(`discord.js`);
module.exports = {
//definition
name: "glifestats", //the name of the command
category: "⌨️ Programming", //the category this will be listed at, for the help cmd
aliases: [""], //every parameter can be an alias
cooldown: 4, //this will set it to a 4 second cooldown
usage: "glifestats <id>", //this is for the help command for EACH cmd
description: "check stats", //the description of the command
};
run: async (client, message, args, cmduser, text, prefix) => {
await interaction.deferReply();
const term = interaction.options.getString('term');
const query = new URLSearchParams({ term });
const { list } = await fetch(`https://api.gtaliferp.fr:8443/v1/extinction/profiles/main/${query}`)
.then(response => response.json());
}
When i try to do this command, it does nothing.
It needs to get the query from the user message and post it to the url, example:
.command 4443
bot returns the https://api.gtaliferp.fr:8443/v1/extinction/profiles/main/4443 data and postes it.
And also, i wanted to make the different data on an embed like this: data 1: data data 2: data .... but i cant do it, ( check the url provided for the data titles if you want to help with that)
So you seperated your module from the rest of the command with this line marked below
module.exports = {
//definition
name: "glifestats", //the name of the command
category: "⌨️ Programming", //the category this will be listed at, for the help cmd
aliases: [""], //every parameter can be an alias
cooldown: 4, //this will set it to a 4 second cooldown
usage: "glifestats <id>", //this is for the help command for EACH cmd
description: "check stats", //the description of the command
} //here
Also term is reqesting an option that is not defined
const term = interaction.options.getString('term');
Interaction is not defined
run: async (client, message, args, cmduser, text, prefix) => {
await interaction.deferReply();
const term = interaction.options.getString('term');
Try this
const config = require(`${process.cwd()}/botconfig/config.json`) // is this needed if not, delete
var ee = require(`${process.cwd()}/botconfig/embed.json`) // is this needed if not, delete
const fetch = require("node-fetch");
const {
MessageEmbed
} = require(`discord.js`); // is this needed if not, delete
module.exports = {
name: "glifestats", //the name of the command
category: "⌨️ Programming", //the category this will be listed at, for the help cmd
aliases: [""], //every parameter can be an alias
cooldown: 4, //this will set it to a 4 second cooldown
usage: "glifestats <id>", //this is for the help command for EACH cmd
description: "check stats", //the description of the command
options: [{
name: "term",
description: "Code to search",
required: true,
type: "STRING",
}],
run: async (client, interaction) => {
await interaction.deferReply();
const term = interaction.options.getString('term');
const url = `https://api.gtaliferp.fr:8443/v1/extinction/profiles/main/${term}`
const list = await fetch(url).then(response => response.json())
// Do something with list
console.log(list)
return interaction.followUp({
content: `List has been logged but can't be sent yet because it is an object and need to be further worked to get specific elements from it`
})
// Above seemed cleaner to me
/*
const query = new URLSearchParams({
term
});
const {
list
} = await fetch(`https://api.gtaliferp.fr:8443/v1/extinction/profiles/main/${query}`)
.then(response => response.json());
*/
}
}
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!
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.
My problem is the following: when compiling, I get the error that the property 'execute' is not defined. What I'm trying to do is open a file that is in another folder and dock it in the if, I was guided by the command handling documentation, I don't know if the error is in the other file which is called 'ping.js'. I recently started, so I don't fully understand it.
The main code is as follows:
const Discord = require('discord.js');
const { token, default_prefix } = require('./conf.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!');
});
client.on('message', async message => {
if (!message.content.startsWith(default_prefix) || message.author.bot) return;
const args = message.content.slice(default_prefix.length).split(/ +/);
const command = args.shift().toLowerCase();
if (command === 'ping') {
client.commands.get('ping').execute(message, args);
}
});
client.login(token);
While the 'ping.js' code is:
const Discord = require('discord.js');
module.exports = {
description: "Get the latency of the bot.",
usage: {},
examples: {},
aliases: [ "pong", "latency", "uptime" ],
permissionRequired: 0,
checkArgs: (args) => !args.length
}
module.exports.run = async function (client, message, args, config, gdb, prefix, permissionLevel, db) {
let botMsg = await message.channel.send("Pinging")
botMsg.edit({
embed: {
name: "ping",
title: "📶 Ping",
color: 0x2ed32e,
description: [
"**Server**: `" + (message.createdAt - message.createdAt) + "ms`",
"**API**: `" + Math.round(client.ws.ping) + "ms`",
"**Uptime**: `" + msToTime(client.uptime) + "`"
].join("\n"),
footer: { text: "Requested by " + message.author.tag, icon_url: message.author.displayAvatarURL }
}
})
}
function msToTime(ms) {...
}
It works, but if I add it directly to the main code, but I don't want that. If you have any ideas or know the solution, I would appreciate it.
It's saying execute is undefined because you didn't define execute it in ping.js.
You can do either:
In ping.js change module.exports.run to module.exports.execute
OR in your main file, change client.commands.get('ping').execute to client.commands.get('ping').run
The reasoning for the is when calling command.execute() you are attempting to call a function named 'execute' in the command's module. Since you named it run instead of execute, it looks for the wrong function and doesn't find it.
That's because you named it run and not execute on this line:
module.exports.run = async function ()
change it to execute and it should work fine, if you wanna keep the keyword run, instead of client.commands.get('ping').execute(message, args), use client.commands.get('ping').run(message, args)
Also I should mention you have a lot of parameters:
execute function (client, message, args, config, gdb, prefix, permissionLevel, db) {
//...
}
Any after args will be undefined as you only pass in messsage and args, here:
client.commands.get('ping').execute(message, args)
Please help me understand how can i call that ping.js from user input, like if a user type ping it will Trigger cuz of the aliases but if a user types a full phrase it won't trigger.
Or in a non headic question how can i implent this to work -> if (message.content.includes('ping'))
Sorry in advance and thanks a lot
ping.js
const Discord = require('discord.js')
const colors = require('../lib/colors.json')
exports.run = async (client, message, args, level) => {
try {
const pingEmbed = new Discord.RichEmbed()
.setColor(colors.default)
.setFooter('ping)
.addField(`${message.author.id}`, 'hey')
const msg = await message.channel.send(pingEmbed)
const embed = new Discord.RichEmbed()
.setColor(colors.default)
.addField('...',
`${msg.createdTimestamp - message.createdTimestamp}ms`)
msg.edit(embed)
} catch (err) {
message.channel.send('There was an error!\n' + err).catch()
}
}
exports.conf = {
enabled: true,
aliases: ['ping'],
guildOnly: false,
permLevel: 'User'
}
exports.help = {
name: 'ping,
category: 'tools,
description: 'ping pong',
usage: 'ping'
}
If you want to check whether a message contains any of the aliases you can just use Array.some() like this:
let aliases = ['your', 'command', 'aliases']
client.on('message', message => {
if (aliases.some(trigger => message.content.includes(trigger))) {
// The message includes at least one of your keywords
}
})
In this example is just declared aliases, but you can use the array from your command and integrate this method in your normal command handler.