I am trying to make a discord.js snipe command and I keep getting an error message: Cannot read properties of undefined (reading 'get'). I created command handlers and event handlers and everything works fine, even the messageDelete event. I get this message every time I run the command
Snipe command:
module.exports = {
commands: ['snipe','sn','s'],
requiredRoles: ['Members'],
callback : (client, message, args) => {
const msg = client.snipes.get(message.channel.id)
if(!msg) return message.channel.send("There's nothing to snipe!")
message.channel.send(`${msg.author} deleted: ${msg.content}`)
}
}
Index file:
const path = require('path')
const fs = require('fs')
const { Client, Intents, Collection } = require('discord.js');
const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] });
const config = require('./config.json');
require('./util/loadEvents')(client);
client.snipes = new Collection()
Event Handler:
const fs = require('fs');
module.exports = client => {
fs.readdir("events/", (_err, files) => {
files.forEach((file) => {
if (!file.endsWith(".js")) return;
const event = require(`../events/${file}`);
let eventName = file.split(".")[0];
client.on(eventName, event.bind(null, client));
delete require.cache[require.resolve(`../events/${file}`)];
});
});
}
And messageDelete Event:
module.exports = async (client,message) => {
if(message.author.client) return;
client.snipes.set(message.channel.id, {
content: message.content,
author: message.author.tag,
})
}
All other commands work perfectly
Make sure you pass the arguments in the correct order.
If you run the callback like this:
callback(message, arguments, arguments.join(' '), client);
The order should be like this:
module.exports = {
commands: ['snipe', 'sn', 's'],
requiredRoles: ['Members'],
callback: (message, arguments, joinedArguments, client) => {
const msg = client.snipes.get(message.channel.id);
if (!msg) return message.channel.send("There's nothing to snipe!");
message.channel.send(`${msg.author} deleted: ${msg.content}`);
}
};
Related
Im trying to create a discord bot, theres one command that returns the ping when /ping is typed, and another one im trying to add that restarts the bot when /restart is typed. But when I type /restart, it functions like I typed /ping and replied with the ping. I cannot find a solution to my problem so any help is appreciated. If you need more information on this please reply to me.
Here is a file called "handleCommands" with its code:
const { REST } = require('discord.js');
const { Routes } = require('discord-api-types/v9');
const fs = require('fs');
const pingCommand = require(`./src/commands/tools/ping.js`);
const restartCommand = require('../../commands/tools/restart.js');
module.exports = (client) => {
client.handleCommands = async () => {
const commandFolders = fs.readdirSync('./src/commands');
for (const folder of commandFolders) {
const commandFiles = fs
.readdirSync(`./src/commands/${folder}`)
.filter((file) => file.endsWith(".js"));
const { commands, commandArray } = client;
for (const file of commandFiles) {
const command = require(`../../commands/${folder}/${file}`);
if (command.data.name !== 'restart') {
commands.set(command.data.name, command);
commandArray.push(command.data.toJSON());
} else {
commands.set(restartCommand.data.name, restartCommand);
commandArray.push(restartCommand.data.toJSON());
}
}
}
const clientId = '(BotsClientIdWentHere)';
const guildId = '(ServersClientIdWentHere';
const rest = new REST({ version: '9' }).setToken(process.env.token);
try {
console.log('Started refreshing application (/) commands.');
await rest.put(
Routes.applicationGuildCommands(clientId, guildId), {
body: client.commandArray,
});
console.log('Successfully reloaded application (/) commands.')
} catch (error) {
console.error(error);
}
};
};
Here is code from restart.js:
const { SlashCommandBuilder } = require('discord.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('restart')
.setDescription('Restarts the bot (Debug)'),
async execute(interaction, client) {
// Shut down the bot
await client.destroy();
// Log the bot back in to Discord
await client.login(MyBotsTokenWentHere);
// Send a message to confirm that the bot has been restarted
await interaction.editReply({
content: 'Bot restarted successfully'
});
}
}
A file called "interactionCreate":
module.exports = {
name: "interactionCreate",
async execute(interaction, client) {
console.log("Received interaction event:", interaction);
if (interaction.isChatInputCommand()) {
console.log("Received chat input command:", interaction.commandName);
const { commands } = client;
const { commandName } = interaction;
const command = commands.get(commandName);
if (!command) return;
try {
await command.execute(interaction, client);
} catch (error) {
console.error(error);
await interaction.reply({
content: `Something went wrong.. Please try again later. If this issue persists, please message my creator.`,
ephermeral: true,
});
}
}
},
};
And bot.js:
require("dotenv").config();
const { token } = process.env;
const { Client, Collection, GatewayIntentBits } = require("discord.js");
const fs = require("fs");
const client = new Client({ intents: GatewayIntentBits.Guilds });
client.commands = new Collection();
client.commandArray = [];
const functionFolders = fs.readdirSync(`./src/functions`);
for (const folder of functionFolders) {
const functionFiles = fs
.readdirSync (`./src/functions/${folder}`)
.filter((file) => file.endsWith('.js'));
for (const file of functionFiles)
require(`./functions/${folder}/${file}`)(client);
}
client.handleEvents();
client.handleCommands();
client.login(token);
Here is also the ping file code:
const { SlashCommandBuilder } = require('discord.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('ping')
.setDescription('Returns the bots ping (Debug)'),
async execute(interaction, client) {
const message = await interaction.deferReply({
fetchReply: true
});
const currentTime = Date.now();
const responseTime = currentTime - interaction.createdTimestamp;
const responseTimeSeconds = responseTime / 1000; // convert to seconds
const newMessage = `API Latency: ${client.ws.ping}\nClient Ping: ${message.createdTimestamp - interaction.createdTimestamp}\nTime: ${responseTimeSeconds} seconds`
await interaction.editReply({
content: newMessage
});
}
}
And here I attacked a picture of the file heirarchy.
enter image description here
I tried to add functions that were supposed to add the function to table and add logs to the console to try to see what its printing but in the end the last error was "ReferenceError: (MyBotsTokenWentHere) is not defined". Any help appreciated.
Edit: Problem solved. Here is the updated restart.js and handleCommands files:
const { SlashCommandBuilder } = require('discord.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('restart')
.setDescription('Restarts the bot (Debug)'),
async execute(interaction, client) {
// Send a reply to the command message
await interaction.deferReply({
content: 'Restarting the bot...'
});
// Shut down the bot
await client.destroy();
// Log the bot back in to Discord
await client.login(MyBotsTokenWentHere);
// Edit the reply to confirm that the bot has been restarted
await interaction.editReply({
content: 'Bot restarted successfully'
});
}
}
handleCommands:
const { REST } = require('discord.js');
const { Routes } = require('discord-api-types/v9');
const fs = require('fs');
const pingCommand = require(`../../commands/tools/ping.js`);
const restartCommand = require('../../commands/tools/restart.js');
module.exports = (client) => {
client.handleCommands = async () => {
const commandFolders = fs.readdirSync('./src/commands');
for (const folder of commandFolders) {
const commandFiles = fs
.readdirSync(`./src/commands/${folder}`)
.filter((file) => file.endsWith(".js"));
const { commands, commandArray } = client;
for (const file of commandFiles) {
const command = require(`../../commands/${folder}/${file}`);
//console.log(`loading ${command.data.name} from commands/${folder}/${file}`)
if (command.data.name !== 'restart') {
commands.set(command.data.name, command);
commandArray.push(command.data.toJSON());
} else {
commands.set(restartCommand.data.name, restartCommand);
commandArray.push(restartCommand.data.toJSON());
}
}
}
const clientId = '(ClientIdWentHere)';
const guildId = '(GuildIdWentHere)';
const rest = new REST({ version: '9' }).setToken(process.env.token);
try {
console.log('Started refreshing application (/) commands.');
await rest.put(
Routes.applicationGuildCommands(clientId, guildId), {
body: client.commandArray,
});
console.log('Successfully reloaded application (/) commands.')
} catch (error) {
console.error(error);
}
};
};
I'm trying to get a little familiar with the slash command handler, but I get an error when trying to grab the member id, this happens with just about everything I try to grab.
Here at the top is directly my command, where I try to send a message with the content "user.id".
this is my command:
const { SlashCommandBuilder } = require("#discordjs/builders");
module.exports = {
data: new SlashCommandBuilder()
.setName("avatar")
.setDescription("SERVUSSS")
.addUserOption(option => option.setName("member").setDescription("memberdings").setRequired(true)),
async execute(interaction) {
const user = interaction.options.getUser('target');
await interaction.reply(`${user.id}`);
}
}
this is my deploy file:
require("dotenv").config();
const fs = require("fs");
const { REST } = require("#discordjs/rest");
const { Routes } = require("discord-api-types/v9");
const commands = [];
const commandFiles = fs.readdirSync("./src/commands").filter(file => file.endsWith(".js"));
commandFiles.forEach(commandFile => {
const command = require(`./commands/${commandFile}`);
commands.push(command.data.toJSON());
});
const restClient = new REST({version: "9"}).setToken(process.env.TOKEN);
restClient.put(Routes.applicationGuildCommands(process.env.APPLICATION_ID, process.env.GUILD_ID),
{body: commands }).then(() => console.log("success")).catch(console.error);
my index file:
require("dotenv").config();
const { Client, Collection } = require("discord.js");
const fs = require("fs");
const client = new Client({intents: []});
client.commands = new Collection();
const commandFiles = fs.readdirSync("./src/commands").filter(file => file.endsWith(".js"));
commandFiles.forEach(commandFile => {
const command = require(`./commands/${commandFile}`);
client.commands.set(command.data.name, command);
});
client.once("ready", () => {
console.log("ready!!");
});
client.on("interactionCreate", async (interaction) => {
if(!interaction.isCommand()) return;
const command = client.commands.get(interaction.commandName)
if(command) {
try {
await command.execute(interaction)
} catch(error) {
console.log(error)
if(interaction.deferred || interaction.replied) {
interaction.editReply("error")
} else {
interaction.reply("error")
}
}
}
})
client.login(process.env.TOKEN)
I actually stick to it pretty much all the time
https://discordjs.guide/ just do not understand what I'm doing wrong
Since option name is member then it's going to be
const user = interaction.options.getUser('member');
In your command file, the name for the option is given as member, but when you are using interaction.options.getUser(), you are passing the name as 'target'. So all you have to do is change the line where you are declaring the user to: const user = interaction.options.getUser('member')
I'm trying to create a discord bot that will where someone can enter the slash command /suggestion and the bot will take that suggestion and turn it into an embed and send it into a specific suggestions channel with two emojis, an X and Checkmark.
After getting it all written and doing node deploy-commands.js and getting no errors, I inputted node . with also no errors in the terminal.
But when I went into the discord and enter the /suggestions command, I get an error in the terminal which is:
TypeError: Cannot read properties of undefined (reading 'join')
and I have no idea how to follow the error to see where it's originating from.
Does anyone have any thoughts on this?
I'll leave my index.js, suggestions.js, and deploy-commands.js below.
index.js
// Require the necessary discord.js classes
const fs = require('fs');
const { Client, Collection, Intents, } = require('discord.js');
const { token } = require('./config.json');
const client = new Client({
intents: [
Intents.FLAGS.GUILDS,
Intents.FLAGS.GUILD_MESSAGES,
Intents.FLAGS.GUILD_MESSAGE_REACTIONS,
],
});
client.commands = new Collection();
client.events = new 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);
}
// When the client is ready, run this code (only once)
client.once('ready', () => {
console.log("You are now connected to Boombap Suggestions!");
});
client.on('interactionCreate', async (interaction) => {
if (!interaction.isCommand()) return;
const command = client.commands.get(interaction.commandName);
if (!command) return;
try {
await command.execute(interaction);
} catch (error) {
console.error(error);
return interaction.reply({
content: 'There was an error while executing this command!',
ephemeral: true,
});
}
});
// Login to Discord with your client's token
client.login(token);
suggestions.js
module.exports = {
name: 'suggestions',
aliases: ['suggest', 'suggestion'],
permissions: [],
description: 'creates a suggestion!',
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!');
let messageArgs = args.join(' ');
const embed = new discord.MessageEmbed()
.setColor('5104DB')
.setAuthor(message.author.tag, message.author.displayAvatarURL({ dynamic: true }))
.setDescription(messageArgs);
channel.send(embed).then((msg) => {
msg.react('β');
msg.react('β
');
message.delete();
}).catch((err) => {
throw err;
});
}
}
deploy-commands.js
const { SlashCommandBuilder } = require('#discordjs/builders');
const { REST } = require('#discordjs/rest');
const { Routes } = require('discord-api-types/v9');
const { clientId, guildId, token } = require('./config.json');
const commands = [
new SlashCommandBuilder().setName('suggestions').setDescription('Submit A Suggestion!'),
]
.map(command => command.toJSON());
const rest = new REST({ version: '9' }).setToken(token);
rest.put(Routes.applicationGuildCommands(clientId, guildId), { body: commands })
.then(() => console.log('Successfully registered application commands.'))
.catch(console.error);
You're only passing the interaction at command.execute(interaction) yet you're expecting message, args, etc at execute(message, args, cmd, client, discord). As args is undefined you receive "TypeError: Cannot read properties of undefined (reading 'join')" .
Another problem is that you're using v13 of discord.js and still having some v12 syntax, just like in your previous post.
As you are using slash commands, you will have no args, you could add a string option in your deploy-commands.js file using the addStringOption() method. You should also mark this command option as required by using the setRequired() method.
Update commands in deploy-commands.js:
const commands = [
new SlashCommandBuilder()
.setName('suggest')
.setDescription('Submit a suggestion!')
.addStringOption((option) =>
option
.setName('suggestion')
.setDescription('Enter your suggestion')
.setRequired(true),
),
].map((command) => command.toJSON());
In your suggestions.js file, you can get this option from the CommandInteractionOptionResolver using interaction.options.getString('suggestion').
There are some changes to how setAuthor() works in v13. It now accepts an EmbedAuthorData object that has a name and an iconURL property.
Replace your suggestions.js with the following:
const { MessageEmbed } = require('discord.js');
module.exports = {
name: 'suggest',
aliases: ['suggest', 'suggestion'],
permissions: [],
description: 'creates a suggestion!',
async execute(interaction) {
let channel = interaction.guild.channels.cache.find((c) => c.name === 'suggestions');
if (!channel) {
await interaction.reply('`suggestions` channel does not exist!');
return;
}
let suggestion = interaction.options.getString('suggestion');
let embed = new MessageEmbed()
.setColor('5104DB')
.setAuthor({
name: interaction.member.user.tag,
iconURL: interaction.member.displayAvatarURL({ dynamic: true }),
})
.setDescription(suggestion);
let sentEmbed = await channel.send({ embeds: [embed] });
await interaction.reply({
content: 'π Thanks, we have received your suggestion',
ephemeral: true,
});
sentEmbed.react('β');
sentEmbed.react('β
');
},
};
I was adapting my command handler to work with slash and it worked, but now I have other problems
1 - When I try to run the /ping command, "interaction failed" appears and there is no error on the console
2 - I put some console.log() to see if it was delivering the right value, but some variables gave undefined
This is my command handler (index.js):
const fs = require('fs');
const pComandos = fs.readdirSync('Comandos');
client.commands = new Discord.Collection();
client.description = new Discord.Collection();
for (const folder of pComandos) {
const file = fs.readdirSync('Comandos/' + folder);
for (const comando of file) {
let cmd = require(`./Comandos/${folder}/${comando}`);
commandsArray = [];
console.log(chalk.green(`[ C ] O comando ` + chalk.bold(comando) + ` foi carregado!`))
client.commands.set(cmd.help.name, cmd)
if (cmd.help.description) {
cmd.desc = true
cmd.help.description.forEach(desc => client.commands.set(desc, cmd))
}
client.commands.set(cmd)
commandsArray.push({
name: cmd.help.name,
description: cmd.help.description.join("")
})
if (cmd.init) cmd.init(client)
client.on("ready", async() => {
const server = await client.guilds.cache.get("892210305558532116")
server.commands.set(commandsArray)
})
}
}
The interaction event (interactionCreate.js):
const { Interaction, CommandInteraction } = require("discord.js");
const fs = require("fs");
exports.run = (client, interaction) => {
if (interaction.isCommand()) {
const pComandos = fs.readdirSync('./Comandos');
for (const folder of pComandos) {
let file = fs.readdirSync("./Comandos/" + folder);
console.log(file) // [ 'ping.js' ]
for (const comando of file) {
let cmd = require(`../../Comandos/${folder}/${comando}`);
console.log(cmd)
/*
{
run: [AsyncFunction (anonymous)],
help: { name: 'ping', description: [ 'Pong!' ] },
desc: true
}
*/
let command =
client.commands.get(cmd) ||
client.commands.get(client.description.get(cmd));
console.log(command) // undefined
console.log(client.commands.get(cmd)) // undefined
if (command) {
command.run(client, interaction);
}
}
}
}
};
The ping command (ping.js):
const discord = require("discord.js");
exports.run = async (client, interaction) => {
interaction.deferUpdate();
var latencia = Date.now() - interaction.createdTimestamp
interaction.reply({content: `<:emoji_3:892431734203891722> | Ping atual do client: ${client.ws.ping} (${latencia}).\nπΊ | Timezone: ${process.env.TZ}`});
};
exports.help = {
name: "ping",
description: ["Pong!"]
};
This is my file organization: https://prnt.sc/20ddh4e
And the console (Console.log values ββare in the interactionCreate.js code): https://prnt.sc/20ddnlv
You should call interaction.deferReply() followed by interaction.editReply(content). interaction.deferUpdate() is used for updates, not replies.
I'm trying to create a ping command for my discord bot. My code seems pretty straightforward:
index.js:
require("dotenv").config();
const { Client, Intents, Collection } = require("discord.js");
const client = new Client({
intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES],
});
const fs = require("fs");
client.commands = new 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.data.name, command);
}
const eventFiles = fs
.readdirSync("./events")
.filter((file) => file.endsWith(".js"));
for (const file of eventFiles) {
const event = require(`./events/${file}`);
if (event.once) {
client.once(event.name, (...args) => event.execute(...args, client));
} else {
client.on(event.name, (...args) => event.execute(...args, client));
}
}
client.on("interactionCreate", (interaction) => {
console.log(interaction);
});
client.login(process.env.TOKEN);
messageCreate.js:
require("dotenv").config();
module.exports = {
name: "messageCreate",
on: true,
async execute(msg, client) {
// If message author is a bot, or the message doesn't start with the prefix, return.
if (msg.author.bot || !msg.content.startsWith(process.env.PREFIX)) return;
var command = msg.content.substring(1).split(" ")[0].toLowerCase();
// Remove the command from the args
var args = msg.content.substring().split(/(?<=^\S+)\s/)[1];
if (!client.commands.has(command)) return;
try {
await client.commands.get(command).execute(msg, args, client);
} catch (error) {
console.error(error);
await msg.reply({
content: "Error: Please check console for error(s)",
ephemeral: true,
});
}
},
};
ping.js:
const { SlashCommandBuilder } = require("#discordjs/builders");
const { MessageEmbed } = require("discord.js");
module.exports = {
data: new SlashCommandBuilder()
.setName("ping")
.setDescription("Replies to ping with pong"),
async execute(msg, args, client, interaction) {
const embed = new MessageEmbed()
.setColor("#0099ff")
.setTitle("π Pong!")
.setDescription(
`Latency is ${
Date.now() - msg.createdTimestamp
}ms. API Latency is ${Math.round(client.ws.ping)}ms`
)
.setTimestamp();
await interaction.reply({
embeds: [embed],
ephemeral: true,
});
},
};
I'm passing my msg parameter, so why is it that it doesn't recognize the msg.createdTimestamp within ping.js? EDIT: I've updated some of my code, updating the way the parameters are passed. Now I'm getting a TypeError: Cannot read properties of undefined (reading 'reply') error in my ping.js file.
So I figured it out. The msg portion of what I'm passing actually gets passed down to the interaction argument. Just had to change msg to interaction to get everything to work:
ping.js
const { SlashCommandBuilder } = require("#discordjs/builders");
const { MessageEmbed } = require("discord.js");
module.exports = {
data: new SlashCommandBuilder()
.setName("ping")
.setDescription("Replies to ping with pong"),
async execute(interaction, args, client) {
const embed = new MessageEmbed()
.setColor("#0099ff")
.setTitle("π Pong!")
.setDescription(
`Latency is ${
Date.now() - interaction.createdTimestamp
}ms. API Latency is ${Math.round(client.ws.ping)}ms`
)
.setTimestamp();
await interaction.reply({
embeds: [embed],
ephemeral: true,
});
},
};