feat: add multiple discord bot cogs

Adds new cogs including DataManager, Hiring, KofiShop, Logging, ModMail, MORS, ServiceReview, StaffMsg, and Translator to enhance bot functionality for data management, hiring processes, logging events, and more.
This commit is contained in:
2025-09-23 00:28:29 -04:00
parent c2367369f1
commit 81f2eee409
63 changed files with 2824 additions and 6 deletions

View File

@@ -0,0 +1,90 @@
import discord
import datetime
from redbot.core import commands, Config, app_commands
from typing import Optional
class Modmail(commands.Cog):
"""
A private, forum-based ModMail system.
"""
def __init__(self, bot):
self.bot = bot
self.config = Config.get_conf(self, identifier=1234567890, force_registration=True)
default_guild = {
"forum_channel": None,
"enabled": False,
"active_threads": {},
"closed_threads": {} # NEW: To log closed tickets for purging
}
self.config.register_guild(**default_guild)
# ... existing on_message listener ...
@commands.Cog.listener()
async def on_message(self, message: discord.Message):
if message.author.bot:
return
# --- User to Staff DM Logic ---
if isinstance(message.channel, discord.DMChannel):
# ... existing user DM logic ...
pass
# --- Staff to User Reply Logic ---
elif isinstance(message.channel, discord.Thread):
# ... existing staff reply logic ...
pass
@app_commands.command(name="close")
@app_commands.guild_only()
async def modmail_close(self, interaction: discord.Interaction, *, reason: Optional[str] = "No reason provided."):
"""Close the current ModMail ticket."""
guild = interaction.guild
if not guild:
await interaction.response.send_message("This command can only be used in a server.", ephemeral=True)
return
# NEW: Safely check if the interaction has a channel
if not interaction.channel:
await interaction.response.send_message("This command cannot be used in this context.", ephemeral=True)
return
# ... existing logic to check if it's a modmail thread ...
thread_id_str = str(interaction.channel.id)
async with self.config.guild(guild).active_threads() as active_threads:
user_id = active_threads.pop(thread_id_str, None)
if user_id:
# NEW: Log the closed thread with a timestamp
async with self.config.guild(guild).closed_threads() as closed_threads:
closed_threads[thread_id_str] = datetime.datetime.now(datetime.timezone.utc).isoformat()
# ... existing logic to send final message and archive thread ...
user = self.bot.get_user(int(user_id))
if user:
embed = discord.Embed(
title="Ticket Closed",
description=f"Your ModMail ticket has been closed.\n**Reason:** {reason}",
color=0x8b9ed7 # Pastel Blue
)
try:
await user.send(embed=embed)
except discord.Forbidden:
pass
await interaction.response.send_message("Ticket has been closed and archived.", ephemeral=True)
if isinstance(interaction.channel, discord.Thread):
await interaction.channel.edit(archived=True, locked=True)
else:
await interaction.response.send_message("This does not appear to be an active ModMail ticket.", ephemeral=True)
@commands.group(aliases=["mmset"]) # type: ignore
@commands.guild_only()
@commands.admin_or_permissions(manage_guild=True)
async def modmailset(self, ctx: commands.Context):
"""Configure ModMail settings."""
pass
# ... existing modmailset subcommands ...