blob: ea852550c5d596b8431500f65a440a077ed6cfdb [file] [log] [blame]
Skyler Greyda16adf2023-03-05 10:22:12 +00001import { getCommandMentionByName } from "./../utils/getCommandDataByName.js";
TheCodedProf21c08592022-09-13 14:14:43 -04002import Discord, { ActionRowBuilder, ButtonBuilder, OverwriteType, ChannelType, ButtonStyle } from "discord.js";
pineafan63fc5e22022-08-04 22:04:10 +01003import EmojiEmbed from "../utils/generateEmojiEmbed.js";
pineafan813bdf42022-07-24 10:39:10 +01004import getEmojiByName from "../utils/getEmojiByName.js";
5import client from "../utils/client.js";
6
Skyler Grey75ea9172022-08-06 10:22:23 +01007export async function create(
8 guild: Discord.Guild,
PineaFane6ba7882023-01-18 20:41:16 +00009 user: Discord.User,
Skyler Grey75ea9172022-08-06 10:22:23 +010010 createdBy: Discord.User,
pineafan62ce1922022-08-25 20:34:45 +010011 reason: string | null,
Skyler Grey75ea9172022-08-06 10:22:23 +010012 customReason?: string
13) {
pineafan63fc5e22022-08-04 22:04:10 +010014 const config = await client.database.guilds.read(guild.id);
Skyler Grey11236ba2022-08-08 21:13:33 +010015 const { log, NucleusColors, entry, renderUser, renderChannel, renderDelta } = client.logger;
Skyler Greyda16adf2023-03-05 10:22:12 +000016 const overwrites = [
17 {
18 id: user,
19 allow: ["ViewChannel", "SendMessages", "AttachFiles", "AddReactions", "ReadMessageHistory"],
20 type: OverwriteType.Member
21 }
22 ] as unknown as Discord.OverwriteResolvable[];
pineafan813bdf42022-07-24 10:39:10 +010023 overwrites.push({
24 id: guild.roles.everyone,
TheCodedProf21c08592022-09-13 14:14:43 -040025 deny: ["ViewChannel"],
26 type: OverwriteType.Role
pineafan63fc5e22022-08-04 22:04:10 +010027 });
pineafane23c4ec2022-07-27 21:56:27 +010028 if (config.tickets.supportRole !== null) {
pineafan813bdf42022-07-24 10:39:10 +010029 overwrites.push({
pineafan62ce1922022-08-25 20:34:45 +010030 id: guild.roles.cache.get(config.tickets.supportRole)!,
TheCodedProf21c08592022-09-13 14:14:43 -040031 allow: ["ViewChannel", "SendMessages", "AttachFiles", "AddReactions", "ReadMessageHistory"],
32 type: OverwriteType.Role
pineafan63fc5e22022-08-04 22:04:10 +010033 });
pineafan813bdf42022-07-24 10:39:10 +010034 }
Skyler Greyda16adf2023-03-05 10:22:12 +000035 const targetChannel: Discord.CategoryChannel | Discord.TextChannel = (await guild.channels.fetch(
36 config.tickets.category!
37 ))! as Discord.CategoryChannel | Discord.TextChannel;
pineafan813bdf42022-07-24 10:39:10 +010038
PineaFane6ba7882023-01-18 20:41:16 +000039 let c: Discord.TextChannel | Discord.PrivateThreadChannel;
40 if (targetChannel.type === Discord.ChannelType.GuildCategory) {
41 const overwrites = [
42 {
43 id: user,
44 allow: ["ViewChannel", "SendMessages", "AttachFiles", "AddReactions", "ReadMessageHistory"],
45 type: Discord.OverwriteType.Member
pineafan813bdf42022-07-24 10:39:10 +010046 }
PineaFane6ba7882023-01-18 20:41:16 +000047 ] as Discord.OverwriteResolvable[];
48 overwrites.push({
49 id: guild.roles.everyone,
50 deny: ["ViewChannel"],
51 type: Discord.OverwriteType.Role
Skyler Grey75ea9172022-08-06 10:22:23 +010052 });
PineaFane6ba7882023-01-18 20:41:16 +000053 if (config.tickets.supportRole !== null) {
54 overwrites.push({
55 id: guild.roles.cache.get(config.tickets.supportRole)!,
56 allow: ["ViewChannel", "SendMessages", "AttachFiles", "AddReactions", "ReadMessageHistory"],
57 type: Discord.OverwriteType.Role
58 });
59 }
60
61 try {
62 c = await guild.channels.create({
63 name: `${user.username.toLowerCase()}`,
64 type: ChannelType.GuildText,
65 topic: `${user.id} Active`,
66 parent: config.tickets.category,
67 nsfw: false,
68 permissionOverwrites: overwrites as Discord.OverwriteResolvable[],
69 reason: "Creating ticket"
70 });
71 } catch (e) {
72 return null;
73 }
74 try {
75 await c.send({
76 content:
77 `<@${user.id}>` +
78 (config.tickets.supportRole !== null ? ` • <@&${config.tickets.supportRole}>` : ""),
79 allowedMentions: {
80 users: [user.id],
81 roles: config.tickets.supportRole !== null ? [config.tickets.supportRole] : []
82 }
83 });
84 await c.send({
85 embeds: [
86 new EmojiEmbed()
87 .setTitle("New Ticket")
88 .setDescription(
89 "Ticket created by a Moderator\n" +
Skyler Greyda16adf2023-03-05 10:22:12 +000090 `**Support type:** ${customReason ? customReason : "Appeal submission"}\n` +
91 (reason !== null ? `**Reason:**\n> ${reason}\n` : "") +
92 `**Ticket ID:** \`${c.id}\`\n` +
93 `Type ${getCommandMentionByName("ticket/close")} to close this ticket.`
PineaFane6ba7882023-01-18 20:41:16 +000094 )
95 .setStatus("Success")
96 .setEmoji("GUILD.TICKET.OPEN")
97 ],
98 components: [
99 new ActionRowBuilder<ButtonBuilder>().addComponents([
100 new ButtonBuilder()
101 .setLabel("Close")
102 .setStyle(ButtonStyle.Danger)
103 .setCustomId("closeticket")
104 .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
105 ])
106 ]
107 });
108 } catch (e) {
109 return null;
110 }
111 } else {
Skyler Greyda16adf2023-03-05 10:22:12 +0000112 c = (await targetChannel.threads.create({
113 name: `${user.username} - ${user.id} - Active`,
114 autoArchiveDuration: 60 * 24 * 7,
115 type: Discord.ChannelType.PrivateThread,
116 reason: "Creating ticket"
117 })) as Discord.PrivateThreadChannel;
PineaFane6ba7882023-01-18 20:41:16 +0000118 c.members.add(user.id);
119 c.members.add(createdBy.id);
120 try {
121 await c.send({
122 content:
123 `<@${user.id}>` +
124 (config.tickets.supportRole !== null ? ` • <@&${config.tickets.supportRole}>` : ""),
125 allowedMentions: {
126 users: [user.id],
127 roles: config.tickets.supportRole !== null ? [config.tickets.supportRole] : []
128 }
129 });
130 await c.send({
131 embeds: [
132 new EmojiEmbed()
133 .setTitle("New Ticket")
134 .setDescription(
135 "Ticket created by a Moderator\n" +
Skyler Greyda16adf2023-03-05 10:22:12 +0000136 `**Support type:** ${customReason ? customReason : "Appeal submission"}\n` +
137 (reason !== null ? `**Reason:**\n> ${reason}\n` : "") +
138 `**Ticket ID:** \`${c.id}\`\n` +
139 `Type ${getCommandMentionByName("ticket/close")} to close this ticket.`
PineaFane6ba7882023-01-18 20:41:16 +0000140 )
141 .setStatus("Success")
142 .setEmoji("GUILD.TICKET.OPEN")
143 ],
144 components: [
145 new ActionRowBuilder<ButtonBuilder>().addComponents([
146 new ButtonBuilder()
147 .setLabel("Close")
148 .setStyle(ButtonStyle.Danger)
149 .setCustomId("closeticket")
150 .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
151 ])
152 ]
153 });
154 } catch (e) {
155 return null;
156 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100157 }
PineaFane6ba7882023-01-18 20:41:16 +0000158 const data = {
159 meta: {
160 type: "ticketCreate",
161 displayName: "Ticket Created",
162 calculateType: "ticketUpdate",
163 color: NucleusColors.green,
164 emoji: "GUILD.TICKET.OPEN",
TheCodedProf6ec331b2023-02-20 12:13:06 -0500165 timestamp: Date.now()
PineaFane6ba7882023-01-18 20:41:16 +0000166 },
167 list: {
168 ticketFor: entry(user.id, renderUser(user)),
169 createdBy: entry(createdBy.id, renderUser(createdBy)),
Skyler Greyda16adf2023-03-05 10:22:12 +0000170 created: entry(Date.now().toString(), renderDelta(Date.now())),
PineaFane6ba7882023-01-18 20:41:16 +0000171 ticketChannel: entry(c.id, renderChannel(c))
172 },
173 hidden: {
174 guild: guild.id
175 }
176 };
177 log(data);
pineafan63fc5e22022-08-04 22:04:10 +0100178 return c.id;
pineafan813bdf42022-07-24 10:39:10 +0100179}
180
181export async function areTicketsEnabled(guild: string) {
pineafan63fc5e22022-08-04 22:04:10 +0100182 const config = await client.database.guilds.read(guild);
pineafan813bdf42022-07-24 10:39:10 +0100183 return config.tickets.enabled;
Skyler Grey75ea9172022-08-06 10:22:23 +0100184}