Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a discord bot leave the voice channel after being inactive for x minutes?

I am trying to make a music bot on discord with discord.py. However, I want the bot to leave the voice channel on being inactive for a certain time like 5 minutes. By inactive, I mean that the bot is not playing any songs.

The command used to start the song is

voice.play(discord.FFmpegPCMAudio(audio))

and voice.stop() to stop the song

The voice object is discord.VoiceClient.

like image 843
Sathvik K S Avatar asked Sep 19 '25 14:09

Sathvik K S


2 Answers

Hey I know this thread is almost an year old but I think I got a code that is worth posting for anyone that still has this question.

@commands.Cog.listener()
async def on_voice_state_update(self, member, before, after):
    
    if not member.id == self.bot.user.id:
        return

    elif before.channel is None:
        voice = after.channel.guild.voice_client
        time = 0
        while True:
            await asyncio.sleep(1)
            time = time + 1
            if voice.is_playing() and not voice.is_paused():
                time = 0
            if time == 600:
                await voice.disconnect()
            if not voice.is_connected():
                break

So first things first I found it better to put it in the on_voice_state_update event because putting it in the after statement of the play command would cause it to run that loop every time a song ends.

(If you understand how this code works you don't need to read the rest of this, I'm just gonna explain it.)

alright so first we check if our bot is the one triggering the event:

if not member.id == self.bot.user.id:
    return

after that we check if it was a join event:

elif before.channel is None:

if the before channel is none that means that the bot wasn't in a voice channel then it joined one which is what we are looking for.

then if it enters the elif statment first it declares the variable voice. the fastest way I found to get it, is by using the after statment like this voice = after.channel.guild.voice_client which should give you acess to the guilds voice client!

then we get to the main part of the code! Here is the loop that the bot will be running to check if the bot is playing or not:

    time = 0
    while True:
        await asyncio.sleep(1)
        time = time + 1
        if player.is_playing or player.is_paused:
            time = 0
        if time == 600:
            await voice.disconnect()
        if not player.is_connected:
            break

So we create a variable called time that will add 1 every second it detects the bot is not playing and it confirms that the bot isn't actually paused... then if the bot starts playing again it returns to zero. but if it reaches 600 which is 10 minutes it disconnects the bot from the channel and then it breakes the loop.

oh and don't worry about the @commands.Cog.listener() this is just cause I'm using it in a cog. If you aren't then you should change that to @client.event and remove self from the functions statments.

Sorry that I went full on tutorial mode I just like to explain my codes to people lol.

like image 165
lucas soares Avatar answered Sep 21 '25 02:09

lucas soares


I think this should work. I could check if this fits your needs if you shared your code, but you can give it a try.

while voice.is_playing(): #Checks if voice is playing
    await asyncio.sleep(1) #While it's playing it sleeps for 1 second
else:
    await asyncio.sleep(15) #If it's not playing it waits 15 seconds
    while voice.is_playing(): #and checks once again if the bot is not playing
        break #if it's playing it breaks
    else:
        await voice.disconnect() #if not it disconnects
like image 23
RiveN Avatar answered Sep 21 '25 04:09

RiveN