diff --git a/Commands/close.js b/Commands/close.js new file mode 100644 index 0000000..2a29c8a --- /dev/null +++ b/Commands/close.js @@ -0,0 +1,231 @@ +// SupportBot | Emerald Services +// Close Ticket Command + +const fs = require("fs"); + +const Discord = require("discord.js"); +const yaml = require("js-yaml"); +const supportbot = yaml.load( + fs.readFileSync("./Configs/supportbot.yml", "utf8") +); +const cmdconfig = yaml.load(fs.readFileSync("./Configs/commands.yml", "utf8")); + +const Command = require("../Structures/Command.js"); +const TicketNumberID = require("../Structures/TicketID.js"); + +async function asyncForEach(array, callback) { + for (let index = 0; index < array.length; index++) { + await callback(array[index], index, array); + } +} + +module.exports = new Command({ + name: cmdconfig.CloseTicket, + description: cmdconfig.CloseTicketDesc, + slashCommandOptions: [ + { + name: "reason", + description: "Ticket Close Reason", + type: "STRING", + }, + ], + permission: "SEND_MESSAGES", + + async run(interaction) { + if (!interaction.channel.name.startsWith(`${supportbot.TicketPrefix}`)) { + const Exists = new Discord.MessageEmbed() + .setTitle("No Ticket Found!") + .setDescription(`${supportbot.NoValidTicket}`) + .setColor(supportbot.WarningColour); + return interaction.reply({ embed: Exists }); + } + + if (supportbot.CloseConfirmation) { + const CloseTicketRequest = new Discord.MessageEmbed() + .setTitle(`**${supportbot.ClosingTicket}**`) + .setDescription( + `Please confirm by repeating the following word.. \`${supportbot.ClosingConfirmation_Word}\` ` + ) + .setColor(supportbot.EmbedColour); + + interaction + .reply(CloseTicketRequest) + .then((m) => { + interaction.channel + .awaitMessages( + (response) => + response.content.toLowerCase() === + supportbot.ClosingConfirmation_Word, + { + max: 1, + time: 20000, + errors: ["time"], + } + ) + .then((collected) => { + let logChannel = + interaction.guild.channels.cache.find( + (channel) => channel.name === supportbot.TranscriptLog + ) || + interaction.guild.channels.cache.find( + (channel) => channel.id === supportbot.TranscriptLog + ); + let user = interaction.user; + let reason = + interaction.options.getString("reason") || + "No Reason Provided."; + + let name = interaction.channel.name; + let ticketChannel = interaction.channel; + + interaction + .reply(`**${supportbot.ClosingTicket}**`) + + .then(() => { + const logEmbed = new Discord.MessageEmbed() + .setTitle(supportbot.TranscriptTitle) + .setColor(supportbot.EmbedColour) + .setFooter(supportbot.EmbedFooter) + .addField("Closed By", interaction.user.tag) + .addField("Reason", reason); + + interaction.channel.interactions + .fetch({ limit: 100 }) + .then((msgs) => { + let html = ""; + + msgs = msgs.sort( + (a, b) => a.createdTimestamp - b.createdTimestamp + ); + html += ``; + html += `Server Name: ${interaction.guild.name}
`; + html += `Ticket: ${ticketChannel.name}
`; + html += `Message: ${msgs.size} Messages


`; + + msgs.forEach((msg) => { + if (msg.content) { + html += `User: ${msg.author.tag}
`; + html += `Message: ${msg.content}
`; + html += `-----

`; + } + }); + + logChannel.send({ embeds: [logEmbed] }).catch((err) => { + interaction.reply(err); + }); + + let file = new Discord.MessageAttachment( + Buffer.from(html), + `${name}.html` + ); + logChannel + .send({ embeds: [logEmbed], files: [file] }) + .catch((err) => { + interaction.reply(err); + }); + + interaction.channel.delete().catch((error) => { + if ( + error.code !== + Discord.Constants.APIErrors.UNKNOWN_CHANNEL + ) { + console.error( + "Failed to delete the interaction:", + error + ); + } + }); + }); + }); + }); + }) + .catch(() => { + interaction + .followUp({ + content: "The request to close the ticket has timed out.", + }) + .then((m2) => setTimeout(() => interaction.channel.delete(3000))); + }); + } + + if (!supportbot.CloseConfirmation) { + let logChannel = + interaction.guild.channels.cache.find( + (channel) => channel.name === supportbot.TranscriptLog + ) || + interaction.guild.channels.cache.find( + (channel) => channel.id === supportbot.TranscriptLog + ); + let user = interaction.user; + let reason = + (await interaction.options.getString("reason")) || + "No Reason Provided."; + + let name = interaction.channel.name; + let ticketChannel = interaction.channel; + + interaction + .reply(`**${supportbot.ClosingTicket}**`) + + .then(() => { + const logEmbed = new Discord.MessageEmbed() + .setTitle(supportbot.TranscriptTitle) + .setColor(supportbot.EmbedColour) + .setFooter(supportbot.EmbedFooter) + .addField("Closed By", interaction.user.tag) + .addField("Reason", reason); + + interaction.channel.interactions + .fetch({ limit: 100 }) + .then((msgs) => { + let html = ""; + + msgs = msgs.sort( + (a, b) => a.createdTimestamp - b.createdTimestamp + ); + html += ``; + html += `Server Name: ${interaction.guild.name}
`; + html += `Ticket: ${ticketChannel.name}
`; + html += `Message: ${msgs.size} Messages


`; + + msgs.forEach((msg) => { + if (msg.content) { + html += `User: ${msg.author.tag}
`; + html += `Message: ${msg.content}
`; + html += `-----

`; + } + }); + + logChannel.send({ embeds: [logEmbed] }).catch((err) => { + interaction.reply(err); + }); + + let file = new Discord.MessageAttachment( + Buffer.from(html), + `${name}.html` + ); + logChannel + .send({ embeds: [logEmbed], files: [file] }) + .catch((err) => { + interaction.reply(err); + }); + + interaction.channel.delete().catch((error) => { + if ( + error.code !== Discord.Constants.APIErrors.UNKNOWN_CHANNEL + ) { + console.error("Failed to delete the interaction:", error); + } + }); + }); + }) + .catch(() => { + interaction + .followUp({ + content: "The request to close the ticket has timed out.", + }) + .then((m2) => setTimeout(() => interaction.channel.delete(3000))); + }); + } + }, +});