updated some stuff
This commit is contained in:
parent
94324f4d4a
commit
ad0916477b
5 changed files with 1052 additions and 1049 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -362,5 +362,8 @@ MigrationBackup/
|
||||||
# Fody - auto-generated XML schema
|
# Fody - auto-generated XML schema
|
||||||
FodyWeavers.xsd
|
FodyWeavers.xsd
|
||||||
|
|
||||||
|
# Manually added folders
|
||||||
Windows-x64/
|
Windows-x64/
|
||||||
Linux-x64/
|
Linux-x64/
|
||||||
|
.idea
|
||||||
|
.vs
|
||||||
|
|
|
@ -8,100 +8,100 @@ using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace SupportChild.Commands
|
namespace SupportChild.Commands
|
||||||
{
|
{
|
||||||
public class AddCommand : BaseCommandModule
|
public class AddCommand : BaseCommandModule
|
||||||
{
|
{
|
||||||
[Command("add")]
|
[Command("add")]
|
||||||
[Description("Adds a user to a ticket.")]
|
[Description("Adds a user to a ticket.")]
|
||||||
public async Task OnExecute(CommandContext command, [RemainingText] string commandArgs)
|
public async Task OnExecute(CommandContext command, [RemainingText] string commandArgs)
|
||||||
{
|
{
|
||||||
// Check if the user has permission to use this command.
|
// Check if the user has permission to use this command.
|
||||||
if (!Config.HasPermission(command.Member, "add"))
|
if (!Config.HasPermission(command.Member, "add"))
|
||||||
{
|
{
|
||||||
DiscordEmbed error = new DiscordEmbedBuilder
|
DiscordEmbed error = new DiscordEmbedBuilder
|
||||||
{
|
{
|
||||||
Color = DiscordColor.Red,
|
Color = DiscordColor.Red,
|
||||||
Description = "You do not have permission to use this command."
|
Description = "You do not have permission to use this command."
|
||||||
};
|
};
|
||||||
await command.RespondAsync(error);
|
await command.RespondAsync(error);
|
||||||
command.Client.Logger.Log(LogLevel.Information, "User tried to use the add command but did not have permission.");
|
command.Client.Logger.Log(LogLevel.Information, "User tried to use the add command but did not have permission.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if ticket exists in the database
|
// Check if ticket exists in the database
|
||||||
if (!Database.IsOpenTicket(command.Channel.Id))
|
if (!Database.IsOpenTicket(command.Channel.Id))
|
||||||
{
|
{
|
||||||
DiscordEmbed error = new DiscordEmbedBuilder
|
DiscordEmbed error = new DiscordEmbedBuilder
|
||||||
{
|
{
|
||||||
Color = DiscordColor.Red,
|
Color = DiscordColor.Red,
|
||||||
Description = "This channel is not a ticket."
|
Description = "This channel is not a ticket."
|
||||||
};
|
};
|
||||||
await command.RespondAsync(error);
|
await command.RespondAsync(error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string[] parsedArgs = Utilities.ParseIDs(command.RawArgumentString);
|
string[] parsedArgs = Utilities.ParseIDs(command.RawArgumentString);
|
||||||
foreach (string parsedArg in parsedArgs)
|
foreach (string parsedArg in parsedArgs)
|
||||||
{
|
{
|
||||||
if (!ulong.TryParse(parsedArg, out ulong userID))
|
if (!ulong.TryParse(parsedArg, out ulong userID))
|
||||||
{
|
{
|
||||||
DiscordEmbed error = new DiscordEmbedBuilder
|
DiscordEmbed error = new DiscordEmbedBuilder
|
||||||
{
|
{
|
||||||
Color = DiscordColor.Red,
|
Color = DiscordColor.Red,
|
||||||
Description = "Invalid ID/Mention. (Could not convert to numerical)"
|
Description = "Invalid ID/Mention. (Could not convert to numerical)"
|
||||||
};
|
};
|
||||||
await command.RespondAsync(error);
|
await command.RespondAsync(error);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
DiscordMember mentionedMember;
|
DiscordMember mentionedMember;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
mentionedMember = await command.Guild.GetMemberAsync(userID);
|
mentionedMember = await command.Guild.GetMemberAsync(userID);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
DiscordEmbed error = new DiscordEmbedBuilder
|
DiscordEmbed error = new DiscordEmbedBuilder
|
||||||
{
|
{
|
||||||
Color = DiscordColor.Red,
|
Color = DiscordColor.Red,
|
||||||
Description = "Invalid ID/Mention. (Could not find user on this server)"
|
Description = "Invalid ID/Mention. (Could not find user on this server)"
|
||||||
};
|
};
|
||||||
await command.RespondAsync(error);
|
await command.RespondAsync(error);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await command.Channel.AddOverwriteAsync(mentionedMember, Permissions.AccessChannels, Permissions.None);
|
await command.Channel.AddOverwriteAsync(mentionedMember, Permissions.AccessChannels, Permissions.None);
|
||||||
DiscordEmbed message = new DiscordEmbedBuilder
|
DiscordEmbed message = new DiscordEmbedBuilder
|
||||||
{
|
{
|
||||||
Color = DiscordColor.Green,
|
Color = DiscordColor.Green,
|
||||||
Description = "Added " + mentionedMember.Mention + " to ticket."
|
Description = "Added " + mentionedMember.Mention + " to ticket."
|
||||||
};
|
};
|
||||||
await command.RespondAsync(message);
|
await command.RespondAsync(message);
|
||||||
|
|
||||||
// Log it if the log channel exists
|
// Log it if the log channel exists
|
||||||
DiscordChannel logChannel = command.Guild.GetChannel(Config.logChannel);
|
DiscordChannel logChannel = command.Guild.GetChannel(Config.logChannel);
|
||||||
if (logChannel != null)
|
if (logChannel != null)
|
||||||
{
|
{
|
||||||
DiscordEmbed logMessage = new DiscordEmbedBuilder
|
DiscordEmbed logMessage = new DiscordEmbedBuilder
|
||||||
{
|
{
|
||||||
Color = DiscordColor.Green,
|
Color = DiscordColor.Green,
|
||||||
Description = mentionedMember.Mention + " was added to " + command.Channel.Mention +
|
Description = mentionedMember.Mention + " was added to " + command.Channel.Mention +
|
||||||
" by " + command.Member.Mention + "."
|
" by " + command.Member.Mention + "."
|
||||||
};
|
};
|
||||||
await logChannel.SendMessageAsync(logMessage);
|
await logChannel.SendMessageAsync(logMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
DiscordEmbed message = new DiscordEmbedBuilder
|
DiscordEmbed message = new DiscordEmbedBuilder
|
||||||
{
|
{
|
||||||
Color = DiscordColor.Red,
|
Color = DiscordColor.Red,
|
||||||
Description = "Could not add <@" + parsedArg + "> to ticket, unknown error occured."
|
Description = "Could not add <@" + parsedArg + "> to ticket, unknown error occured."
|
||||||
};
|
};
|
||||||
await command.RespondAsync(message);
|
await command.RespondAsync(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
File diff suppressed because it is too large
Load diff
|
@ -12,296 +12,296 @@ using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace SupportChild
|
namespace SupportChild
|
||||||
{
|
{
|
||||||
internal class EventHandler
|
internal class EventHandler
|
||||||
{
|
{
|
||||||
private DiscordClient discordClient;
|
private DiscordClient discordClient;
|
||||||
|
|
||||||
//DateTime for the end of the cooldown
|
//DateTime for the end of the cooldown
|
||||||
private static Dictionary<ulong, DateTime> reactionTicketCooldowns = new Dictionary<ulong, DateTime>();
|
private static Dictionary<ulong, DateTime> reactionTicketCooldowns = new Dictionary<ulong, DateTime>();
|
||||||
|
|
||||||
public EventHandler(DiscordClient client)
|
public EventHandler(DiscordClient client)
|
||||||
{
|
{
|
||||||
discordClient = client;
|
this.discordClient = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Task OnReady(DiscordClient client, ReadyEventArgs e)
|
internal Task OnReady(DiscordClient client, ReadyEventArgs e)
|
||||||
{
|
{
|
||||||
discordClient.Logger.Log(LogLevel.Information, "Client is ready to process events.");
|
discordClient.Logger.Log(LogLevel.Information, "Client is ready to process events.");
|
||||||
|
|
||||||
// Checking activity type
|
// Checking activity type
|
||||||
if (!Enum.TryParse(Config.presenceType, true, out ActivityType activityType))
|
if (!Enum.TryParse(Config.presenceType, true, out ActivityType activityType))
|
||||||
{
|
{
|
||||||
Console.WriteLine("Presence type '" + Config.presenceType + "' invalid, using 'Playing' instead.");
|
Console.WriteLine("Presence type '" + Config.presenceType + "' invalid, using 'Playing' instead.");
|
||||||
activityType = ActivityType.Playing;
|
activityType = ActivityType.Playing;
|
||||||
}
|
}
|
||||||
|
|
||||||
discordClient.UpdateStatusAsync(new DiscordActivity(Config.presenceText, activityType), UserStatus.Online);
|
this.discordClient.UpdateStatusAsync(new DiscordActivity(Config.presenceText, activityType), UserStatus.Online);
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Task OnGuildAvailable(DiscordClient client, GuildCreateEventArgs e)
|
internal Task OnGuildAvailable(DiscordClient client, GuildCreateEventArgs e)
|
||||||
{
|
{
|
||||||
discordClient.Logger.Log(LogLevel.Information, $"Guild available: {e.Guild.Name}");
|
discordClient.Logger.Log(LogLevel.Information, $"Guild available: {e.Guild.Name}");
|
||||||
|
|
||||||
IReadOnlyDictionary<ulong, DiscordRole> roles = e.Guild.Roles;
|
IReadOnlyDictionary<ulong, DiscordRole> roles = e.Guild.Roles;
|
||||||
|
|
||||||
foreach ((ulong roleID, DiscordRole role) in roles)
|
foreach ((ulong roleID, DiscordRole role) in roles)
|
||||||
{
|
{
|
||||||
discordClient.Logger.Log(LogLevel.Information, role.Name.PadRight(40, '.') + roleID);
|
discordClient.Logger.Log(LogLevel.Information, role.Name.PadRight(40, '.') + roleID);
|
||||||
}
|
}
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Task OnClientError(DiscordClient client, ClientErrorEventArgs e)
|
internal Task OnClientError(DiscordClient client, ClientErrorEventArgs e)
|
||||||
{
|
{
|
||||||
discordClient.Logger.Log(LogLevel.Error, $"Exception occured: {e.Exception.GetType()}: {e.Exception}");
|
discordClient.Logger.Log(LogLevel.Error, $"Exception occured: {e.Exception.GetType()}: {e.Exception}");
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task OnMessageCreated(DiscordClient client, MessageCreateEventArgs e)
|
internal async Task OnMessageCreated(DiscordClient client, MessageCreateEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.Author.IsBot)
|
if (e.Author.IsBot)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if ticket exists in the database and ticket notifications are enabled
|
// Check if ticket exists in the database and ticket notifications are enabled
|
||||||
if (!Database.TryGetOpenTicket(e.Channel.Id, out Database.Ticket ticket) || !Config.ticketUpdatedNotifications)
|
if (!Database.TryGetOpenTicket(e.Channel.Id, out Database.Ticket ticket) || !Config.ticketUpdatedNotifications)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sends a DM to the assigned staff member if at least a day has gone by since the last message and the user sending the message isn't staff
|
// Sends a DM to the assigned staff member if at least a day has gone by since the last message and the user sending the message isn't staff
|
||||||
IReadOnlyList<DiscordMessage> messages = await e.Channel.GetMessagesAsync(2);
|
IReadOnlyList<DiscordMessage> messages = await e.Channel.GetMessagesAsync(2);
|
||||||
if (messages.Count > 1 && messages[1].Timestamp < DateTimeOffset.UtcNow.AddDays(Config.ticketUpdatedNotificationDelay * -1) && !Database.IsStaff(e.Author.Id))
|
if (messages.Count > 1 && messages[1].Timestamp < DateTimeOffset.UtcNow.AddDays(Config.ticketUpdatedNotificationDelay * -1) && !Database.IsStaff(e.Author.Id))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
DiscordEmbed message = new DiscordEmbedBuilder
|
DiscordEmbed message = new DiscordEmbedBuilder
|
||||||
{
|
{
|
||||||
Color = DiscordColor.Green,
|
Color = DiscordColor.Green,
|
||||||
Description = "A ticket you are assigned to has been updated: " + e.Channel.Mention
|
Description = "A ticket you are assigned to has been updated: " + e.Channel.Mention
|
||||||
};
|
};
|
||||||
|
|
||||||
DiscordMember staffMember = await e.Guild.GetMemberAsync(ticket.assignedStaffID);
|
DiscordMember staffMember = await e.Guild.GetMemberAsync(ticket.assignedStaffID);
|
||||||
await staffMember.SendMessageAsync(message);
|
await staffMember.SendMessageAsync(message);
|
||||||
}
|
}
|
||||||
catch (NotFoundException) { }
|
catch (NotFoundException) { }
|
||||||
catch (UnauthorizedException) { }
|
catch (UnauthorizedException) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Task OnCommandError(CommandsNextExtension commandSystem, CommandErrorEventArgs e)
|
internal Task OnCommandError(CommandsNextExtension commandSystem, CommandErrorEventArgs e)
|
||||||
{
|
{
|
||||||
switch (e.Exception)
|
switch (e.Exception)
|
||||||
{
|
{
|
||||||
case CommandNotFoundException _:
|
case CommandNotFoundException _:
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
case ChecksFailedException _:
|
case ChecksFailedException _:
|
||||||
{
|
{
|
||||||
foreach (CheckBaseAttribute attr in ((ChecksFailedException)e.Exception).FailedChecks)
|
foreach (CheckBaseAttribute attr in ((ChecksFailedException)e.Exception).FailedChecks)
|
||||||
{
|
{
|
||||||
DiscordEmbed error = new DiscordEmbedBuilder
|
DiscordEmbed error = new DiscordEmbedBuilder
|
||||||
{
|
{
|
||||||
Color = DiscordColor.Red,
|
Color = DiscordColor.Red,
|
||||||
Description = ParseFailedCheck(attr)
|
Description = this.ParseFailedCheck(attr)
|
||||||
};
|
};
|
||||||
e.Context?.Channel?.SendMessageAsync(error);
|
e.Context?.Channel?.SendMessageAsync(error);
|
||||||
}
|
}
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
discordClient.Logger.Log(LogLevel.Error, $"Exception occured: {e.Exception.GetType()}: {e.Exception}");
|
discordClient.Logger.Log(LogLevel.Error, $"Exception occured: {e.Exception.GetType()}: {e.Exception}");
|
||||||
DiscordEmbed error = new DiscordEmbedBuilder
|
DiscordEmbed error = new DiscordEmbedBuilder
|
||||||
{
|
{
|
||||||
Color = DiscordColor.Red,
|
Color = DiscordColor.Red,
|
||||||
Description = "Internal error occured, please report this to the developer."
|
Description = "Internal error occured, please report this to the developer."
|
||||||
};
|
};
|
||||||
e.Context?.Channel?.SendMessageAsync(error);
|
e.Context?.Channel?.SendMessageAsync(error);
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task OnReactionAdded(DiscordClient client, MessageReactionAddEventArgs e)
|
internal async Task OnReactionAdded(DiscordClient client, MessageReactionAddEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.Message.Id != Config.reactionMessage) return;
|
if (e.Message.Id != Config.reactionMessage) return;
|
||||||
|
|
||||||
DiscordGuild guild = e.Message.Channel.Guild;
|
DiscordGuild guild = e.Message.Channel.Guild;
|
||||||
DiscordMember member = await guild.GetMemberAsync(e.User.Id);
|
DiscordMember member = await guild.GetMemberAsync(e.User.Id);
|
||||||
|
|
||||||
if (!Config.HasPermission(member, "new") || Database.IsBlacklisted(member.Id)) return;
|
if (!Config.HasPermission(member, "new") || Database.IsBlacklisted(member.Id)) return;
|
||||||
if (reactionTicketCooldowns.ContainsKey(member.Id))
|
if (reactionTicketCooldowns.ContainsKey(member.Id))
|
||||||
{
|
{
|
||||||
if (reactionTicketCooldowns[member.Id] > DateTime.Now) return; // cooldown has not expired
|
if (reactionTicketCooldowns[member.Id] > DateTime.Now) return; // cooldown has not expired
|
||||||
else reactionTicketCooldowns.Remove(member.Id); // cooldown exists but has expired, delete it
|
else reactionTicketCooldowns.Remove(member.Id); // cooldown exists but has expired, delete it
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DiscordChannel category = guild.GetChannel(Config.ticketCategory);
|
DiscordChannel category = guild.GetChannel(Config.ticketCategory);
|
||||||
DiscordChannel ticketChannel = await guild.CreateChannelAsync("ticket", ChannelType.Text, category);
|
DiscordChannel ticketChannel = await guild.CreateChannelAsync("ticket", ChannelType.Text, category);
|
||||||
|
|
||||||
if (ticketChannel == null) return;
|
if (ticketChannel == null) return;
|
||||||
|
|
||||||
ulong staffID = 0;
|
ulong staffID = 0;
|
||||||
if (Config.randomAssignment)
|
if (Config.randomAssignment)
|
||||||
{
|
{
|
||||||
staffID = Database.GetRandomActiveStaff(0)?.userID ?? 0;
|
staffID = Database.GetRandomActiveStaff(0)?.userID ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
long id = Database.NewTicket(member.Id, staffID, ticketChannel.Id);
|
long id = Database.NewTicket(member.Id, staffID, ticketChannel.Id);
|
||||||
reactionTicketCooldowns.Add(member.Id, DateTime.Now.AddSeconds(10)); // add a cooldown which expires in 10 seconds
|
reactionTicketCooldowns.Add(member.Id, DateTime.Now.AddSeconds(10)); // add a cooldown which expires in 10 seconds
|
||||||
string ticketID = id.ToString("00000");
|
string ticketID = id.ToString("00000");
|
||||||
|
|
||||||
await ticketChannel.ModifyAsync(model => model.Name = "ticket-" + ticketID);
|
await ticketChannel.ModifyAsync(model => model.Name = "ticket-" + ticketID);
|
||||||
await ticketChannel.AddOverwriteAsync(member, Permissions.AccessChannels, Permissions.None);
|
await ticketChannel.AddOverwriteAsync(member, Permissions.AccessChannels, Permissions.None);
|
||||||
await ticketChannel.SendMessageAsync("Hello, " + member.Mention + "!\n" + Config.welcomeMessage);
|
await ticketChannel.SendMessageAsync("Hello, " + member.Mention + "!\n" + Config.welcomeMessage);
|
||||||
|
|
||||||
// Remove user's reaction
|
// Remove user's reaction
|
||||||
await e.Message.DeleteReactionAsync(e.Emoji, e.User);
|
await e.Message.DeleteReactionAsync(e.Emoji, e.User);
|
||||||
|
|
||||||
// Refreshes the channel as changes were made to it above
|
// Refreshes the channel as changes were made to it above
|
||||||
ticketChannel = await SupportChild.GetClient().GetChannelAsync(ticketChannel.Id);
|
ticketChannel = await SupportChild.GetClient().GetChannelAsync(ticketChannel.Id);
|
||||||
|
|
||||||
if (staffID != 0)
|
if (staffID != 0)
|
||||||
{
|
{
|
||||||
DiscordEmbed assignmentMessage = new DiscordEmbedBuilder
|
DiscordEmbed assignmentMessage = new DiscordEmbedBuilder
|
||||||
{
|
{
|
||||||
Color = DiscordColor.Green,
|
Color = DiscordColor.Green,
|
||||||
Description = "Ticket was randomly assigned to <@" + staffID + ">."
|
Description = "Ticket was randomly assigned to <@" + staffID + ">."
|
||||||
};
|
};
|
||||||
await ticketChannel.SendMessageAsync(assignmentMessage);
|
await ticketChannel.SendMessageAsync(assignmentMessage);
|
||||||
|
|
||||||
if (Config.assignmentNotifications)
|
if (Config.assignmentNotifications)
|
||||||
{
|
{
|
||||||
DiscordEmbed message = new DiscordEmbedBuilder
|
DiscordEmbed message = new DiscordEmbedBuilder
|
||||||
{
|
{
|
||||||
Color = DiscordColor.Green,
|
Color = DiscordColor.Green,
|
||||||
Description = "You have been randomly assigned to a newly opened support ticket: " +
|
Description = "You have been randomly assigned to a newly opened support ticket: " +
|
||||||
ticketChannel.Mention
|
ticketChannel.Mention
|
||||||
};
|
};
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
DiscordMember staffMember = await guild.GetMemberAsync(staffID);
|
DiscordMember staffMember = await guild.GetMemberAsync(staffID);
|
||||||
await staffMember.SendMessageAsync(message);
|
await staffMember.SendMessageAsync(message);
|
||||||
}
|
}
|
||||||
catch (NotFoundException)
|
catch (NotFoundException)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
catch (UnauthorizedException)
|
catch (UnauthorizedException)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log it if the log channel exists
|
// Log it if the log channel exists
|
||||||
DiscordChannel logChannel = guild.GetChannel(Config.logChannel);
|
DiscordChannel logChannel = guild.GetChannel(Config.logChannel);
|
||||||
if (logChannel != null)
|
if (logChannel != null)
|
||||||
{
|
{
|
||||||
DiscordEmbed logMessage = new DiscordEmbedBuilder
|
DiscordEmbed logMessage = new DiscordEmbedBuilder
|
||||||
{
|
{
|
||||||
Color = DiscordColor.Green,
|
Color = DiscordColor.Green,
|
||||||
Description = "Ticket " + ticketChannel.Mention + " opened by " + member.Mention + ".\n",
|
Description = "Ticket " + ticketChannel.Mention + " opened by " + member.Mention + ".\n",
|
||||||
Footer = new DiscordEmbedBuilder.EmbedFooter { Text = "Ticket " + ticketID }
|
Footer = new DiscordEmbedBuilder.EmbedFooter {Text = "Ticket " + ticketID}
|
||||||
};
|
};
|
||||||
await logChannel.SendMessageAsync(logMessage);
|
await logChannel.SendMessageAsync(logMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task OnMemberAdded(DiscordClient client, GuildMemberAddEventArgs e)
|
internal async Task OnMemberAdded(DiscordClient client, GuildMemberAddEventArgs e)
|
||||||
{
|
{
|
||||||
if (!Database.TryGetOpenTickets(e.Member.Id, out List<Database.Ticket> ownTickets))
|
if (!Database.TryGetOpenTickets(e.Member.Id, out List<Database.Ticket> ownTickets))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Database.Ticket ticket in ownTickets)
|
foreach (Database.Ticket ticket in ownTickets)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
DiscordChannel channel = await client.GetChannelAsync(ticket.channelID);
|
DiscordChannel channel = await client.GetChannelAsync(ticket.channelID);
|
||||||
if (channel?.GuildId == e.Guild.Id)
|
if (channel?.GuildId == e.Guild.Id)
|
||||||
{
|
{
|
||||||
await channel.AddOverwriteAsync(e.Member, Permissions.AccessChannels, Permissions.None);
|
await channel.AddOverwriteAsync(e.Member, Permissions.AccessChannels, Permissions.None);
|
||||||
DiscordEmbed message = new DiscordEmbedBuilder()
|
DiscordEmbed message = new DiscordEmbedBuilder()
|
||||||
.WithColor(DiscordColor.Green)
|
.WithColor(DiscordColor.Green)
|
||||||
.WithDescription("User '" + e.Member.Username + "#" + e.Member.Discriminator + "' has rejoined the server, and has been re-added to the ticket.");
|
.WithDescription("User '" + e.Member.Username + "#" + e.Member.Discriminator + "' has rejoined the server, and has been re-added to the ticket.");
|
||||||
await channel.SendMessageAsync(message);
|
await channel.SendMessageAsync(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception) { }
|
catch (Exception) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task OnMemberRemoved(DiscordClient client, GuildMemberRemoveEventArgs e)
|
internal async Task OnMemberRemoved(DiscordClient client, GuildMemberRemoveEventArgs e)
|
||||||
{
|
{
|
||||||
if (Database.TryGetOpenTickets(e.Member.Id, out List<Database.Ticket> ownTickets))
|
if (Database.TryGetOpenTickets(e.Member.Id, out List<Database.Ticket> ownTickets))
|
||||||
{
|
{
|
||||||
foreach (Database.Ticket ticket in ownTickets)
|
foreach(Database.Ticket ticket in ownTickets)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
DiscordChannel channel = await client.GetChannelAsync(ticket.channelID);
|
DiscordChannel channel = await client.GetChannelAsync(ticket.channelID);
|
||||||
if (channel?.GuildId == e.Guild.Id)
|
if (channel?.GuildId == e.Guild.Id)
|
||||||
{
|
{
|
||||||
DiscordEmbed message = new DiscordEmbedBuilder()
|
DiscordEmbed message = new DiscordEmbedBuilder()
|
||||||
.WithColor(DiscordColor.Red)
|
.WithColor(DiscordColor.Red)
|
||||||
.WithDescription("User '" + e.Member.Username + "#" + e.Member.Discriminator + "' has left the server.");
|
.WithDescription("User '" + e.Member.Username + "#" + e.Member.Discriminator + "' has left the server.");
|
||||||
await channel.SendMessageAsync(message);
|
await channel.SendMessageAsync(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception) { }
|
catch (Exception) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Database.TryGetAssignedTickets(e.Member.Id, out List<Database.Ticket> assignedTickets) && Config.logChannel != 0)
|
if (Database.TryGetAssignedTickets(e.Member.Id, out List<Database.Ticket> assignedTickets) && Config.logChannel != 0)
|
||||||
{
|
{
|
||||||
DiscordChannel logChannel = await client.GetChannelAsync(Config.logChannel);
|
DiscordChannel logChannel = await client.GetChannelAsync(Config.logChannel);
|
||||||
if (logChannel != null)
|
if (logChannel != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
foreach (Database.Ticket ticket in assignedTickets)
|
foreach (Database.Ticket ticket in assignedTickets)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
DiscordChannel channel = await client.GetChannelAsync(ticket.channelID);
|
DiscordChannel channel = await client.GetChannelAsync(ticket.channelID);
|
||||||
if (channel?.GuildId == e.Guild.Id)
|
if (channel?.GuildId == e.Guild.Id)
|
||||||
{
|
{
|
||||||
DiscordEmbed message = new DiscordEmbedBuilder()
|
DiscordEmbed message = new DiscordEmbedBuilder()
|
||||||
.WithColor(DiscordColor.Red)
|
.WithColor(DiscordColor.Red)
|
||||||
.WithDescription("Assigned staff member '" + e.Member.Username + "#" + e.Member.Discriminator + "' has left the server: <#" + channel.Id + ">");
|
.WithDescription("Assigned staff member '" + e.Member.Username + "#" + e.Member.Discriminator + "' has left the server: <#" + channel.Id + ">");
|
||||||
await logChannel.SendMessageAsync(message);
|
await logChannel.SendMessageAsync(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception) { }
|
catch (Exception) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string ParseFailedCheck(CheckBaseAttribute attr)
|
private string ParseFailedCheck(CheckBaseAttribute attr)
|
||||||
{
|
{
|
||||||
switch (attr)
|
switch (attr)
|
||||||
{
|
{
|
||||||
case CooldownAttribute _:
|
case CooldownAttribute _:
|
||||||
return "You cannot use do that so often!";
|
return "You cannot use do that so often!";
|
||||||
case RequireOwnerAttribute _:
|
case RequireOwnerAttribute _:
|
||||||
return "Only the server owner can use that command!";
|
return "Only the server owner can use that command!";
|
||||||
case RequirePermissionsAttribute _:
|
case RequirePermissionsAttribute _:
|
||||||
return "You don't have permission to do that!";
|
return "You don't have permission to do that!";
|
||||||
case RequireRolesAttribute _:
|
case RequireRolesAttribute _:
|
||||||
return "You do not have a required role!";
|
return "You do not have a required role!";
|
||||||
case RequireUserPermissionsAttribute _:
|
case RequireUserPermissionsAttribute _:
|
||||||
return "You don't have permission to do that!";
|
return "You don't have permission to do that!";
|
||||||
case RequireNsfwAttribute _:
|
case RequireNsfwAttribute _:
|
||||||
return "This command can only be used in an NSFW channel!";
|
return "This command can only be used in an NSFW channel!";
|
||||||
default:
|
default:
|
||||||
return "Unknown Discord API error occured, please try again later.";
|
return "Unknown Discord API error occured, please try again later.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,84 +1,84 @@
|
||||||
bot:
|
bot:
|
||||||
# Bot token.
|
# Bot token.
|
||||||
token: "<add-token-here>"
|
token: "<add-token-here>"
|
||||||
# Command prefix.
|
# Command prefix.
|
||||||
prefix: "-"
|
prefix: "-"
|
||||||
# Channel where ticket logs are posted (recommended)
|
# Channel where ticket logs are posted (recommended)
|
||||||
log-channel: 000000000000000000
|
log-channel: 000000000000000000
|
||||||
# Category where the ticket will be created, it will have the same permissions of that ticket plus read permissions for the user opening the ticket (recommended)
|
# Category where the ticket will be created, it will have the same permissions of that ticket plus read permissions for the user opening the ticket (recommended)
|
||||||
ticket-category: 000000000000000000
|
ticket-category: 000000000000000000
|
||||||
# A message which will open new tickets when users react to it (optional)
|
# A message which will open new tickets when users react to it (optional)
|
||||||
reaction-message: 000000000000000000
|
reaction-message: 000000000000000000
|
||||||
# Message posted when a ticket is opened.
|
# Message posted when a ticket is opened.
|
||||||
welcome-message: "Please describe your issue below, and include all information needed for us to help you."
|
welcome-message: "Please describe your issue below, and include all information needed for us to help you."
|
||||||
# Decides what messages are shown in console
|
# Decides what messages are shown in console
|
||||||
# Possible values are: Critical, Error, Warning, Information, Debug.
|
# Possible values are: Critical, Error, Warning, Information, Debug.
|
||||||
console-log-level: "Information"
|
console-log-level: "Information"
|
||||||
# Format for timestamps in transcripts and google sheets if used
|
# Format for timestamps in transcripts and google sheets if used
|
||||||
timestamp-format: "yyyy-MM-dd HH:mm"
|
timestamp-format: "yyyy-MM-dd HH:mm"
|
||||||
# Whether or not staff members should be randomly assigned tickets when they are made. Individual staff members can opt out using the toggleactive command.
|
# Whether or not staff members should be randomly assigned tickets when they are made. Individual staff members can opt out using the toggleactive command.
|
||||||
random-assignment: true
|
random-assignment: true
|
||||||
# If set to true the rasssign command will include staff members set as inactive if a specific role is specified in the command.
|
# If set to true the rasssign command will include staff members set as inactive if a specific role is specified in the command.
|
||||||
# This can be useful if you have admins set as inactive to not automatically recieve tickets and then have moderators elevate tickets when needed.
|
# This can be useful if you have admins set as inactive to not automatically recieve tickets and then have moderators elevate tickets when needed.
|
||||||
random-assign-role-override: true
|
random-assign-role-override: true
|
||||||
# Sets the type of activity for the bot to display in its presence status
|
# Sets the type of activity for the bot to display in its presence status
|
||||||
# Possible values are: Playing, Streaming, ListeningTo, Watching, Competing
|
# Possible values are: Playing, Streaming, ListeningTo, Watching, Competing
|
||||||
presence-type: "ListeningTo"
|
presence-type: "ListeningTo"
|
||||||
# Sets the activity text shown in the bot's status
|
# Sets the activity text shown in the bot's status
|
||||||
presence-text: "-new"
|
presence-text: "-new"
|
||||||
|
|
||||||
notifications:
|
notifications:
|
||||||
# Notifies the assigned staff member when a new message is posted in a ticket if the ticket has been silent for a configurable amount of time
|
# Notifies the assigned staff member when a new message is posted in a ticket if the ticket has been silent for a configurable amount of time
|
||||||
# Other staff members and bots do not trigger this.
|
# Other staff members and bots do not trigger this.
|
||||||
ticket-updated: true
|
ticket-updated: true
|
||||||
# The above notification will only be sent if the ticket has been silent for more than this amount of days. Default is 0.5 days.
|
# The above notification will only be sent if the ticket has been silent for more than this amount of days. Default is 0.5 days.
|
||||||
ticket-updated-delay: 0.5
|
ticket-updated-delay: 0.5
|
||||||
# Notifies staff when they are assigned to tickets
|
# Notifies staff when they are assigned to tickets
|
||||||
assignment: true
|
assignment: true
|
||||||
# Notifies the user opening the ticket that their ticket was closed and includes the transcript
|
# Notifies the user opening the ticket that their ticket was closed and includes the transcript
|
||||||
closing: true
|
closing: true
|
||||||
|
|
||||||
database:
|
database:
|
||||||
# Address and port of the mysql server
|
# Address and port of the mysql server
|
||||||
address: "127.0.0.1"
|
address: "127.0.0.1"
|
||||||
port: 3306
|
port: 3306
|
||||||
# Name of the database to use
|
# Name of the database to use
|
||||||
name: "supportbot"
|
name: "supportchild"
|
||||||
# Username and password for authentication
|
# Username and password for authentication
|
||||||
user: ""
|
user: ""
|
||||||
password: ""
|
password: ""
|
||||||
|
|
||||||
# Set up which roles are allowed to use different commands.
|
# Set up which roles are allowed to use different commands.
|
||||||
# Example:
|
# Example:
|
||||||
# new: [ 000000000000000000, 111111111111111111 ]
|
# new: [ 000000000000000000, 111111111111111111 ]
|
||||||
# They are grouped into suggested command groups below for first time setup.
|
# They are grouped into suggested command groups below for first time setup.
|
||||||
permissions:
|
permissions:
|
||||||
# Public commands
|
# Public commands
|
||||||
close: []
|
close: []
|
||||||
list: []
|
list: []
|
||||||
new: []
|
new: []
|
||||||
say: []
|
say: []
|
||||||
status: []
|
status: []
|
||||||
summary: []
|
summary: []
|
||||||
transcript: []
|
transcript: []
|
||||||
# Moderator commands
|
# Moderator commands
|
||||||
add: []
|
add: []
|
||||||
addmessage: []
|
addmessage: []
|
||||||
assign: []
|
assign: []
|
||||||
blacklist: []
|
blacklist: []
|
||||||
listassigned: []
|
listassigned: []
|
||||||
listoldest: []
|
listoldest: []
|
||||||
listunassigned: []
|
listunassigned: []
|
||||||
move: []
|
move: []
|
||||||
rassign: []
|
rassign: []
|
||||||
removemessage: []
|
removemessage: []
|
||||||
setsummary: []
|
setsummary: []
|
||||||
toggleactive: []
|
toggleactive: []
|
||||||
unassign: []
|
unassign: []
|
||||||
unblacklist: []
|
unblacklist: []
|
||||||
# Admin commands
|
# Admin commands
|
||||||
addstaff: []
|
addstaff: []
|
||||||
reload: []
|
reload: []
|
||||||
removestaff: []
|
removestaff: []
|
||||||
setticket: []
|
setticket: []
|
||||||
unsetticket: []
|
unsetticket: []
|
Loading…
Reference in a new issue