Discord.js Music Bot in a command handler - javascript

I want to make a music bot in my command handler, but I ran into some problems.
This is the command handler I use:
delete require.cache[require.resolve(`./commands/${command}.js`)];
let commandFile = require(`./commands/${command}.js`);
commandFile.run(client, message, args);
And in my play.js file I have a queue:
var servers = {};
I don't know how to make it so that I can skip a song (using the skip command - skip.js) in the queue. Code for skipping:
if (server.dispatcher) server.dispatcher.end();
I tried looking at tutorials but they all do it in one file which makes it easier because you can just put the "var servers = {};" on the top and its going to work. I couldn't find any tutorials where they shown how to make it so that you can use a command handler like mine.
Here are all the files:
play.js - https://hastebin.com/dijavugufu.js
skip.js - https://hastebin.com/kupecayotu.js
It would also be nice if someone told me how to modify some other music bot commands to work with a command handler.

Hey man not sure if you're still looking for an answer but I'm also working on a bot with a command handler. The way I got around this was to export the skip function directly from the play file and use that function in the skip file. Here's kinda what I did.
/*In play.js*/
var dispatcher;
async function Play(connection, message){
dispatcher = await connection.playStream("your url and options here");
}
module.exports.Skip = function(){
if(dispatcher) dispatcher.end();
}
/*In skip.js*/
const playModule = require("your_path_to/play.js");
module.exports.run = async (client, message, args) => {
var skip = playModule.Skip();
}
Sorry, I'm still pretty new to Node.js and creating a Discord bot and this may not be the most elegant solution. But the main point is that I got around it by writing the function in play.js and exporting that function to skip.js and calling it there.

Related

Listen for commands within a command discord.js

I am building a discord bot using slash commands with discord.js V14.7.1.
I have a command that sets up a listener for images from the command user. I want this command to stop collecting images when the same command is used again by the command user so only one instance of it is active at a time.
In discord.js, I have my command files separate from my command handler which I basically copied from the discord.js guide and am running commands via command.execute(). Currently, I am passing in the client as an argument for #execute and then within the commands separate file I am using the following code to shut down the image collector.
client.on(Events.InteractionCreate, async i => {
if (!i.isChatInputCommand()) return;
const command = client.commands.get(i.commandName);
const isSameCommand = command.data.name == interaction.commandName;
const isSameUser = i.user.id == interaction.user.id;
if (isSameCommand && isSameUser) {
imageCollector.stop();
}
});
After several people use the command I get the following warning: (node:20760) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 22 interactionCreate listeners added to [Client]. Use emitter.setMaxListeners() to increase limit. I think I can tell why this is occurring and presume it to be a problem if the bot is left running for a very long time, but I don't know how else to solve the problem or clean up the listeners.
I think it would be easier to not create a listener for every user.
Assuming the users are sending images in normal messages, you can put this logic in the messageCreate event listener.
let usersToCollect = [] //The slash command pushes and removes images to this array, you can use database later
client.on('messageCreate', async function (message) {
if (!message.attachements) return // Your logic for determining if its an image here
if (usersToCollect.includes(message.author.id) {
// save image
}
}

Words filter stopped working - Discord.JS 12

Hello!
So I'm currently updating my bot to version 12.3.1 of DiscordJS. Unfortunately, I got stuck on a problem that I can't really find a workaround. So, my bot has a module to filter out all of the bad words, like profanity, racial slurs, etc.
It's currently working just fine on 11.4, but cannot get it to work on 12.3.1
For some reason, the bot just does not react at all to given message.
I had two "filters" one for words, one for invites. Both of them stopped working.
bot.on('message', async message => {
// Events Listeners
if (message.author.bot) return;
if (message.channel.type === 'dm') return;
let messageArray = message.content.split(' ');
let command = messageArray[0];
let args = messageArray.slice(1);
if (!command.startsWith(prefix)) return;
let cmd = bot.commands.get(command.slice(prefix.length)) || bot.aliases.get(command.slice(prefix.length));
if (cmd) cmd.run(bot, message, args);
// First filter
var array = ['testing', 'yes', 'no'];
if (array.includes(message.content.toLocaleLowerCase())) {
message.channel.send('test')
}
// Second filter
if (message.content.includes('discord.gg/') {
message.delete()
}
}
That's the current one I found from another StackOverflow post, made 2 months ago.
Discord.js V12 Rude words filter not working
I'd really love to get some help if possible, as I can't find any reason why this feature has stopped working.
Thank you! :)
Your filters are after your command handling logic.
You have the line:
if (!command.startsWith(prefix)) return;
early in your code, and this causes message handling to terminate immediately on any message which is not a command. Due to this, the code will never reach your filters unless the message starts with your bot's prefix, at which point the message content cannot possibly be equal to any of the words and is extremely unlikely to contain discord.gg/.
Simply move your filters to the beginning of your message handler. Or alternatively separate the command handling and filter handling into separate functions, so that the return statement above only exits the command handling and the filter handling will still run.

How do I and what does it mean to splice this discord,js command code?

I've been working on a discord bot that uses javascript. I found this command online that I wanted to add to it.
const Discord = require('discord.js')
module.exports.run = async (bot, message, args) => {
if(!message.member.hasPermission("MANAGE_MESSAGES")) return message.reply("No");
let botmessage = args.join(" ");
message.delete().catch();
message.channel.send(botmessage);
}
module.exports.help = {
name: "say"
}
when I say :say Hello! or :say RandomText, the discord bot should reply with Hello!, RandomText, etc.
But instead it replies with :say RandomText.
to remove :say from the reply someone told me I have to splice it at the 1st space, but I have no idea what that means.
Well assuming the main file is fine and there's only problems in this file, you can try this (code below). It works fine without async so you can take that away.
module.exports = {
name: 'say',
execute(message, args) {
if(!message.member.hasPermission("MANAGE_MESSAGES")) return message.reply("No");
let botmessage = args.join(" ");
message.delete().catch();
message.channel.send(botmessage);
}
}
This should work just fine, but make sure you have a message you want the bot to say the same thing to right after the command (for example, if your prefix is '!', then you need to write something like !say repeat this or something). Hope this helps :)

connection.playStream is not a function

I know that there are a lot of question on this topic, but I browsed all of them but none of the answers seemed to fix my issue. I'm just creating a Discord bot for fun, I have almost never programmed in JavaScript but I wanted to try it.
My Code looks like this:
var url = "https://www.youtube.com/watch?v=HHv-s2OqYpw"
if(!message.member.voice.channel){
message.channel.send("Join a voice channel.");
return
} else {
vc = message.member.voice.channel;
connection = await vc.join();
isValid = ytdl.validateURL(url);
if(!isValid){
message.channel.send("The url you gave doesn't exist");
} else {
const stream = ytdl(url, {filter: "audioonly"});
const dispatcher = connection.playStream(stream)
dispatcher.on("end", function() {
vc.leave()
message.channel.send("Done playing the only music I can play lol")
})
I could do that it could play more songs but I only want it to play this one and in the terminal i get this error:
connection.playStream is not a function
I do have ytdl-core and opusscript installed and they both have the newest version. I tried doing this in lots of different ways, and it really annoys me that I can't figure out what the problem is. Sorry for bad english and thank those who help me. Have a nice day!
https://discord.js.org/#/docs/main/stable/class/VoiceConnection?scrollTo=play
As you can see, there's a VoiceConnection#play() method, and since you're most likely on v12, this is the method you're looking for.
const stream = ytdl(url, options);
const dispatcher = connection.play(stream);

Overlapping commands?

I'm trying to make a fun little discord chat bot with JavaScript and node.js and I'd like to put in a specific command without it affecting another one I already have set up.
She works wonderfully on all the servers I have her on, and I've got it set up so that when someone in the server says anything with "rei are", she responds with a constant from areResponses.
//const!!!
const areResponses = ["HELL yeah!", "Yep!", "I'm pretty sure that's true!", "I\'m not gonna put all the responses here because then it'd be too long..."];
//theres some other bot stuff (console log, now playing) under here but it isn't relevant until...
//the basics...
if (message.content.toLowerCase().includes("rei are")) {
var response = areResponses [Math.floor(Math.random()*areResponses.length)];
message.channel.send(response).then().catch(console.error);
}
What I want to have happen is, preferably, this command to function without setting off the "rei are" command I coded in.
if(message.content.toLowerCase().includes("rei are you happy")) {
message.channel.send("Yes, absolutely.");
}
As of right now, whenever I try to input the above command, it just triggers the "rei are" command AND the "rei are you happy" command with two messages...
else/if chains work beautifully for this actually!!!
if(message.content.toLowerCase().includes("rei do you like girls")) {
message.channel.send("Yes, absolutely. Girls are just... yeah...");
}
else if (message.content.toLowerCase().includes("rei are")) {
var response = areResponses [Math.floor(Math.random()*areResponses.length)];
message.channel.send(response).then().catch(console.error);
}
All you need to do is put the command that would overlap with the larger commands at the very bottom of the else if chain, and then you're good!!

Categories

Resources