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
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.
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()
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
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) => ({
...
});
``
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.