discord.js / ytdl-core play command - javascript

this is my second question today. I'm using discord.js v13. Earlier I looked into finding out how to make audio play from the bot, and now I am attempting to make a queue work for my discord.js bot. My problem is getting the queue defined from index.js correctly. I will provide the error log along with my code.
error logs: https://i.imgur.com/ScDcJHK.jpg
index.js
const fs = require('fs');
const { Collection, Client, Intents } = require('discord.js');
const Levels = require('discord-xp');
require('dotenv').config();
const client = new Client({
presence: {
status: 'idle',
afk: false,
activities: [{
name: 'The Official Xontavs',
type: 'WATCHING'
}],
},
intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES, Intents.FLAGS.GUILD_VOICE_STATES, Intents.FLAGS.GUILD_PRESENCES, Intents.FLAGS.GUILD_MEMBERS]
});
client.queue = new Map();
const mongoose = require('./database/mongoose.js');
Levels.setURL(`mongodb+srv://discordbot:${process.env.PASS}#bot.z8ki0.mongodb.net/myFirstDatabase?retryWrites=true&w=majority`);
['aliases', 'commands'].forEach(x => client[x] = new Collection());
['command', 'event'].forEach(x => require(`./handlers/${x}`)(client));
mongoose.init();
client.login(process.env.CLIENT_TOKEN); // SECRET TOKEN
play.js
const ytdl = require('ytdl-core');
const ytSearch = require('yt-search');
const { getVoiceConnection, joinVoiceChannel, AudioPlayerStatus, createAudioResource, getNextResource, createAudioPlayer, NoSubscriberBehavior } = require('#discordjs/voice');
const { createReadStream} = require('fs');
module.exports = {
name: "play",
category: "music",
description: "plays a song",
usage: "<id | mention>",
run: async (client, message, args, queue) => {
const voiceChannel = message.member.voice.channel;
if (!voiceChannel) return message.channel.send('You are not in a voice channel.');
const permissions = voiceChannel.permissionsFor(message.client.user);
if (!permissions.has('CONNECT', 'SPEAK')) return message.channel.send('You do not have the correct permissions');
if(!args.length) return message.channel.send('You need to send the second argument');
const server_queue = queue.get(message.guild.id);
let song = {};
if (ytdl.validateURL(args[0])) {
const song_info = await ytdl.getInfo(args[0]);
song = { title: song_info.videoDetails.title, url: song_info.videoDetails.video_url }
} else {
const video_finder = async (query) =>{
const videoResult = await ytSearch(query);
return (videoResult.videos.length > 1) ? videoResult.videos[0] : null;
}
const video = await video_finder(args.join(' '));
if (video){
song = { title: video.title, url: video.url }
} else {
message.channel.send('Error finding video.');
}
}
if (!server_queue){
const queue_constructor = {
voice_channel: voiceChannel,
text_channel: message.channel,
connection: null,
songs: []
}
queue.set(message.guild.id, queue_constructor);
queue_constructor.songs.push(song);
try {
const connection = joinVoiceChannel({
channelId: voiceChannel.id,
guildId: message.guild.id,
adapterCreator: message.guild.voiceAdapterCreator
});
queue_constructor.connection = connection;
video_player(message.guild, queue_constructor.songs[0]);
} catch (err) {
queue.delete(message.guild.id);
message.channel.send('Error connecting');
throw err;
}
} else {
server_queue.songs.push(song);
return message.channel.send(`**${song.title}** added to queue.`);
}
//audioPlayer.play(createAudioResource(stream, {seek: 0, volume: 1}))
//audioPlayer.on(AudioPlayerStatus.Idle, () => {
//audioPlayer.stop();
//connection.destroy();
//message.channel.send('Leaving VC');
//});
}
}
const video_player = async (guild, song, queue) => {
const song_queue = queue.get(guild.id);
if(!song) {
connection.destroy();
queue.delete(guild.id);
return;
}
const audioPlayer = createAudioPlayer();
song_queue.connection.subscribe(audioPlayer);
const stream = ytdl(song.url, { filter: 'audioonly' });
audioPlayer.play(createAudioResource(stream, {seek: 0, volume: 1}))
audioPlayer.on(AudioPlayerStatus.Idle, () => {
song_queue.songs.shift();
video_player(guild, song_queue.songs[0]);
});
song_queue.text_channel.send(`Now playing **${song.title}**`)
}
messageCreate.js (if needed)
const del = require('../../functions.js');
const Levels = require('discord-xp');
require('dotenv').config();
const prefix = process.env.PREFIX;
const queue = new Map();
module.exports = async (Discord, client, message) => {
if (message.author.bot || !message.guild) return;
const randomXP = Math.floor(Math.random() * 14) + 1; //1-15
const hasLeveledUP = await Levels.appendXp(message.author.id, message.guild.id, randomXP);
if (hasLeveledUP) {
const user = await Levels.fetch(message.author.id, message.guild.id);
message.channel.send(`${message.member} is now level ${user.level}.`);
}
//const args = message.content.startsWith(prefix) ? message.content.slice(prefix.length).trim().split(/ +/g) : message.content.replace(/[^\s]*/, '').trim().split(/ +/g);
const args = message.content.slice(prefix.length).trim().split(" ");
const cmd = args.shift().toLowerCase();
if (cmd.length === 0) return;
let command = client.commands.get(cmd) || client.commands.find(c => c.aliases?.includes(cmd));
if (command) {
command.run(client, message, args, queue);
}
}
Any help is appreciated because I'm really not smart and I'm still trying to learn how all this stuff works, especially with discord.js v13

In
video_player(message.guild, queue_constructor.songs[0]);
You only put two parameters and as you said in the comments, you only had to change it to this to fix your problem
video_player(message.guild, queue_constructor.songs[0], queue, audioPlayer)

Related

How to set up a SlashCommand with custom options for discord

I've been at this for 4h now... I'm making a discord bot that should take a user's input and define the word using an API call. I have an index.js that should call my urban.js file and define a word a user inputs. For example, if a user inputs "/urban cow," the bot should put the definition of a cow. However, right now it cannot read the option after "/urban" no matter what I try.
// THIS IS MY urban.js FILE
const {
SlashCommandBuilder,
SlashCommandStringOption
} = require('#discordjs/builders');
const {
request
} = require('undici');
const {
MessageEmbed
} = require('discord.js');
const wait = require('node:timers/promises').setTimeout;
const trim = (str, max) => (str.length > max ? `${str.slice(0, max - 3)}...` : str);
async function getJSONResponse(body) {
let fullBody = '';
for await (const data of body) {
fullBody += data.toString();
}
return JSON.parse(fullBody);
}
module.exports = {
data: new SlashCommandBuilder()
.setName('urban')
.setDescription('Replies with definition!')
.addStringOption(option =>
option.setName('input')
.setDescription('word to define')
.setRequired(true)),
async execute(interaction) {
const term = interaction.options.getString('input')
console.log(term);
const query = new URLSearchParams({
term
});
const dictResult = await request(`https://api.urbandictionary.com/v0/define?${query}`);
const {
list
} = await getJSONResponse(dictResult.body);
if (!list.length) {
return interaction.editReply(`No results found for **${term}**.`);
}
const [answer] = list;
const embed = new MessageEmbed()
.setColor('#EFFF00')
.setTitle(answer.word)
.setURL(answer.permalink)
.addFields({
name: 'Definition',
value: trim(answer.definition, 1024)
}, {
name: 'Example',
value: trim(answer.example, 1024)
}, {
name: 'Rating',
value: `${answer.thumbs_up} thumbs up. ${answer.thumbs_down} thumbs down.`,
}, );
interaction.editReply({
embeds: [embed]
});
},
};
// THIS IS THE INDEX JS FILE. It's not a filepath issue.
const {
token
} = require('./config.json');
const fs = require('node:fs');
const path = require('node:path');
const {
Client,
Collection,
Intents,
MessageEmbed,
DiscordAPIError
} = require('discord.js');
const wait = require('node:timers/promises').setTimeout;
const client = new Client({
intents: [Intents.FLAGS.GUILDS]
});
client.commands = new Collection();
const commandsPath = path.join(__dirname, 'commands');
const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
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));
}
}
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);
}
client.once('ready', () => {
console.log('Ready!');
});
client.on('interactionCreate', async interaction => {
if (!interaction.isCommand()) return;
const command = client.commands.get(interaction.commandName);
await interaction.deferReply({
ephemeral: true
});
await wait(4000);
if (!command) return;
try {
await command.execute(interaction);
} catch (error) {
console.error(error);
}
});
console.log(token)
client.login(token)
When I console.log(interaction.options.getString('input'))
it just gives me null.
when I console.log interaction it gives me a detailed account of the command and everything else like the user that sent it. But none of the information from the SlashCommand data. Please help.

Startup TypeError: Cannot read property 'Collection' of undefined

So I've had multiple problems one after another. The first being;
TypeError [CLIENT_MISSING_INTENTS]: Valid intents must be provided for the Client
Which I solved by changing up my code from:
const Discord = require("discord.js");
const bot = new Discord.Client();
To:
const { Client, Intents, Discord } = require("discord.js");
const bot = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] });
But now I am running into a seperate issue. Where I keep getting this error;
Startup TypeError: Cannot read property 'Collection' of undefined
This is really frustrated because I've been at this problem for a couple of hours. Any help would be massively appreciated!
All essential code:
const { Client, Intents } = require("discord.js");
const bot = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] });
const { prefix, token, mongoPath } = require("./jsonFiles/config.json");
const mongoose = require("mongoose");
const mongo = require("./utility/mongo.js");
const fs = require("fs");
const Levels = require("discord-xp");
bot.login(token);
bot.commands = new Discord.Collection();
bot.cooldowns = new Discord.Collection();
const commandFolders = fs.readdirSync("./commands");
for (const folder of commandFolders) {
//Finds the name of the command
const commandFiles = fs
.readdirSync(`./commands/${folder}`)
.filter((file) => file.endsWith(".js"));
for (const file of commandFiles) {
const command = require(`./commands/${folder}/${file}`);
bot.commands.set(command.name, command);
}
}
bot.on("ready", async () => {
console.log("Connect as " + bot.user.tag);
//levels(bot);
await mongo().then(() => {
try {
console.log("Connected to mongo!");
} finally {
mongoose.connection.close();
}
});
bot.user.setActivity(".help", {
type: "WATCHING",
});
});
bot.on("message", async (message) => {
try {
await mongo().then(async (mongoose) => {
Levels.setURL(mongoPath);
if (!message.guild) return;
if (message.author.bot) return;
const randomAmountOfXp = Math.floor(Math.random() * 20) + 1; // Min 1, Max 30
const hasLeveledUp = await Levels.appendXp(
message.author.id,
message.guild.id,
randomAmountOfXp
);
if (hasLeveledUp) {
const user = await Levels.fetch(message.author.id, message.guild.id);
message.channel.send(
`${message.author}, congratulations! You have leveled up to **${user.level}** in \`${message.guild.name}\` :sunglasses:`
);
}
});
if (!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).trim().split(/ +/);
const commandName = args.shift().toLowerCase();
const command =
bot.commands.get(commandName) ||
bot.commands.find((cmd) => cmd.aliases && cmd.aliases.includes(commandName));
if (!command) return;
if (command.guildOnly && message.channel.type === "dm")
return message.reply("I can't execute that command inside DMs!");
if (command.permissions) {
const authorPerms = message.channel.permissionsFor(message.author);
if (!authorPerms || !authorPerms.has(command.permissions)) {
if (message.author.id !== "344834268742156298") {
return message.reply("YOU DO NOT HAVE PERMISSION (git gud scrub)");
}
}
}
if (command.creator === true && message.author.id !== "344834268742156298")
return message.reply("Wait what, you are not creator man, you cannot use the command!!!!!");
if (command.args === true && !args.length) {
let reply = `You didn't provide a valid arguments, ${message.author}!`;
if (command.usage) {
reply += `\nThe proper usage would be: \`${prefix}${command.name} ${command.usage}\``;
}
message.delete({
timeout: 25 * 1000,
});
return message.channel.send(reply).then((message) => {
message.delete({
timeout: 25 * 1000,
});
});
}
const { cooldowns } = bot;
if (!cooldowns.has(command.name)) {
cooldowns.set(command.name, new Discord.Collection());
}
const now = Date.now();
const timestamps = cooldowns.get(command.name);
const cooldownAmount = (command.cooldown ?? 1.5) * 1000;
if (timestamps.has(message.author.id)) {
const expirationTime = timestamps.get(message.author.id) + cooldownAmount;
if (now < expirationTime) {
const timeLeft = (expirationTime - now) / 1000;
return message.reply(
`please wait ${timeLeft.toFixed(1)} more second(s) before reusing the \`${
command.name
}\` command.`
);
}
}
timestamps.set(message.author.id, now);
setTimeout(() => timestamps.delete(message.author.id), cooldownAmount);
const maxArguments = command.maxArgs || null;
if (
args.length < command.minArgs ||
(maxArguments !== null && command.args === "true" && args.length > command.maxArgs)
) {
let reply = `\nThe proper usage would be: \`${prefix}${command.name} ${command.usage}\``;
return message.channel.send(reply);
}
try {
command.execute(message, args, message.guild);
} catch (err) {
console.log(err);
}
} catch (err) {
console.log(err);
}
});
At the top you never defined Discord properly. You are trying to access the non-existant Discord property of the discord.js module with object destructuring. There are 2 quick fixes for this, the first one will be faster however.
//at the top change the declaration of Client
const Discord = {
Client,
Intents
} = require('discord.js')
//Discord is module discord.js
Or you can do
const {
Collection,
Client,
Intents
} = require('discord.js')
//use new Collection() instead of new Discord.Collection()
Try instead of:
const { Client, Intents } = require("discord.js");
Try:
const Discord = require("discord.js"), { Client, Intents } = Discord;
Or you can also import Collection from discord:
const { Client, Intents, Collection } = require("discord.js");
and replace:
new Discord.Collection() with new Collection()

Discord js doesn't plays audio anymore

I had a base discordjs code that could play 2 audio files, leave and join voice channels, but I did created a new file with this code followed from a youtube video:
const ytSearch = require('yt-search');
module.exports = {
name: 'play',
descreption: 'Play',
async execute(message, args) {
const voiceChannel = message.member.voice.channel;
if (!voiceChannel) return message.send('PALI! Egy voice channelben bent kéne lenne, már nemazé!');
const permissions = voiceChannel.permissionsFor(message.client.user);
if (!permissions.has('Player')) return message.reply('Kéne rang is nem gondolnád?, hogy a bánat egyeki a lelked!');
if (!args.length) return message.channel.reply('KÖZÖLDNÉDHOGYMIAKUKITAKARSZ?? (Need more argumets)');
const connection = await voiceChannel.join();
const videoFinder = async (query) => {
const videoResult = await ytSearch(query);
return (videoResult.videos.length > 1) ? videoResult.videos[0] : null;
}
const video = await videoFinder(args.join(' '));
if (video) {
const stream = ytdl(video.url, { filter: 'audioonly' });
connection.play(stream, { seek: 0, volume: 100 })
on('finish', () => {
voiceChannel.leave();
});
await message.reply(`Most játszom: ***${video.title}$***`)
}
else {
message.channel.send('Nem találtam videót.')
}
}
}
Then I tried to imploment it into my other js file, but after I did it it gave me errors so I gave it up and deleted all that stuff, but now the original code just doesn't wants to play audio, it doesn't gives me errors or anything, I tried everthing I could but I couldn't solve it. Any solutions?
Here's the code:
const Discord = require('discord.js');
const client = new Discord.Client();
//const ytdl = require('ytdl-core');
//const ytSearch = require('yt-search');
var prefix = ';';
client.login('CENSORED');
client.on('ready', () =>{
console.log('\n ----------WELCOME TO ADY STUDIOS AUTOMATIC------------')
})
client.on('message', async message => {
if (message.content === ';join') {
if (message.member.voice.channel) {
const connection = await message.member.voice.channel.join();
} else {
message.reply('You need to join a voice channel first!');
}
}
if(message.content === ';leave'){
message.guild.me.voice.channel.leave();
}
if (message.content === ';coconut') {
const connection = await message.member.voice.channel.join();
const dispatcher = connection.play('./coconut.m4a');
}
if (message.content === ';roll'){
const connection = await message.member.voice.channel.join();
const dispatcher = connection.play('./rickroll.m4a');
}
});
{ "dependencies": { "#discordjs/opus": "^0.3.2", "discord.js": "^12.3.1", "ffmpeg-static": "^4.2.7", "mysql": "^2.18.1", "opusscript": "0.0.7", "request": "^2.88.2", "ytdl-core": "^4.2.1" } } install disc should be work

Erro:SyntaxError: Unexpected token ':' in MUSIC BOT

I am creating a music bot, and one command of he is prefix + "play", and in the chat I put "!play + [a youtube link]", but this error appeared on the console. The code of "play" is:
===================================================================
const Discord = require('discord.js');
const ytdl = require("ytdl-core");
module.exports.run = async (bot, message, args) => {
name: "play",
description: "Play a song in your channel!",
async execute(message) {
try {
const args = message.content.split(" ");
const queue = message.client.queue;
const serverQueue = message.client.queue.get(message.guild.id);
const voiceChannel = message.member.voice.channel;
if (!voiceChannel)
return message.channel.send(
"You need to be in a voice channel to play music!"
);
const permissions = voiceChannel.permissionsFor(message.client.user);
if (!permissions.has("CONNECT") || !permissions.has("SPEAK")) {
return message.channel.send(
"I need the permissions to join and speak in your voice channel!"
);
}
const songInfo = await ytdl.getInfo(args[1]);
const song = {
title: songInfo.videoDetails.title,
url: songInfo.videoDetails.video_url
};
if (!serverQueue) {
const queueContruct = {
textChannel: message.channel,
voiceChannel: voiceChannel,
connection: null,
songs: [],
volume: 5,
playing: true
};
queue.set(message.guild.id, queueContruct);
queueContruct.songs.push(song);
try {
var connection = await voiceChannel.join();
queueContruct.connection = connection;
this.play(message, queueContruct.songs[0]);
} catch (err) {
console.log(err);
queue.delete(message.guild.id);
return message.channel.send(err);
}
} else {
serverQueue.songs.push(song);
return message.channel.send(
`${song.title} has been added to the queue!`
);
}
} catch (error) {
console.log(error);
message.channel.send(error.message);
}
},
play(message, song) {
const queue = message.client.queue;
const guild = message.guild;
const serverQueue = queue.get(message.guild.id);
if (!song) {
serverQueue.voiceChannel.leave();
queue.delete(guild.id);
return;
}
const dispatcher = serverQueue.connection
.play(ytdl(song.url))
.on("finish", () => {
serverQueue.songs.shift();
this.play(message, serverQueue.songs[0]);
})
.on("error", error => console.error(error));
dispatcher.setVolumeLogarithmic(serverQueue.volume / 5);
serverQueue.textChannel.send(`Starting play: **${song.title}**`);
}
};
===================================================================
The error is: "Erro:SyntaxError: Unexpected token ':'".
Someone can help me plese?
If its supposed to return an object, put parentheses around it, like this:
// From
module.exports.run = async (bot, message, args) => {
...
};
// To
module.exports.run = async (bot, message, args) => ({
...
});
``

Working on a Discord bot with discord.js, tempmute won't work

making a discord bot in javascript with visual studio code but for some reason getting an error. I'll show you the code that is relevant first.
Overall trying to get a temporary mute function to work and I want to add it to the available commands which pops up when you hit !help. Table looks like this:
!help
classes I'm working with
Here is the index.js:
const { Client, Collection } = require("discord.js");
const { config } = require("dotenv");
const fs = require("fs");
const client = new Client({
disableEveryone: true
});
client.commands = new Collection();
client.aliases = new Collection();
client.categories = fs.readdirSync("./commands/");
config({
path: __dirname + "/.env"
});
["command"].forEach(handler => {
require(`./handlers/${handler}`)(client);
});
client.on("ready", () => {
console.log(`Hi, ${client.user.username} is now online!`);
client.user.setPresence({
status: "online",
game: {
name: "you get boosted❤️",
type: "Watching"
}
});
});
client.on("message", async message => {
const prefix = "!";
if (message.author.bot) return;
if (!message.guild) return;
if (!message.content.startsWith(prefix)) return;
if (!message.member) message.member = await message.guild.fetchMember(message);
const args = message.content.slice(prefix.length).trim().split(/ +/g);
const cmd = args.shift().toLowerCase();
if (cmd.length === 0) return;
let command = client.commands.get(cmd);
if (!command) command = client.commands.get(client.aliases.get(cmd));
if (command)
command.run(client, message, args);
});
client.login(process.env.TOKEN);
Here is tempmute:
bot.on('message', message => {
let args = message.content.substring(PREFIX.length).split(" ");
switch (args[0]) {
case 'mute':
var person = message.guild.member(message.mentions.users.first() || message.guild.members.get(args[1]));
if(!person) return message.reply("I CANT FIND THE USER " + person)
let mainrole = message.guild.roles.find(role => role.name === "Newbie");
let role = message.guild.roles.find(role => role.name === "mute");
if(!role) return message.reply("Couldn't find the mute role.")
let time = args[2];
if(!time){
return message.reply("You didnt specify a time!");
}
person.removeRole(mainrole.id)
person.addRole(role.id);
message.channel.send(`#${person.user.tag} has now been muted for ${ms(ms(time))}`)
setTimeout(function(){
person.addRole(mainrole.id)
person.removeRole(role.id);
console.log(role.id)
message.channel.send(`#${person.user.tag} has been unmuted.`)
}, ms(time));
break;
}
});
Here is the help.js which lists all commands
const { RichEmbed } = require("discord.js");
const { stripIndents } = require("common-tags");
module.exports = {
name: "help",
aliases: ["h"],
category: "info",
description: "Returns all commands, or one specific command info",
usage: "[command | alias]",
run: async (client, message, args) => {
if (args[0]) {
return getCMD(client, message, args[0]);
} else {
return getAll(client, message);
}
}
}
function getAll(client, message) {
const embed = new RichEmbed()
.setColor("RANDOM")
const commands = (category) => {
return client.commands
.filter(cmd => cmd.category === category)
.map(cmd => `- \`${cmd.name}\``)
.join("\n");
}
const info = client.categories
.map(cat => stripIndents`**${cat[0].toUpperCase() + cat.slice(1)}** \n${commands(cat)}`)
.reduce((string, category) => string + "\n" + category);
return message.channel.send(embed.setDescription(info));
}
function getCMD(client, message, input) {
const embed = new RichEmbed()
const cmd = client.commands.get(input.toLowerCase()) || client.commands.get(client.aliases.get(input.toLowerCase()));
let info = `No information found for command **${input.toLowerCase()}**`;
if (!cmd) {
return message.channel.send(embed.setColor("RED").setDescription(info));
}
if (cmd.name) info = `**Command name**: ${cmd.name}`;
if (cmd.aliases) info += `\n**Aliases**: ${cmd.aliases.map(a => `\`${a}\``).join(", ")}`;
if (cmd.description) info += `\n**Description**: ${cmd.description}`;
if (cmd.usage) {
info += `\n**Usage**: ${cmd.usage}`;
embed.setFooter(`Syntax: <> = required, [] = optional`);
}
return message.channel.send(embed.setColor("GREEN").setDescription(info));
}
ERROR:
Error message, bot not defined.
Overall trying to get a temporary mute function to work and I want to add it to the available commands which pops up when you hit !help. Table looks like this:
!help
I think the tempmute simply doesn't work because you use bot.on() instead of client.on(), which was defined in the index.js. I can't help you for the rest but everything is maybe related to this.

Categories

Resources