Make progress on ticket creations + fixes

This commit is contained in:
Isaac
2022-08-08 01:36:14 +01:00
parent fcd390bc9d
commit 01e479dab5
11 changed files with 220 additions and 75 deletions

View File

@@ -1,3 +1,4 @@
/* eslint-disable max-lines */
const {
ActionRowBuilder,
ModalBuilder,
@@ -10,6 +11,9 @@ const emoji = require('node-emoji');
const ms = require('ms');
const { EmbedBuilder } = require('discord.js');
/**
* @typedef {import('@prisma/client').Category & {guild: import('@prisma/client').Guild} & {questions: import('@prisma/client').Question[]}} CategoryGuildQuestions
*/
module.exports = class TicketManager {
constructor(client) {
/** @type {import("client")} */
@@ -18,15 +22,15 @@ module.exports = class TicketManager {
/**
* @param {object} data
* @param {string} data.category
* @param {string} data.categoryId
* @param {import("discord.js").ButtonInteraction|import("discord.js").SelectMenuInteraction} data.interaction
* @param {string?} [data.topic]
*/
async create({
categoryId, interaction, topic, reference,
categoryId, interaction, topic, referencesMessage, referencesTicket,
}) {
const cacheKey = `cache/category+guild+questions:${categoryId}`;
/** @type {import('@prisma/client').Category} */
/** @type {CategoryGuildQuestions} */
let category = await this.client.keyv.get(cacheKey);
if (!category) {
category = await this.client.prisma.category.findUnique({
@@ -104,7 +108,8 @@ module.exports = class TicketManager {
.setCustomId(JSON.stringify({
action: 'questions',
categoryId,
reference,
referencesMessage,
referencesTicket,
}))
.setTitle(category.name)
.setComponents(
@@ -154,7 +159,8 @@ module.exports = class TicketManager {
.setCustomId(JSON.stringify({
action: 'topic',
categoryId,
reference,
referencesMessage,
referencesTicket,
}))
.setTitle(category.name)
.setComponents(
@@ -183,20 +189,140 @@ module.exports = class TicketManager {
* @param {string?} [data.topic]
*/
async postQuestions({
categoryId, interaction, topic, reference,
categoryId, interaction, topic, referencesMessage, referencesTicket,
}) {
await interaction.deferReply({ ephemeral: true });
console.log(require('util').inspect(interaction, {
colors: true,
depth: 10,
}));
if (interaction.isModalSubmit()) {
const cacheKey = `cache/category+guild+questions:${categoryId}`;
/** @type {CategoryGuildQuestions} */
const category = await this.client.keyv.get(cacheKey);
let answers;
if (interaction.isModalSubmit()) {
answers = category.questions.map(q => ({
questionId: q.id,
userId: interaction.user.id,
value: interaction.fields.getTextInputValue(q.id),
}));
if (category.customTopic) topic = interaction.fields.getTextInputValue(category.customTopic);
}
/** @type {import("discord.js").Guild} */
const guild = this.client.guilds.cache.get(category.guild.id);
const getMessage = this.client.i18n.getLocale(category.guild.locale);
const creator = await guild.members.fetch(interaction.user.id);
const number = (await this.client.prisma.ticket.count({ where: { guildId: category.guild.id } })) + 1;
const channelName = category.channelName
.replace(/{+\s?(user)?name\s?}+/gi, creator.user.username)
.replace(/{+\s?(nick|display)(name)?\s?}+/gi, creator.displayName)
.replace(/{+\s?num(ber)?\s?}+/gi, number === 1488 ? '1487b' : number);
const allow = ['ViewChannel', 'ReadMessageHistory', 'SendMessages', 'EmbedLinks', 'AttachFiles'];
/** @type {import("discord.js").TextChannel} */
const channel = await guild.channels.create({
name: channelName,
parent: category.discordCategory,
permissionOverwrites: [
{
deny: ['ViewChannel'],
id: guild.roles.everyone,
},
{
allow: allow,
id: this.client.user.id,
},
{
allow: allow,
id: creator.id,
},
...category.staffRoles.map(id => ({
allow: allow,
id,
})),
],
rateLimitPerUser: category.ratelimit,
reason: `${creator.user.tag} created a ticket`,
topic: `${creator}${topic?.length > 0 ? ` | ${topic}` : ''}`,
});
const embed = new EmbedBuilder()
.setColor(category.guild.primaryColour)
.setAuthor({
iconURL: creator.displayAvatarURL(),
name: creator.displayName,
})
.setDescription(
category.openingMessage
.replace(/{+\s?(user)?name\s?}+/gi, creator.user.toString()),
);
if (answers) {
embed.setFields(
category.questions.map(q => ({
name: q.label,
value: interaction.fields.getTextInputValue(q.id) || getMessage('ticket.answers.no_value'),
})),
);
} else if (topic) {
embed.setFields({
name: getMessage('ticket.opening_message.fields.topic'),
value: topic,
});
}
if (category.guild.footer) {
embed.setFooter({
iconURL: guild.iconURL(),
text: category.guild.footer,
});
}
// TODO: add edit button (if topic or questions)
// TODO: add close and claim buttons if enabled
const pings = category.pingRoles.map(r => `<@&${r}>`).join(' ');
const sent = await channel.send({
content: getMessage('ticket.opening_message.content', {
creator: interaction.user.toString(),
staff: pings ? pings + ',' : '',
}),
embeds: [embed],
});
await sent.pin({ reason: 'Ticket opening message' });
const pinned = channel.messages.cache.last();
if (pinned.system) {
pinned
.delete({ reason: 'Cleaning up system message' })
.catch(() => this.client.log.warn('Failed to delete system pin message'));
}
// TODO: referenced msg or ticket
const data = {
category: { connect: { id: categoryId } },
createdBy: {
connectOrCreate: {
create: { id: interaction.user.id },
where: { id: interaction.user.id },
},
},
guild: { connect: { id: category.guild.id } },
id: channel.id,
number,
openingMessage: sent.id,
topic,
};
if (referencesTicket) data.referencesTicket = { connect: { id: referencesTicket } };
let message;
if (referencesMessage) message = this.client.prisma.archivedMessage.findUnique({ where: { id: referencesMessage } });
if (message) data.referencesMessage = { connect: { id: referencesMessage } }; // only add if the message has been archived ^^
if (answers) data.questionAnswers = { createMany: { data: answers } };
const ticket = await this.client.prisma.ticket.create({ data });
console.log(ticket);
interaction.editReply({
components: [],
embeds: [],
});
// TODO: log channel
}
};