Search code examples
javascriptdiscord.js

discord.js 14: How can I make my bot leave the channel after my bot finished playing an MP3 file?


My problem is when I do my slash command to make the bot enter in the vocal channel, I can't make it leave until the MP3 file is over. Here is the content of my JavaScript file:

const { SlashCommandBuilder, ChannelType, VoiceState, } = require('discord.js');
const { EmbedBuilder } = require('discord.js');
const { getVoiceConnection, entersState, joinVoiceChannel, createAudioPlayer, createAudioResource, VoiceConnectionStatus } = require('@discordjs/voice');
const { Client, GatewayIntentBits } = require('discord.js');
const { join } = require('node:path');

const client = new Client({ intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildVoiceStates,
  ],
});

module.exports = {
    data: new SlashCommandBuilder()
        .setName('padoru')
        .setDescription('Elle est partout.....fuyez..')
        .addChannelOption(option => option.setName('channel').setDescription('Le channel vocal à rejoindre.').setRequired(true).addChannelTypes(ChannelType.GuildVoice)),


    async execute(interaction) {

        if (interaction.isChatInputCommand()) {
            if (interaction.commandName === 'padoru') {
                const voiceChannel = interaction.options.getChannel('channel');
                const voiceConnection = joinVoiceChannel({

                    channelId: voiceChannel.id,
                    guildId: interaction.guild.id,
                    adapterCreator: interaction.guild.voiceAdapterCreator,
                    selfDeaf: false,

                })

                const connection = getVoiceConnection(interaction.guild.id);

                const player = createAudioPlayer();

                let resource = createAudioResource(join(__dirname, '../../medias/sound_effect/padorupadoru.mp3'));

                try {

                await entersState(voiceConnection, VoiceConnectionStatus.Ready, 5000);

                console.log("Connected: " + voiceChannel.guild.name);

                } catch (error) {

                console.log("Voice Connection not ready within 5s.", error);

                return null;

                }

                connection.subscribe(player);
                player.play(resource);
                if (player.pause(), () => voiceConnection.disconnect());


            }
        }

I'm only finding older versions of discord.js about how to do it, but in the v14, I didn't find much. I didn't find how to do it in discord.js 14.

I somehow managed to making it work, but with the setTimeout function. I am still reading the documentation, but I still don't find how to manage to leave the voice channel at the end of the song.


Solution

  • To let the bot leave the voice channel once the bot has finished playing the MP3 file, we need to check that it is not playing (in discord terms: it is not speaking). So you have to create a player const player = createAudioPlayer(); which is used to play the audio and in the very next line you wrote if player.pause disconnect it. So now think what are the options we can get. For me, I think there should be a player.speak` or a event listener. So I checked the documentation and I found out that there is an event listener.

    So the code will be:

    // Your code ...
    connection.subscribe(player);
    player.play(resource);
    
    player.on('stateChange', (oldState, newState) => {
      if (newState.status === 'idle') voiceConnection.destroy();
    });
    // Your code ...