Skip to content

Commit

Permalink
Config Update: Delete ticket on close button
Browse files Browse the repository at this point in the history
  • Loading branch information
Uo1428 committed Jun 15, 2024
1 parent a42256b commit 88e7c08
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 118 deletions.
1 change: 1 addition & 0 deletions config/config.example.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
"createTranscript": true, // If set to true, when the ticket is closed a transcript will be generated and sent in the logs channel
"askReason": true, // If false the ticket will be closed without asking the reason
"whoCanCloseTicket": "STAFFONLY", // STAFFONLY (roles configured at "rolesWhoHaveAccessToTheTickets") or EVERYONE
"deleteTicket": false, // when enabled, it will delete the ticket on clicking close button
"closeTicketCategoryId": "" // The id of the category where a closed ticket will be moved to. Leave blank to disable this feature
},
"uuidType": "uuid", // uuid or emoji
Expand Down
83 changes: 50 additions & 33 deletions src/events/interactionCreate.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
import { ActionRowBuilder, GuildChannel, GuildMember, Interaction, ModalBuilder, SelectMenuComponentOptionData, StringSelectMenuBuilder, TextInputBuilder, TextInputStyle } from "discord.js";
import {
ActionRowBuilder,
GuildChannel,
GuildMember,
Interaction,
ModalBuilder,
SelectMenuComponentOptionData,
StringSelectMenuBuilder,
TextInputBuilder,
TextInputStyle,
} from "discord.js";
import { log } from "../utils/logs";
import {createTicket} from "../utils/createTicket";
import { createTicket } from "../utils/createTicket";
import { close } from "../utils/close";
import { claim } from "../utils/claim";
import { closeAskReason } from "../utils/close_askReason";
import { deleteTicket } from "../utils/delete";
import {BaseEvent, ExtendedClient} from "../structure";
import { BaseEvent, ExtendedClient } from "../structure";

/*
Copyright 2023 Sayrix (github.com/Sayrix)
Expand All @@ -19,7 +29,7 @@ export default class InteractionCreateEvent extends BaseEvent {
super(client);
}

public async execute(interaction: Interaction): Promise<void> {
public async execute(interaction: Interaction): Promise<void> {
if (interaction.isChatInputCommand()) {
const command = this.client.commands.get(interaction.commandName);
if (!command) return;
Expand All @@ -30,7 +40,7 @@ export default class InteractionCreateEvent extends BaseEvent {
console.error(error);
await interaction.reply({
content: "There was an error while executing this command!",
ephemeral: true
ephemeral: true,
});
}
}
Expand All @@ -40,32 +50,35 @@ export default class InteractionCreateEvent extends BaseEvent {
await interaction.deferReply({ ephemeral: true }).catch((e) => console.log(e));

const tCount = this.client.config.ticketTypes.length;
if(tCount === 0 || tCount > 25) {
await interaction.followUp({content: this.client.locales.getValue("invalidConfig"), ephemeral: true});
if (tCount === 0 || tCount > 25) {
await interaction.followUp({ content: this.client.locales.getValue("invalidConfig"), ephemeral: true });
throw new Error("ticketTypes either has nothing or exceeded 25 entries. Please check the config and restart the bot");
}

for (const role of this.client.config.rolesWhoCanNotCreateTickets) {
if (role && (interaction.member as GuildMember | null)?.roles.cache.has(role)) {
interaction
.editReply({
content: "You can't create a ticket because you are blacklisted"
content: "You can't create a ticket because you are blacklisted",
})
.catch((e) => console.log(e));
return;
}
}

// Max Ticket
if (this.client.config.maxTicketOpened > 0) {
const ticketsOpened = (await this.client.prisma.$queryRaw<[{count: bigint}]>
`SELECT COUNT(*) as count FROM tickets WHERE closedby IS NULL AND creator = ${interaction.user.id}`)[0].count;
const ticketsOpened = (
await this.client.prisma.$queryRaw<
[{ count: bigint }]
>`SELECT COUNT(*) as count FROM tickets WHERE closedby IS NULL AND creator = ${interaction.user.id}`
)[0].count;

// If maxTicketOpened is 0, it means that there is no limit
if (ticketsOpened >= this.client.config.maxTicketOpened) {
interaction
.editReply({
content: this.client.locales.getValue("ticketLimitReached").replace("TICKETLIMIT", this.client.config.maxTicketOpened.toString())
content: this.client.locales.getValue("ticketLimitReached").replace("TICKETLIMIT", this.client.config.maxTicketOpened.toString()),
})
.catch((e) => console.log(e));
return;
Expand Down Expand Up @@ -101,7 +114,7 @@ export default class InteractionCreateEvent extends BaseEvent {

if (options.length <= 0) {
interaction.editReply({
content: this.client.locales.getValue("noTickets")
content: this.client.locales.getValue("noTickets"),
});
return;
}
Expand All @@ -111,7 +124,7 @@ export default class InteractionCreateEvent extends BaseEvent {
.setCustomId("selectTicketType")
.setPlaceholder(this.client.locales.getSubValue("other", "selectTicketTypePlaceholder"))
.setMaxValues(1)
.addOptions(options)
.addOptions(options),
);

interaction
Expand All @@ -127,11 +140,11 @@ export default class InteractionCreateEvent extends BaseEvent {

if (interaction.customId === "close") {
await interaction.deferReply({ ephemeral: true }).catch((e) => console.log(e));
close(interaction, this.client, this.client.locales.getSubValue("other", "noReasonGiven"));
close(interaction, this.client, this.client.locales.getSubValue("other", "noReasonGiven"), this.client.config.closeOption.deleteTicket);
}

if (interaction.customId === "close_askReason") {
closeAskReason(interaction, this.client);
closeAskReason(interaction, this.client, this.client.config.closeOption.deleteTicket);
}

if (interaction.customId === "deleteTicket") {
Expand All @@ -142,8 +155,11 @@ export default class InteractionCreateEvent extends BaseEvent {
if (interaction.isStringSelectMenu()) {
if (interaction.customId === "selectTicketType") {
if (this.client.config.maxTicketOpened > 0) {
const ticketsOpened = (await this.client.prisma.$queryRaw<[{count: bigint}]>
`SELECT COUNT(*) as count FROM tickets WHERE closedby IS NULL AND creator = ${interaction.user.id}`)[0].count;
const ticketsOpened = (
await this.client.prisma.$queryRaw<
[{ count: bigint }]
>`SELECT COUNT(*) as count FROM tickets WHERE closedby IS NULL AND creator = ${interaction.user.id}`
)[0].count;
// If maxTicketOpened is 0, it means that there is no limit
if (ticketsOpened >= this.client.config.maxTicketOpened) {
interaction
Expand All @@ -161,7 +177,7 @@ export default class InteractionCreateEvent extends BaseEvent {
if (ticketType.askQuestions) {
// Sanity Check
const qCount = ticketType.questions.length;
if(qCount === 0 || qCount > 5)
if (qCount === 0 || qCount > 5)
throw new Error(`${ticketType.codeName} has either no questions or exceeded 5 questions. Check your config and restart the bot`);

const modal = new ModalBuilder().setCustomId("askReason").setTitle(this.client.locales.getSubValue("modals", "reasonTicketOpen", "title"));
Expand Down Expand Up @@ -191,8 +207,8 @@ export default class InteractionCreateEvent extends BaseEvent {
invited: true,
},
where: {
channelid: interaction.message.channelId
}
channelid: interaction.message.channelId,
},
});
for (const value of interaction.values) {
await (interaction.channel as GuildChannel | null)?.permissionOverwrites.delete(value).catch((e) => console.log(e));
Expand All @@ -206,28 +222,26 @@ export default class InteractionCreateEvent extends BaseEvent {
id: value,
},
},
this.client
this.client,
);
}

// Update the data in the database
await this.client.prisma.tickets.update({
data: {
invited: JSON.stringify((JSON.parse(ticket?.invited ?? "[]") as string[])
.filter(userid=>interaction.values.find(rUID=>rUID===userid) === undefined))
invited: JSON.stringify(
(JSON.parse(ticket?.invited ?? "[]") as string[]).filter((userid) => interaction.values.find((rUID) => rUID === userid) === undefined),
),
},
where: {
channelid: interaction.channel?.id
}
channelid: interaction.channel?.id,
},
});

await interaction
.update({
content: `> Removed ${
interaction.values.length < 1 ? interaction.values : interaction.values.map((a) => `<@${a}>`).join(", ")
} from the ticket`,
components: [],
});
await interaction.update({
content: `> Removed ${interaction.values.length < 1 ? interaction.values : interaction.values.map((a) => `<@${a}>`).join(", ")} from the ticket`,
components: [],
});
}
}

Expand All @@ -243,6 +257,9 @@ export default class InteractionCreateEvent extends BaseEvent {
if (interaction.customId === "askReasonClose") {
await interaction.deferReply().catch((e) => console.log(e));
close(interaction, this.client, interaction.fields.fields.first()?.value);
} else if (interaction.customId === "askReasonDelete") {
await interaction.deferReply().catch((e) => console.log(e));
close(interaction, this.client, interaction.fields.fields.first()?.value, true);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/structure/ExtendedClient.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Client, ClientOptions, Collection, Routes} from "discord.js";
import {BaseCommand, ConfigType} from "./";
import {PrismaClient} from "@prisma/client";
import {PrismaClient} from "../../node_modules/.prisma/client";
import fs from "fs-extra";
import path from "node:path";
import {AddCommand, MassAddCommand, ClaimCommand, CloseCommand, RemoveCommand, RenameCommand, clearDM} from "../commands";
Expand Down
1 change: 1 addition & 0 deletions src/structure/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export type ConfigType = {
askReason: boolean;
whoCanCloseTicket: "STAFFONLY" | "EVERYONE";
closeTicketCategoryId?: string;
deleteTicket: boolean,
};
uuidType: "uuid" | "emoji";
status: {
Expand Down
Loading

0 comments on commit 88e7c08

Please sign in to comment.