feat: detailed ticket close log message

This commit is contained in:
Isaac
2025-02-26 04:16:34 +00:00
parent 6274f66d44
commit 27d17fb4ce
3 changed files with 109 additions and 124 deletions

View File

@@ -335,6 +335,7 @@ log:
ticket:
added: Added members
description: "{user} {verb} a ticket"
feedback: Feedback
reason: Reason
removed: Removed members
ticket: Ticket

View File

@@ -1,7 +1,4 @@
const {
ActionRowBuilder,
ButtonBuilder,
ButtonStyle,
cleanCodeBlockContent,
EmbedBuilder,
} = require('discord.js');
@@ -137,7 +134,7 @@ async function logAdminEvent(client, {
* @param {string} details.action
*/
async function logTicketEvent(client, {
userId, action, target, diff,
userId, action, target, diff, payload,
}) {
const ticket = await client.tickets.getTicket(target.id);
if (!ticket) return;
@@ -173,6 +170,7 @@ async function logTicketEvent(client, {
name: getMessage('log.ticket.ticket'),
value: target.name ? `${target.name} (\`${target.id}\`)` : target.id,
},
...payload?.fields ?? [],
]),
];
@@ -193,21 +191,7 @@ async function logTicketEvent(client, {
}
return await channel.send({
components:
action === 'close' && target.archive ? [
new ActionRowBuilder()
.addComponents(
new ButtonBuilder()
.setCustomId(JSON.stringify({
action: 'transcript',
ticket: target.id,
}))
.setStyle(ButtonStyle.Primary)
.setEmoji(getMessage('buttons.transcript.emoji'))
.setLabel(getMessage('buttons.transcript.text')),
),
] : [],
components: payload?.components ?? [],
embeds,
});
}

View File

@@ -750,7 +750,7 @@ module.exports = class TicketManager {
let working = true;
if (currentHours[0] === currentHours[1] || now.isAfter(end)) { // staff have the day off or have finished for the day
// first look for the next working day *this* week (after today)
// first look for the next working day *this* week (after today)
let nextIndex = workingHours.findIndex((hours, i) => i > now.day() && hours[0] !== hours[1]);
// if there isn't one, look for the next working day *next* week (before and including today's weekday)
if (!nextIndex) nextIndex = workingHours.findIndex((hours, i) => i <= now.day() && hours[0] !== hours[1]);
@@ -1263,10 +1263,113 @@ module.exports = class TicketManager {
await channel.delete('Ticket closed' + (member ? ` by ${member.displayName}` : '') + reason ? `: ${reason}` : '');
}
const components = [];
if (ticket.guild.archive) {
components.push(
new ActionRowBuilder()
.addComponents(
new ButtonBuilder()
.setCustomId(JSON.stringify({
action: 'transcript',
ticket: ticket.id,
}))
.setStyle(ButtonStyle.Primary)
.setEmoji(getMessage('buttons.transcript.emoji'))
.setLabel(getMessage('buttons.transcript.text')),
),
);
}
const fields = {
closed: {
inline: true,
name: getMessage('dm.closed.fields.closed.name'),
value: getMessage('dm.closed.fields.closed.value', {
duration: ms(ticket.closedAt - ticket.createdAt, { long: true }),
timestamp: `<t:${Math.floor(ticket.closedAt / 1000)}:f>`,
}),
},
closedById: ticket.closedById && {
inline: true,
name: getMessage('dm.closed.fields.closed_by'),
value: `<@${ticket.closedById}>`,
},
created: {
inline: true,
name: getMessage('dm.closed.fields.created'),
value: `<t:${Math.floor(ticket.createdAt / 1000)}:f>`,
},
feedback: ticket.feedback && {
inline: true,
name: getMessage('dm.closed.fields.feedback'),
value: Array(ticket.feedback.rating).fill('⭐').join(' ') + ` (${ticket.feedback.rating}/5)`,
},
firstResponseAt: ticket.firstResponseAt && {
inline: true,
name: getMessage('dm.closed.fields.response'),
value: ms(ticket.firstResponseAt - ticket.createdAt, { long: true }),
},
reason: reason && {
inline: true,
name: getMessage('dm.closed.fields.reason'),
value: reason,
},
ticket: {
inline: true,
name: getMessage('dm.closed.fields.ticket'),
value: `${ticket.category.name} **#${ticket.number}**`,
},
topic: ticket.topic && {
inline: true,
name: getMessage('dm.closed.fields.topic'),
value: await quick('crypto', worker => worker.decrypt(ticket.topic)),
},
};
const dmEmbed = new ExtendedEmbedBuilder({
iconURL: channel.guild.iconURL(),
text: ticket.guild.footer,
})
.setColor(ticket.guild.primaryColour)
.setTitle(getMessage('dm.closed.title'));
dmEmbed.addFields(fields.ticket);
if (ticket.topic) dmEmbed.addFields(fields.topic);
dmEmbed.addFields(fields.created, fields.closed);
if (ticket.firstResponseAt) dmEmbed.addFields(fields.firstResponseAt);
if (ticket.feedback) dmEmbed.addFields(fields.feedback);
if (ticket.closedById) dmEmbed.addFields(fields.closedById);
if (reason) dmEmbed.addFields(fields.reason);
try {
const creator = channel?.guild.members.cache.get(ticket.createdById);
if (creator) {
await creator.send({
components,
embeds: [dmEmbed],
});
}
} catch (error) {
this.client.log.error(error);
}
const fieldsArray = [];
if (ticket.topic) fieldsArray.push(fields.topic);
fieldsArray.push(fields.created, fields.closed);
if (ticket.firstResponseAt) fieldsArray.push(fields.firstResponseAt);
if (fields.feedback) fields.feedback.name = getMessage('log.ticket.feedback');
if (reason) fieldsArray.push(fields.reason);
logTicketEvent(this.client, {
action: 'close',
payload: {
components,
fields: fieldsArray,
},
target: {
archive: ticket.guild.archive,
id: ticket.id,
name: `${ticket.category.name} **#${ticket.number}**`,
reason,
@@ -1274,108 +1377,5 @@ module.exports = class TicketManager {
userId: closedBy || this.client.user.id,
});
try {
const creator = channel?.guild.members.cache.get(ticket.createdById);
if (creator) {
const embed = new ExtendedEmbedBuilder({
iconURL: channel.guild.iconURL(),
text: ticket.guild.footer,
})
.setColor(ticket.guild.primaryColour)
.setTitle(getMessage('dm.closed.title'))
.addFields([
{
inline: true,
name: getMessage('dm.closed.fields.ticket'),
value: `${ticket.category.name} **#${ticket.number}**`,
},
]);
if (ticket.topic) {
embed.addFields({
inline: true,
name: getMessage('dm.closed.fields.topic'),
value: await quick('crypto', worker => worker.decrypt(ticket.topic)),
});
}
embed.addFields([
{
inline: true,
name: getMessage('dm.closed.fields.created'),
value: `<t:${Math.floor(ticket.createdAt / 1000)}:f>`,
},
{
inline: true,
name: getMessage('dm.closed.fields.closed.name'),
value: getMessage('dm.closed.fields.closed.value', {
duration: ms(ticket.closedAt - ticket.createdAt, { long: true }),
timestamp: `<t:${Math.floor(ticket.closedAt / 1000)}:f>`,
}),
},
]);
if (ticket.firstResponseAt) {
embed.addFields({
inline: true,
name: getMessage('dm.closed.fields.response'),
value: ms(ticket.firstResponseAt - ticket.createdAt, { long: true }),
});
}
if (ticket.feedback) {
embed.addFields({
inline: true,
name: getMessage('dm.closed.fields.feedback'),
value: Array(ticket.feedback.rating).fill('⭐').join(' ') + ` (${ticket.feedback.rating}/5)`,
});
}
if (ticket.closedById) {
embed.addFields({
inline: true,
name: getMessage('dm.closed.fields.closed_by'),
value: `<@${ticket.closedById}>`,
});
}
if (reason) {
embed.addFields({
inline: true,
name: getMessage('dm.closed.fields.reason'),
value: reason,
});
}
const components = [];
if (ticket.guild.archive) {
components.push(
new ActionRowBuilder()
.addComponents(
new ButtonBuilder()
.setCustomId(JSON.stringify({
action: 'transcript',
ticket: ticket.id,
}))
.setStyle(ButtonStyle.Primary)
.setEmoji(getMessage('buttons.transcript.emoji'))
.setLabel(getMessage('buttons.transcript.text')),
),
);
}
await creator.send({
components,
embeds: [embed],
});
}
} catch (error) {
this.client.log.error(error);
}
}
};