blob/commands/ticket.py
2025-01-25 16:31:29 -05:00

223 lines
9.2 KiB
Python

import discord
import pymongo
import os
import asyncio
from discord.ext import commands
from discord.ui import Button, button, View
from discord import app_commands
client = pymongo.MongoClient(os.getenv('mongo_url'))
db = client.tickets
async def send_log(title: str, guild: discord.Guild, description: str, color: discord.Color):
guild_coll = db.guilds
ticket_log_id = guild_coll.find_one({"_id": guild.id})['log_channel']
ticket_log = guild.get_channel(ticket_log_id)
embed = discord.Embed(
title=title,
description=description,
color=color
)
await ticket_log.send(embed=embed)
class CreateButton(View):
def __init__(self):
super().__init__(timeout=None)
@button(label="Create Ticket", style=discord.ButtonStyle.blurple, emoji="🎫", custom_id="ticketopen")
async def ticket(self, interaction: discord.Interaction, button: Button):
await interaction.response.defer(ephemeral=True)
# db setup
guild_coll = db.guilds
guild = guild_coll.find_one({"_id": interaction.guild.id})
if guild is None:
await interaction.response.send_message("Tickets is not setup for this server...")
return
# category stuff & check if user already has a ticket opened
category: discord.CategoryChannel = discord.utils.get(interaction.guild.categories, name="OPENED TICKETS")
for ch in category.text_channels:
if ch.topic == f"{interaction.user.id} DO NOT CHANGE THE TOPIC OF THIS CHANNEL!":
await interaction.response.send_message(
"You already have a ticket open! Ticket located in {0}".format(ch.mention), ephemeral=True)
return
# send message to let the user know the bot is doing things
await interaction.response.send_message("Creating a ticket...")
# get the ticket number
ticket_num = guild['ticket_count'] + 1
# channel settings & create channel
r1: discord.Role = discord.utils.get(interaction.guild.roles, name="Ticket Master")
overwrites = {
interaction.guild.default_role: discord.PermissionOverwrite(read_messages=False),
r1: discord.PermissionOverwrite(read_messages=True, send_messages=True, manage_messages=True),
interaction.user: discord.PermissionOverwrite(read_messages=True, send_messages=True),
interaction.guild.me: discord.PermissionOverwrite(read_messages=True, send_messages=True)
}
channel = await category.create_text_channel(
name=f"ticket-{ticket_num}",
topic=f"{interaction.user.id} DO NOT CHANGE THE TOPIC OF THIS CHANNEL!",
overwrites=overwrites
)
em = discord.Embed(description="Someone will be here to assist you shortly.\nTo close this ticket react with 🔒",color=interaction.user.color)
em.set_footer(text="Powered by Blob", icon_url=interaction.guild.me.avatar)
await channel.send(f"{interaction.user.mention} Welcome to your ticket. {r1.mention}\n\nPlease don't ping staff, they will be here soon.\n\n",embed=em, view=CloseButton())
await interaction.followup.send(f"Ticket created in {channel.mention}", ephemeral=True)
await send_log(
title="Ticket Created",
description=f"Created by: {interaction.user.mention}",
color=discord.Color.green(),
guild=interaction.guild
)
class CloseButton(View):
def __init__(self):
super().__init__(timeout=None)
@button(label="Close Ticket", style=discord.ButtonStyle.red, custom_id="closeticket", emoji="🔒")
async def close(self, interaction: discord.Interaction, button: Button):
channel = interaction.channel
# get the ticket number
split_channel_name = channel.name.split("ticket-")
ticket = split_channel_name[1]
# send a message to the user letting them know the ticket is being closed
await interaction.response.send_message("Attempting to close this ticket...")
# get the author of the ticket
ticket_author = channel.topic.split(" ")[0]
# edit the channel
category: discord.CategoryChannel = discord.utils.get(interaction.guild.categories, name="CLOSED TICKETS")
r1: discord.Role = discord.utils.get(interaction.guild.roles, name="Ticket Master")
overwrites = {
interaction.guild.default_role: discord.PermissionOverwrite(read_messages=False),
r1: discord.PermissionOverwrite(read_messages=True, send_messages=True, manage_messages=True),
interaction.guild.me: discord.PermissionOverwrite(read_messages=True, send_messages=True)
}
await interaction.channel.edit(category=category, overwrites=overwrites)
# update the db
ticket_coll = db.tickets
guild_coll = db.guilds
ticket_coll.update_one({"_id": int(ticket_author)}, {"$set": {"opened": False}})
guild_coll.update_one({"_id": interaction.guild.id}, {"$pull": {"opened_tickets": int(ticket)}})
guild_coll.update_one({"_id": interaction.guild.id}, {"$push": {"closed_tickets": int(ticket)}})
# tell the user the ticket was closed
await interaction.channel.send(
embed = discord.Embed(
title="Ticket Closed",
description="This ticket has been closed\n\nTicket closed by {0}".format(interaction.user.mention),
color=interaction.user.color
),
view=TrashButton()
)
await send_log(
title="Ticket Closed",
description=f"Closed by: {interaction.user.mention}",
color=discord.Color.yellow(),
guild=interaction.guild
)
class TrashButton(View):
def __init__(self):
super().__init__(timeout=None)
@button(label="Trash Ticket", style=discord.ButtonStyle.red, custom_id="trash", emoji="🗑️")
async def trash(self, interaction: discord.Interaction, button: Button):
await interaction.response.defer(ephemeral=True)
await interaction.channel.send("Deleting ticket in 3 seconds")
await asyncio.sleep(3)
await interaction.channel.delete()
ticket_coll = db.tickets
guild_coll = db.guilds
ticket_author = int(interaction.channel.topic.split(" ")[0])
ticket = int(interaction.channel.name.split('ticket-')[1])
ticket_coll.delete_one({"_id": ticket_author})
guild_coll.update_one({"_id": interaction.guild.id}, {"$pull": {"closed_tickets": ticket}})
await send_log(
title="Ticket Deleted",
description=f"Deleted by: {interaction.user.mention}",
color=discord.Color.red(),
guild=interaction.guild
)
class Ticket(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.Cog.listener()
async def on_ready(self):
print('Tickets Online')
ticket = app_commands.Group(name="tickets", description="Have an issue? Create a ticket now")
@ticket.command(name="setup", description="Setup tickets")
@commands.has_permissions(administrator=True)
async def setup(self, interaction: discord.Interaction):
await interaction.response.send_message("Starting the setup process")
coll = db.guilds
guild = coll.find_one({"_id": interaction.guild.id})
if guild is not None:
await interaction.followup.send("Ticket has already been setup for this server")
return
if not discord.utils.get(interaction.guild.categories, name="OPENED TICKETS"):
await interaction.guild.create_category(name="OPENED TICKETS")
if not discord.utils.get(interaction.guild.categories, name="CLOSED TICKETS"):
await interaction.guild.create_category(name="CLOSED TICKETS")
if not discord.utils.get(interaction.guild.roles, name="Ticket Master"):
await interaction.guild.create_role(name="Ticket Master")
if not discord.utils.get(interaction.guild.channels, name="ticket-logs"):
await interaction.guild.create_text_channel(name="ticket-logs")
log_channel = discord.utils.get(interaction.guild.channels, name="ticket-logs")
coll.insert_one({"_id": interaction.guild.id, "ticket_count": 0, "opened_tickets": [], "closed_tickets": [],
"log_channel": log_channel.id})
await interaction.followup.send("Tickets have been setup. Users can use `/ticket create` in any channel.")
await log_channel.send("This channel will now be used for ticket logging.")
@ticket.command(name="create", description="Create a ticket")
@commands.has_permissions(administrator=True)
async def ticket(self, interaction: discord.Interaction):
# db setup
guild_coll = db.guilds
guild = guild_coll.find_one({"_id": interaction.guild.id})
if guild is None:
await interaction.response.send_message("Tickets is not setup for this server...")
return
await interaction.response.send_message(
embed=discord.Embed(
description="Click the button below to create a ticket",
color=interaction.user.color
),
view=CreateButton()
)
async def setup(bot):
await bot.add_cog(Ticket(bot))