Files
SupportBot/Commands/ticket.js
T

308 lines
10 KiB
JavaScript
Raw Permalink Normal View History

2021-10-24 22:46:36 +01:00
const fs = require("fs");
2021-12-14 18:04:38 -06:00
const {
2022-07-23 07:50:12 +01:00
EmbedBuilder,
2022-07-22 13:19:05 +01:00
ApplicationCommandOptionType,
ApplicationCommandType,
2022-08-11 19:19:29 +01:00
ChannelType,
2024-06-12 12:54:31 +01:00
ActionRowBuilder,
ButtonBuilder,
StringSelectMenuBuilder,
StringSelectMenuOptionBuilder,
GuildMemberRoleManager,
2021-12-14 18:04:38 -06:00
} = require("discord.js");
2021-10-24 22:46:36 +01:00
const yaml = require("js-yaml");
2022-08-12 01:35:36 +01:00
2024-06-12 12:54:31 +01:00
const panelconfig = yaml.load(fs.readFileSync("./Configs/ticket-panel.yml", "utf8"));
const supportbot = yaml.load(fs.readFileSync("./Configs/supportbot.yml", "utf8"));
const cmdconfig = yaml.load(fs.readFileSync("./Configs/commands.yml", "utf8"));
const msgconfig = yaml.load(fs.readFileSync("./Configs/messages.yml", "utf8"));
2021-10-24 22:46:36 +01:00
const Command = require("../Structures/Command.js");
const TicketNumberID = require("../Structures/TicketID.js");
module.exports = new Command({
2022-07-23 07:50:12 +01:00
name: cmdconfig.OpenTicket.Command,
description: cmdconfig.OpenTicket.Description,
2022-07-22 13:19:05 +01:00
type: ApplicationCommandType.ChatInput,
options: [
2021-10-24 22:46:36 +01:00
{
name: "reason",
description: "Ticket Reason",
2022-07-22 13:19:05 +01:00
type: ApplicationCommandOptionType.String,
2021-10-24 22:46:36 +01:00
},
],
2022-07-23 07:50:12 +01:00
permissions: cmdconfig.OpenTicket.Permission,
2021-10-24 22:46:36 +01:00
async run(interaction) {
2022-02-11 23:34:38 -06:00
let department = interaction.customId?.split("-")[1] || null;
2024-06-12 12:54:31 +01:00
let TicketData = JSON.parse(fs.readFileSync("./Data/TicketData.json", "utf8"));
const { getRole, getChannel } = interaction.client;
2021-12-18 20:54:01 -06:00
let User = interaction.guild.members.cache.get(interaction.user.id);
2021-10-24 22:46:36 +01:00
if (
2022-08-12 01:35:36 +01:00
supportbot.Ticket.TicketsPerUser &&
2024-06-12 12:54:31 +01:00
TicketData.tickets.filter((t) => t.user === interaction.user.id && t.open).length >= supportbot.Ticket.TicketsPerUser
2021-12-18 20:54:01 -06:00
) {
return interaction.reply({
embeds: [
{
title: "Too Many Tickets!",
2022-08-12 01:35:36 +01:00
description: `You can't have more than ${supportbot.Ticket.TicketsPerUser} open tickets!`,
color: supportbot.Embed.Colours.Warn,
2021-12-18 20:54:01 -06:00
},
],
2021-12-18 20:56:30 -06:00
ephemeral: true,
2021-12-18 20:54:01 -06:00
});
}
2024-06-12 12:54:31 +01:00
2022-08-12 01:35:36 +01:00
if (User.roles.cache.has(supportbot.Roles.ModRoles.Blacklisted)) {
2021-12-18 20:56:30 -06:00
return interaction.reply({
2022-08-12 01:35:36 +01:00
content: msgconfig.Ticket.Blacklisted,
2021-12-18 20:56:30 -06:00
ephemeral: true,
2024-06-12 12:54:31 +01:00
});
}
2022-08-11 19:19:29 +01:00
2022-08-12 01:35:36 +01:00
if (User.roles.cache.has(supportbot.Roles.ModRoles.Muted)) {
2022-06-23 20:58:03 +02:00
return interaction.reply({
2022-08-12 01:35:36 +01:00
content: msgconfig.Ticket.Muted,
2022-06-23 20:58:03 +02:00
ephemeral: true,
2024-06-12 12:54:31 +01:00
});
}
2021-10-24 22:46:36 +01:00
2021-11-23 15:48:45 -06:00
let ticketNumberID = await TicketNumberID.pad();
2024-06-12 12:54:31 +01:00
const TicketSubject = interaction.options?.getString("reason") || msgconfig.Ticket.InvalidSubject;
2021-10-24 22:46:36 +01:00
2022-07-23 07:50:12 +01:00
const TicketExists = new EmbedBuilder()
2021-10-24 22:46:36 +01:00
.setTitle("Ticket Exists!")
2022-08-12 01:35:36 +01:00
.setDescription(msgconfig.Ticket.TicketExists);
2021-10-24 22:46:36 +01:00
if (
2022-02-04 17:55:02 -06:00
await interaction.guild.channels.cache.find(
2024-06-12 12:54:31 +01:00
(ticketChannel) => ticketChannel.name === `${supportbot.Ticket.Channel}${ticketNumberID}`
2022-02-04 17:55:02 -06:00
)
2021-10-24 22:46:36 +01:00
) {
2022-02-04 17:55:02 -06:00
return await interaction.reply({
embeds: [TicketExists],
ephemeral: true,
});
2021-10-24 22:46:36 +01:00
}
2022-08-12 01:35:36 +01:00
const Staff = await getRole(supportbot.Roles.StaffMember.Staff, interaction.guild);
const Admin = await getRole(supportbot.Roles.StaffMember.Admin, interaction.guild);
2022-02-11 23:34:38 -06:00
if (!Staff || !Admin)
2021-11-23 16:51:28 -06:00
return interaction.reply({
2024-06-12 12:54:31 +01:00
content: "Some roles seem to be missing!\nPlease check for errors when starting the bot.",
2021-11-23 16:51:28 -06:00
ephemeral: true,
});
2022-08-12 01:35:36 +01:00
2024-06-12 12:54:31 +01:00
const TicketCategory = interaction.guild.channels.cache.find(
(c) => c.name === supportbot.Ticket.TicketCategory || c.id === supportbot.Ticket.TicketCategory
2021-12-14 18:04:38 -06:00
);
2024-06-12 12:54:31 +01:00
2024-06-13 17:36:44 +01:00
const channel = await getChannel(supportbot.Ticket.TicketCategory, interaction.guild);
2024-06-12 12:54:31 +01:00
const ticketChannel = await channel.threads.create({
name: `${supportbot.Ticket.Channel}${ticketNumberID}`,
type: ChannelType.PrivateThread,
parent: TicketCategory,
autoArchiveDuration: 60,
reason: 'support ticket',
});
if (supportbot.Ticket.ClaimTickets.Enabled === false) {
const InvStaff = await ticketChannel.send(`<@&${Staff.id}> <@&${Admin.id}>`)
setTimeout(() => {
InvStaff.delete();
}, 2000)
2021-12-14 18:04:38 -06:00
}
2024-06-12 12:54:31 +01:00
// TICKET CLAIMING SYSTEM [START]
if (supportbot.Ticket.ClaimTickets.Enabled) {
const InvStaff1 = await ticketChannel.send(`<@&${Admin.id}>`)
setTimeout(() => {
InvStaff1.delete();
}, 2000)
const claimChannel = await getChannel(
supportbot.Ticket.ClaimTickets.Channel,
interaction.guild
);
const claimEmbed = new EmbedBuilder()
.setTitle(msgconfig.Ticket.ClaimTickets.ClaimTitle)
.setDescription(msgconfig.Ticket.ClaimTickets.ClaimMessage
.replace('%user%', interaction.user.id)
)
.setColor(supportbot.Embed.Colours.General);
const claimButton = new ButtonBuilder()
.setCustomId(`claimticket-${ticketChannel.id}`)
.setLabel(supportbot.Ticket.ClaimTickets.ButtonTitle)
.setStyle(supportbot.Ticket.ClaimTickets.Button);
const row = new ActionRowBuilder().addComponents(claimButton);
await claimChannel.send({
content: `<@&${Staff.id}>`,
embeds: [claimEmbed],
components: [row]
2021-12-19 13:02:43 -06:00
});
2024-06-12 12:54:31 +01:00
}
// TICKET CLAIMING SYSTEM [END]
if (!department) {
await ticketChannel.members.add(interaction.user.id);
2021-12-19 13:02:43 -06:00
}
2024-06-12 12:54:31 +01:00
TicketData.tickets.push({
2021-11-23 15:48:45 -06:00
id: ticketChannel.id,
name: ticketChannel.name,
2022-02-17 19:57:11 -06:00
user: interaction.user.id,
2021-11-23 15:48:45 -06:00
number: ticketNumberID,
reason: TicketSubject,
2021-12-18 20:54:01 -06:00
open: true,
2021-12-14 18:04:38 -06:00
subUsers: [],
2024-06-12 12:54:31 +01:00
createdAt: new Date().toISOString(),
claimedAt: null, // Will be updated when claimed
2021-11-23 15:48:45 -06:00
});
2024-06-12 12:54:31 +01:00
2021-11-23 15:48:45 -06:00
fs.writeFileSync(
"./Data/TicketData.json",
JSON.stringify(TicketData, null, 4),
(err) => {
if (err) console.error(err);
}
);
2021-10-24 22:46:36 +01:00
2022-07-23 07:50:12 +01:00
const CreatedTicket = new EmbedBuilder()
2021-12-14 18:04:38 -06:00
.setDescription(
2024-06-12 12:54:31 +01:00
msgconfig.Ticket.TicketCreatedAlert.replace(/%ticketauthor%/g, interaction.user.id)
2021-12-14 18:04:38 -06:00
.replace(/%ticketid%/g, ticketChannel.id)
.replace(/%ticketusername%/g, interaction.user.username)
)
2022-08-12 01:35:36 +01:00
.setColor(supportbot.Embed.Colours.General);
2021-12-14 18:04:38 -06:00
await interaction.reply({ embeds: [CreatedTicket], ephemeral: true });
2021-10-24 22:46:36 +01:00
2022-08-12 01:35:36 +01:00
if (supportbot.Ticket.AllowMentions) {
await ticketChannel.send(`${interaction.user}`);
2021-10-24 22:46:36 +01:00
}
2022-07-23 07:50:12 +01:00
const TicketMessage = new EmbedBuilder()
2024-06-12 12:54:31 +01:00
.setAuthor({
name: msgconfig.Ticket.TicketAuthorTitle.replace(/%ticketauthor%/g, interaction.user.id)
.replace(/%ticketid%/g, ticketChannel.id)
.replace(/%ticketusername%/g, interaction.user.username),
iconURL: interaction.user.displayAvatarURL(),
})
2021-10-24 22:46:36 +01:00
.setTitle(
2022-08-12 01:35:36 +01:00
msgconfig.Ticket.TicketTitle.replace(/%ticketauthor%/g, interaction.user.id)
2021-10-24 22:46:36 +01:00
.replace(/%ticketid%/g, ticketChannel.id)
.replace(/%ticketusername%/g, interaction.user.username)
)
.setDescription(
2022-08-12 01:35:36 +01:00
msgconfig.Ticket.TicketMessage.replace(/%ticketauthor%/g, interaction.user.id)
2021-10-24 22:46:36 +01:00
.replace(/%ticketid%/g, ticketChannel.id)
.replace(/%ticketusername%/g, interaction.user.username)
)
2022-08-12 01:35:36 +01:00
.setColor(supportbot.Embed.Colours.General);
2021-10-24 22:46:36 +01:00
2024-06-12 12:54:31 +01:00
const SelectMenus = new StringSelectMenuBuilder()
.setCustomId("ticketcontrolpanel")
.setPlaceholder("Ticket Control Panel")
.addOptions(
new StringSelectMenuOptionBuilder()
.setLabel("Add User")
.setDescription("Add a user to the ticket.")
.setEmoji(supportbot.SelectMenus.Tickets.AddUserEmoji)
.setValue("ticketadduser"),
new StringSelectMenuOptionBuilder()
.setLabel("Remove User")
.setDescription("Remove a user from the ticket.")
.setEmoji(supportbot.SelectMenus.Tickets.RemoveUserEmoji)
.setValue("ticketremoveuser"),
new StringSelectMenuOptionBuilder()
.setLabel("Close")
.setDescription("Close the ticket.")
.setEmoji(supportbot.SelectMenus.Tickets.CloseEmoji)
.setValue("ticketclose"),
new StringSelectMenuOptionBuilder()
.setLabel("Enable Invites")
.setDescription("Enable invites.")
.setEmoji(supportbot.SelectMenus.Tickets.EnableInvitesEmoji)
.setValue("enableinvites"),
new StringSelectMenuOptionBuilder()
.setLabel("Disable Invites")
.setDescription("Disable invites.")
.setEmoji(supportbot.SelectMenus.Tickets.DisableInvitesEmoji)
.setValue("disableinvites"),
);
const row2 = new ActionRowBuilder().addComponents(SelectMenus);
2021-10-24 22:46:36 +01:00
2022-06-23 00:05:08 +01:00
if (!department) {
2021-12-14 18:04:38 -06:00
try {
2024-06-12 12:54:31 +01:00
let buttons = supportbot.Departments.map((x) =>
new ButtonBuilder()
2022-02-11 23:34:38 -06:00
.setCustomId("Department" + supportbot.Departments.indexOf(x))
.setLabel(x.title)
.setStyle(x.color)
.setEmoji(x.emoji)
2021-12-14 18:04:38 -06:00
);
2024-06-12 12:54:31 +01:00
if (supportbot.Ticket.AllowMentions) {
await ticketChannel.send("<@&" + supportbot.Ticket.RoleMention + ">");
}
const row = new ActionRowBuilder().addComponents(buttons);
2021-12-14 18:04:38 -06:00
const m = await ticketChannel.send({
embeds: [TicketMessage],
2024-06-12 12:54:31 +01:00
components: [row2],
2021-12-04 20:57:23 -06:00
});
2021-10-24 22:46:36 +01:00
2021-12-18 20:54:01 -06:00
try {
2021-12-18 22:59:05 -06:00
const filter = (i) => i.user.id === interaction.user.id;
2024-06-12 12:54:31 +01:00
await m.awaitMessageComponent({
2021-12-18 20:54:01 -06:00
filter,
max: 1,
componentType: "BUTTON",
2022-08-12 01:35:36 +01:00
time: supportbot.Ticket.Timeout * 60000,
2021-12-18 20:54:01 -06:00
});
} catch (e) {
2024-06-12 12:54:31 +01:00
if (e.code === "COLLECTOR_ERROR") {
2021-12-18 20:54:01 -06:00
try {
2024-06-12 12:54:31 +01:00
let ticket = TicketData.tickets.findIndex((t) => t.id === ticketChannel.id);
2021-12-18 20:54:01 -06:00
TicketData.tickets[ticket].open = false;
fs.writeFileSync(
"./Data/TicketData.json",
JSON.stringify(TicketData, null, 4),
(err) => {
if (err) console.error(err);
}
);
interaction.user.send(
"Your ticket has timed out. Please open a new one, and select a department."
);
2024-06-12 12:54:31 +01:00
} catch (error) {
console.error("An error occurred while handling collector:", error);
}
2021-12-18 22:42:51 -06:00
return await ticketChannel.delete();
}
2021-12-18 20:54:01 -06:00
}
2024-06-12 12:54:31 +01:00
} catch (error) {
console.error("Error sending message:", error);
}
2021-10-24 22:46:36 +01:00
} else {
2022-02-11 23:34:38 -06:00
await ticketChannel.send({
embeds: [TicketMessage],
components: [row2],
});
2024-06-12 12:54:31 +01:00
2021-10-24 22:46:36 +01:00
}
2024-06-12 12:54:31 +01:00
2021-10-24 22:46:36 +01:00
},
});