diff --git a/app/internal/bot_manager.py b/app/internal/bot_manager.py index 0fb9bab..c5b7a38 100644 --- a/app/internal/bot_manager.py +++ b/app/internal/bot_manager.py @@ -23,6 +23,7 @@ class DiscordBotManager: self.loop = asyncio.get_event_loop() self.lock = asyncio.Lock() self._ready_event = asyncio.Event() + self._voice_ready_event = asyncio.Event() async def start_bot(self, token: str): async with self.lock: @@ -52,10 +53,11 @@ class DiscordBotManager: LOGGER.warning(f"Error leaving voice channel: '{e}'") # Attempt to reconnect to the channel after a brief pause await asyncio.sleep(2) - # You might need to store the previous channel ID more robustly - # for reconnection attempts in a real application await self.join_voice_channel(guild_id, before.channel.id) + if member == self.bot.user and before.channel is None and after.channel is not None: + print(f"{member.name} joined voice channel {after.channel.name}") + self._voice_ready_event.set() # Load Opus for the current CPU await self.load_opus() @@ -66,12 +68,11 @@ class DiscordBotManager: # Wait for the on_ready event to be set by the bot task LOGGER.info("Waiting for bot to become ready...") try: - # Add a timeout for robustness in case on_ready never fires - await asyncio.wait_for(self._ready_event.wait(), timeout=60.0) # Adjust timeout as needed + await asyncio.wait_for(self._ready_event.wait(), timeout=60.0) LOGGER.info("Bot is ready, start_bot returning.") + return except asyncio.TimeoutError: LOGGER.error("Timeout waiting for bot to become ready. Bot might have failed to start.") - # Optionally cancel the bot task if it didn't become ready if self.bot_task and not self.bot_task.done(): self.bot_task.cancel() raise RuntimeError("Bot failed to become ready within timeout.") @@ -85,6 +86,7 @@ class DiscordBotManager: await self.bot_task self.bot_task = None self.voice_clients.clear() + self._ready_event.clear() LOGGER.info("Bot has been stopped.") async def join_voice_channel(self, guild_id: int, channel_id: int, ng_threshold: int = 50, device_id: int = 4): @@ -119,6 +121,16 @@ class DiscordBotManager: except Exception as e: LOGGER.error(f"Failed to connect to voice channel: {e}") + LOGGER.info("Waiting for bot to join voice...") + try: + await asyncio.wait_for(self._voice_ready_event.wait(), timeout=60.0) + LOGGER.info("Bot joined voice, returning.") + return + except asyncio.TimeoutError: + LOGGER.error("Timeout waiting for bot to join voice.") + raise RuntimeError("Bot failed to join voice within timeout.") + + async def leave_voice_channel(self, guild_id: int): if not self.bot: raise RuntimeError("Bot is not running.")