Rapptz / discord.py

An API wrapper for Discord written in Python.
http://discordpy.rtfd.org/en/latest
MIT License
14.83k stars 3.76k forks source link

Problem when my bot tries to connect to a voice channel #9616

Open Motiver7 opened 1 year ago

Motiver7 commented 1 year ago

Summary

The channel.connect() never ends. The bot appears in the channel on Discord, but the code "thinks" he isn't connected.

Reproduction Steps

Minimal Reproducible Code

class Blindtest(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.musiques = []

    def cog_check(interaction):
        member = interaction.guild.get_member(interaction.user.id)
        salon_blindtest = interaction.guild.get_channel(CHANNEL_ID)
        return member.voice != None and member.voice.channel == salon_blindtest and interaction.channel == salon_blindtest

    @app_commands.command(description = "Permet de jouer un morceau de musique")
    @app_commands.check(cog_check)
    async def play(self, interaction: discord.Interaction):
        member = interaction.guild.get_member(interaction.user.id)
        url = 'SOME URL'
        client = interaction.guild.voice_client
        if client and client.channel and client.is_connected():
            self.musiques.append(url)
        else:
            channel = member.voice.channel
            self.musiques = []
            print(1)
            client = await channel.connect()
            print(2)
            self.play_song(client, self.musiques, url)
        await interaction.response.send_message(':notes: Je lance la lecture !')

class MyBot(commands.Bot):
    def __init__(self):
        super().__init__(command_prefix = "!", intents = intents, description = "Tapez !aide")
        #self.tree = app_commands.CommandTree(self)

    async def setup_hook(self):
        pass

bot = MyBot()

@bot.event
async def on_ready():
    await bot.wait_until_ready()
    print('Connecté en tant que', bot.user
    await bot.load_extension(NAME_OF_THE_FILE)
    bot.tree.copy_global_to(guild = MY_GUILD)
    await bot.tree.sync(guild = MY_GUILD)
    print('Prêt !')

bot.run(MY_TOKEN)

Expected Results

The bot should connect to the vocal channel, send a message, and then start playing a file via the function play_song. It should too print "1" and then "2" in the console.

Actual Results

I get the "1" in the console, but never the "2".

The bot appears connected to the channel on Discord. However, the code below channel.connect() is never executed. I made some experiments, and I can see that when I ask for is_connected(), the answer is False.

Intents

intents = discord.Intents.all()

System Information

Checklist

Additional Context

I wrote this code in March 2023 and it worked perfectly. Then I tried it again in July, without any modification, and it wasn't working anymore. It still is broken.

I saw that I'm not the only one with this problem, but I also saw that many people do not have this problem. I suspected a firewall blocking so I disabled it and nothing changed. Still, I am not convinced because I don't know which port is used for the voice channel connection. If anyone knows that, I can try to specifically allow it in my firewall.

I put here only the part of the code which is concerned by the problem. The COG is in a separate python file. I think I put all code needed to understand the problem. Let me know if something is missing.

alexraskin commented 1 year ago

Are you running await bot.load_extension(NAME_OF_THE_FILE) in the on_ready() function? That should be passed in the setup hook function. Per the docs, the on_ready() function has a chance of getting called twice.

patttterson commented 1 year ago

By the way, never sync commands in the on_ready() function. You only need to sync when commands are updated, not every time you run your bot.

No767 commented 1 year ago

Chances are, your variable channel is actually None and it's not returning any errors because you don't have an error handler set up

Motiver7 commented 1 year ago

@alexraskin Thank you for the advice. I admit I didn't really understand what was the setup_hook

@20kzhan Yes, but I have to do it when I change the code, and it is correlated with the reboots of the bot.

@No767 It is impossible because of the cog_check, I wouldn't have the print(1) then. And I have an error handler on the cog_check which I indeed forgot to show here.

No767 commented 1 year ago

@No767 It is impossible because of the cog_check, I wouldn't have the print(1) then. And I have an error handler on the cog_check which I indeed forgot to show here.

@Motiver7 You don't really need cog_check for error handling. Handle error handling directly on CommandTree.on_error instead.

Also as a side note, the purpose of commands.Cog.cog_check (which you did override in your code) is to apply a check for every single prefixed command and subcommand. (docs)

Motiver7 commented 1 year ago

Yes I'm aware of that, I want the check to be active on all the commands of this cog. Basically, they all are commands which make the bot play a sound, stop, etc. so I just check that the person who runs the command is connected to the right vocal channel.

But with or without the cog_check the channel.connect() never ends...

No767 commented 1 year ago

Are you sure that you are getting an error? My leading theory would be that the voice channel you are trying to get is None, thus resulting in an error when your bot tries to connect to it, and 2 never prints

Motiver7 commented 1 year ago

I just checked in my code, I have an error handler which raises any error for this command (the cog_check error is handled separately of course). As the cog_check succeeds, I'm sure that member.voice.channel == salon_blindtest (see the cog_check) so it's not None. Then no error is raised so the channel.connect() doesn't exactly fail. A theory of mine would be that it is waiting for something like a route through a certain communication port, but I even don't know which port is used for this, so I can't verify my firewall...

And apart of any code consideration, I test the bot myself and I am sure to be connected in the right vocal channel when I run the command, so definitely channel is not None

No767 commented 1 year ago

@Motiver7 There is no ports actively used for voice connections.

Note that you'll get faster support on the discord server instead.