So I have help.js file where I require all other commands so that I can have access to their usage,
This is my help.js codes:
//Here is how I require all other commands...
const Discord = require('discord.js');
const client = new Discord.Client();
const fs = require('fs');
//If i removed this from here...
const commandFolders = fs.readdirSync('./commands/');
client.commands = new Discord.Collection();
for (const folder of commandFolders) {
const commandFiles = fs.readdirSync(`./commands/${folder}/`).filter(file => file.endsWith('.js'));
for (const file of commandFiles) {
const command = require(`../${folder}/${file}`);
client.commands.set(command.name, command);
}
}
//To here... the syntax is now defined on ban.js...
module.exports = {
name: 'help',
syntax: {
syntax: { //I will use this if for example a command has invalid syntax
color: 0xeb4034,
title: 'Oops!',
description: 'Looks like your syntax is invalid, see\n`?help {command}` for more description.'
},
}
execute: async function(message, args) {
//Here I call the ban usage
switch (args[0]) {
case 'ban':
let { usage } = client.commands.get('ban');
return message.channel.send({ embed: usage }); //This worked
}
More codes...
}
But suddenly if I call the syntax in help.js from other file... it is undefined, but if I hover it, it's showing the value of the syntax,
Heres my ban.js codes:
const Discord = require('discord.js');
const { syntax } = require('../Global/help');
module.exports = {
name: 'ban',
usage: {
color: 0x1e90ff,
title: 'Ban',
description: '`Usage:` {prefix}ban user time {optional reason}\n`Example:` ?ban <#message.author.tag> 1h/1m/1s Bad dude'
},
execute: async function(message, args) {
//If I hover on the syntax, it is showing the value, but the result is undefined...
console.log(syntax); //Shows undefined
if (args.length < 1) return message.channel.send({ embed: syntax }); //Made an error
}
}
This is how my files and folders are setup
How do I fix this?
Edit: I found the solution, its not running the code above the module.exports of ban.js so I made a function that returns the syntax
You didn't constructed your client properly
const client = new Discord.Client({
intents: ["GUILDS","GUILD_MEMBERS","GUILD_MESSAGES"]
});
Related
I just created a bot, doesn't do anything special, but it just won't answer commands.
I enable intents on the dev portal, I gave him admin privileges, the bot is online. It won't give me any error. Looking for something similar but it all ends up in something to do with the intents which I feel that they are right. This is the code:
const { Client, GatewayIntentBits, Partials, ActivityType } = require("discord.js");
const fs = require("fs");
require("dotenv").config();
const mySecret = process.env['TOKEN']
const { setCommands } = require("./commands/help.js")
const { prefix } = require("./config.js");
const commands = {};
const client = new Client(
{
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
GatewayIntentBits.GuildMembers,
],
partials: [
Partials.Message,
Partials.User,
Partials.Channel,
Partials.GuildMember
]
});
// load commands
const commandFiles = fs.readdirSync("./commands").filter(file => file.endsWith(".js"));
for (const file of commandFiles) {
const command = require(`./commands/${file}`);
commands[command.name] = command;
}
setCommands(commands)
// login bot
client.on("ready", () => {
console.log(`Logged in as ${client.user.tag}`);
client.user.setActivity('Dimensions', {
type: ActivityType.Listening
})
});
client.on("message", message => {
console.log(message)
if(!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).trim().split(/ +/);
const command = args.shift().toLowerCase();
let cmd = commands[command];
if(cmd)
cmd.execute(message, args)
});
client.login(mySecret);
This is the comand
module.exports = {
name: "ping",
description: "Replies with 'pong'",
execute: (message) => {
message.channel.send("pong")
}
}
This is my config file
module.exports = {
prefix: "!"
}
There is a help.js too where I set up some help commands with other commands, I don't think is relevant but I'll update it if it is. Also, this is running on replit, not sure if that matters?
Thankss
You have to return the execute to execute the code:
module.exports = {
name: "ping",
description: "Replies with 'pong'",
execute: (message) => {
return message.channel.send("pong")
}
}
Im using discord js to make a multi-purpose discord bot for my server, but its giving me this error:
ValidationError: Expected a string primitive
It was working fine yesterday but i forgot to save something and i dont know what.
const fs = require('node:fs');
const path = require('node:path');
const {
Client,
GatewayIntentBits,
Partials,
Collection,
} = require("discord.js");
const { Player } = require('discord-player');
const { Routes } = require('discord-api-types/v10');
const { token, prefix, guildId, clientId } = require('./config.json');
const { REST } = require('#discordjs/rest');
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.MessageContent,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.GuildPresences,
GatewayIntentBits.GuildVoiceStates
],
partials: [
Partials.Channel,
Partials.Message,
Partials.User,
Partials.GuildMember,
],
});
client.player = new Player(client, {
ytdlOptions: {
quality: "highestaudio",
highWaterMark: 1 << 25
}
});
module.exports = client;
// command handler
//slash commands
const slashCommands = [];
client.slashCommands = new Collection();
const commandsPath = path.join(__dirname, "commands"); // E:\yt\discord bot\js\intro\commands
const slash_commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('S.js'));
for(const file of slash_commandFiles)
{
const filePath = path.join(commandsPath, file);
const command = require(filePath);
client.slashCommands.set(command.data.name, command);
slashCommands.push(command.toJSON());
}
console.log(slashCommands);
//message commands
client.messageCommands = new Collection();
const message_commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('M.js'));
for (const file of message_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.messageCommands.set(command.Name, command);
}
//event handler
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));
}
}
// messageCommand handler
client.on('messageCreate', (message) => {
const args = message.content.slice(prefix.length).split(' ');
const command = args[0];
if (client.messageCommands.get(command)) {
let Command = client.messageCommands.get(command);
Command.execute(message);
}
});
client.on('ready', () => {
const rest = new REST({ version: '9' }).setToken(token);
rest.put(Routes.applicationGuildCommands(clientId, guildId),
{ body: slashCommands })
.then(() => console.log('Successfully updated commands for guild ' + guildId))
.catch(console.error);
console.log('bot is online!');
client.user.setStatus('idle');
});
client.login(token);
im sure there's nothing wrong with any of the command files because it was working fine yesterday.
there's 100% an error in this line slashCommands.push(command.toJSON()); but I cant seem to fix it. The command.toJSON() console logs just fine but gives an error while trying to push into the list
Ran into the same issue, turns out options (i.e. addUserOption) require a description. Point is it's really confusing as this error shows up when doing command.data.toJSON(). If you are dynamically loading the command files as described in the guide and running into this issue, then try manually doing a require to trigger the validation beforehand.
Try using command.data.toJSON() as command is a nested object with a data and an execute key.
I've fixed it, there was a url in the json which seemed to be causing some issue, I removed the file with the url and its working now
I'm getting this error message on heroku and I think I'm getting it cause of Procfile.
I'm using Worker at the moment, but I'm trying to figure out how to have heroku access both index.js and ping.js. Unless I'm reading the error message completely wrong and this could be a different issue. Any help is appreciated!
EDIT:
Here's my code for index.js
const Discord = require('discord.js');
const music = require('#koenie06/discord.js-music');
const fs = require('fs');
const { dir } = require('console');
const bot = new Discord.Client({
shards: "auto",
intents: [
Discord.Intents.FLAGS.GUILDS,
Discord.Intents.FLAGS.GUILD_MESSAGES,
Discord.Intents.FLAGS.GUILD_MESSAGE_REACTIONS,
Discord.Intents.FLAGS.DIRECT_MESSAGES,
Discord.Intents.FLAGS.GUILD_VOICE_STATES
]
});
bot.commands = new Discord.Collection();
bot.aliases = new Discord.Collection();
//Command handler and aliases
fs.readdirSync('./commands/').forEach(dir => {
//in the commands folder, we gonna check for the category
fs.readdir(`./commands/${dir}`, (err, files) => {
//console log error(catch error)
if(err)throw err;
//checking if the files ends with .js if its a javascript file
var jsFiles = files.filter(f => f.split('.').pop() === 'js');
//if there is no commands in the file it will return
if(jsFiles.length <= 0) {
console.log("Can't find any commands");
return;
}
jsFiles.forEach(file => {
//console the loaded commands
var fileGet = require(`./commands/${dir}/${file}`);
console.log(`[COMMAND HANDLER] - File ${file} was loaded`);
//gonna let the commands run
try {
bot.commands.set(fileGet.help.name, fileGet);
// it search in the commands folder if there is any aliases
fileGet.help.aliases.forEach(alias => {
bot.aliases.set(alias, fileGet.help.name);
})
} catch(err) {
//catch error in console
return console.log(err);
}
})
})
})
/**
* ECHO STUFF
*/
//slash command to echo
bot.on('ready', async () => {
bot.user.setPresence({ activities: [{ name: "Tedi", type: "WATCHING"}] });
console.log("bye");
const data = {
name: 'echo',
description: 'Echo your text',
options: [{
name: 'text',
type: 'STRING',
description: 'The user input',
required: true,
}],
};
const command = await bot.guilds.cache.get('872986148681703444')?.commands.create(data);
})
bot.on('messageCreate', async message => {
if(message.author.bot || message.channel.type == 'DM') return
let prefix = '~'
let messageArray = message.content.split(' ');
let cmd = messsageArray[0];
let args = messageArray.slice(1);
//it will make the cmd work with his original name and his aliases
let commands = bot.commands.get(cmd.slice(prefix.length)) || bot.commands.get(bot.aliases.get(cmd.slice(prefix.length)));
if(commands) {
if(!message.content.startsWith(prefix)) return
commands.run(bot, message, args, prefix);
}
})
//interactionCreate for echo slash command
bot.on('interactionCreate', async interaction => {
/**
* isButton() used to check if its a button
* isCommand() used to check if its a slash command
* isSelectMenu() used to check if its a dropdown menu
* isMessageComponent()
*/
if(interaction.isCommand()) {
if(interaction.commandName === 'echo') {
const text = interaction.options.getString('text');
await interaction.reply({ content: text, ephemeral: false}); //if ephemeral if true, it would make the slash command private
}
}
})
bot.login(process.env.token);
Here is my ping.js
const Discord = require("discord.js");
module.exports.run = async (Client, message, args, prefix) => {
message.channel.send("pong")
}
module.exports.help = {
name: "ping",
aliases: ["p"]
}
This error is not because of Heroku, it's basically because there is a file in your command handler that doesn't have a name while handling it, as example like this code over here:
const Discord = require("discord.js");
module.exports.run = async (Client, message, args, prefix) => {
message.channel.send("pong")
}
module.exports.help = {
// here the name isn't included
aliases: ["p"]
}
// so just check if you have a file without a name while handling it and put a name, and if you don't want aliases make it `aliases: []`
This command handler should be like thisCommands Folder commands > Subfolder e.g. Moderation > kick.jsThats how it works, also thank you for watching my videos, I'm UltraX :)
In this line of code I am trying to send private message, to initial message author. For some unknown reason there is an error:
(node:17560) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'send' of undefined
Here is this line of code:
const appStart = await message.author.send(questions[collectCounter++]);
Here is whole file:
const Discord = require("discord.js");
const {Client, Message, MessageEmbed} = require("discord.js");
module.exports = {
name: 'apply',
/**
*
* #param {Client} client
* #param {Messafe} message
* #param {String[]} args
*/
run : async(client, message, args) => {
const questions = [
"What is your in-game name?",
"Do you accept the rules?",
"How old are you?",
"Where are you from?",
"How long have you been playing Minecraft?",
"Where did you find the server?",
"Have you ever been banned from another server on Minecraft? If yes, what was the reason?",
"Why should we accept you?",
]
let collectCounter = 0;
let endCounter = 0;
const filter = (m) => m.author.id === message.author.id;
const appStart = await message.author.send(questions[collectCounter++]);
const channel = appStart.channel;
const collector = channel.createMessageCollector(filter);
collector.on("collect", () => {
if(collectCounter < questions.length) {
channel.send(questions[collectedCounter++]);
} else {
channel.send("Your application has been sent!");
collector.stop("fulfilled");
}
});
const appsChannel = client.channel.cache.get('863534867668009004');
collector.on('end', (collected, reason) => {
if(reason === 'fulfilled') {
let index = 1;
const mappedResponses = collected.map((msg) => {
return `&{index++}) &{questions[endCounter++]}\n-> ${msg.content}`
})
.join('\n\n');
}
appsChannel.send(message.channel.send('New Application!', mappedResponses));
});
},
};
This is my index.js:
const fs = require("fs");
const Discord = require("discord.js");
const client = new Discord.Client();
client.commands = new Discord.Collection();
const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js'));
const BOT_ID = "863550035923697674";
const prefix = "!";
client.on("ready", () => {
console.log(`Logged in as ${client.user.tag}!`);
client.user.setActivity("ur cheat files...", {
type: "WATCHING",
url: "https://discord.gg/bzYXx8t3fE"
});
});
for(const file of commandFiles) {
const command = require(`./commands/${file}`);
client.commands.set(command.name, command);
}
client.on("message", message => {
let userID = message.author.id;
if (userID == BOT_ID) {
return;
}
const version = "Wersja bota 0.2";
///const args = message.content;
const args = message.content.slice(prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
if(!client.commands.has(command)) return;
try{
client.commands.get(command).run(message, args);
}catch(error){
console.error(error);
message.reply('**There was an issue executing that command!**');
}
});
client.login("tokenishere");
Thanks for help!
This just means that message is not what you think it is. In your command handler, you executed the command with the arguments message and args (order matters). However, in the command file, you expected the parameters to be client, message, and then args.
This means, that in your command file, client actually refers to the message, message actually refers to the args, and the third parameter doesn't exist.
To fix this problem, you can modify the names and order of the parameters in either file.
This is an easy fix... as #Lioness100 mentioned your parameters are wrong and im here to show a code example
locate this line of code in index.js :
client.commands.get(command).run(message, args);
// and change it to
client.commands.get(command).run(message, args, client);
after wards go to your "File" and fine this line of code :
run : async(client, message, args) => {
// And change it to
run : async(message, args) => {
Your problem was that you were executing wrong parameters in Your "File" so you just needed to change your parameters from client, message, args to message, args, client
This is a common mistake
I sort of need help here, honestly not sure where I went wrong, here is the full code. I am sort of new, just trying to bring back the mention user and the reason back in a message instead of doing anything with this information.
const { client, MessageEmbed } = require('discord.js');
const { prefix } = require("../config.json");
module.exports = {
name: "report",
description: "This command allows you to report a user for smurfing.",
catefory: "misc",
usage: "To report a player, do $report <discord name> <reason>",
async execute(message, client){
function getUserFromMention(mention) {
if (!mention) return;
if (mention.startsWith('<#') && mention.endsWith('>')) {
mention = mention.slice(2, -1);
if (mention.startsWith('!')) {
mention = mention.slice(1);
}
return client.users.cache.get(mention);
}
}
const args = message.content.slice(prefix.length).trim().split(/ +/);
const command = args.shift().toLowerCase();
const offender = getUserFromMention(args[0]);
if (args.length < 2) {
return message.reply('Please mention the user you want to report and specify a reason.');
}
const reason = args.slice(1).join(' ');
message.reply("You reported",offender,"for reason:", reason)
}
}
If I put no mention, I end up with this
And If I do put a mention
this
I get the above error with no response.
(node:4044) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'cache' of undefined
Index.js:
const fs = require('fs');
const Discord = require("discord.js");
const { prefix, token } = require('./config.json');
const client = new Discord.Client();
client.prefix = prefix;
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);
}
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.login(token);
You don't have to create a function to get a mention from a message, you can use the Message.mentions property to get the mentions, check the docs for other info about it.
This should solve your issue.
const { prefix } = require("../config.json");
module.exports = {
name: "report",
description: "This command allows you to report a user for smurfing.",
catefory: "misc",
usage: "To report a player, do $report <discord name> <reason>",
async execute(message, client) {
const args = message.content.slice(1).trim().split(/ +/);
const offender = message.mentions.users.first();
// users is a collection, so we use the first method to get the first element
// Docs: https://discord.js.org/#/docs/collection/master/class/Collection
if (args.length < 2 || !offender.username) {
return message.reply('Please mention the user you want to report and specify a reason.');
}
const reason = args.slice(1).join(' ');
message.reply(`You reported ${offender} for reason: ${reason}`);
}
}
Why are you calling client in a command file if you already started a new instance of a client in your root file? try removing client from the top of the code. Hope that works