Search code examples
javascriptdiscord.jsdistube

Discord.js Music Bot not working (Distube Framework)


I'm trying to create a Discord Music Bot with discord.js and the Distube Framework, the code is fine and I don't have any errors, but as soon as I try to play a music with my command ("/play song"), the bot joins the channel and sends the embed, but instantly state the music as finished and never plays it.

Here is my code:

App.js

const Distube = require("distube")
const { SoundCloudPlugin } = require("@distube/soundcloud")
const { SpotifyPlugin } = require("@distube/spotify")
/* eslint new-cap: ["error", { "properties": false }] */
client.distube = new Distube.default(client, {
    leaveOnEmpty: true,
    emptyCooldown: 30,
    leaveOnFinish: false,
    emitNewSongOnly: true,
    updateYouTubeDL: true,
    nsfw: true,
    youtubeCookie: process.env.ytcookie,
    plugins: [new SoundCloudPlugin(), new SpotifyPlugin()]
})
const status = (queue) => `Volume: \`${queue.volume}%\` | Loop: \`${queue.repeatMode ? queue.repeatMode === 2 ? "All Queue" : "This Song" : "Off"}\` | Autoplay: \`${queue.autoplay ? "On" : "Off"}\` | Filter: \`${queue.filters.join(", ") || "Off"}\``

client.distube
    .on("playSong", (queue, song) => {          //command to play a song
        const embed = new MessageEmbed()
            .setColor("RANDOM")
            .setAuthor("Started Playing", "https://raw.githubusercontent.com/HELLSNAKES/Music-Slash-Bot/main/assets/music.gif")
            .setThumbnail(song.thumbnail)
            .setDescription(`[${song.name}](${song.url})`)
            .addField("**Views:**", song.views.toString(), true)
            .addField("**Like:**", song.likes.toString(), true)
            .addField("**Duration:**", song.formattedDuration.toString(), true)
            .addField("**Status**", status(queue).toString())
            .setFooter(`Requested by ${song.user.username}`, song.user.avatarURL())
            .setTimestamp()
        queue.textChannel.send({ embeds: [embed] })
    })

play.js

module.exports = {
    name: "play",
    description: "Playing music",
    options: [
        {
            name: "query",
            type: 3,
            description: "The song you want to play | Supported url: youtube,soundcloud,spotify",
            required: true
        }
    ],
    timeout: 5000,
    run: async (interaction, client) => {
        const voiceChannel = interaction.member.voice.channel
        const queue = await client.distube.getQueue(interaction)
        const query = interaction.options.get("query").value
        if (!voiceChannel) {
            return interaction.reply({ content: "Please join a voice channel!", ephemeral: true })
        }
        if (queue) {
            if (interaction.member.guild.me.voice.channelId !== interaction.member.voice.channelId) {
                return interaction.reply({ content: "You are not on the same voice channel as me!", ephemeral: true })
            }
        }
        await interaction.reply("**Searching and attempting...**")
        await interaction.editReply("Searching done :ok_hand: ")
        client.distube.play(voiceChannel, query, { //Should play the song
            textChannel: interaction.channel,
            member: interaction.member
        })
    }
}

enter image description here


Solution

  • This is an issue caused by the delay between calling a song and actually starting to play it if leaveOnFinish is toggled on. It can be fixed by setting leaveOnFinish to false and then waiting a bit after the queue has ended to disconnect the bot. Here's how I have setup my bot to leave 2 minutes after the final song is played.

          setTimeout(async () => {
            if (!queue.textChannel.guild.me.voice.channelId) {
              return clearTimeout();
            }
            let queue_music = await client.distube.getQueue(queue.voiceChannel);
    
            if (queue_music !== undefined && queue_music.playing) {
              clearTimeout();
            } else if (queue_music == undefined || queue_music.songs.length === 0) {
              queue.textChannel
                .send({
                  embeds: [
                    new MessageEmbed()
                      .setDescription("Finished!")
                  ],
                })
                .catch(() => { })
              queue.stop(client.voice.channel)
            }
          }, 120000)