Search code examples
asynchronousdiscorddiscord.pyyoutube-dl

How to disconnect a discord bot from voice channel after user left?


I would like to add an event that my music bot leaves the voice channel immediately if the user leaves while the song is still playing. If there are multiple users in the channel, the bot should of course stay in the channel. I only have one approach there, but would need help. I would try the following:

async def check_member(self, ctx):
    channel = ctx.author.voice.channel
    member_count = len(voice_channel.members)
    if member_count == 1:
        await channel.disconnect

but somehow this doesn't seem to work. I know for fact that there is a similar post but this did not work for me too as I defined some things different.

My second attempt was:

    async def check_member(self, ctx):
        channel = ctx.author.voice.channel
        member_count = len(channel.members)
        client = ctx.guild.voice_client
        if member_count == 1:
            await client.disconnect()

(Did not work either.)

To define does not work: I build the function in a different way now:

    @tasks.loop(seconds=2)
    async def check(self, ctx):
        voice_channel = ctx.author.voice.channel
        member_count = len(voice_channel.members)
        client = ctx.guild.voice_client
        if member_count == 1:
            await client.disconnect()

This is now a total different count. What I am trying to do is loop the commands.Cog.listener() function every 2 seconds. For tests I played a song and left instantly after the bot started playing. I thought the bot would leave the channel too but it did not. There was no output in my log that I defined something wrong.


Solution

  • A loop is kinda unefficient, you can simply use the on_voice_state_update event

    async def on_voice_state_update(member, before, after):
        voice_state = member.guild.voice_client
        # Checking if the bot is connected to a channel and if there is only 1 member connected to it (the bot itself)
        if voice_state is not None and len(voice_state.channel.members) == 1:
            # You should also check if the song is still playing
            await voice_state.disconnect()
    

    Reference: