import discord from discord.ext import commands from discord import app_commands # Import the app_commands module from internal.drb_srv_api import SystemAPIWrapper, NodeAPIWrapper # This is a standard setup for a command module (often called a "Cog") # It inherits from commands.Cog class DrbCommands(commands.Cog): """A collection of example slash commands.""" # The __init__ method takes the bot instance as an argument def __init__(self, bot): self.bot = bot self.drb_sys_api = SystemAPIWrapper() self.drb_node_api = NodeAPIWrapper() # Connect a bot with the selected system to the channel the requester is in / move the bot to the channel the requester is in @commands.hybrid_command(name="join", description="Request a bot to join your channel listening to a system.") @app_commands.describe(system_name="The name of the system to join.") async def join(self, ctx: commands.Context, system_name:str): # Get the system details sys_search_results = await self.drb_sys_api.search_systems(name=system_name) selected_system = None # Make sure there is a system found if len(sys_search_results) == 1: selected_system = sys_search_results[0] else: pass # Replace with code to ask the user which they would like if not selected_system: return # Get all the nodes that have this system avail_on_nodes = selected_system['avail_on_nodes'] selected_node_id = None if len(avail_on_nodes) == 0: return if len(avail_on_nodes) == 1: selected_node_id = avail_on_nodes[0] else: return # TODO - Implement this # Check to see if there is a preferred node for the system, if not select one # check to make sure it's available, if not loop back and select the next one if not selected_node_id: return # Get the channel the user is currently in channel_id = ctx.author.voice.channel.id # Get the guild the user messaged from guild_id = ctx.guild.id print(selected_node_id, selected_system['_id'], guild_id, channel_id) api_response = await self.drb_node_api.join(selected_node_id, selected_system['_id'], guild_id, channel_id) if isinstance(ctx, commands.Context): # This was invoked as a prefix command (e.g., !hello) await ctx.send(f"{api_response}!") elif isinstance(ctx, discord.Interaction): # This was invoked as a slash command (/hello) await ctx.response.send_message(f"{api_response}!") @join.autocomplete("system_name") async def system_name_autocomplete(self, interaction: discord.Interaction, current: str, ) -> list[app_commands.Choice[str]]: """ Autocomplete for system_name, fetches systems. """ # Fetch systems from your database (async call) systems = await self.drb_sys_api.search_systems(name=current) # Create app_commands.Choice objects return [ app_commands.Choice(name=system, value=system) for system in systems[:25] # Discord has a limit of 25 choices ] @commands.hybrid_command(name="leave", description="Request that a bot leave your server.") async def leave(self, ctx: commands.Context): if isinstance(ctx, commands.Context): # This was invoked as a prefix command (e.g., !hello) await ctx.send(f"Hello, {ctx.author.display_name}!") elif isinstance(ctx, discord.Interaction): # This was invoked as a slash command (/hello) await ctx.response.send_message(f"Hello, {ctx.user.display_name}!") # Disconnect the selected bot from the server the requster is in # --- Setup Function --- async def setup(bot): """Adds the SlashExampleCommands cog to the bot and syncs slash commands.""" await bot.add_cog(DrbCommands(bot)) print("Hybrid commands cog loaded. Remember to sync commands!")