I've been making my first discord bot recently and today I'm facing an issue for a little requirement. I need my bot to connect to all voice channels of the server and play a mp3 file. It's for an alert message.
I first made a basic test with this code to play the mp3 in the channel the user who launch the command is connected :
exports.run = async (client, message, args, level) => {
if (message.member.voiceChannel) {
message.member.voiceChannel.join()
.then(connection => {
const dispatcher = connection.playFile('/home/pi/.discordbots/TARVIS/1.mp3');
dispatcher.on("end", end => {message.member.voiceChannel.leave()});
})
.catch(console.error);
}
};
The code above works fine
So I tried to make it for all voice channels :
let voiceChannels = message.guild.channels.filter(channel => channel.type == 'voice');
voiceChannels.forEach(channel =>
channel.join()
.then(connection => {
const dispatcher = connection.playFile('/home/pi/.discordbots/TARVIS/1.mp3');
dispatcher.on("end", end => { channel.leave() });
})
.catch(console.error)
);
The problem is that the bot connect to the first channel and then directly connect to the second without having time to play the file in the first channel.
I think I have to look at the client.createVoiceBroadcast();
method. I tried to use it but I wasn't able to find a good example. Here is what I tried but it's not working too :
exports.run = (client, message, args, level) => {
let voiceChannels = message.guild.channels.filter(channel => channel.type == 'voice');
const broadcast = client.createVoiceBroadcast();
broadcast.playFile('/home/pi/.discordbots/TARVIS/1.mp3');
voiceChannels.forEach(channel =>
channel.join()
.then(connection => {
const dispatcher = connection.playBroadcast(broadcast);
dispatcher.on("end", end => { channel.leave() });
})
.catch(console.error)
);
Expected result is the bot connects in each voice channel, one by one and play the mp3 file.
Thank you in advance for your help
EDIT
I tried to make an async function and use the await on the connection.playFile()
but I still having the same problem. Bot connect to all voice channel but do not wait for the file to be played.
Here is the code I tried:
exports.run = async (client, message, args, level) => {
async function play(voiceChannel) {
console.log(voiceChannel.name + ` Type:` + voiceChannel.type + ` (` + voiceChannel.id + `)`);
voiceChannel.join().then(async function (connection) {
dispatcher = await connection.playFile('/home/pi/.discordbots/TARVIS/sncf.mp3');
dispatcher.on('end', function () {
voiceChannel.leave()
});
});
}
let voiceChannels = message.guild.channels.filter(channel => channel.type == 'voice');
voiceChannels.map(vc => play(vc));
};
I'm pretty sure the solution is near... but I'm stuck... Does someone can help me to find the correct syntax ?
EDIT 2
Here is what I tried with your solution:
exports.run = async (client, message, args, level) => {
async function play(voiceChannels) {
for (let channel of voiceChannels) {
console.log('Joining channel ' + channel.name);
await channel.join().then(async (connection) => {
console.log('Joined channel');
let dispatcher = connection.playFile('/home/pi/.discordbots/TARVIS/sncf.mp3');
await dispatcher.on('end', function () {
channel.leave();
});
});
}
}
let channels = message.guild.channels.filter(channel => channel.type == 'voice');
console.log(channels);
play(channels);
};