How can I make my Discord bot respond to commands multiple times?

I’ve been working on a Discord bot that plays random sound clips. It’s supposed to join a voice channel when a user types !womble, play a clip, and then leave. But I’m having trouble.

The bot works fine the first time I use the command. It joins the channel, plays a sound, and leaves. But after that, it stops responding to !womble. I can still use !summon to bring it into a channel, but !womble doesn’t do anything.

Here’s a part of my code:

@commands.command(pass_context=True, no_pm=True)
async def play_clip(self, ctx):
    voice_state = self.get_voice_state(ctx.message.server)
    if not voice_state.voice:
        if not await ctx.invoke(self.join_channel):
            return

    try:
        clip = random.choice(os.listdir('sounds'))
        full_path = os.path.join('sounds', clip)
        player = voice_state.voice.create_ffmpeg_player(full_path, after=lambda: self.leave_channel(ctx))
        player.start()
    except Exception as e:
        await self.bot.send_message(ctx.message.channel, f'Error: {type(e).__name__} - {e}')


def leave_channel(self, ctx):
    voice_state = self.get_voice_state(ctx.message.server)
    asyncio.run_coroutine_threadsafe(voice_state.voice.disconnect(), voice_state.voice.loop)

I’ve tried asking for help in the Discord API server, but it’s pretty busy there. Any ideas on why the bot only responds once?

yo, sounds like ur bot might be hangin on to the voice state after leavin. try clearin the voice state when it disconnects:

def leave_channel(self, ctx):
    voice_state = self.get_voice_state(ctx.message.server)
    asyncio.run_coroutine_threadsafe(voice_state.voice.disconnect(), voice_state.voice.loop)
    self.voice_states.pop(ctx.message.server.id, None)  # add this line

that might fix it. lmk if it works!

I encountered a similar issue when developing my Discord bot. The problem likely stems from the voice state not being properly cleared after disconnecting. To resolve this, you should modify your leave_channel method to explicitly remove the voice state after disconnection.

Here’s a suggested modification:

def leave_channel(self, ctx):
    voice_state = self.get_voice_state(ctx.message.server)
    asyncio.run_coroutine_threadsafe(voice_state.voice.disconnect(), voice_state.voice.loop)
    self.voice_states.pop(ctx.message.server.id, None)

This ensures that the voice state is completely removed, allowing the bot to respond to subsequent commands. Additionally, consider implementing error handling and logging to catch any potential exceptions during this process. This approach should resolve the issue and enable your bot to consistently respond to commands.

Hey there! I’ve been through this exact headache with my own Discord bot. The issue is likely that your bot’s voice state isn’t being properly cleaned up after disconnecting. Here’s what worked for me:

Instead of using asyncio.run_coroutine_threadsafe, try using the bot’s loop directly. Also, make sure to clear the voice state after disconnecting. Here’s how I tweaked my leave_channel method:

async def leave_channel(self, ctx):
    voice_state = self.get_voice_state(ctx.message.server)
    if voice_state.voice:
        await voice_state.voice.disconnect()
        self.voice_states.pop(ctx.message.server.id, None)

This approach ensures a clean disconnect and state reset. It solved my recurring command issues. Give it a shot and let us know if it helps!