Discord Bot CommandFile is not a constructor - javascript

I'm currently trying to reorganize my Bot for my Discord Server by upgrading my Command Handler.
Most of the command I have also upgraded but one command stands out because it is not working.
When I try to run that command the following happens:
(node:7020) UnhandledPromiseRejectionWarning: TypeError: CommandFile.run is not a constructor
at module.exports.run (C:\Users\jason\OneDrive\Bureaublad\KoalaBot\KoalaBotV2.1\src\commands\Music\Play.js:43:20)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
(node:7020) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:7020) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
And this is the code I have for the part that is currently not working, full code is somewhere down below:
if (!Validate) {
let CommandFile = require(`./Search.js`);
return new CommandFile.run(Client, message, args, ops);
}
The Command Handler I'm using is from MenuDocs v12 Tutorial.
I've tried placing this part into a function outside the class and called the function after the if statement but to no avail.
let CommandFile = require(`./Search.js`);
return CommandFile.run(Client, message, args, ops);
I have also checked if it was the correct file location of the Search.js.
Search.js File:
const Command = require('../../Structures/Command.js');
const Discord = require("discord.js");
const Search= require('yt-search');
module.exports = class extends Command {
// eslint-disable-next-line no-unused-vars
async run(message, args, ops) {
const Client = this.client
//Search for videos based on arguments
Search(args.join(' '), function(err, res) {
//Error Handling
let errembed = new Discord.MessageEmbed()
.setColor("#218559")
.setAuthor(Client.user.username, Client.user.displayAvatarURL({ dynamic:true }))
.setDescription("Sorry, something went wrong")
if (err) return message.channel.send(errembed);
//Show first 10 results
let Videos = res.videos.slice(0, 10);
//Loop for output string
let Resp = '';
for (var i in Videos) {
Resp += `**[${parseInt(i)+1}]:** \`${Videos[i].title}\`\n`;
}
//Text Info Instructions
Resp += `\n**Choose a number between** \`1-${Videos.length}\``;
//Embed
let Embed = new Discord.MessageEmbed()
.setColor("#218559")
.setTitle("Search Results")
.setAuthor(Client.user.username, Client.user.displayAvatarURL({ dynamic:true }))
.setDescription(Resp)
.setThumbnail(Client.user.displayAvatarURL({ dynamic:true }))
//Send output
message.channel.send(Embed);
//Message collector
const Filter = m => !isNaN(m.content) && m.content < Videos.length+1 && m.content > 0;
//Filter accepts only numbers
const Collector = message.channel.createMessageCollector(Filter);
//Update collector variables
Collector.videos = Videos;
//Create Listener Event
Collector.once('collect', function(m) {
//Run play command, passing in the url as args[0]
let CommandFile = require(`./Play.js`);
CommandFile.run(Client, message, [this.videos[parseInt(m.content)-1].url], ops);
});
});
}
};
This all worked with the previous command handler I was using.
The complete Play.js:
const Command = require('../../Structures/Command.js');
const Discord = require("discord.js");
const ytdl = require("ytdl-core");
module.exports = class extends Command {
constructor(...args) {
super(...args, {
aliases: ['p']
});
}
// eslint-disable-next-line no-unused-vars
async run(message, args, ops) {
const Client = this.client
//Check if author is connected to a voice channel
let AC = new Discord.MessageEmbed()
.setColor("#218559")
.setAuthor(Client.user.username, Client.user.displayAvatarURL({
dynamic: true
}))
.setDescription("You have to be connected to a voice channel, you dummy!")
if (!message.member.voice.channel) return message.channel.send(AC);
//Check if author input an URL
let VU = new Discord.MessageEmbed()
.setColor("#218559")
.setAuthor(Client.user.username, Client.user.displayAvatarURL({
dynamic: true
}))
.setDescription("Hey Dumdum, you need a valid URL")
if (!args[0]) return message.channel.send(VU);
//Validate Info
let Validate = await ytdl.validateURL(args[0]);
//Check Validation
if (!Validate) {
let CommandFile = require(`./Search.js`);
return new CommandFile.run(Client, message, args, ops);
}
//Fetch video information
let Info = await ytdl.getInfo(args[0]);
//Fetch Active
let Data = ops.active.get(message.guild.id) || {};
//Update the Data
if (!Data.Connection) Data.Connection = await message.member.voice.channel.join();
if (!Data.Queue) Data.Queue = [];
Data.guildID = message.guild.id;
//Add song to queue
Data.Queue.push({
SongTitle: Info.videoDetails.title,
Requester: message.author.tag,
url: args[0],
AnnounceChannel: message.channel.id
})
//If there is no dispatcher, run the play function
let QA = new Discord.MessageEmbed()
.setColor("#218559")
.setAuthor(Client.user.username, Client.user.displayAvatarURL({
dynamic: true
}))
.setDescription(`Added to Queue: ${Info.videoDetails.title} | Requested by my favourite dummy ${Data.Queue[0].Requester}`)
if (!Data.Dispatcher) Play(Client, ops, Data);
else {
message.channel.send(QA);
}
//Update the Map
ops.active.set(message.guild.id, Data);
}
};
//Play Function
async function Play(Client, ops, Data) {
//Send Now Playing Message
let NP = new Discord.MessageEmbed()
.setColor("#218559")
.setAuthor(Client.user.username, Client.user.displayAvatarURL({
dynamic: true
}))
.setDescription(`Now playing: ${Data.Queue[0].SongTitle} | Requested by my favourite dummy ${Data.Queue[0].Requester}`)
Client.channels.cache.get(Data.Queue[0].AnnounceChannel).send(NP);
//Update Dispatcher Data
Data.Dispatcher = await Data.Connection.play(ytdl(Data.Queue[0].url, {
filter: "audioonly"
}));
Data.Dispatcher.guildID = Data.guildID;
//Listener event
Data.Dispatcher.once("finish", function() {
//Finish Function
finish(Client, ops, this);
});
}
function finish(Client, ops, Dispatcher) {
//Fetch Guild Object from Map
let Fetched = ops.active.get(Dispatcher.guildID);
//Remove the previous SongTitle
Fetched.Queue.shift();
//Check if Queue is empty
if (Fetched.Queue.length > 0) {
//Update the map with the new queue
ops.active.set(Dispatcher.guildID, Fetched);
//Play the next song
Play(Client, ops, Fetched);
} else {
//Delete the guild object from the Map
ops.active.delete(Dispatcher.guildID);
//Leave the voice channel
let vc = Client.guilds.cache.get(Dispatcher.guildID).me.voice.channel;
if (vc) vc.leave();
}
}
Someone suggested I do this in the Search.js but the error there is that it isn't a class.
class Search extends Command {
async run(message, args, ops) {
/* things here */
}
};
module.exports = { Search };

run is not a static method, but you're calling it like one. add a parentheses when you initialize the exported class inside the required commandfile.
if (!Validate) {
let CommandFile = require(`./Search.js`);
return new CommandFile.run(Client, message, args, ops);
}
Node expects an empty constructor when you initialize a new class, so it views the run method you're calling as a constructor. The problem is that run isn't called by the actual class.
This
return new CommandFile.run(Client, message, args, ops);
should become this:
return new CommandFile().run(Client, message, args, ops);
Use this same logic wherever you initialize a new class without calling an empty constructor.
Unrelated to your issue, you do const Client = this.client which will turn up undefined since this.client isn't anything. there is no point in setting it as a class field from what i'm seeing of the file. Just set Client to a new Discord.Client() instead.
Hope this helped and good luck!

Related

Command interaction not responding

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
}

Output increasing every time the command is used

I tried to make a kick members script in discord.js. My error is, that every time I send the !kick command the message gets displayed one more time. For example, if I send !kick for the first time, it would send this response: "Please specify a user!". If I send it for the second time, it would send that message twice, and so on. My code:
const Discord = require("discord.js")
exports.run = async(client, msg, args) => {
msg.delete();
if(!msg.member.hasPermission('KICK_MEMBERS')) return msg.reply('you don\'t have permission to use this command!')
const user = msg.mentions.users.first() || msg.guild.members.cache.get(args[0]);
if(!user) return msg.reply(`please specify a user you wish to be punished.`).then(msg => msg.delete({timeout: 5000}));
let member;
try {
member = await msg.guild.members.fetch(user)
} catch(err) {
member = null;
}
if(member){
if(member.hasPermission('MANAGE_MESSAGES')) return msg.reply('that user is too cool to be banned.').then(msg => msg.delete({timeout: 5000}));
}
let reason = args.slice(1).join(' ');
if(!reason) return msg.reply('please specify a reason.').then(msg => msg.delete({timeout: 5000}));
let channel = msg.guild.channels.cache.find(c => name.name === '📁┊discord_logs');
let log = new Discord.MessageEmbed()
.setColor('#0088FF')
.setDescription(`${user} has been kicked by ${msg.author} for ${reason}`)
channel.send(log);
let userLog = new Discord.MessageEmbed()
.setColor('#0088FF')
.setDescription(`You have been kicked from Scratta for: ${reason}`)
try {
await user.send(userLog);
} catch(err) {
console.warn(err);
}
member.kick(reason)
let confir = new Discord.MessageEmbed()
.setColor('#0088FF')
.setDescription(`${user} has been kicked from Scratta.`)
msg.channel.send(confir);
msg.delete();
}
You‘re missing this line at the top in your module.exports:
if (msg.author.bot) return;
This will make sure that the bot doesn‘t react to his own message

Need Assistance With My unmute command for discord.js

Basically This command is giving one major issue and that the fact that when the user is muted he won't be unmuted because of the command not responding back to the mute command
const Discord = require('discord.js');
const fs = module.require('fs');
module.exports.run = async (client, message, args) => {
if (!message.member.hasPermission('MANAGE_MESSAGES')) return;
let unMute = message.mentions.members.first() || message.guild.members.cache.get(args[0]);
if (!unMute) {
let exampleEmbed = new Discord.MessageEmbed()
.setDescription("__UNMUTE INFO__")
.setColor(client.colors.success)
.setThumbnail(client.user.displayAvatarURL())
.addField(`Unmute Command`, `Unmutes a mentioned user.`)
.addField(`Unmute Command`, `Unmutes User By Id.`)
.addField("Example", `${client.config.prefix}Unmutes #user`)
.addField("Example", `${client.config.prefix}Unmutes #id`)
message.channel.send(exampleEmbed);
return;
}
let role = message.guild.roles.cache.find(r => r.name === 'Muted');
message.channel.send(`Please Check roles to be sure user was unmuted`);
if (!role || !unMute.roles.cache.has(role.id)) return message.channel.send(`That user is not muted.`);
if (!role || !unMute.roles.cache.has(User.id)) return message.channel.send(`----`);
let guild = message.guild.id;
let member = client.mutes[unMute.id];
if (member) {
if (member === message.guild.id) {
delete client.mutes[unMute.id];
fs.writeFile("./mutes.json", JSON.stringify(client.mutes), err => {
if (err) throw err;
})
await unMute.roles.remove(role.id);
message.channel.send(`:white_check_mark: ${unMute} Has been unmuted.`);
}
return;
}
await unMute.roles.remove(role.id);
message.channel.send(`:white_check_mark: ${unMute} Has been unmuted.`);
message.delete();
}
module.exports.config = {
name: 'unmute',
description: 'Unmute a user.',
access: 'Manage Messages Permission',
usage: 'unmute #vision'
}
I'm Also getting an error message when manually unmuting the user
(node:6604) UnhandledPromiseRejectionWarning: ReferenceError: User is not defined
Any Form of help would be greatly appreciated and thank you for your time.
On the line if (!role || !unMute.roles.cache.has(User.id)) return message.channel.send('----'), you reference the variable User, but you haven't definied it anywhere, and even if it was defined, you need a role not a member or user. I'm pretty sure it should instead be Role.id. Also, not 100% sure on this, but I tnink it should just be Role not Role.id.

Discord.js embed image not working. (Could not interpret "{'url': 'https://cdn.nekos.life/boobs/boobs105.gif'}" as string.)

My command.js
based on some other bots like HarutoHiroki Bot thst open source on Github and the Nekos.life documentation
const Discord = require('discord.js');
const client = require('nekos.life');
const neko = new client();
module.exports.run = async (bot, message, args) => {
if (message.channel.nsfw === true) {
link = await neko.nsfw.boobs()
console.log(link)
const embed = new Discord.MessageEmbed()
.setAuthor(`Some neko boobs`)
.setColor('#00FFF3')
.setImage(link)
.setFooter(`Bot by`);
message.channel.send(embed);
}
else {
message.channel.send("This isn't NSFW channel!")
}
};
module.exports.config = {
name: "boobs",
description: "",
usage: "*boobs",
accessableby: "Members",
aliases: []
}
Error:
> node .
(node:25052) ExperimentalWarning: Conditional exports is an experimental feature. This feature could change at any time
Logged in and connected as Bot#1234
{ url: 'https://cdn.nekos.life/boobs/boobs105.gif' }
(node:25052) UnhandledPromiseRejectionWarning: DiscordAPIError: Invalid Form Body
embed.image.url: Could not interpret "{'url': 'https://cdn.nekos.life/boobs/boobs105.gif'}" as string.
at RequestHandler.execute (C:\Users\User\Documents\GitHub\Bot\node_modules\discord.js\src\rest\RequestHandler.js:170:25)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
(node:25052) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)(node:25052) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
My Question
how to fix this? (I tried the hole day but didn't got it working need help soon as possible)
I fixed it:
const Discord = require('discord.js');
const client = require('nekos.life');
const neko = new client();
module.exports.run = async (bot, message, args) => {
if (message.channel.nsfw === true) {
link = await neko.nsfw.boobs()
const embed = new Discord.MessageEmbed()
.setAuthor(`Some neko boobs`)
.setColor('#00FFF3')
.setImage(link.url)
.setFooter(`Bot by`);
message.channel.send(embed);
}
else {
message.channel.send("This isn't NSFW channel!")
}
};
module.exports.config = {
name: "boobs",
description: "",
usage: "*boobs",
accessableby: "Members",
aliases: []
}
It looks like neko.nsfw.boobs() returns an object, not a string. Try this instead:
const { url } = await neko.nsfw.boobs(); // get only the URL, not the whole object
const embed = new Discord.MessageEmbed()
.setAuthor(`Some neko boobs`)
.setColor('#00FFF3')
.setImage(link.url)
.setFooter(`Bot by`);
message.channel.send(embed);
Here's a code snippet example:
const link = {
url: 'https://cdn.nekos.life/boobs/boobs105.gif'
};
console.log(link); // this will not give the link. it will give the whole object
/* using object destructuring, you can use brackets to capture one
property of an array. in this case, the url.
Object Destructuring - https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
*/
const {
url
} = link;
console.log(url); // this will give *only* the link
console.log(link.url); // another method to give only the link

Temporary mute command returning error 'Cannot read property 'slice' of undefined'

I am trying to create a temporary mute command, that will unmute the muted user in the given time.
Here's my code:
const Discord = require("discord.js");
const ms = require("ms");
module.exports = {
name: 'mute',
description: 'mute a specific user',
usage: '[tagged user] [mute time]',
async execute(message, embed, args) {
let tomute = message.guild.member(message.mentions.users.first() || message.guild.members.get(args[0]));
if (!tomute) return message.reply("Couldn't find user.");
const reason = args.slice(1).join(' ');
if (tomute.hasPermission("MANAGE_MESSAGES")) return message.reply("Can't mute them!");
const muterole = message.guild.roles.cache.find(muterole => muterole.name === "muted");
if (!muterole) {
try {
muterole = await message.guild.roles.create({
name: "muted",
color: "#000000",
permissions: []
})
message.guild.channels.cache.forEach(async (channel, id) => {
await channel.overwritePermissions(muterole, {
SEND_MESSAGES: false,
ADD_REACTIONS: false
});
});
} catch (e) {
console.log(e.stack);
}
}
const mutetime = args.slice(2).join(' ');
//here is the start of the error
await (tomute.roles.add(muterole.id));
message.reply(`<#${tomute.id}> has been muted for ${ms(ms(mutetime))} `);
setTimeout(function() {
tomute.roles.remove(muterole.id);
message.channel.send(`<#${tomute.id}> has been unmuted!`);
}, ms(mutetime));
}
}
Currently getting the following error: Cannot read property 'slice' of undefined
Do you have any idea on how to fix the command?
edit
this after a year and this is for future people who come here
the issue was here
async execute(message, embed, args) {
i never passed embed from my main file so args was undefined
embed part was where the args should have been, I was stupid at that time and was new to coding, but as I now have some experience, I decided to edit this to show what wrong
It means that somewhere in your code, you have a value which is undefined and you try to use the string/array function slice on it but undefined does not have this function : so it is a error.

Categories

Resources