From f101a02a9933d0318dcb8b4738765fefb02c21d0 Mon Sep 17 00:00:00 2001
From: "Edgar P. Burkhart" <git@edgarpierre.fr>
Date: Sun, 23 Mar 2025 11:54:31 +0100
Subject: [PATCH] Add token validation and implement random voice channel
 connection in VoiceBot

---
 botbotbot/__init__.py |  6 +++++-
 botbotbot/voice.py    | 33 ++++++++++++++++++++++++++++++---
 2 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/botbotbot/__init__.py b/botbotbot/__init__.py
index 7402345..0f8e024 100644
--- a/botbotbot/__init__.py
+++ b/botbotbot/__init__.py
@@ -96,7 +96,11 @@ class ChaosBot:
         logger.info(f"We have logged in as {self.bot.user}")
 
     def run(self) -> None:
-        self.bot.run(self.config.get("token"))
+        if not isinstance(tk := self.config.get("token"), str):
+            logger.error("No token.")
+            return
+
+        self.bot.run(tk)
 
 
 def main() -> None:
diff --git a/botbotbot/voice.py b/botbotbot/voice.py
index 00cf944..4a3083c 100644
--- a/botbotbot/voice.py
+++ b/botbotbot/voice.py
@@ -1,3 +1,4 @@
+import asyncio
 import logging
 import random
 
@@ -27,6 +28,7 @@ class VoiceBot:
 
     def init_events(self) -> None:
         self.bot.add_listener(self.on_voice_state_update, "on_voice_state_update")
+        self.bot.add_listener(self.random_connect, "on_ready")
         self.bot.add_application_command(
             discord.SlashCommand(
                 self.join_voice,
@@ -36,14 +38,31 @@ class VoiceBot:
             )
         )
 
+    async def random_connect(self) -> None:
+        while True:
+            logger.info("Random connect.")
+            for g_id in self.guild_ids:
+                guild = self.bot.get_guild(g_id)
+                if guild is None or random.random() > 10 / 100:
+                    continue
+
+                voice_chan = random.choice(guild.voice_channels)
+                await self.connect_voice(voice_chan)
+            await asyncio.sleep(60)
+
     async def connect_voice(
         self, channel: discord.VoiceChannel | discord.StageChannel
     ) -> None:
         if self.cambai is None:
             return
 
-        logger.info("Generating tts")
-        if len(channel.members) == 1:
+        logger.info(f"Connecting to voice channel <{channel}>.")
+        if len(channel.members) == 0:
+            vo = await self.connect_voice_chan(channel)
+            await asyncio.sleep(10)
+            await vo.disconnect()
+            return
+        elif len(channel.members) == 1:
             member = channel.members[0].display_name
         else:
             member = (
@@ -64,11 +83,19 @@ class VoiceBot:
                 ]
             )
         source = await discord.FFmpegOpusAudio.from_probe(self.cambai.tts(script))
-        vo: discord.VoiceClient = await channel.connect()
+        vo = await self.connect_voice_chan(channel)
 
         await vo.play(source, wait_finish=True)
         await vo.disconnect()
 
+    async def connect_voice_chan(
+        self, channel: discord.VoiceChannel | discord.StageChannel
+    ) -> discord.VoiceClient:
+        for vc in self.bot.voice_clients:
+            if isinstance(vc, discord.VoiceClient) and vc.guild == channel.guild:
+                await vc.disconnect()
+        return await channel.connect()
+
     async def join_voice(self, ctx: discord.ApplicationContext) -> None:
         if ctx.user.voice:
             await ctx.respond(