const ytdl = require('ytdl-core');
const ytSearch = require('yt-search');
module.exports = {
name: 'play',
description: "plays music in voice chat",
async execute(message, args, Discord){
const voiceChannel = message.member.voice.channel;
if (!voiceChannel) return message.channel.send('You need to be in a voice channel to listen to music!');
const permissions = voiceChannel.permissionsFor(message.client.user);
if (!permissions.has('CONNECT')) return message.reply("You don't have the correct permissions to request music!");
if (!permissions.has('SPEAK')) return message.reply("You don't have the correct permissions to request music!");
if (!args.length) return message.channel.send("You Can't Request for no Music Silly >_<");
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: 1})
.on('finish', () =>{
voiceChannel.leave();
});
await message.reply(`:Thumbsup: Now Playing >>>${video.title}<<<`)
} else {
message.reply('No Video Results Found :(');
}
}
}
My Error message is const connection = await voiceChannel.join();
TypeError: voiceChannel.join is not a function
If any of you have a suggestion that may work please feel free to edit it. It can also only detect if someone is in voice chat at start up of the bot, so if your in voice chat at start of bot it sends the in voice chat message while your in and out of voice chat
While transitioning from discord.js v12 - v13 we have encountered a breaking change that is switching to #discordjs/voice a seperate library for voice to play with discord.js, now as suggested from the comment here I see you're using the most latest version of discord.js where the VoiceChannel#join method no longer exists. You have to propose the following changes:
Install #discordjs/voice using npm install #discordjs/voice
You need to establish a voiceConnection, and further create an AudioPlayer instance and go ahead and call the AudioPlayer#subscribe method to this player, you would have to do some base additions for the same which are exhibited below:
const {
joinVoiceChannel,
createAudioPlayer,
createAudioResource
} = require('#discordjs/voice');
const connection = joinVoiceChannel({
channelId: message.member.voice.channel.id,
guildId: message.guild.id,
adapterCreator: message.guild.voiceAdapterCreator,
});
const stream = ytdl(video.url, {
filter: "audioonly"
});
const player = createAudioPlayer();
const resource = createAudioResource(stream);
async function play() {
await player.play(resource);
connection.subscribe(player);
}
They just made it overcomplex for beginners to comprehend so don't worry! If you feel like you're over- exhausting yourselves you can always downgrade to a lower version like so:
npm uninstall discord.js
npm install discord.js#12.5.3
Welcome to stackoverflow 😄
Related
I am creating a bot using guide by Discord.js, however after like 3 or sometimes 3 commands the bot stops working and i get
discord message
i have tried to restart it many times but after sometime it just stop working again and again
const fs = require('node:fs');
const path = require('node:path')
const { Client, Events, GatewayIntentBits, Collection ,ActionRowBuilder,EmbedBuilder, StringSelectMenuBuilder } = require('discord.js');
const { token } = require('./config.json');
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
client.commands = new Collection();
const commandsPath = path.join(__dirname,'commands');
const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
for (const file of commandFiles) {
const filePath = path.join(commandsPath,file);
const command = require(filePath);
if('data' in command && 'execute' in command){
client.commands.set(command.data.name,command);
}else{
console.log(`[WARNING] The command at ${filePath} is missing`);
}
}
client.once(Events.ClientReady, () => {
console.log('Ready!');
})
//menu
client.on(Events.InteractionCreate, async interaction => {
if (!interaction.isChatInputCommand()) return;
if (interaction.commandName === 'ping') {
const row = new ActionRowBuilder()
.addComponents(
new StringSelectMenuBuilder()
.setCustomId('select')
.setPlaceholder('Nothing selected')
);
const embed = new EmbedBuilder()
.setColor(0x0099FF)
.setTitle('pong')
.setDescription('Some description here')
.setImage('https://media.istockphoto.com/id/1310339617/vector/ping-pong-balls-isolated-vector-illustration.jpg?s=612x612&w=0&k=20&c=sHlz5sbJrymDo7vfTQIuaj4lbmwlvAhVE7Uk_631ZA8=')
await interaction.reply({ content: 'Pong!', ephemeral: true, embeds: [embed]});
}
});
//======================================================================================================================
client.on(Events.InteractionCreate, async interaction => {
if (!interaction.isChatInputCommand ||
interaction.isButton() ||
interaction.isModalSubmit()) return;
const command = interaction.client.commands.get(interaction.commandName);
if (!command) {
console.error(`No command matching ${interaction.commandName} was found`)
return;
}
try {
await command.execute(interaction);
}catch(error){
console.error(error);
await interaction.reply({content: 'There was an error while executing this command!', ephemeral: true});
}
console.log(interaction);
});
client.login(token);
Error i get in terminal
I wanted this bot to continue to execute commands as long as it's up and running
This is a common error in Discord.JS that occurs when you already replied to an interaction and you attempt to reply again.
From the discord.js discord server:
You have already replied to the interaction.
• Use .followUp() to send a new message
• If you deferred reply it's better to use .editReply()
• Responding to slash commands / buttons / select menus
To fix this error, you can use .followUp() to send another message to the channel or .editReply() to edit the reply as shown above.
You can see the documentation on a command interaction here
Yes the problem is that you cant reply to a slash command more then once in discords api so instead you should use
interaction.channel.send()
or
interaction.editReply()
The audio player doesn't play anything in the voice channel. There is only the green ring around the profile but no sound. Does anyone know why? I'm using discord.js v13
const { Client, Intents, discord } = require('discord.js');
const client = new Client({ intents: [ Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES, Intents.FLAGS.GUILD_VOICE_STATES ]});
const { joinVoiceChannel } = require('#discordjs/voice');
const { createAudioPlayer, AudioPlayerStatus, createAudioResource } = require('#discordjs/voice');
client.on("message", message => {
if(message.content.startsWith("!play")){
const channel = message.member.voice.channel
const player = createAudioPlayer();
player.on(AudioPlayerStatus.Playing, () => {
message.channel.send("Now playing")
})
player.on("error", error => {
console.log(error)
})
const resource = createAudioResource('./music.mp3');
player.play(resource)
const connection = joinVoiceChannel({
channelId: message.member.voice.channel.id,
guildId: message.guild.id,
adapterCreator: message.guild.voiceAdapterCreator
});
const subscription = connection.subscribe(player)
if(subscription){
setTimeout(() => {
subscription.unsubscribe()
}, 15_000)
}
}
})
Your code seems to be fine whats causing the problem is that you need to install ffmpeg-static ( you can find the relating post from the discord.js documentation here ). ffmpeg is used for converting mp3 files to something your discord bot can play. You should also have #discordjs/voice and discord.js but by the looks of it you have.
Please let me know if installing ffmpeg-static solves your problem
So, It's been two long days traying to figure what the reck is going on... I'm creating a Bot to my Discord Channel that plays an audio.mp3 when a command is written, like !laugh then the bot should enter the voice channel and reproduce laugh.mp3. I've tried in so manny different ways but the bot keeps entering the channel, the green circle quickly appears but no sound is played...
const { join } = require('path');
const { joinVoiceChannel, createAudioPlayer, createAudioResource, getVoiceConnection, entersState, StreamType, AudioPlayerStatus, VoiceConnectionStatus, AudioResource } = require("#discordjs/voice");
module.exports = {
name: 'laugh',
aliases: ["l"],
run: async(client, message, args) => {
const player = createAudioPlayer()
const connection = joinVoiceChannel({
channelId: message.member.voice.channel.id,
guildId: message.guild.id,
adapterCreator: message.guild.voiceAdapterCreator
}).subscribe(player)
let resource = createAudioResource(join('./som/', 'laugh.mp3'));
player.play(resource)
player.on(AudioPlayerStatus.AutoPaused, () => {
player.stop();
});
}
}
I've already tried to caugh error but apparently nothing is wrong, I already have all intents in my index.js.
So, anyone could help me find a solution?
Past the 3rd day I resolved to find other library I could use to solve the problem, turns out I found a solution using FS!
Instead of only try to play the file, I've created a stream and then I just play the stream... In terms of performance that's not the greatest solution ever, but it works!
That's how it goes:
const {createReadStream } = require('fs')
const { join } = require('path');
const { joinVoiceChannel, createAudioPlayer, createAudioResource,
getVoiceConnection, entersState, StreamType, AudioPlayerStatus,
VoiceConnectionStatus, AudioResource } = require("#discordjs/voice");
module.exports = {
name: 'laugh',
aliases: ["l"],
run: async(client, message, args) => {
const player = createAudioPlayer();
const connection = joinVoiceChannel({
channelId: message.member.voice.channel.id,
guildId: message.guild.id,
adapterCreator: message.guild.voiceAdapterCreator,
selfDeaf: false,
}).subscribe(player);
let resource = createAudioResource(createReadStream(join(__dirname, 'som/laugh.mp3')), {
inlineVolume : true
});
resource.volume.setVolume(0.9);
console.log(join(__dirname, 'som/laugh.mp3'));
player.play(resource)
player.on(AudioPlayerStatus.AutoPaused, () => {
player.stop();
});
Something I must alert is about Replit not resolving properly Node.js 17 and other dependencies, so to bring your Bot up 24/7 use Heroku and GitHub. To finish the GUILD_VOICE_STATES Intents are required to be set, I was using 32767 but somehow this wasn't working.
That's it!
I recently installed Discord.js 13.1.0 and my music commands broke because, apparently, channel.join(); is not a function, although I have been using it for months on 12.5.3...
Does anybody know a fix for this?
Some parts of my join command:
const { channel } = message.member.voice;
const voiceChannel = message.member.voice.channel;
await channel.join();
It results in the error.
Discord.js no longer supports voice. You need to use the other package they made (#discordjs/voice). You can import joinVoiceChannel from there.
//discord.js and client declaration
const { joinVoiceChannel } = require('#discordjs/voice');
client.on('messageCreate', message => {
if(message.content === '!join') {
joinVoiceChannel({
channelId: message.member.voice.channel.id,
guildId: message.guild.id,
adapterCreator: message.guild.voiceAdapterCreator
})
}
})
I am using ytdl-core and node-opus to add music functionality to my bot. I am also following a tutorial. Up until I started to add queuing functionality, the bot worked fine. As I integrated the queuing, the bot could still join and leave voice channels, but can't play music. It outputs (node:22116) UnhandledPromiseRejectionWarning: ReferenceError: play is not defined
As per comments on the video, I have tried switching play to playstream. This worked originally, but doesn't help, only outputting that it is not defined.
Here is the command:
if (!message.member.voiceChannel) return message.channel.send("You must be connected to a voice channel.");
if (!args[0]) return message.channel.send("You must supply a __valid__ URL.");
let validate = await ytdl.validateURL(args[0]);
if (!validate) return message.channel.send("You must supply a __valid__ URL.");
let info = await ytdl.getInfo(args[0]);
let data = active.get(message.guild.id) || {};
if (!data.connection) data.connection = await message.member.voiceChannel.join();
if (!data.queue) data.queue = [];
data.guildID = message.guild.id;
data.queue.push ({
songTitle: info.title,
requester: message.author.tag,
url: args[0],
announceChannel: message.channel.id
});
if (!data.dispatcher) play();
else {
message.channel.send(`Added song to queue: ${info.title} || Requested by: ${message.author.id}`);
active.set(message.guild.id, data);
I'd like to be able to still follow the tutorial to fully integrate the queuing.
You didn't define the play() function in previous code, so you also can't use it.
Here is an example of how your play() function could look:
const queue = msg.client.queue;
const ytdl = require('ytdl-core');
async function play(guild, song) {
const serverQueue = await queue.get(guild.id);
if (!song) {
await serverQueue.voiceChannel.leave();
await queue.delete(guild.id);
return;
}
const stream = await ytdl(song.url, {
filter: 'audioonly'
});
const dispatcher = await serverQueue.connection.playStream(stream)
.on('end', async reason => {
if (reason === 'Stream is not generating quickly enough.');
serverQueue.songs.shift('Stream is not generating quickly enough');
await play(guild, serverQueue.songs[0]);
})
.on('error', error => console.error(error));
dispatcher.setVolumeLogarithmic(serverQueue.volume / 5);
}
My queue is constructed as following:
const queueConstruct = {
textChannel: msg.channel,
voiceChannel: voiceChannel,
connection: null,
songs: [],
volume: 2,
playing: true
};
It could be that you have to change some lines of code, so that it works for your bot!