import datetime import re import discord import json import os import dotenv dotenv.load_dotenv() TICKETS_FILE_PATH = '/mnt/tickets.json' DISCORD_TOKEN = os.getenv('DISCORD_TOKEN') intents = discord.Intents.default() client = discord.Client(intents=intents) def set_client(c): global client client = c print("Client set") if not os.path.exists(TICKETS_FILE_PATH): with open(TICKETS_FILE_PATH, 'w') as f: json.dump({"server": {}}, f) def is_server_valid(server:str): server = server with open(TICKETS_FILE_PATH, 'r') as f: ticketsData = json.load(f) if server in ticketsData['server']: return True return False async def create_ticket(user_id, server:str): with open(TICKETS_FILE_PATH, 'r') as f: ticketsData = json.load(f) if server not in ticketsData['server']: return "Server not found" tickets = ticketsData['server'][server]['tickets'] if user_id != str(client.application.owner.id): for ticket in tickets: if ticket['user_id'] == user_id and ticket['status'] == "open": return "You already have an open ticket" ticketNum = len(tickets) + 1 # Generate a ticket name user = await client.fetch_user(int(user_id)) if user == None: return "User not found" # Create a new ticket channel guild = await client.fetch_guild(int(server)) guild = client.get_guild(int(server)) ticketName = f"{ticketNum}-{user.name}-ticket" category = discord.utils.get(guild.categories, id=int(ticketsData['server'][server]['category'])) if category == None: return "Category not found" # Create the ticket channel ticketChannel = await guild.create_text_channel(ticketName, category=category) # Remove the default permissions await ticketChannel.set_permissions(guild.default_role, read_messages=False, send_messages=False) # Add the user to the ticket channel await ticketChannel.set_permissions(user, read_messages=True, send_messages=True) # Add the modRole to the ticket channel admin = guild.get_role(int(ticketsData['server'][server]['adminRole'])) await ticketChannel.set_permissions(admin, read_messages=True, send_messages=True) # Add the ticket to the tickets list tickets.append({ 'user_id': user_id, 'channel_id': ticketChannel.id, 'status': "open", 'members': [user_id] }) ticketsData['server'][server]['tickets'] = tickets with open(TICKETS_FILE_PATH, 'w') as f: json.dump(ticketsData, f) await ticketChannel.send(f"G'day <@{user_id}>, your ticket has been created. Please let us know how we can help you.") await ticketChannel.send(f"Commands: \n - Add a user to the ticket\n - Remove a user from the ticket\n - Rename the ticket\n - Close the ticket") return f"Ticket <#{ticketChannel.id}> created" async def ticketAddServer(server, category, adminRole,closedCategory): with open(TICKETS_FILE_PATH, 'r') as f: ticketsData = json.load(f) ticketsData['server'][server] = { 'category': category, 'closedCategory': closedCategory, 'adminRole': adminRole, 'tickets': [] } with open(TICKETS_FILE_PATH, 'w') as f: json.dump(ticketsData, f) return "Server added" async def close_ticket(user_id,channel_id, server): with open(TICKETS_FILE_PATH, 'r') as f: ticketsData = json.load(f) tickets = ticketsData['server'][server]['tickets'] validTicket = False for ticket in tickets: if str(ticket['channel_id']) == channel_id: ticket['status'] = "closed" validTicket = True break if not validTicket: return "This ticket does not exist" ticketsData['server'][server]['tickets'] = tickets with open(TICKETS_FILE_PATH, 'w') as f: json.dump(ticketsData, f) # Remove read and send permissions for everyone guild = await client.fetch_guild(int(server)) guild = client.get_guild(int(server)) ticketChannel = guild.get_channel(int(channel_id)) await ticketChannel.set_permissions(guild.default_role, read_messages=False, send_messages=False) for member in ticket['members']: user = await client.fetch_user(int(member)) await ticketChannel.set_permissions(user, read_messages=False, send_messages=False) await ticketChannel.send(f"This ticket has been closed by <@{user_id}>") # Move to the closed category closedCategory = discord.utils.get(guild.categories, id=int(ticketsData['server'][server]['closedCategory'])) if closedCategory == None: return "Category not found" await ticketChannel.edit(category=closedCategory) async def addMemberToTicket(user_id, channel_id, server): guild = await client.fetch_guild(int(server)) guild = client.get_guild(int(server)) user = await fuzzyUser(user_id, guild) if user == False: return "User not found" user_id = str(user.id) with open(TICKETS_FILE_PATH, 'r') as f: ticketsData = json.load(f) tickets = ticketsData['server'][server]['tickets'] validTicket = False for ticket in tickets: if str(ticket['channel_id']) == channel_id: if user_id in ticket['members']: return "User already in ticket" ticket['members'].append(user_id) validTicket = True break if not validTicket: return "This ticket does not exist" ticketsData['server'][server]['tickets'] = tickets with open(TICKETS_FILE_PATH, 'w') as f: json.dump(ticketsData, f) ticketChannel = guild.get_channel(int(channel_id)) await ticketChannel.set_permissions(user, read_messages=True, send_messages=True) await ticketChannel.send(f"{user.mention} has been added to the ticket") return "User added to ticket" async def removeMemberFromTicket(user_id, channel_id, server): guild = await client.fetch_guild(int(server)) guild = client.get_guild(int(server)) user = await fuzzyUser(user_id, guild) if user == False: return "User not found" user_id = str(user.id) with open(TICKETS_FILE_PATH, 'r') as f: ticketsData = json.load(f) tickets = ticketsData['server'][server]['tickets'] validTicket = False for ticket in tickets: if str(ticket['channel_id']) == channel_id: if user_id not in ticket['members']: return "User not found in ticket" ticket['members'].remove(user_id) validTicket = True break if not validTicket: return "This ticket does not exist" ticketsData['server'][server]['tickets'] = tickets with open(TICKETS_FILE_PATH, 'w') as f: json.dump(ticketsData, f) ticketChannel = guild.get_channel(int(channel_id)) await ticketChannel.set_permissions(user, read_messages=False, send_messages=False) await ticketChannel.send(f"{user.mention} has been removed from the ticket") return "User removed from ticket" async def reopen_ticket(user_id,channel_id,guild_id): with open(TICKETS_FILE_PATH, 'r') as f: ticketsData = json.load(f) tickets = ticketsData['server'][guild_id]['tickets'] validTicket = False for ticket in tickets: if str(ticket['channel_id']) == channel_id: if ticket['status'] == "open": return "Ticket is already open" ticket['status'] = "open" validTicket = True break if not validTicket: return "This ticket does not exist" ticketsData['server'][guild_id]['tickets'] = tickets with open(TICKETS_FILE_PATH, 'w') as f: json.dump(ticketsData, f) guild = await client.fetch_guild(int(guild_id)) guild = client.get_guild(int(guild_id)) channel = guild.get_channel(int(channel_id)) # Remove read and send permissions for everyone await channel.set_permissions(guild.default_role, read_messages=False, send_messages=False) for member in ticket['members']: user = await client.fetch_user(int(member)) await channel.set_permissions(user, read_messages=True, send_messages=True) await channel.send(f"This ticket has been reopened by <@{user_id}>") # Move to the closed category category = discord.utils.get(guild.categories, id=int(ticketsData['server'][guild_id]['category'])) if category == None: return "Category not found" await channel.edit(category=category) return "Ticket reopened" async def rename_ticket(user_id,channel_id,server_id,newName): try: guild = await client.fetch_guild(int(server_id)) guild = client.get_guild(int(server_id)) channel = guild.get_channel(int(channel_id)) await channel.edit(name=newName) return "Ticket renamed" except: return "Error renaming ticket" async def fuzzyUser(search, guild): user = None try: user = await client.fetch_user(int(search)) except: pass if user == None: user = discord.utils.get(guild.members, name=search) if user == None: user = discord.utils.get(guild.members, nick=search) if user == None: user = discord.utils.get(guild.members, global_name=search) if user == None: user = discord.utils.get(guild.members, global_name=search) if user == None: user = guild.get_member_named(search) if user == None: user = await guild.query_members(search) if len(user) > 0: user = user[0] else: return False if user == None: return False return user