I am attempting to create a bot, this is my first attempt at it so any help would be greatly appreciated! I am using the SlashCommandBuilder and deploy-commands.js to send commands/listen for commands with my bot. I am looking to create a function that retrieves the Discord users ID, I will then take that ID and use it to search my database on Airtable for the corresponding table with the same name, then it will find the Cash column to collect the data and send it back to the user in an embed or message. I have been unable to figure out how to pull the user ID from the command user...
Here is the error output I get when I run the script:
const member = interaction.member;
^
TypeError: Cannot read properties of undefined (reading 'member')
at getDiscordUserID (C:\Users\Sauce\Desktop\FrontierEconomyBot\functions\getDiscordUserID.js:3:30)
at Object.<anonymous> (C:\Users\Sauce\Desktop\FrontierEconomyBot\functions\searchairtable.js:6:14)
at Module._compile (node:internal/modules/cjs/loader:1205:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1259:10)
at Module.load (node:internal/modules/cjs/loader:1068:32)
at Module._load (node:internal/modules/cjs/loader:909:12)
at Module.require (node:internal/modules/cjs/loader:1092:19)
at require (node:internal/modules/cjs/helpers:103:18)
at Object.<anonymous> (C:\Users\Sauce\Desktop\FrontierEconomyBot\commands\cash.js:2:28)
at Module._compile (node:internal/modules/cjs/loader:1205:14)
Node.js v19.1.0
Here is my index.js file for reference as well as the function I have tried to create, and the deploy-commands script juuuuust in case.
INDEX.JS
const fs = require('node:fs');
const path = require('node:path');
const { Client, Collection, Events, GatewayIntentBits } = require('discord.js');
const { token } = require('./config.json');
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
client.commands = new Collection();
const commandsPath = path.join(__dirname, 'commands');
const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
for (const file of commandFiles) {
const filePath = path.join(commandsPath, file);
const command = require(filePath);
client.commands.set(command.data.name, command);
}
client.once(Events.ClientReady, () => {
console.log('Ready!');
});
client.on(Events.InteractionCreate, async interaction => {
if (!interaction.isChatInputCommand()) return;
const command = client.commands.get(interaction.commandName);
if (!command) return;
try {
await command.execute(interaction);
} catch (error) {
console.error(error);
await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true });
}
});
client.login(token);
GETUSERID.JS
async function getDiscordUserID(interaction) {
const member = interaction.member;
if (!member) {
console.error('Interaction does not have a member');
return null;
}
const user = member.user;
if (!user) {
console.error('Interaction member does not have a user');
return null;
}
const userID = user.id;
return userID;
}
module.exports = { getDiscordUserID };
DEPLOY-COMMANDS.JS
const { REST, Routes } = require('discord.js');
const { clientId, guildId, token } = require('../config.json');
const fs = require('node:fs');
const commands = [];
// Grab all the command files from the commands directory you created earlier
const commandFiles = fs.readdirSync('../commands').filter(file => file.endsWith('.js'));
// Grab the SlashCommandBuilder#toJSON() output of each command's data for deployment
for (const file of commandFiles) {
const command = require(`../commands/${file}`);
commands.push(command.data.toJSON());
}
// Construct and prepare an instance of the REST module
const rest = new REST({ version: '10' }).setToken(token);
// and deploy your commands!
(async () => {
try {
console.log(`Started refreshing ${commands.length} application (/) commands.`);
// The put method is used to fully refresh all commands in the guild with the current set
const data = await rest.put(
Routes.applicationGuildCommands(clientId, guildId),
{ body: commands },
);
console.log(`Successfully reloaded ${data.length} application (/) commands.`);
} catch (error) {
// And of course, make sure you catch and log any errors!
console.error(error);
}
})();
Related
I started programming a discord bot with nodejs on replete and I use code similar to the example in the official site of discord.js. Bot registered the command and it appears in discord but when I run it doesn't work.
The application did not respond
This is the code I use to make the command:
const { SlashCommandBuilder } = require('discord.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('hi')
.setDescription('say hi'),
async execute(interaction) {
await interaction.reply('hi');
},
};
The index code:
const { Client, Events, GatewayIntentBits } = require('discord.js');
const token = process.env['TOKEN']
const clientId = process.env['APID']
const guildId = process.env['SID']
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
//
const { REST, Routes } = require('discord.js');
/*const { clientId, guildId, token } = require('./config.json');*/
const fs = require('node:fs');
const commands = [];
// Grab all the command files from the commands directory you created earlier
const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js'));
// Grab the SlashCommandBuilder#toJSON() output of each command's data for deployment
for (const file of commandFiles) {
const command = require(`./commands/${file}`);
commands.push(command.data.toJSON());
}
// Construct and prepare an instance of the REST module
const rest = new REST({ version: '10' }).setToken(token);
// and deploy your commands!
(async () => {
try {
console.log(`Started refreshing ${commands.length} application (/) commands.`);
// The put method is used to fully refresh all commands in the guild with the current set
const data = await rest.put(
Routes.applicationGuildCommands(clientId, guildId),
{ body: commands },
);
console.log(`Successfully reloaded ${data.length} application (/) commands.`);
} catch (error) {
// And of course, make sure you catch and log any errors!
console.error(error);
}
})();
//
client.on("ready", () => {
console.log("Bot is online!");
})
client.login(process.env['TOKEN']);
Project Structure
Command Registered
Bot Config
Bot Scopes
Bot Permissions
I am using Discord.js library to build a Discord bot. I am following the Official Documentation and I am facing an error while handling events.
File Structure:
index.js
const fs = require('node:fs');
const path = require('node:path');
const { Client, GatewayIntentBits } = require('discord.js');
require('dotenv').config()
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
const eventsPath = path.join(__dirname, 'events');
const eventFiles = fs.readdirSync(eventsPath).filter(file => file.endsWith('.js'));
for (const file of eventFiles) {
const filePath = path.join(eventsPath, file);
const event = require(filePath);
if (event.once) {
client.once(event.name, (...args) => event.execute(...args));
} else {
client.on(event.name, (...args) => event.execute(...args));
}
}
client.login(process.env.token)
interactionCreate.js
module.exports = {
name: 'interactionCreate',
async execute(interaction) {
if (!interaction.isChatInputCommand()) return;
const command = interaction.client.commands.get(interaction.commandName); console.log("command ", interaction.client)
if (!command) {
console.error(`No command matching ${interaction.commandName} was found.`);
return;
}
try {
await command.execute(interaction);
} catch (error) {
console.error(`Error executing ${interaction.commandName}`);
console.error(error);
}
},
};
The slash command worked successfully when I used the below method in index.js file, instead of creating a new interactionCreate.js file
client.on(Events.InteractionCreate, async (interaction) => {
console.log(interaction)
if (!interaction.isChatInputCommand()) return;
const command = client.commands.get(interaction.commandName);
if (!command) return;
try {
await command.execute(interaction);
} catch (error) {
console.error(error);
await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true });
}
});
But as soon as I moved this function to interactionCreate.js file, The program started throwing the following error
Any help or advice is appreciated! Thank you
You need to refer to the commands file in index.js because your bot doesn't know about the commands method
From the official document you linked,
add this in index.js
client.commands = new Collection();
const commandsPath = path.join(__dirname, 'commands');
const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
for (const file of commandFiles) {
const filePath = path.join(commandsPath, file);
const command = require(filePath);
// 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.data.name, command);
}
I am making a Discord bot using slash command, and i am stuck at this point. Here is the code of my index.js file
const commands = []
const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js'));
for (const file of commandFiles) {
const command = require(`./commands/${file}`);
commands.push(command.data.toJSON());
}
const rest = new REST({ version: '9' }).setToken(token);
(async () => {
try {
console.log('Started refreshing application (/) commands.');
await rest.put(
Routes.applicationGuildCommands(clientId, guildId),
{ body: commands },
);
console.log('Successfully reloaded application (/) commands.');
} catch (error) {
console.error(error);
}
})();
client.on('ready' , () => {
console.log('I am online')
client.user.setActivity('MUSIC 🎧', {type:'LISTENING'})
})
client.on('interactionCreate', async interaction => {
if(!interaction.isCommand())return
const command = interaction.commands.get(interaction.commandName);
if(!command)return
try {
await command.execute(interaction)
} catch (err) {
console.error(err)
await interaction.reply('There was an error trying to execute that command!')
}
})
And a ping.js file to send simple PING-PONG message.
const { SlashCommandBuilder } = require('#discordjs/builders')
module.exports = {
data: new SlashCommandBuilder()
.setName("ping")
.setDescription("PING-PONG"),
async execute (interaction) {
await interaction.reply("Pong!")
}
}
ERROR is:
const command = interaction.commands.get(interaction.commandName);
^
TypeError: Cannot read properties of undefined (reading 'get')
at Client.<anonymous> (C:\vs\Adele music bot\index.js:52:42)
at Client.emit (node:events:520:28)
Everything is fine, it registers slash commands but as soon as i use /ping it just shows the above error.
It seems like you have copied and pasted code from different places and just hoped it worked. The error means interaction.commands is undefined, which it is.
From what I can see, you wanted a Discord.Collection with all your interaction commands within. For the purposes of this, we will use client.commands.
Code sample
/* Create the collection */
client.commands = new Discord.Collection()
const commands = []
const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js'));
for (const file of commandFiles) {
const command = require(`./commands/${file}`);
commands.push(command.data.toJSON());
/* Add data to the collection */
client.commands.set(command.name, command);
}
...
/* Get the command */
const command = client.commands.get(interaction.commandName);
const {Collection} = require('discord.js');
import the collection from discord package.
then after creating the client
client.commands = new Collection();
use the above snippet
then
const command = client.commands.get(interaction.commandName);
write this line where the error originates.
basically you first need to make a new collection of commands for the client.
then you need to add the data to add data to the collection but using below command.
client.commands.set();
then after this only you can use the get command
client.commands.set();
I'm new to using Discord.js, and after looking through the basic guide/docs, I'm still somehow confused as to how to allow event and/or command files to access the main client instance. For example, I may want to call client.database within an event file in order to make use of CRUD operations.
I did some digging on my own, and I saw that someone had implemented this by getting rid of the .execute function in each of the event files, and passing in event.bind(null, client) to client.on(). I don't really understand it though:
https://github.com/KSJaay/Alita/blob/fe2faf3c684227e29fdef228adaae2ee1c87065b/Alita.js
https://github.com/KSJaay/Alita/blob/master/Events/guildMemberRemove.js
My Main File:
require("dotenv").config();
const fs = require('fs');
util = require('util');
readdir = util.promisify(fs.readdir);
const { Client, Collection, Intents } = require('discord.js');
const client = new Client({ intents: [Intents.FLAGS.GUILDS] });
const mongoose = require('mongoose');
client.events = new Collection();
client.commands = new Collection();
//client.database = require('./src/db/index.js')
async function init() {
const eventFiles = fs.readdirSync('./src/discord/events').filter(file => file.endsWith('.js'));
for (const file of eventFiles) {
const event = require(`./events/${file}`);
const eventName = file.split(".")[0];
if (event.once) {
client.once(eventName, (...args) => event.execute(...args));
} else {
client.on(eventName, (...args) => event.execute(...args));
}
}
const commandFiles = await readdir('./src/discord/commands')
commandFiles.filter(file => file.endsWith('.js'));
for (const file of commandFiles) {
const command = require(`./commands/${file}`);
client.commands.set(command.data.name, command);
}
mongoose.connect(process.env.DB_CONNECT, {
useNewUrlParser: true,
useUnifiedTopology: true
}).then(() => {
console.log('Connected to MongoDB')
}).catch((err) => {
console.log('Unable to connect to MongoDB Database.\nError: ' + err)
})
await client.login(process.env.TOKEN);
}
init();
My Sample Event:
module.exports = {
name: 'interactionCreate',
async execute(interaction) {
console.log(`${interaction.user.tag} in #${interaction.channel.name} triggered an 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 });
}
},
};
Get the client using .client on an object, an Interaction in this case
const command = interaction.client.commands.get(interaction.commandName)
Recently, I've been working on a bot called Music Bot. And, it showed up with this error message:
C:\Users\yuhao\Desktop\discord-bot-master\index.js:51
client.login(token);
^
ReferenceError: token is not defined
at Object.<anonymous> (C:\Users\yuhao\Desktop\discord-bot-master\index.js:51:14)
at Module._compile (internal/modules/cjs/loader.js:1144:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1164:10)
at Module.load (internal/modules/cjs/loader.js:993:32)
at Function.Module._load (internal/modules/cjs/loader.js:892:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
at internal/main/run_main_module.js:17:47
C:\Users\yuhao\Desktop\discord-bot-master>
My token format have lots of dots, but, at ReferenceError, it showed up with no dots and the one before the dot.
This the the script for index.js:
const fs = require('fs')
const Discord = require('discord.js');
const Client = require('./client/Client');
const {
prefix,
token,
} = require('./config.json');
const client = new Client();
client.commands = new Discord.Collection();
const queue = new Map();
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);
}
console.log(client.commands);
client.once('ready', () => {
console.log('Ready!');
});
client.once('reconnecting', () => {
console.log('Reconnecting!');
});
client.once('disconnect', () => {
console.log('Disconnect!');
});
client.on('message', async message => {
const args = message.content.slice(prefix.length).split(/ +/);
const commandName = args.shift().toLowerCase();
const command = client.commands.get(commandName);
if (message.author.bot) return;
if (!message.content.startsWith(prefix)) return;
try {
command.execute(message);
} catch (error) {
console.error(error);
message.reply('There was an error trying to execute that command!');
}
});
client.login(token);
And this is config.json:
{
"prefix": "!",
"token": "token"
}
Thats all. Help me please on reply section, thx!
Your problem is that you haven't populated your token or prefix. You need to parse your JSON like this for the object in question to be populated.
JS:
const fs = require('fs')
...
const config = JSON.parse(fs.readFileSync(filename, "UTF-8");
client.login(config.token);
TS (with a class so you don't have to worry about mistyping values, as you will get autocompletion):
export default class Settings {
public token: String;
public prefix: String;
}
...
const config: Settings = JSON.parse(fs.readFileSync(filename, "UTF-8");
client.login(config.token);
use like this
const fs = require('fs')
const Discord = require('discord.js');
const Client = require('./client/Client');
const config = require('./config.json');
const client = new Client();
client.commands = new Discord.Collection();
const queue = new Map();
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);
}
console.log(client.commands);
client.once('ready', () => {
console.log('Ready!');
});
client.once('reconnecting', () => {
console.log('Reconnecting!');
});
client.once('disconnect', () => {
console.log('Disconnect!');
});
client.on('message', async message => {
const args = message.content.slice(config.prefix.length).split(/ +/);
const commandName = args.shift().toLowerCase();
const command = client.commands.get(commandName);
if (message.author.bot) return;
if (!message.content.startsWith(config.prefix)) return;
try {
command.execute(message);
} catch (error) {
console.error(error);
message.reply('There was an error trying to execute that command!');
}
});
client.login(config.token);