Refactor random assignment and make it only assign staff with read access

This commit is contained in:
Toastie 2024-12-27 19:43:06 +13:00
parent 12337101b7
commit dac221246c
Signed by: toastie_t0ast
GPG key ID: 27F3B6855AFD40A4
3 changed files with 43 additions and 57 deletions

View file

@ -160,13 +160,13 @@ public class NewCommand
"!\nIs the channel limit reached in the server or ticket category?");
}
ulong staffID = 0;
DiscordMember assignedStaff = null;
if (Config.randomAssignment)
{
staffID = Database.GetRandomActiveStaff(0)?.userID ?? 0;
assignedStaff = await RandomAssignCommand.GetRandomVerifiedStaffMember(ticketChannel, userID, 0, null);
}
long id = Database.NewTicket(member.Id, staffID, ticketChannel.Id);
long id = Database.NewTicket(member.Id, assignedStaff?.Id ?? 0, ticketChannel.Id);
try
{
await ticketChannel.ModifyAsync(modifiedAttributes => modifiedAttributes.Name = "ticket-" + id.ToString("00000"));
@ -209,20 +209,19 @@ public class NewCommand
await Interviewer.StartInterview(ticketChannel);
}
if (staffID != 0)
if (assignedStaff != null)
{
await ticketChannel.SendMessageAsync(new DiscordEmbedBuilder
{
Color = DiscordColor.Green,
Description = "Ticket was randomly assigned to <@" + staffID + ">."
Description = "Ticket was randomly assigned to " + assignedStaff.Mention + "."
});
if (Config.assignmentNotifications)
{
try
{
DiscordMember staffMember = await category.Guild.GetMemberAsync(staffID);
await staffMember.SendMessageAsync(new DiscordEmbedBuilder
await assignedStaff.SendMessageAsync(new DiscordEmbedBuilder
{
Color = DiscordColor.Green,
Description = "You have been randomly assigned to a newly opened support ticket: " +

View file

@ -31,9 +31,14 @@ public class RandomAssignCommand
}
// Get a random staff member who is verified to have the correct role if applicable
DiscordMember staffMember = await GetRandomVerifiedStaffMember(command, role, ticket);
DiscordMember staffMember = await GetRandomVerifiedStaffMember(command.Channel, ticket.creatorID, ticket.assignedStaffID, role);
if (staffMember == null)
{
await command.RespondAsync(new DiscordEmbedBuilder
{
Color = DiscordColor.Red,
Description = "Error: Could not find an applicable staff member with access to this channel."
}, true);
return;
}
@ -66,7 +71,7 @@ public class RandomAssignCommand
Description = "You have been randomly assigned to a support ticket: " + command.Channel.Mention
});
}
catch (UnauthorizedException) { }
catch (UnauthorizedException) { /* ignore */ }
}
try
@ -89,62 +94,50 @@ public class RandomAssignCommand
}
}
private static async Task<DiscordMember> GetRandomVerifiedStaffMember(SlashCommandContext command, DiscordRole targetRole, Database.Ticket ticket)
internal static async Task<DiscordMember> GetRandomVerifiedStaffMember(DiscordChannel channel, ulong creatorID, ulong currentStaffID, DiscordRole targetRole)
{
if (targetRole != null) // A role was provided
List<Database.StaffMember> staffMembers;
ulong[] ignoredUserIDs = [creatorID, currentStaffID];
if (targetRole == null)
{
// No role was specified, any active staff will be picked
staffMembers = Database.GetActiveStaff(ignoredUserIDs);
}
else
{
// Check if role rassign should override staff's active status
List<Database.StaffMember> staffMembers = Config.randomAssignRoleOverride
? Database.GetAllStaff(ticket.assignedStaffID, ticket.creatorID)
: Database.GetActiveStaff(ticket.assignedStaffID, ticket.creatorID);
staffMembers = Config.randomAssignRoleOverride
? Database.GetAllStaff(ignoredUserIDs)
: Database.GetActiveStaff(ignoredUserIDs);
}
// Randomize the list before checking for roles in order to reduce number of API calls
staffMembers.Shuffle();
// Randomize the list before checking for roles in order to reduce number of API calls
staffMembers.Shuffle();
// Get the first staff member that has the role
foreach (Database.StaffMember sm in staffMembers)
// Get the first staff member that has the role
foreach (Database.StaffMember staffMember in staffMembers)
{
try
{
try
DiscordMember verifiedMember = await channel.Guild.GetMemberAsync(staffMember.userID);
// If a role is set filter to only members with that role
if (targetRole == null || verifiedMember.Roles.Any(role => role.Id == targetRole.Id))
{
DiscordMember verifiedMember = await command.Guild.GetMemberAsync(sm.userID);
if (verifiedMember?.Roles?.Any(role => role.Id == targetRole.Id) ?? false)
// Only assign staff members with access to this channel
if (verifiedMember.PermissionsIn(channel).HasFlag(DiscordPermissions.AccessChannels))
{
return verifiedMember;
}
}
catch (Exception e)
{
command.Client.Logger.Log(LogLevel.Information, e, "Error occured trying to find a staff member in the rassign command.");
}
}
catch (Exception e)
{
Logger.Error("Error occured trying to find a staff member for random assignment. User ID: " + staffMember.userID, e);
}
}
else // No role was specified, any active staff will be picked
{
Database.StaffMember staffEntry = Database.GetRandomActiveStaff(ticket.assignedStaffID, ticket.creatorID);
if (staffEntry == null)
{
await command.RespondAsync(new DiscordEmbedBuilder
{
Color = DiscordColor.Red,
Description = "Error: There are no other staff members to choose from."
}, true);
return null;
}
// Get the staff member from discord
try
{
return await command.Guild.GetMemberAsync(staffEntry.userID);
}
catch (NotFoundException) { }
}
// Send a more generic error if we get to this point and still haven't found the staff member
await command.RespondAsync(new DiscordEmbedBuilder
{
Color = DiscordColor.Red,
Description = "Error: Could not find an applicable staff member."
}, true);
return null;
}
}

View file

@ -466,12 +466,6 @@ public static class Database
}
}
public static StaffMember GetRandomActiveStaff(params ulong[] ignoredUserIDs)
{
List<StaffMember> staffMembers = GetActiveStaff(ignoredUserIDs);
return staffMembers.Any() ? staffMembers[RandomNumberGenerator.GetInt32(staffMembers.Count)] : null;
}
public static List<StaffMember> GetActiveStaff(params ulong[] ignoredUserIDs)
{
using MySqlConnection c = GetConnection();