# cmd_twitch.py from twitchio.ext import commands import globals from cmd_common import common_commands as cc from modules.permissions import has_permission from modules.utility import handle_help_command, is_channel_live, command_allowed_twitch def setup(bot, db_conn=None): """ This function is called to load/attach commands to the `bot`. We also attach the db_conn and log so the commands can use them. """ @bot.command(name='funfact', aliases=['fun-fact']) @command_allowed_twitch async def cmd_funfact(ctx: commands.Context, *keywords: str): # Convert keywords tuple to list and pass to get_fun_fact. fact = cc.get_fun_fact(list(keywords)) # Reply to the invoking user by prefixing their name. await ctx.reply(f"@{ctx.author.name} {fact}") @bot.command(name="greet") @command_allowed_twitch async def cmd_greet(ctx: commands.Context): if not await is_channel_live(): result = cc.greet(ctx.author.display_name, "Twitch") await ctx.reply(result) @bot.command(name="ping") @command_allowed_twitch async def cmd_ping(ctx: commands.Context): if not await is_channel_live(): result = cc.ping() await ctx.reply(result) @bot.command(name="howl") @command_allowed_twitch async def cmd_howl(ctx: commands.Context): if not await is_channel_live(): response = cc.handle_howl_command(ctx) await ctx.reply(response) @bot.command(name="hi") @command_allowed_twitch async def cmd_hi(ctx: commands.Context): if not await is_channel_live(): user_id = str(ctx.author.id) # Twitch user ID user_roles = [role.lower() for role in ctx.author.badges.keys()] # "roles" from Twitch badges if not has_permission("hi", user_id, user_roles, "twitch"): return await ctx.send("You don't have permission to use this command.") await ctx.reply("Hello there!") # @bot.command(name="acc_link") # @monitor_cmds(bot.log) # async def cmd_acc_link(ctx, link_code: str): # """Handles the Twitch command to link accounts.""" # from modules import db # twitch_user_id = str(ctx.author.id) # twitch_username = ctx.author.name # # Check if the link code exists # result = db.run_db_operation( # bot.db_conn, "read", # "SELECT DISCORD_USER_ID FROM link_codes WHERE LINK_CODE = ?", (link_code,), # bot.log # ) # if not result: # await ctx.send("Invalid or expired link code. Please try again.") # return # discord_user_id = result[0][0] # # Store the Twitch user info in the users table # db.run_db_operation( # bot.db_conn, "update", # "UPDATE users SET twitch_user_id = ?, twitch_username = ?, datetime_linked = CURRENT_TIMESTAMP WHERE discord_user_id = ?", # (twitch_user_id, twitch_username, discord_user_id), bot.log # ) # # Remove the used link code # db.run_db_operation(bot.db_conn, "write", "DELETE FROM link_codes WHERE LINK_CODE = ?", (link_code,), bot.log) # # Notify the user # await ctx.send(f"✅ Successfully linked Discord user **{discord_user_id}** with Twitch account **{twitch_username}**.") # @bot.command(name="quote") # async def cmd_quote(ctx: commands.Context): # """ # Handles the !quote command with multiple subcommands. # Usage: # - !quote # -> Retrieves a random (non-removed) quote. # - !quote # -> Retrieves the specific quote by ID. # - !quote add # -> Adds a new quote and replies with its quote number. # - !quote remove # -> Removes the specified quote. # - !quote info # -> Displays stored information about the quote (as an embed on Discord). # - !quote search [keywords] # -> Searches for the best matching quote based on the provided keywords. # - !quote last/latest/newest # -> Retrieves the latest (most recent) non-removed quote. # """ # if not bot.db_conn: # return await ctx.send("Database is unavailable, sorry.") # parts = ctx.message.content.strip().split() # args = parts[1:] if len(parts) > 1 else [] # def get_twitch_game_for_channel(chan_name): # # Placeholder for your actual logic to fetch the current game # return "SomeGame" # result = await cc.handle_quote_command( # db_conn=bot.db_conn, # is_discord=False, # ctx=ctx, # args=args, # get_twitch_game_for_channel=get_twitch_game_for_channel # ) # await ctx.send(result) @bot.command(name="quote") @command_allowed_twitch async def cmd_quote(ctx: commands.Context): """ Handles the !quote command with multiple subcommands. Usage: - !quote -> Retrieves a random (non-removed) quote. - !quote -> Retrieves the specific quote by ID. - !quote add -> Adds a new quote and replies with its quote number. - !quote remove -> Removes the specified quote. - `!quote restore ` -> Restores a previously removed quote. - !quote info -> Displays stored information about the quote (as an embed on Discord). - !quote search [keywords] -> Searches for the best matching quote based on the provided keywords. - !quote last/latest/newest -> Retrieves the latest (most recent) non-removed quote. """ if not await is_channel_live(): if not globals.init_db_conn: await ctx.reply("Database is unavailable, sorry.") return # Parse the arguments from the message text args = ctx.message.content.strip().split() args = args[1:] if args else [] globals.log(f"'quote' command initiated with arguments: {args}", "DEBUG") globals.log(f"'quote' command message content: {ctx.message.content}", "DEBUG") def get_twitch_game_for_channel(chan_name): # Placeholder for your actual logic to fetch the current game return "SomeGame" result = await cc.handle_quote_command( db_conn=globals.init_db_conn, is_discord=False, ctx=ctx, args=args, get_twitch_game_for_channel=get_twitch_game_for_channel ) globals.log(f"'quote' result: {result}", "DEBUG") await ctx.reply(result) @bot.command(name="help") @command_allowed_twitch async def cmd_help(ctx): if not await is_channel_live(bot): parts = ctx.message.content.strip().split() cmd_name = parts[1] if len(parts) > 1 else None await handle_help_command(ctx, cmd_name, bot, is_discord=False) ###################### # The following log entry must be last in the file to verify commands loading as they should ###################### # Debug: Print that commands are being registered try: globals.log(f"Registering commands for Twitch: {list(bot.commands.keys())}", "DEBUG") except Exception as e: globals.log(f"An error occured while printing registered commands for Twitch: {e}", "WARNING")