discordbot/cogs/status_cog.py
2025-04-25 14:03:49 -06:00

105 lines
4.4 KiB
Python

import discord
from discord.ext import commands
from discord import app_commands
from typing import Optional, Literal
class StatusCog(commands.Cog):
"""Commands for managing the bot's status"""
def __init__(self, bot: commands.Bot):
self.bot = bot
async def _set_status_logic(self,
status_type: Literal["playing", "listening", "streaming", "watching", "competing"],
status_text: str,
stream_url: Optional[str] = None) -> str:
"""Core logic for setting the bot's status"""
# Map the status type to the appropriate ActivityType
activity_types = {
"playing": discord.ActivityType.playing,
"listening": discord.ActivityType.listening,
"streaming": discord.ActivityType.streaming,
"watching": discord.ActivityType.watching,
"competing": discord.ActivityType.competing
}
activity_type = activity_types.get(status_type.lower())
if not activity_type:
return f"Invalid status type: {status_type}. Valid types are: playing, listening, streaming, watching, competing."
try:
# For streaming status, we need a URL
if status_type.lower() == "streaming" and stream_url:
await self.bot.change_presence(activity=discord.Streaming(name=status_text, url=stream_url))
else:
await self.bot.change_presence(activity=discord.Activity(type=activity_type, name=status_text))
return f"Status set to: {status_type.capitalize()} {status_text}"
except Exception as e:
return f"Error setting status: {str(e)}"
# --- Prefix Command ---
@commands.command(name="setstatus")
@commands.is_owner()
async def set_status(self, ctx: commands.Context, status_type: str, *, status_text: str):
"""Set the bot's status (Owner only)
Valid status types:
- playing
- listening
- streaming (requires a URL in the status text)
- watching
- competing
Example:
!setstatus playing Minecraft
!setstatus listening to music
!setstatus streaming https://twitch.tv/username Stream Title
!setstatus watching YouTube
!setstatus competing in a tournament
"""
# For streaming status, extract the URL from the status text
stream_url = None
if status_type.lower() == "streaming":
parts = status_text.split()
if len(parts) >= 2 and (parts[0].startswith("http://") or parts[0].startswith("https://")):
stream_url = parts[0]
status_text = " ".join(parts[1:])
response = await self._set_status_logic(status_type, status_text, stream_url)
await ctx.reply(response)
# --- Slash Command ---
@app_commands.command(name="setstatus", description="Set the bot's status")
@app_commands.describe(
status_type="The type of status to set",
status_text="The text to display in the status",
stream_url="URL for streaming status (only required for streaming status)"
)
@app_commands.choices(status_type=[
app_commands.Choice(name="Playing", value="playing"),
app_commands.Choice(name="Listening", value="listening"),
app_commands.Choice(name="Streaming", value="streaming"),
app_commands.Choice(name="Watching", value="watching"),
app_commands.Choice(name="Competing", value="competing")
])
async def set_status_slash(self,
interaction: discord.Interaction,
status_type: str,
status_text: str,
stream_url: Optional[str] = None):
"""Slash command version of set_status."""
# Check if user is the bot owner
if interaction.user.id != self.bot.owner_id:
await interaction.response.send_message("This command can only be used by the bot owner.", ephemeral=True)
return
response = await self._set_status_logic(status_type, status_text, stream_url)
await interaction.response.send_message(response)
async def setup(bot: commands.Bot):
await bot.add_cog(StatusCog(bot))
print("StatusCog loaded successfully!")