258 lines
9.5 KiB
Python
258 lines
9.5 KiB
Python
# cmd_discord.py
|
|
import discord
|
|
from discord.ext import commands
|
|
from discord import app_commands
|
|
from typing import Optional
|
|
|
|
from cmd_common import common_commands as cc
|
|
from modules.permissions import has_permission
|
|
from modules.utility import handle_help_command
|
|
import globals
|
|
|
|
def setup(bot, db_conn=None):
|
|
"""
|
|
Attach commands to the Discord bot, store references to db/log.
|
|
"""
|
|
|
|
config_data = globals.load_config_file()
|
|
|
|
@bot.command()
|
|
@commands.is_owner()
|
|
async def sync_commands(ctx):
|
|
"""
|
|
Trigger manual command sync. OWNER ONLY
|
|
"""
|
|
if commands.is_owner():
|
|
primary_guild_int = int(config_data["discord_guilds"][0])
|
|
primary_guild = discord.Object(id=primary_guild_int)
|
|
await ctx.send(f"Initiating slash sync to Discord Guild '{primary_guild_int}' ...")
|
|
try:
|
|
await bot.tree.sync(guild=primary_guild)
|
|
reply = "... Commands synced!"
|
|
except Exception as e:
|
|
reply = f"... Commands failed to sync! Error message:\n{e}"
|
|
globals.log(f"'sync_commands' failed to sync command tree\n{e}", "ERROR")
|
|
else:
|
|
reply = "You're not the registered owner of me!"
|
|
await ctx.send(reply)
|
|
|
|
@bot.hybrid_command(name="available", description="List commands available to you")
|
|
async def available(ctx):
|
|
available_cmds = []
|
|
for command in bot.commands:
|
|
try:
|
|
# This will return True if the command's checks pass for the given context.
|
|
if await command.can_run(ctx):
|
|
available_cmds.append(command.name)
|
|
except commands.CheckFailure:
|
|
# The command's checks did not pass.
|
|
pass
|
|
except Exception as e:
|
|
# In case some commands fail unexpectedly during checks.
|
|
globals.log(f"Error checking command {command.name}: {e}", "ERROR")
|
|
if available_cmds:
|
|
await ctx.send("Available commands: " + ", ".join(sorted(available_cmds)))
|
|
else:
|
|
await ctx.send("No commands are available to you at this time.")
|
|
|
|
@bot.hybrid_command(name="help", description="Get information about commands")
|
|
@app_commands.describe(
|
|
command="The command to get help info about. Defaults to 'help'"
|
|
)
|
|
async def cmd_help(ctx: commands.Context, *, command: str = ""):
|
|
"""
|
|
e.g. !help
|
|
!help quote
|
|
"""
|
|
result = await handle_help_command(ctx, command, bot, is_discord=True)
|
|
await ctx.send(result)
|
|
|
|
|
|
@bot.hybrid_command(name="greet", description="Make me greet you")
|
|
async def cmd_greet(ctx):
|
|
result = cc.greet(ctx.author.display_name, "Discord")
|
|
await ctx.send(result)
|
|
|
|
@bot.hybrid_command(name="ping", description="Check my uptime")
|
|
async def cmd_ping(ctx):
|
|
result = cc.ping()
|
|
# Get heartbeat latency. Discord only
|
|
latency = round(float(bot.latency) * 1000)
|
|
result += f" (*latency: {latency}ms*)"
|
|
await ctx.send(result)
|
|
|
|
@bot.hybrid_command(name="howl", description="Attempt a howl")
|
|
async def cmd_howl(ctx):
|
|
response = cc.handle_howl_command(ctx)
|
|
await ctx.send(response)
|
|
|
|
# @monitor_cmds(bot.log)
|
|
# @bot.hybrid_command(name="reload", description="Dynamically reload commands (INOP)")
|
|
# async def cmd_reload(ctx):
|
|
# """ Dynamically reloads Discord commands. """
|
|
# try:
|
|
# import cmd_discord
|
|
# import importlib
|
|
# importlib.reload(cmd_discord)
|
|
# cmd_discord.setup(bot)
|
|
# await ctx.send("Commands reloaded on first try!")
|
|
# except Exception as e:
|
|
# try:
|
|
# await bot.reload_extension("cmd_discord")
|
|
# await ctx.send("Commands reloaded on second try!")
|
|
# except Exception as e:
|
|
# try:
|
|
# await bot.unload_extension("cmd_discord")
|
|
# await bot.load_extension("cmd_discord")
|
|
# await ctx.send("Commands reloaded on third try!")
|
|
# except Exception as e:
|
|
# await ctx.send(f"Fallback reload failed: {e}")
|
|
|
|
@bot.hybrid_command(name="hi", description="Dev command for testing permissions system")
|
|
async def cmd_hi(ctx):
|
|
user_id = str(ctx.author.id)
|
|
user_roles = [role.name.lower() for role in ctx.author.roles] # Normalize to lowercase
|
|
|
|
if not has_permission("hi", user_id, user_roles, "discord"):
|
|
await ctx.send("You don't have permission to use this command.")
|
|
return
|
|
|
|
await ctx.send("Hello there!")
|
|
|
|
# @monitor_cmds(bot.log)
|
|
# @bot.hybrid_command(name="quote", description="Interact with the quotes system")
|
|
# async def cmd_quote(ctx, query: str = None):
|
|
# """
|
|
# !quote
|
|
# !quote add <text>
|
|
# !quote remove <id>
|
|
# !quote <id>
|
|
# """
|
|
# if not bot.db_conn:
|
|
# return await ctx.send("Database is unavailable, sorry.")
|
|
|
|
# args = query.split()
|
|
|
|
# # Send to our shared logic
|
|
# await cc.handle_quote_command(
|
|
# db_conn=bot.db_conn,
|
|
# log_func=bot.log,
|
|
# is_discord=True,
|
|
# ctx=ctx,
|
|
# args=list(args),
|
|
# get_twitch_game_for_channel=None # None for Discord
|
|
# )
|
|
|
|
# @monitor_cmds(bot.log)
|
|
# @bot.hybrid_group(name="quote", description="Interact with the quotes system", with_app_command=True)
|
|
# async def cmd_quote(ctx, query: str = None):
|
|
# """
|
|
# Usage:
|
|
# !quote -> get a random quote
|
|
# !quote <id> -> get a specific quote by number
|
|
# As a slash command, leave the query blank for a random quote or type a number.
|
|
# """
|
|
# if not bot.db_conn:
|
|
# return await ctx.send("Database is unavailable, sorry.")
|
|
|
|
# # Only process the base command if no subcommand was invoked.
|
|
# # When query is provided, split it into arguments (for a specific quote lookup).
|
|
# args = query.split() if query else []
|
|
|
|
# await cc.handle_quote_command(
|
|
# db_conn=bot.db_conn,
|
|
# log_func=bot.log,
|
|
# is_discord=True,
|
|
# ctx=ctx,
|
|
# args=args,
|
|
# get_twitch_game_for_channel=None # None for Discord
|
|
# )
|
|
|
|
@bot.hybrid_group(name="quote", description="Interact with the quotes system", with_app_command=True)
|
|
async def cmd_quote(ctx, *, id: Optional[int] = None):
|
|
"""
|
|
Handles base quote commands.
|
|
- `!quote` -> Fetch a random quote
|
|
- `!quote <id>` -> Fetch a specific quote by ID
|
|
- `/quote` or `/quote <id>` -> Works for slash commands
|
|
"""
|
|
if not bot.db_conn:
|
|
return await ctx.send("Database is unavailable, sorry.")
|
|
|
|
# If no query is provided, fetch a random quote.
|
|
if not id:
|
|
args = []
|
|
else:
|
|
args = id.split() # Split query into arguments
|
|
|
|
globals.log(f"'quote' command initiated with arguments: {args}", "DEBUG")
|
|
|
|
result = await cc.handle_quote_command(
|
|
db_conn=bot.db_conn,
|
|
is_discord=True,
|
|
ctx=ctx,
|
|
args=args,
|
|
get_twitch_game_for_channel=None
|
|
)
|
|
|
|
globals.log(f"'quote' result: {result}")
|
|
|
|
await ctx.send(result)
|
|
|
|
@cmd_quote.command(name="add", description="Add a quote")
|
|
async def cmd_quote_add(ctx, *, text: str):
|
|
"""
|
|
Usage:
|
|
- `!quote add <text>`
|
|
- `/quote add text:<your quote>` for slash commands.
|
|
"""
|
|
if not bot.db_conn:
|
|
return await ctx.send("Database is unavailable, sorry.")
|
|
|
|
# Ensure text isn't empty
|
|
if not text.strip():
|
|
return await ctx.send("You must provide a quote text.")
|
|
|
|
args = ["add", text] # Properly format arguments
|
|
|
|
result = await cc.handle_quote_command(
|
|
db_conn=bot.db_conn,
|
|
is_discord=True,
|
|
ctx=ctx,
|
|
args=args,
|
|
get_twitch_game_for_channel=None
|
|
)
|
|
|
|
await ctx.send(result)
|
|
|
|
@cmd_quote.command(name="remove", description="Remove a quote by number")
|
|
async def cmd_quote_remove(ctx, id: int):
|
|
"""
|
|
Usage:
|
|
- `!quote remove <id>`
|
|
- `/quote remove id:<quote number>`
|
|
"""
|
|
if not bot.db_conn:
|
|
return await ctx.send("Database is unavailable, sorry.")
|
|
|
|
args = ["remove", str(id)] # Properly pass the ID as an argument
|
|
|
|
result = await cc.handle_quote_command(
|
|
db_conn=bot.db_conn,
|
|
is_discord=True,
|
|
ctx=ctx,
|
|
args=args,
|
|
get_twitch_game_for_channel=None
|
|
)
|
|
|
|
await ctx.send(result)
|
|
|
|
######################
|
|
# 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:
|
|
command_names = [cmd.name for cmd in bot.commands] # Extract command names
|
|
globals.log(f"Registering commands for Discord: {command_names}", "DEBUG")
|
|
except Exception as e:
|
|
globals.log(f"An error occured while printing registered commands for Discord: {e}", "WARNING") |