Discord bot won't automatically exit voice channels

Hey everyone! I’m working on a Discord bot using Python and I’m stuck on a voice channel issue. My bot can join voice channels when users do, but I can’t figure out how to make it leave when everyone else has left.

I’ve got this code that makes the bot join:

@bot.event
aasync def on_voice_update(user, previous, current):
    if current.channel and not previous.channel:
        if not bot.voice_connections:
            await current.channel.connect()

It works fine, but I’m lost on how to make the bot exit when the channel’s empty. I’ve tried a few things, but no luck. Any ideas on how to detect when a channel is empty and make the bot leave automatically?

I’ve got manual join and leave commands working, but I really want this to happen without needing commands. Can anyone help me out with this? Thanks!

I encountered a similar issue before and discovered that scheduling a periodic background task to check channel activity worked better than relying solely on voice state update events. Instead of trying to catch every voice update, I set up a task that runs every few seconds. This task reviews all active voice connections, checks if there are any non-bot members in each channel, and disconnects the bot if it finds that only it remains. This approach is both reliable and resource efficient, while also helping to manage errors like connection issues or missing permissions.

I hope this insight is helpful.

I’ve dealt with this exact problem in my Discord bot projects. Here’s what worked for me:

Instead of relying on voice state updates, I implemented a loop that checks the voice channel every 30 seconds or so. It’s more reliable and catches edge cases better.

Here’s a basic implementation:

import asyncio

async def check_voice_channel():
    while True:
        for vc in bot.voice_clients:
            if len([m for m in vc.channel.members if not m.bot]) == 0:
                await vc.disconnect()
        await asyncio.sleep(30)

bot.loop.create_task(check_voice_channel())

This runs in the background, checks all voice connections, and disconnects if only bots are left. It’s simple but effective. You might need to tweak the sleep time based on your needs.

Remember to handle potential errors and edge cases in a production environment!

hey there! i’ve had this problem too. what worked for me was using a background task to check the channel every minute or so. here’s a quick example:

async def check_empty():
    while True:
        for vc in bot.voice_clients:
            if not [m for m in vc.channel.members if not m.bot]:
                await vc.disconnect()
        await asyncio.sleep(60)

just add this to ur code and it should work. good luck!