2022-04-18 10:52:03 +00:00
using System ;
2022-02-21 08:40:09 +00:00
using System.Collections.Generic ;
2024-12-26 05:36:20 +00:00
using System.ComponentModel ;
2022-02-21 08:40:09 +00:00
using System.IO ;
using System.Threading.Tasks ;
2024-12-26 05:36:20 +00:00
using DSharpPlus.Commands ;
using DSharpPlus.Commands.ContextChecks ;
using DSharpPlus.Commands.Processors.SlashCommands ;
2022-02-21 08:40:09 +00:00
using DSharpPlus.Entities ;
using DSharpPlus.Exceptions ;
2022-08-21 07:34:11 +00:00
namespace SupportChild.Commands ;
2024-12-26 05:36:20 +00:00
public class CloseCommand
2022-02-21 08:40:09 +00:00
{
2024-12-27 03:58:26 +00:00
// TODO: Refactor this class a whole lot
2024-10-29 10:14:47 +00:00
private static Dictionary < ulong , string > closeReasons = new Dictionary < ulong , string > ( ) ;
2024-12-27 04:00:24 +00:00
private static List < ulong > currentlyClosingTickets = new List < ulong > ( ) ;
2024-10-29 10:14:47 +00:00
2024-12-26 05:36:20 +00:00
[RequireGuild]
[Command("close")]
[Description("Closes this ticket.")]
public async Task OnExecute ( SlashCommandContext command ,
[Parameter("reason")] [ Description ( "(Optional) The reason for closing this ticket." ) ] string reason = "" )
2024-10-29 09:10:37 +00:00
{
// Check if ticket exists in the database
if ( ! Database . TryGetOpenTicket ( command . Channel . Id , out Database . Ticket _ ) )
{
2024-12-26 05:36:20 +00:00
await command . RespondAsync ( new DiscordEmbedBuilder
2024-10-29 09:10:37 +00:00
{
Color = DiscordColor . Red ,
Description = "This channel is not a ticket."
} ) ;
return ;
}
DiscordInteractionResponseBuilder confirmation = new DiscordInteractionResponseBuilder ( )
. AddEmbed ( new DiscordEmbedBuilder
{
Color = DiscordColor . Cyan ,
Description = "Are you sure you wish to close this ticket? You cannot re-open it again later."
} )
2024-12-27 03:58:26 +00:00
. AddComponents ( new DiscordButtonComponent ( DiscordButtonStyle . Danger , "supportchild_closeconfirm" , "Confirm" ) ) ;
2024-10-29 09:10:37 +00:00
2024-12-26 05:36:20 +00:00
await command . RespondAsync ( confirmation ) ;
2024-10-29 10:14:47 +00:00
closeReasons . Add ( command . Channel . Id , reason ) ;
2024-10-29 09:10:37 +00:00
}
public static async Task OnConfirmed ( DiscordInteraction interaction )
{
2024-12-27 04:00:24 +00:00
if ( currentlyClosingTickets . Contains ( interaction . Channel . Id ) )
2024-10-29 09:10:37 +00:00
{
2024-12-27 04:00:24 +00:00
await interaction . CreateResponseAsync ( DiscordInteractionResponseType . ChannelMessageWithSource ,
new DiscordInteractionResponseBuilder ( ) . AddEmbed ( new DiscordEmbedBuilder
{
Color = DiscordColor . Red ,
Description = "This ticket is already closing."
} ) . AsEphemeral ( ) ) ;
2024-10-29 09:10:37 +00:00
return ;
}
try
{
2024-12-27 04:00:24 +00:00
currentlyClosingTickets . Add ( interaction . Channel . Id ) ;
await interaction . CreateResponseAsync ( DiscordInteractionResponseType . DeferredMessageUpdate ) ;
2024-10-29 10:14:47 +00:00
2024-12-27 04:00:24 +00:00
// Check if ticket exists in the database
if ( ! Database . TryGetOpenTicket ( interaction . Channel . Id , out Database . Ticket ticket ) )
{
currentlyClosingTickets . Remove ( interaction . Channel . Id ) ;
await interaction . EditOriginalResponseAsync ( new DiscordWebhookBuilder ( ) . AddEmbed ( new DiscordEmbedBuilder
{
Color = DiscordColor . Red ,
Description = "This channel is not a ticket."
} ) ) ;
return ;
}
2024-12-27 03:58:26 +00:00
2024-12-27 04:00:24 +00:00
// Build transcript
try
2024-12-27 03:58:26 +00:00
{
2024-12-27 04:00:24 +00:00
await Transcriber . ExecuteAsync ( interaction . Channel . Id , ticket . id ) ;
2024-12-27 03:58:26 +00:00
}
2024-12-27 04:00:24 +00:00
catch ( Exception e )
2024-12-27 03:58:26 +00:00
{
2024-12-27 04:00:24 +00:00
currentlyClosingTickets . Remove ( interaction . Channel . Id ) ;
Logger . Error ( "Exception occured when trying to save transcript while closing ticket: " + e ) ;
await interaction . EditOriginalResponseAsync ( new DiscordWebhookBuilder ( ) . AddEmbed ( new DiscordEmbedBuilder
{
Color = DiscordColor . Red ,
Description = "ERROR: Could not save transcript file. Aborting..."
} ) ) ;
return ;
}
2024-12-27 03:58:26 +00:00
2024-12-27 04:00:24 +00:00
string closeReason = "" ;
if ( closeReasons . TryGetValue ( interaction . Channel . Id , out string cachedReason ) )
2024-12-27 03:58:26 +00:00
{
2024-12-27 04:00:24 +00:00
closeReason = "\nReason: " + cachedReason + "\n" ;
}
2024-12-27 03:58:26 +00:00
2024-12-27 04:00:24 +00:00
string fileName = Transcriber . GetZipFilename ( ticket . id ) ;
string filePath = Transcriber . GetZipPath ( ticket . id ) ;
long zipSize = 0 ;
2024-12-27 03:58:26 +00:00
2024-12-27 04:00:24 +00:00
// If the zip transcript doesn't exist, use the html file.
try
2024-10-29 09:10:37 +00:00
{
2024-12-27 04:23:03 +00:00
FileInfo fileInfo = new FileInfo ( filePath ) ;
if ( ! fileInfo . Exists | | fileInfo . Length > = 26214400 )
2024-12-26 12:21:37 +00:00
{
2024-12-27 04:00:24 +00:00
fileName = Transcriber . GetHTMLFilename ( ticket . id ) ;
filePath = Transcriber . GetHtmlPath ( ticket . id ) ;
2024-12-26 12:21:37 +00:00
}
2024-12-27 04:23:03 +00:00
zipSize = fileInfo . Length ;
2024-12-27 04:00:24 +00:00
}
catch ( Exception e )
{
currentlyClosingTickets . Remove ( interaction . Channel . Id ) ;
await interaction . EditOriginalResponseAsync ( new DiscordWebhookBuilder ( ) . AddEmbed ( new DiscordEmbedBuilder
{
Color = DiscordColor . Red ,
Description = "ERROR: Could not find transcript file. Aborting..."
} ) ) ;
Logger . Error ( "Failed to access transcript file:" , e ) ;
return ;
}
2024-10-29 09:10:37 +00:00
2024-12-27 04:00:24 +00:00
// Check if the chosen file path works.
if ( ! File . Exists ( filePath ) )
{
currentlyClosingTickets . Remove ( interaction . Channel . Id ) ;
await interaction . EditOriginalResponseAsync ( new DiscordWebhookBuilder ( ) . AddEmbed ( new DiscordEmbedBuilder
{
Color = DiscordColor . Red ,
Description = "ERROR: Could not find transcript file. Aborting..."
} ) ) ;
Logger . Error ( "Transcript file does not exist: \"" + filePath + "\"" ) ;
return ;
}
2024-10-29 09:10:37 +00:00
2024-12-27 03:58:26 +00:00
try
2024-10-29 09:10:37 +00:00
{
2024-12-27 04:00:24 +00:00
await using FileStream file = new FileStream ( filePath , FileMode . Open , FileAccess . Read ) ;
2024-12-27 07:17:14 +00:00
await LogChannel . Success ( "Ticket " + ticket . id . ToString ( "00000" ) + " closed by " + interaction . User . Mention + ".\n" + closeReason , ticket . id , new Utilities . File ( fileName , file ) ) ;
2024-12-27 04:00:24 +00:00
}
2024-12-27 07:17:14 +00:00
catch ( Exception e )
2024-12-27 04:00:24 +00:00
{
2024-12-27 07:17:14 +00:00
Logger . Error ( "Error occurred sending transcript log message. " , e ) ;
2024-12-27 04:00:24 +00:00
}
if ( Config . closingNotifications )
{
try
2024-12-26 12:21:37 +00:00
{
2024-12-27 04:00:24 +00:00
DiscordUser staffMember = await SupportChild . client . GetUserAsync ( ticket . creatorID ) ;
await using FileStream file = new ( filePath , FileMode . Open , FileAccess . Read ) ;
DiscordMessageBuilder message = new ( ) ;
if ( zipSize > = 26214400 )
2024-12-27 03:58:26 +00:00
{
2024-12-27 04:00:24 +00:00
message . AddEmbed ( new DiscordEmbedBuilder
2024-12-27 03:58:26 +00:00
{
2024-12-27 04:00:24 +00:00
Color = DiscordColor . Orange ,
Description = "Ticket " + ticket . id . ToString ( "00000" ) + " which you opened has now been closed, check the transcript for more info.\n\n" +
"The zip file is too large, sending only the HTML file. Ask an administrator for the zip if you need it.\"\n" + closeReason ,
Footer = new DiscordEmbedBuilder . EmbedFooter
{
Text = "Ticket: " + ticket . id . ToString ( "00000" )
}
} ) ;
}
else
2024-12-27 03:58:26 +00:00
{
2024-12-27 04:00:24 +00:00
message . AddEmbed ( new DiscordEmbedBuilder
2024-12-27 03:58:26 +00:00
{
2024-12-27 04:00:24 +00:00
Color = DiscordColor . Green ,
Description = "Ticket " + ticket . id . ToString ( "00000" ) + " which you opened has now been closed, " + "check the transcript for more info.\n" + closeReason ,
Footer = new DiscordEmbedBuilder . EmbedFooter
{
Text = "Ticket: " + ticket . id . ToString ( "00000" )
}
} ) ;
}
2024-10-29 09:10:37 +00:00
2024-12-27 04:00:24 +00:00
message . AddFiles ( new Dictionary < string , Stream > { { fileName , file } } ) ;
2024-10-29 09:10:37 +00:00
2024-12-27 04:00:24 +00:00
await staffMember . SendMessageAsync ( message ) ;
}
2024-12-27 07:17:14 +00:00
catch ( NotFoundException ) { /* ignore */ }
catch ( UnauthorizedException ) { /* ignore */ }
2024-10-29 09:10:37 +00:00
}
2024-12-27 04:00:24 +00:00
Database . ArchiveTicket ( ticket ) ;
Database . TryDeleteInterview ( interaction . Channel . Id ) ;
2024-10-29 09:10:37 +00:00
2024-12-27 04:00:24 +00:00
await interaction . EditOriginalResponseAsync ( new DiscordWebhookBuilder ( ) . AddEmbed ( new DiscordEmbedBuilder
{
Color = DiscordColor . Green ,
Description = "Channel will be deleted in 3 seconds..."
} ) ) ;
2024-10-29 09:10:37 +00:00
2024-12-27 04:00:24 +00:00
await Task . Delay ( 3000 ) ;
2024-10-29 09:10:37 +00:00
2024-12-27 04:00:24 +00:00
// Delete the channel and database entry
await interaction . Channel . DeleteAsync ( "Ticket closed." ) ;
2024-10-29 09:10:37 +00:00
2024-12-27 04:00:24 +00:00
Database . DeleteOpenTicket ( ticket . id ) ;
2024-10-29 10:14:47 +00:00
2024-12-27 04:00:24 +00:00
closeReasons . Remove ( interaction . Channel . Id ) ;
currentlyClosingTickets . Remove ( interaction . Channel . Id ) ;
}
catch ( Exception e )
{
currentlyClosingTickets . Remove ( interaction . Channel . Id ) ;
await interaction . EditOriginalResponseAsync ( new DiscordWebhookBuilder ( ) . AddEmbed ( new DiscordEmbedBuilder
{
Color = DiscordColor . Red ,
Description = "An unexpected error occurred when trying to close ticket. Aborting..."
} ) ) ;
Logger . Error ( "An unexpected error occurred when trying to close ticket:" , e ) ;
}
2024-10-29 09:10:37 +00:00
}
2022-05-19 11:38:59 +00:00
}