My bot has a command located in /commands/developer/reload.js and it's purpose is to unload a command then load it again. But when trying to find the commands folder it throws an error saying Cannot find module '../undefined/help.js' but the path is ../misc/help.js
Code:
const fs = require('fs');
module.exports = {
name: 'reload',
description: 'Reloads a command',
args: true,
usage: '<command_name>',
cooldown: 1,
aliases: ['rl', 'restart'],
execute(message, args) {
const commandName = args[0].toLowerCase();
const command = message.client.commands.get(commandName) || message.client.commands.find(cmd => cmd.aliases && cmd.aliases.includes(commandName));
if(!command) {
return message.channel.send(`There is no command called '${commandName}'`);
}
// commandFolders returns undefined
const commandFolders = fs.readdirSync('./commands');
// Also returns undefined
const folderName = commandFolders.find(folder => {
fs.readdirSync(`./commands/${folder}`).includes(`${command.name}.js`);
})
// Command errors out here
delete require.cache[require.resolve(`../${folderName}/${command.name}.js`)];
// This part never runs.
try {
const newCommand = require(`../${folderName}/${command.name}.js`);
message.client.commands.set(newCommand.name, newCommand);
message.channel.send(`Command '${newCommand.name}' was reload successfully`)
} catch (err) {
console.error(err);
message.channel.send(`There was an error while reloading a Command.`)
}
}
}
The reason why you are getting the folder as undefined is because you are not returning the folder you are trying to find in the folderName function. It is trying to find a folder with the command and even if it does, you are not doing anything with it, you are not returning it or logging it into the console. So you just have to return it, the folderName function might look something like this:
const folderName = commandFolders.find(folder => fs.readdirSync(`commands/${folder}`).includes(`${command.name}.js`)) // If you want a one-liner
// Or
const folderName = commandFolders.find(folder => {
return fs.readdirSync(`commands/${folder}`).includes(`${command.name}.js`)
})
If the error persists, the error is most likely there because the path is not correct. So in that case, please provide the folder structure of your bot
Related
When i run 'node .' in the terminal it produces this error
TypeError: Cannot read properties of undefined (reading 'commands')
This is strange as I haven't changed anything, I simply just came back to my work.
This is the Commands.js file :
const { Perms } = require("../Validation/Permissions");
const { Client } = require("discord.js");
/**
* #param {Client} Client
*/
module.exports = async (client, PG, Ascii) => {
const Table = new Ascii("Command Loaded");
CommandsArray = [];
(await PG(`${process.cwd()}/Commands/*/*.js`)).map(async (file) => {
const command = require(file);
if(!command.name)
return Table.addRow(file.split("/")[7], "⛔ FAILED", "Missing a
name.")
if(!command.context && !command.description)
return Table.addRow(command.name, "⛔ FAILED", "Missing a
description.")
if(command.permission) {
if(Perms.includes(command.permission))
command.defaultPermission = false;
else
return Table.addRow(command.name, "⛔ FAILED", "Permission is
invalid.")
}
client.commands.set(command.name, command);
CommandsArray.push(command);
await Table.addRow(command.name, "✔ SUCCESSFUL");
});
console.log(Table.toString());
// Permissions Check //
client.on("ready", async () => {
const MainGuild = await
client.guilds.cache.get("961963167410454598");
MainGuild.commands.set(CommandsArray).then(async (command) =>
{
const Roles = (commandName) => {
const cmdPerms = CommandsArray.find((c) => c.name ===
commandName).permission;
if(!cmdPerms) return null;
return MainGuild.roles.cache.filter((r) =>
r.permissions.has(cmdPerms));
}
const fullPermissions = command.reduce((accumulator, r)
=> {
const roles = Roles(r.name);
if(!roles) return accumulator;
const permissions = roles.reduce((a, r) => {
return [...a, {id: r.id, type: "ROLE",
permission: true}]
}, [])
return [...accumulator, {id: r.id, permissions}]
}, [])
await MainGuild.commands.permissions.set({
fullPermissions });
});
});
}
The full error is :
C:\Users\wrigh\Documents\Discord Bots\Practice Bot -
Copy\Structures\Handlers\Commands.js:43
MainGuild.commands.set(CommandsArray).then(async (command) =>
{
It's line 43, or just under // Permissions Check // if you can't find it.
Any help is appreciated.
Again there have been no changes except uploading it to github, this is when i realised it stopped working.
Sorry about the format of the code, it got messed up when i pasted it in.
If you need to look at any other files please just ask!
If you are trying to access an attribute of an object (ex. object.userName) and it's undefined, you should console log out the entire object, and see if that property even exists on the object, or if the entire object is undefined as well.
From that point, if the client object does not have the property you're looking for, or if it is undefined itself, you can trace your issue down further from there.
I appreciate you uploading your code, but typically you want to have the code embedded into your question itself so we can run it there and inspect it properly.
this code is not executing the desired function which is to be able to initiate a message to repeat on a set interval. When debugging there are no errors and the bot comes online fine but the command can't be used and it says nothing to suggest what the problem is.
I need a professionals help to identify the reason this code is not working and why the bot acts as if it does not even exist.
This is the shortest amount of code to replicate the results I have left out the config.json because it has my token but I know for sure that that file is configured properly anyway
Test.ts file in commands folder
const Discord = require("discord.js");
const source = require('../index');
module.exports.run = (Client, message, args) => {
if (!args [0]) return message.reply(`Please specify if you are turning the command on or off!`);
if (args[1]) return message.reply(`Please specify if you are turning the command on or off! [Too many Arguments!]`);
switch (args[0])
{
default:
{
message.reply('Invalid argument specified.')
break;
}
case "on":
{
if (!source.timedCheck){
source.timedCheck =setInterval(() =>{
// Function for set interval
console.log("Interval cycle run!" + (val++) + "times!");
valcheck();
}, 25 * 10000);
message.reply('command started!');
} else {
return message.reply(`command already running!`)
}
break;
}
case "off":
{
if (source.timedCheck){
message.reply(`user has turned off command!`);
clearInterval(source.timedCheck);
source.timedCheck = undefined;
} else {
return message.reply(`command already offline!`)
}
break;
}
}
let valcheck = () => {
if (source.val > 5){
clearInterval(source.timedCheck);
source.timedCheck = undefined;
message.channel.send(`command finished as scheduled!`);
}
};
};
module.exports.help = {
name: "test",
usage: "test <on/off>"
};
Index.js file
// Require the necessary discord.js classes
const { Client, Intents } = require('discord.js');
const { token } = require('./config.json');
// Create a new client instance
const client = new Client({ intents: [Intents.FLAGS.GUILDS] });
// When the client is ready, run this code (only once)
client.once('ready', () => {
console.log('Ready!');
});
// Export variables for commands
module.exports.timedCheck = undefined;
module.exports.val = 0;
// Login to Discord with your client's token
client.login(token);
You didn't tell the bot to execute this command. In your Index file you have to require the command file, catch the "message" or the "interactionCreate" events and then execute your command.
This code is incomplete and I can only guide you in a direction as you miss many things in your code.
You should read a tutorial: https://discordjs.guide/creating-your-bot/creating-commands.html#command-deployment-script
client.commands = new Discord.Collection();
const commandFiles = fs.readdirSync('./src/commands');
// require every command and add to commands collection
for (const file of commandFiles) {
const command = require(`./src/commands/${file}`);
client.commands.set(command.name, command);
}
client.on('message', async message => {
// extract your args from the message, something like:
const args = message.content.slice(prefix.length).split(/ +/);
try {
command.execute(message, args, client); // provide more vars if you need them
} catch (error) {
// handle errors here
}
I am trying to import a variable from one of my files (File 1) and use it in File 2. I have imported File 2 into File 1 but I am receiving error. My channel ID is correct, in this case you would have to choose the channel so the channel ID is not the issue here.
TypeError: setr.send is not a function
File 1
const Discord = require("discord.js");
const axios = require("axios");
let config = require("../config.json");
module.exports = {
name: "setrestart",
description: "sets the restart channel",
async execute(message, args) {
const perm = new Discord.MessageEmbed()
.setDescription(":x: You do not have permission to use this command.")
.setColor("#E74C3C");
if (!message.guild.me.hasPermission("ADMINISTRATOR"))
return message.channel.send(perm);
if (message.author.id !== "ID")
return message.channel.send(perm);
const channelx =
message.mentions.channels.first() ||
message.guild.channels.cache.find((c) => c.id === args[0]);
if (!channelx)
return message.channel.send(
`:x: Please specify the channel where server restarts will go!`
);
message.reply(`All server restart logs will now go to ${channelx}.`)
},
};
File 2
const Discord = require("discord.js");
const axios = require("axios");
let config = require("../config.json");
let setr = require("./setrestart"); // This is importing file 1
module.exports = {
name: "restart",
description: "send a restart message in status channel",
async execute(message, args) {
const perm = new Discord.MessageEmbed()
.setDescription(":x: You do not have permission to use this command.")
.setColor("#E74C3C");
if (!message.guild.me.hasPermission("ADMINISTRATOR"))
return message.channel.send(perm);
if (message.author.id !== "ID")
return message.channel.send(perm);
const restart = new Discord.MessageEmbed()
.setTitle(" Server Restarted! ")
.setDescription(`F8 connect to ${config.SERVER_URL} `)
.setColor("RANDOM")
.setTimestamp()
.setFooter(`${config.SERVER_LOGO}`);
setr.channelx.send(restart) // This does not work.
},
};
Help is much appreciated.
Edit: I left out the most crucial thing about what I am trying to import.
I am trying to import channelx which is in File 1 and I am trying to use the variable in File 2.
Output
User: /setrestart #channel
Bot: All server restart logs will now go to ${channelx}.
User: /restart
Bot: Embed sent in channelx
The variable channelx is accessible only in the function scope of execute(), you can't import it. Basically after the function goes out of scope the variable is lost. Use a global object, note that the object is destroyed when the program exits. So if you are trying to make some kind of bot's configuration, you want to save the object to a file.
Here is an example of how to properly implement what you are trying to do.
File 1 (file1.js):
// ... Load storage from a JSON file ...
const storage = {};
module.exports = {
name: "setrestart",
description: "sets the restart channel",
async execute(message, args) {
// ... Permission checking ...
const channelx = message.mentions.channels.first() ||
message.guild.channels.cache.find((c) => c.id === args[0]);
if (!channelx) {
return message.channel.send(
`:x: Please specify the channel where server restarts will go!`
);
}
// Store restart channel id per guild
storage[message.guild.id] = channelx.id;
message.reply(`All server restart logs will now go to ${channelx}.`);
// ... Write to the storage JSON file and update it with new data ...
},
};
module.exports.storage = storage;
File 2 (file2.js):
const Discord = require("discord.js");
const file1 = require("./file1.js");
module.exports = {
name: "restart",
description: "send a restart message in status channel",
async execute(message, args) {
// ... Permission checking ...
const restart = new Discord.MessageEmbed()
.setTitle(" Server Restarted! ")
.setColor("RANDOM")
.setTimestamp();
const channelId = file1.storage[message.guild.id];
// If there is no restart channel set, default to the system channel
if (!channelId) channelId = message.guild.systemChannelID;
const channel = await message.client.channels.fetch(channelId);
channel.send(restart);
},
};
Note that I have remove some parts of your code, to make it work on my machine.
Using discord.js ^12.5.3.
I am pretty sure you can't use the module.exports in that way. You should just add the channelx to the exports instead.
using this.channelx = channelx.
This is not how importing and exporting works. Your channelx variable is defined within the execution of a function, and you are not returning it.
I am not sure how the whole Discord API works and what are the shapes that get returned, but you should be able to do something like this:
File 1
module.exports = {
name: "setrestart",
description: "sets the restart channel",
async execute(message, args) {
// ... everything as per your file
message.reply(`All server restart logs will now go to ${channelx}.`);
return channelx;
},
};
File 2
module.exports = {
name: "restart",
description: "send a restart message in status channel",
async execute(message, args) {
// ... everything the same as per your file
const channelx = await setr.execute(message, args);
channelx.send(restart);
},
};
Basically, what is happening here is that the first module exposes a function that figures out your target channel and then returns it.
Once you return it, you can do whatever you want with that.
Please be aware that your first function might not need to be async as you don't have any await instruction.
Read more about scope: https://developer.mozilla.org/en-US/docs/Glossary/Scope
I'm having some trouble coding prefix changing in my Discord bot. I've got all the basic functionality working:
The prefix is saved in a config file
The bot can write to the file and save it for later use
However, I can't seem to get the bot to use the new prefix after it's changed until I restart the bot. The config file shows that the prefix has been changed, but the bot doesn't respond to it.
So, my question is either, how can I refresh the memory so that the config is reloaded, or how can I get the bot to read my config again and use the new prefix?
Thanks!
prefix.js:
const fs = require('fs'); // node.js file system module
config = require('../config.json');
const Discord = require("discord.js");
module.exports = {
name: 'prefix', // command keyword
description: 'Changes the bot prefix', // info about command
group: 'settings', // command group (not displayed in !help [command name])
aliases: ['botprefix', 'newprefix'], // using these keywords also triggers command
usage: '[new prefix]', // how command is supposed to be used
cooldown: '1', // time command cannot be reused after it has been called
args: true, // are arguments required
execute(message, args) {
fs.exists("../config.json", function (error) {
if (error) {
console.log(error);
}
})
? fs
.readFile("../config.json", function (error) {
if (error) {
console.log(error);
}
})
.toString()
: config.prefix;
const newPrefix = args.shift().toString();
newConfig = {
token: config.token,
prefix: newPrefix,
};
fs.writeFile("config.json", JSON.stringify(newConfig, null, 2), function (
error
) {
if (error) {
console.log(error);
}
});
}
config.json:
{
"token": "token",
"prefix": "!"
}
If you want to access data via require, it won't be updated later as the function is run once at the beginnign of the project, even if you re-require it. This article can give you a bit more background on it. Basically: Always use fs.readFile and you're fine
I'm relatively new to Cloud Functions and have been trying to solve this issue for a while. Essentially, the function I'm trying to write is called whenever there is a complete upload onto Firebase Cloud Storage. However, when the function runs, half the time, it runs to the following error:
The following error occured: { Error: ENOENT: no such file or directory, open '/tmp/dataprocessing/thisisthefilethatiswritten.zip'
errno: -2,
code: 'ENOENT',
syscall: 'open',
path: '/tmp/dataprocessing/thisisthefilethatiswritten.zip' }
Here's the code:
const functions = require('firebase-functions');
const admin = require('firebase-admin')
const inspect = require('util').inspect
const path = require('path');
const os = require('os');
const fs = require('fs-extra');
const firestore = admin.firestore()
const storage = admin.storage()
const runtimeOpts = {
timeoutSeconds: 540,
memory: '2GB'
}
const uploadprocessing = functions.runWith(runtimeOpts).storage.object().onFinalize(async (object) => {
const filePath = object.name
const fileBucket = object.bucket
const bucket_fileName = path.basename(filePath);
const uid = bucket_fileName.match('.+?(?=_)')
const original_filename = bucket_fileName.split('_').pop()
const bucket = storage.bucket(fileBucket);
const workingDir = path.join(os.tmpdir(), 'dataprocessing/');
const tempFilePath = path.join(workingDir, original_filename);
await fs.ensureDir(workingDir)
await bucket.file(filePath).download({destination: tempFilePath})
//this particular code block I included because I was worried that the file wasn't
//being uploaded to the tmp directly, but the results of the function
//seems to confirm to me that the file does exist.
await fs.ensureFile(tempFilePath)
console.log('success!')
fs.readdirSync(workingDir).forEach(file => {
console.log('file found: ', file);
});
console.log('post success')
fs.readdirSync('/tmp/dataprocessing').forEach(file => {
console.log('tmp file found: ', file);
})
fs.readFile(tempFilePath, function (err, buffer) {
if (!err) {
//data processing comes here. Please note that half the time it never gets into this
//loop as instead it goes into the else function below and outputs that error.
}
else {
console.log("The following error occured: ", err);
}
})
fs.unlinkSync(tempFilePath);
return
})
module.exports = uploadprocessing;
I've been trying so many different things and the weird thing is that when I add code into the "if (!err)" (which doesn't actually run because of the err) it just arbitrarily starts working sometimes quite consistently, but then it stops working when I add different code. I would have assumed that the issue arises from the code that I added, but then the error comes up literally when I just change/add/remove comments as well... Which should technically have no effect on the function running...
Any thoughts? Thank you in advance!!! :)
fs.readFile is asynchronous and returns immediately. Your callback function is invoked some time later with the contents of the buffer. This means that fs.unlinkSync is going to delete the file at the same time it's being read. This means you effectively have a race condition, and it's possible that the file will be removed before it's ever read.
Your code should wait until the read is complete before moving on to the delete. Perhaps you want to use fs.readFileSync instead.