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