This commit is contained in:
parent
c37ba86917
commit
7064f0a1f7
109
bot.py
109
bot.py
@ -17,6 +17,8 @@ import tools
|
|||||||
from tools import parse_time, read_reminders, store_reminder, write_reminders
|
from tools import parse_time, read_reminders, store_reminder, write_reminders
|
||||||
import asyncio
|
import asyncio
|
||||||
from discord.ext import tasks, commands
|
from discord.ext import tasks, commands
|
||||||
|
from discord.ext.commands import has_permissions, MissingPermissions
|
||||||
|
import support
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -233,9 +235,9 @@ async def ssl(ctx, domain: str, showcert: bool = False, notifymeonexpiry: bool =
|
|||||||
|
|
||||||
expiry_date = cert_obj.not_valid_after
|
expiry_date = cert_obj.not_valid_after
|
||||||
# Check if expiry date is past
|
# Check if expiry date is past
|
||||||
if expiry_date < datetime.datetime.now():
|
if expiry_date < datetime.datetime.utcnow():
|
||||||
message = message + "\n## Expiry Date:\n:x: Certificate has expired\n"
|
message = message + "\n## Expiry Date:\n:x: Certificate has expired\n"
|
||||||
elif expiry_date < datetime.datetime.now() + datetime.timedelta(days=7):
|
elif expiry_date < datetime.datetime.utcnow() + datetime.timedelta(days=7):
|
||||||
message = message + "\n## Expiry Date:\n:warning: Certificate expires soon\n"
|
message = message + "\n## Expiry Date:\n:warning: Certificate expires soon\n"
|
||||||
else:
|
else:
|
||||||
message = message + "\n## Expiry Date:\n:white_check_mark: Certificate is valid\n"
|
message = message + "\n## Expiry Date:\n:white_check_mark: Certificate is valid\n"
|
||||||
@ -363,7 +365,7 @@ async def checkForSSLExpiry():
|
|||||||
# Get expiry date
|
# Get expiry date
|
||||||
cert_obj = x509.load_pem_x509_certificate(cert.encode("utf-8"), default_backend())
|
cert_obj = x509.load_pem_x509_certificate(cert.encode("utf-8"), default_backend())
|
||||||
expiry_date = cert_obj.not_valid_after
|
expiry_date = cert_obj.not_valid_after
|
||||||
if expiry_date < datetime.datetime.now() + datetime.timedelta(days=7):
|
if expiry_date < datetime.datetime.utcnow() + datetime.timedelta(days=7):
|
||||||
user = await client.fetch_user(int(userid))
|
user = await client.fetch_user(int(userid))
|
||||||
if user:
|
if user:
|
||||||
await user.send(f"SSL certificate for {domain} expires soon")
|
await user.send(f"SSL certificate for {domain} expires soon")
|
||||||
@ -507,6 +509,105 @@ async def timestamp(ctx, when: str):
|
|||||||
else:
|
else:
|
||||||
await ctx.response.send_message("Invalid time format. Please use something like `1d 3h` or `4hr`. End with `ago` to convert to past time",ephemeral=True)
|
await ctx.response.send_message("Invalid time format. Please use something like `1d 3h` or `4hr`. End with `ago` to convert to past time",ephemeral=True)
|
||||||
|
|
||||||
|
#region Tickets
|
||||||
|
@tree.command(name="ticket", description="Create a ticket")
|
||||||
|
async def ticket(ctx):
|
||||||
|
if (ctx.guild == None):
|
||||||
|
await ctx.response.send_message("This command can only be used in a server",ephemeral=True)
|
||||||
|
return
|
||||||
|
|
||||||
|
server = ctx.guild.id
|
||||||
|
if not support.is_server_valid(str(server)):
|
||||||
|
await ctx.response.send_message("This server is not registered",ephemeral=True)
|
||||||
|
return
|
||||||
|
await ctx.response.send_message("Creating ticket...",ephemeral=True)
|
||||||
|
await support.create_ticket(str(ctx.user.id), str(ctx.guild.id))
|
||||||
|
|
||||||
|
|
||||||
|
@tree.command(name="ticketaddserver", description="Add a server to the ticket system")
|
||||||
|
@commands.has_permissions(administrator=True)
|
||||||
|
async def ticketaddserver(ctx, category: str, modrole: discord.Role, closedcategory: str):
|
||||||
|
if (ctx.user.id != ADMINID):
|
||||||
|
await log("User: " + str(ctx.user.name) + " tried to use the ticketAddServer command")
|
||||||
|
await ctx.response.send_message("You don't have permission to use this command",ephemeral=True)
|
||||||
|
else:
|
||||||
|
await ctx.response.send_message("Adding server to ticket system",ephemeral=True)
|
||||||
|
result = await support.ticketAddServer(ctx.guild.id, category, modrole.id,closedcategory)
|
||||||
|
await ctx.channel.send(result)
|
||||||
|
|
||||||
|
|
||||||
|
@tree.command(name="adduser", description="Add a user to a ticket")
|
||||||
|
async def adduser(ctx, user: discord.User):
|
||||||
|
if (ctx.guild == None):
|
||||||
|
await ctx.response.send_message("This command can only be used in a server",ephemeral=True)
|
||||||
|
return
|
||||||
|
|
||||||
|
server = ctx.guild.id
|
||||||
|
if not support.is_server_valid(str(server)):
|
||||||
|
await ctx.response.send_message("This server is not registered",ephemeral=True)
|
||||||
|
return
|
||||||
|
result = await support.addMemberToTicket(user,str(ctx.channel.id), str(ctx.guild.id))
|
||||||
|
await ctx.response.send_message(result,ephemeral=True)
|
||||||
|
|
||||||
|
@tree.command(name="removeuser", description="Remove a user from a ticket")
|
||||||
|
async def removeuser(ctx, user: discord.User):
|
||||||
|
if (ctx.guild == None):
|
||||||
|
await ctx.response.send_message("This command can only be used in a server",ephemeral=True)
|
||||||
|
return
|
||||||
|
|
||||||
|
server = ctx.guild.id
|
||||||
|
if not support.is_server_valid(str(server)):
|
||||||
|
await ctx.response.send_message("This server is not registered",ephemeral=True)
|
||||||
|
return
|
||||||
|
result = await support.removeMemberFromTicket(user,str(ctx.channel.id), str(ctx.guild.id))
|
||||||
|
await ctx.response.send_message(result,ephemeral=True)
|
||||||
|
|
||||||
|
|
||||||
|
@tree.command(name="closeticket", description="Close a ticket")
|
||||||
|
async def closeticket(ctx):
|
||||||
|
if (ctx.guild == None):
|
||||||
|
await ctx.response.send_message("This command can only be used in a server",ephemeral=True)
|
||||||
|
return
|
||||||
|
|
||||||
|
server = ctx.guild.id
|
||||||
|
if not support.is_server_valid(str(server)):
|
||||||
|
await ctx.response.send_message("This server is not registered",ephemeral=True)
|
||||||
|
return
|
||||||
|
await ctx.response.send_message("Closing ticket",ephemeral=True)
|
||||||
|
await support.close_ticket(str(ctx.user.id),str(ctx.channel.id), str(ctx.guild.id))
|
||||||
|
|
||||||
|
@tree.command(name="reopenticket", description="Reopen a ticket")
|
||||||
|
async def reopenticket(ctx):
|
||||||
|
if (ctx.guild == None):
|
||||||
|
await ctx.response.send_message("This command can only be used in a server",ephemeral=True)
|
||||||
|
return
|
||||||
|
|
||||||
|
server = ctx.guild.id
|
||||||
|
if not support.is_server_valid(str(server)):
|
||||||
|
await ctx.response.send_message("This server is not registered",ephemeral=True)
|
||||||
|
return
|
||||||
|
await ctx.response.send_message("Reopening ticket",ephemeral=True)
|
||||||
|
await support.reopen_ticket(str(ctx.user.id),str(ctx.channel.id), str(ctx.guild.id))
|
||||||
|
|
||||||
|
@tree.command(name="renameticket", description="Rename a ticket")
|
||||||
|
async def renameticket(ctx, name: str):
|
||||||
|
if (ctx.guild == None):
|
||||||
|
await ctx.response.send_message("This command can only be used in a server",ephemeral=True)
|
||||||
|
return
|
||||||
|
|
||||||
|
server = ctx.guild.id
|
||||||
|
if not support.is_server_valid(str(server)):
|
||||||
|
await ctx.response.send_message("This server is not registered",ephemeral=True)
|
||||||
|
return
|
||||||
|
|
||||||
|
result = await support.rename_ticket(str(ctx.user.id),str(ctx.channel.id), str(ctx.guild.id),name)
|
||||||
|
await ctx.response.send_message(result,ephemeral=True)
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@tasks.loop(seconds=10)
|
@tasks.loop(seconds=10)
|
||||||
async def check_reminders():
|
async def check_reminders():
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
@ -529,6 +630,7 @@ async def check_reminders():
|
|||||||
async def on_ready():
|
async def on_ready():
|
||||||
global ADMINID
|
global ADMINID
|
||||||
ADMINID = client.application.owner.id
|
ADMINID = client.application.owner.id
|
||||||
|
support.set_client(client)
|
||||||
await tree.sync()
|
await tree.sync()
|
||||||
updateStatus()
|
updateStatus()
|
||||||
check_reminders.start()
|
check_reminders.start()
|
||||||
@ -538,3 +640,4 @@ async def on_ready():
|
|||||||
client.run(TOKEN)
|
client.run(TOKEN)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
279
support.py
Normal file
279
support.py
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
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 != "admin":
|
||||||
|
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</adduser:1204746777639653386> <user> - Add a user to the ticket\n</removeuser:1204747212878520402> <user> - Remove a user from the ticket\n</renameticket:1204758890332291123> <new_name> - Rename the ticket\n</closeticket:1204742678005424131> - 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
|
Loading…
Reference in New Issue
Block a user