Discord.js: Debian 8 not resolving voiceChannel.join

Created on 23 Mar 2018  ·  23Comments  ·  Source: discordjs/discord.js

Please describe the problem you are having in as much detail as possible:
voiceChannel.join never resolves it's promise, when logging message.guild.voiceConnection.status, I get a continuous 1. As far as I understand, this means it's not connected but trying to. This never goes away and it never resolves it's connection.

several people were trying to figure out the issue in discord.js chat, but were unable to. This was kind of late at night though, so not many around. I've tried this also with just skipping the promise method entirely and just throwing a sleep in there for kicks, but to no avail. The below code was actually from another issue from the discord.js github to test the problem, just to see if it was my code by chance. This below never completes the connection.

ffmpeg is installed to the server itself utilizing apt-get install ffmpeg, and node-opus was installed to the bot. Also tried switching regions to see if that was the issue or not, since it seems that has been an issue in the past.

Include a reproducible code sample here, if possible:

const ytdl = require('ytdl-core');
const Dispatchers = new Map();

function play(connection) {
  let Dispatch = Dispatchers.get(message.guild.id);
  let stream = ytdl('https://www.youtube.com/watch?v=Hb4fzFk4U-s', { format: 'audioonly' })
  let dispatcher = connection.playStream(stream, { volume: 1 });

  dispatcher.once('end', (r) => {
    play(connection);
  })

  Dispatch.dispatcher = dispatcher;
}

  message.member.voiceChannel.join().then(connection => {
  play(connection);

  let Dispatch = {
    connection: connection,
    msg: msg
  }

  Dispatchers.set(message.guild.id, Dispatch);
})

Further details:

  • discord.js version: 11.3.2
  • node.js version: v9.8.0
  • Operating system: debian 8.8 Jessie
  • ffmpeg version: 2.6.9
  • Priority this issue should have – please be realistic and elaborate if possible:
    low/medium

  • [x ] I found this issue while running code on a full privileged account

  • [ ] I have also tested the issue on latest master, commit hash:
medium potentially fixed voice bug

All 23 comments

Not particularly pertaining to the issue but a quick tip for you; Making a Dispatchers map seems quite unessecary, as Discord.js already stores one for you. Get the voice channel via client.voiceConnections.get(msg.guild.id) which returns a VoiceConnection type, which has the property VoiceConnection#dispatcher in both Stable and Master docs.

That's what discord is for 😐

@KyeNormanGill I don't know his Discord tag, nor would I have known how to contact him at all. I assume I could have looked up his username, but this issue tracker may not be a bad place to say that because it could be part of the cause of his problem. How would I know?

Have you tried catching errors from the promise to see if that gives you any information?

@hydrabolt never resolves the promise when put in promise form and just sits there attempting to resolve with status 1

Can you try updating your discord.js and see if you can still reproduce this?

I have the exact same problem. I updated to 12.0.0-dev and I still have the problem.

Here is my code :

private async _joinVoiceChannel(message: Message): Promise<void> {
    const { voiceChannel } = message.member;

    const voiceConnection = await voiceChannel.join();
    this._voiceChannel = voiceChannel;
    this._voiceConnection = voiceConnection;
}

The voiceChannel.join(); is never resolved sometime, and it's not triggering an error either. The bot is joining the channel though.

Sometime it works, sometime it's never resolved and I don't have any scenario to reproduce the bug.
I had the problem on Ubuntu 16.04 and when deploying on OpenShift. I never had the bug on Windows.

Thank you for your help.

After investigating for a bit, it seems like I found a part of the problem.
The promise is never resolved because of this : (ClientVoiceManager, line 72, joinChannel(channel) method)

connection.once('authenticated', () => {
  connection.once('ready', () => resolve(connection));
  connection.once('error', reject);
  connection.once('disconnect', () => this.connections.delete(channel.guild.id));
});

The authenticated event is emitted, but "ready", "error" and "disconnect" are not. Because of that, the promise is never resolved, nor rejected.

After some more investigation, it seems like onSessionDescription is never triggered on VoiceConnection.
This might be because no Constants.VoiceOPCodes.SESSION_DESCRIPTION packet are received.

I went deeper again but my poor knowledge of the Discord API isn't enough to fix the bug.
In VoiceUDPClient, the socket created in createUDPSocket(address) is waiting for a message (socket.once('message')).
But in fact, it's never receiving one.
I think that's the core of the bug. Because the socket is never receiving a message, it's never sending the SELECT_PROTOCOL packet and if the SELECT_PROTOCOL packet is never sent, the SESSION_DESCRIPTION packet will never be received. That's why VoiceConnection is never ready.

I really hope someone will help me find the problem with all these informations because I'm stuck with a bot that can't join a channel for some reasons.
Thank you.

How strange, I'll try to investigate this week. Do you have a firewall interfering with your bot?

When I'm on Ubuntu I have a Firewall which might be the problem, but I don't know about Openshift. But the fact that it worked at a moment and now it doesn't anymore made me doubt.

Can you try updating to the latest master? I pushed a change that might fix this for you.

The promise is still not resolving with this patch

Could you try the latest master branch again? If it's still not working I'll try something different

I'm closing this issue as it seems to be inactive, if you can still reproduce please reopen.

I have the same issue with my Ubuntu 18.04 server.
The promise created by join() does not ever resolve, even though the bot does join the voice channel.

The same problem, connection to channel works on my laptop but gets stuck on the remote host (herokuapp).

3320

Same issue

@amishshah @mzabad-r7 @thezoomlesss @godleydemon did you find a workaround?

I gave up on it until that gets fixed.

If someone still comes here

function play(message, bot) { //Adds Music to Queue and starts Playing if not playing already

    let Pos = MusicQueue.length + 1;

    if (message.author.lastMessage.member.voiceChannelID) { //Only add if User is in a VoiceChannel

        message.channel.send("Added Song to Queue at Position " + Pos);
        MusicQueue.push(message.content.substring(6));

        if (MusicQueue.length == 1) {
            if (!inChannel) {
                join(message, bot);
            }
        }
    } else {
        message.channel.send('Please join a VoiceChannel');
    }
}

async function playSong() { //Plays a Song

    let Song = MusicQueue.pop();
    ogmessage.channel.send("Now playing " + Song);

    playyt(Musicconnection, Song).then(dispatcher => { //Throws error in console if url isnt valid
        Musicdispatcher = dispatcher;
        Musicdispatcher.on('end', () => {
            if (MusicQueue.length > 0) {
                playSong();
            } else {
                ogmessage.channel.send('End of Queue');
                stop();
            }
        })
    })
}

function join(message, bot) { //Joins VoiceChannel of Caller

    dcbot = bot;
    ogmessage = message;

    dcbot.channels.get(ogmessage.author.lastMessage.member.voiceChannelID).join().then(connection => {

        Musicconnection = connection;
        inChannel = true;
        playyt(connection, MusicQueue.pop()).then(dispatcher => { //Has to be called here so the Promise is returned

            Musicdispatcher = dispatcher;

            dispatcher.on('end', () => {

                if (MusicQueue.length > 0) {
                    playSong();
                } else {
                    ogmessage.channel.send('End of Queue');
                    stop();
                }
            })
        }) 
    });
}

async function playyt(connection, url) {    //Plays the URL
    try {
        var YTStream = await ytdl(url); 
    } catch(error) {
        Logger.log(error);
    }
    return connection.playOpusStream(YTStream);  
}

This above works fine, the Problem was that Musicconnection was still a Promise when playSong() would have been called the first Time, so i packed a single Stream into join().then() and it worked fine aswell as Musicconnection being a VoiceConnection and Musicdispatcher being a StreamDispatcher.

tl;dr Call a playOpusStream inside join().then() and the VoiceConnection will magically appear

Was this page helpful?
0 / 5 - 0 ratings