Added command and functionality to stop interviews
This commit is contained in:
parent
47ff409902
commit
556f082aa2
7 changed files with 179 additions and 74 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using DSharpPlus.Commands;
|
using DSharpPlus.Commands;
|
||||||
|
@ -17,7 +18,7 @@ public class AdminCommands
|
||||||
[Command("setticket")]
|
[Command("setticket")]
|
||||||
[Description("Turns a channel into a ticket. WARNING: Anyone will be able to delete the channel using /close.")]
|
[Description("Turns a channel into a ticket. WARNING: Anyone will be able to delete the channel using /close.")]
|
||||||
public async Task SetTicket(SlashCommandContext command,
|
public async Task SetTicket(SlashCommandContext command,
|
||||||
[Parameter("user")][Description("(Optional) The owner of the ticket.")] DiscordUser user = null)
|
[Parameter("user")] [Description("(Optional) The owner of the ticket.")] DiscordUser user = null)
|
||||||
{
|
{
|
||||||
// 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))
|
||||||
|
@ -63,9 +64,12 @@ public class AdminCommands
|
||||||
[Command("unsetticket")]
|
[Command("unsetticket")]
|
||||||
[Description("Deletes a ticket from the ticket system without deleting the channel.")]
|
[Description("Deletes a ticket from the ticket system without deleting the channel.")]
|
||||||
public async Task UnsetTicket(SlashCommandContext command,
|
public async Task UnsetTicket(SlashCommandContext command,
|
||||||
[Parameter("ticket-id")][Description("(Optional) Ticket to unset. Uses the channel you are in by default. Use ticket ID, not channel ID!")] long ticketID = 0)
|
[Parameter("ticket-id")] [Description("(Optional) Ticket to unset. Uses the channel you are in by default. Use ticket ID, not channel ID!")] long ticketID = 0)
|
||||||
{
|
{
|
||||||
Database.Ticket ticket;
|
Database.Ticket ticket;
|
||||||
|
DiscordChannel channel = null;
|
||||||
|
|
||||||
|
await command.DeferResponseAsync(true);
|
||||||
|
|
||||||
if (ticketID == 0)
|
if (ticketID == 0)
|
||||||
{
|
{
|
||||||
|
@ -79,6 +83,7 @@ public class AdminCommands
|
||||||
}, true);
|
}, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
channel = command.Channel;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -92,10 +97,22 @@ public class AdminCommands
|
||||||
}, true);
|
}, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find the channel if it still exists
|
||||||
|
try
|
||||||
|
{
|
||||||
|
channel = await command.Guild.GetChannelAsync(ticket.channelID);
|
||||||
|
}
|
||||||
|
catch (Exception) { /*ignored*/ }
|
||||||
}
|
}
|
||||||
|
|
||||||
Database.TryDeleteInterview(ticket.channelID);
|
// If the channel exists, stop any ongoing interview
|
||||||
|
if (channel != null)
|
||||||
|
{
|
||||||
|
await Interviewer.StopInterview(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the ticket from the database and respond to command
|
||||||
if (Database.DeleteOpenTicket(ticket.id))
|
if (Database.DeleteOpenTicket(ticket.id))
|
||||||
{
|
{
|
||||||
await command.RespondAsync(new DiscordEmbedBuilder
|
await command.RespondAsync(new DiscordEmbedBuilder
|
||||||
|
|
128
Commands/InterviewCommands.cs
Normal file
128
Commands/InterviewCommands.cs
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using DSharpPlus.Commands;
|
||||||
|
using DSharpPlus.Commands.Processors.SlashCommands;
|
||||||
|
using DSharpPlus.Entities;
|
||||||
|
using DSharpPlus.Exceptions;
|
||||||
|
using SupportChild.Interviews;
|
||||||
|
|
||||||
|
namespace SupportChild.Commands;
|
||||||
|
|
||||||
|
[Command("interview")]
|
||||||
|
[Description("Interview management.")]
|
||||||
|
public class InterviewCommands
|
||||||
|
{
|
||||||
|
[Command("restart")]
|
||||||
|
[Description("Restarts the interview in this ticket, using an updated template if available.")]
|
||||||
|
public async Task Restart(SlashCommandContext command)
|
||||||
|
{
|
||||||
|
if (!Database.TryGetOpenTicket(command.Channel.Id, out Database.Ticket ticket))
|
||||||
|
{
|
||||||
|
await command.RespondAsync(new DiscordEmbedBuilder
|
||||||
|
{
|
||||||
|
Color = DiscordColor.Red,
|
||||||
|
Description = "This channel is not a ticket."
|
||||||
|
}, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await command.DeferResponseAsync(true);
|
||||||
|
|
||||||
|
if (await Interviewer.RestartInterview(command.Channel))
|
||||||
|
{
|
||||||
|
await command.RespondAsync(new DiscordEmbedBuilder
|
||||||
|
{
|
||||||
|
Color = DiscordColor.Green,
|
||||||
|
Description = "Interview restarted."
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await command.RespondAsync(new DiscordEmbedBuilder
|
||||||
|
{
|
||||||
|
Color = DiscordColor.Red,
|
||||||
|
Description = "An error occured when trying to restart the interview."
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DiscordChannel logChannel = await SupportChild.client.GetChannelAsync(Config.logChannel);
|
||||||
|
await logChannel.SendMessageAsync(new DiscordEmbedBuilder
|
||||||
|
{
|
||||||
|
Color = DiscordColor.Green,
|
||||||
|
Description = command.User.Mention + " restarted interview in " + command.Channel.Mention + ".",
|
||||||
|
Footer = new DiscordEmbedBuilder.EmbedFooter
|
||||||
|
{
|
||||||
|
Text = "Ticket: " + ticket.id.ToString("00000")
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (NotFoundException)
|
||||||
|
{
|
||||||
|
Logger.Error("Could not find the log channel.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command("stop")]
|
||||||
|
[Description("Stops the interview in this ticket.")]
|
||||||
|
public async Task Stop(SlashCommandContext command)
|
||||||
|
{
|
||||||
|
if (!Database.TryGetOpenTicket(command.Channel.Id, out Database.Ticket ticket))
|
||||||
|
{
|
||||||
|
await command.RespondAsync(new DiscordEmbedBuilder
|
||||||
|
{
|
||||||
|
Color = DiscordColor.Red,
|
||||||
|
Description = "This channel is not a ticket."
|
||||||
|
}, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Database.TryGetInterview(command.Channel.Id, out InterviewQuestion interviewRoot))
|
||||||
|
{
|
||||||
|
await command.RespondAsync(new DiscordEmbedBuilder
|
||||||
|
{
|
||||||
|
Color = DiscordColor.Red,
|
||||||
|
Description = "There is no interview open in this ticket.."
|
||||||
|
}, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await command.DeferResponseAsync(true);
|
||||||
|
|
||||||
|
if (await Interviewer.StopInterview(command.Channel))
|
||||||
|
{
|
||||||
|
await command.RespondAsync(new DiscordEmbedBuilder
|
||||||
|
{
|
||||||
|
Color = DiscordColor.Green,
|
||||||
|
Description = "Interview stopped."
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await command.RespondAsync(new DiscordEmbedBuilder
|
||||||
|
{
|
||||||
|
Color = DiscordColor.Red,
|
||||||
|
Description = "An error occured when trying to stop the interview."
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DiscordChannel logChannel = await SupportChild.client.GetChannelAsync(Config.logChannel);
|
||||||
|
await logChannel.SendMessageAsync(new DiscordEmbedBuilder
|
||||||
|
{
|
||||||
|
Color = DiscordColor.Green,
|
||||||
|
Description = command.User.Mention + " stopped the interview in " + command.Channel.Mention + ".",
|
||||||
|
Footer = new DiscordEmbedBuilder.EmbedFooter
|
||||||
|
{
|
||||||
|
Text = "Ticket: " + ticket.id.ToString("00000")
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (NotFoundException)
|
||||||
|
{
|
||||||
|
Logger.Error("Could not find the log channel.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,7 +17,7 @@ using SupportChild.Interviews;
|
||||||
namespace SupportChild.Commands;
|
namespace SupportChild.Commands;
|
||||||
|
|
||||||
[Command("interviewtemplate")]
|
[Command("interviewtemplate")]
|
||||||
[Description("Administrative commands.")]
|
[Description("Interview template management.")]
|
||||||
public class InterviewTemplateCommands
|
public class InterviewTemplateCommands
|
||||||
{
|
{
|
||||||
private static readonly string jsonSchema = Utilities.ReadManifestData("Interviews.interview_template.schema.json");
|
private static readonly string jsonSchema = Utilities.ReadManifestData("Interviews.interview_template.schema.json");
|
||||||
|
|
|
@ -206,7 +206,7 @@ public class NewCommand
|
||||||
|
|
||||||
if (Config.interviewsEnabled)
|
if (Config.interviewsEnabled)
|
||||||
{
|
{
|
||||||
Interviewer.StartInterview(ticketChannel);
|
await Interviewer.StartInterview(ticketChannel);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (staffID != 0)
|
if (staffID != 0)
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using DSharpPlus.Commands;
|
|
||||||
using DSharpPlus.Commands.Processors.SlashCommands;
|
|
||||||
using DSharpPlus.Entities;
|
|
||||||
using DSharpPlus.Exceptions;
|
|
||||||
using SupportChild.Interviews;
|
|
||||||
|
|
||||||
namespace SupportChild.Commands;
|
|
||||||
|
|
||||||
public class RestartInterviewCommand
|
|
||||||
{
|
|
||||||
[Command("restartinterview")]
|
|
||||||
[Description("Restarts the automated interview in this ticket, using an updated template if available.")]
|
|
||||||
public async Task OnExecute(SlashCommandContext command)
|
|
||||||
{
|
|
||||||
if (!Database.TryGetOpenTicket(command.Channel.Id, out Database.Ticket ticket))
|
|
||||||
{
|
|
||||||
await command.RespondAsync(new DiscordEmbedBuilder
|
|
||||||
{
|
|
||||||
Color = DiscordColor.Red,
|
|
||||||
Description = "This channel is not a ticket."
|
|
||||||
}, true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await command.DeferResponseAsync(true);
|
|
||||||
await Interviewer.RestartInterview(command);
|
|
||||||
await command.RespondAsync(new DiscordEmbedBuilder
|
|
||||||
{
|
|
||||||
Color = DiscordColor.Green,
|
|
||||||
Description = "Interview restarted."
|
|
||||||
}, true);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
DiscordChannel logChannel = await SupportChild.client.GetChannelAsync(Config.logChannel);
|
|
||||||
await logChannel.SendMessageAsync(new DiscordEmbedBuilder
|
|
||||||
{
|
|
||||||
Color = DiscordColor.Green,
|
|
||||||
Description = command.User.Mention + " restarted interview in " + command.Channel.Mention + ".",
|
|
||||||
Footer = new DiscordEmbedBuilder.EmbedFooter
|
|
||||||
{
|
|
||||||
Text = "Ticket: " + ticket.id.ToString("00000")
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch (NotFoundException)
|
|
||||||
{
|
|
||||||
Logger.Error("Could not find the log channel.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -12,37 +12,51 @@ namespace SupportChild.Interviews;
|
||||||
|
|
||||||
public static class Interviewer
|
public static class Interviewer
|
||||||
{
|
{
|
||||||
public static async void StartInterview(DiscordChannel channel)
|
public static async Task<bool> StartInterview(DiscordChannel channel)
|
||||||
{
|
{
|
||||||
if (channel.Parent == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Database.TryGetInterviewTemplate(channel.Parent.Id, out InterviewQuestion template))
|
if (!Database.TryGetInterviewTemplate(channel.Parent.Id, out InterviewQuestion template))
|
||||||
{
|
{
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
await CreateQuestion(channel, template);
|
await CreateQuestion(channel, template);
|
||||||
Database.SaveInterview(channel.Id, template);
|
return Database.SaveInterview(channel.Id, template);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task RestartInterview(SlashCommandContext command)
|
public static async Task<bool> RestartInterview(DiscordChannel channel)
|
||||||
{
|
{
|
||||||
if (Database.TryGetInterview(command.Channel.Id, out InterviewQuestion interviewRoot))
|
if (Database.TryGetInterview(channel.Id, out InterviewQuestion interviewRoot))
|
||||||
{
|
{
|
||||||
if (Config.deleteMessagesAfterNoSummary)
|
if (Config.deleteMessagesAfterNoSummary)
|
||||||
{
|
{
|
||||||
await DeletePreviousMessages(interviewRoot, command.Channel);
|
await DeletePreviousMessages(interviewRoot, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Database.TryDeleteInterview(command.Channel.Id))
|
if (!Database.TryDeleteInterview(channel.Id))
|
||||||
{
|
{
|
||||||
Logger.Error("Could not delete interview from database. Channel ID: " + command.Channel.Id);
|
Logger.Warn("Could not delete interview from database. Channel ID: " + channel.Id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StartInterview(command.Channel);
|
|
||||||
|
return await StartInterview(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<bool> StopInterview(DiscordChannel channel)
|
||||||
|
{
|
||||||
|
if (Database.TryGetInterview(channel.Id, out InterviewQuestion interviewRoot))
|
||||||
|
{
|
||||||
|
if (Config.deleteMessagesAfterNoSummary)
|
||||||
|
{
|
||||||
|
await DeletePreviousMessages(interviewRoot, channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Database.TryDeleteInterview(channel.Id))
|
||||||
|
{
|
||||||
|
Logger.Warn("Could not delete interview from database. Channel ID: " + channel.Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task ProcessButtonOrSelectorResponse(DiscordInteraction interaction)
|
public static async Task ProcessButtonOrSelectorResponse(DiscordInteraction interaction)
|
||||||
|
@ -180,7 +194,6 @@ public static class Interviewer
|
||||||
(string questionString, InterviewQuestion nextQuestion) = currentQuestion.paths.ElementAt(pathIndex);
|
(string questionString, InterviewQuestion nextQuestion) = currentQuestion.paths.ElementAt(pathIndex);
|
||||||
await HandleAnswer(questionString, nextQuestion, interviewRoot, currentQuestion, interaction.Channel);
|
await HandleAnswer(questionString, nextQuestion, interviewRoot, currentQuestion, interaction.Channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task ProcessResponseMessage(DiscordMessage answerMessage)
|
public static async Task ProcessResponseMessage(DiscordMessage answerMessage)
|
||||||
|
|
|
@ -194,7 +194,7 @@ internal static class SupportChild
|
||||||
typeof(RemoveCategoryCommand),
|
typeof(RemoveCategoryCommand),
|
||||||
typeof(RemoveMessageCommand),
|
typeof(RemoveMessageCommand),
|
||||||
typeof(RemoveStaffCommand),
|
typeof(RemoveStaffCommand),
|
||||||
typeof(RestartInterviewCommand),
|
typeof(InterviewCommands),
|
||||||
typeof(SayCommand),
|
typeof(SayCommand),
|
||||||
typeof(SetSummaryCommand),
|
typeof(SetSummaryCommand),
|
||||||
typeof(StatusCommand),
|
typeof(StatusCommand),
|
||||||
|
|
Loading…
Reference in a new issue