feat: add /tickets command

This commit is contained in:
Isaac 2022-10-26 14:13:45 +01:00
parent 119f997ffe
commit c6f1261478
No known key found for this signature in database
GPG Key ID: 0DE40AE37BBA5C33
4 changed files with 129 additions and 10 deletions

View File

@ -81,7 +81,7 @@ module.exports = class ForceCloseSlashCommand extends SlashCommand {
const getMessage = this.client.i18n.getLocale(settings.locale);
let ticket;
if (!isStaff(interaction.guild, interaction.user.id)) { // if user is not staff
if (!(await isStaff(interaction.guild, interaction.user.id))) { // if user is not staff
return await interaction.editReply({
embeds: [
new ExtendedEmbedBuilder({

View File

@ -36,7 +36,7 @@ module.exports = class ClaimSlashCommand extends SlashCommand {
.filter(c => c.type === 1)
.map(c => `> </${c.name}:${c.id}>: ${c.description}`)
.join('\n');
const ticket = client.application.commands.cache.find(c => c.name === 'new');
const newCommand = client.application.commands.cache.find(c => c.name === 'new');
const fields = [
{
name: getMessage('commands.slash.help.response.commands'),
@ -76,7 +76,7 @@ module.exports = class ClaimSlashCommand extends SlashCommand {
.setTitle(getMessage('commands.slash.help.title'))
.setDescription(staff
? `**Discord Tickets v${version} by eartharoid.**`
: getMessage('commands.slash.help.response.description', { command: `</${ticket.name}:${ticket.id}>` }))
: getMessage('commands.slash.help.response.description', { command: `</${newCommand.name}:${newCommand.id}>` }))
.setFields(fields),
],
});

View File

@ -1,5 +1,9 @@
const { SlashCommand } = require('@eartharoid/dbf');
const { ApplicationCommandOptionType } = require('discord.js');
const { isStaff } = require('../../lib/users');
const ExtendedEmbedBuilder = require('../../lib/embed');
const Cryptr = require('cryptr');
const { decrypt } = new Cryptr(process.env.ENCRYPTION_KEY);
module.exports = class TicketsSlashCommand extends SlashCommand {
constructor(client, options) {
@ -42,5 +46,102 @@ module.exports = class TicketsSlashCommand extends SlashCommand {
});
}
async run(interaction) { }
/**
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async run(interaction) {
/** @type {import("client")} */
const client = this.client;
await interaction.deferReply({ ephemeral: true });
await client.application.commands.fetch();
const member = interaction.options.getMember('member', false) ?? interaction.member;
const ownOrOther = member.id === interaction.member.id ? 'own' : 'other';
const settings = await client.prisma.guild.findUnique({ where: { id: interaction.guild.id } });
const getMessage = client.i18n.getLocale(settings.locale);
if (member.id !== interaction.member.id && !(await isStaff(interaction.guild, interaction.member.id))) {
return await interaction.editReply({
embeds: [
new ExtendedEmbedBuilder({
iconURL: interaction.guild.iconURL(),
text: settings.footer,
})
.setColor(settings.errorColour)
.setTitle(getMessage('commands.slash.tickets.not_staff.title'))
.setDescription(getMessage('commands.slash.tickets.not_staff.description')),
],
});
}
const fields = [];
const open = await client.prisma.ticket.findMany({
include: { category: true },
where: {
createdById: member.id,
guildId: interaction.guild.id,
open: true,
},
});
const closed = await client.prisma.ticket.findMany({
include: { category: true },
orderBy: { createdAt: 'desc' },
where: {
createdById: member.id,
guildId: interaction.guild.id,
open: false,
},
});
if (open.length >= 1) {
fields.push({
name: getMessage('commands.slash.tickets.response.fields.open.name'),
value: open.map(ticket =>{
const topic = ticket.topic ? `- \`${decrypt(ticket.topic).replace(/\n/g, ' ').slice(0, 30) }\`` : '';
return `> <#${ticket.id}> ${topic}`;
}).join('\n'),
});
}
if (closed.length === 0) {
const newCommand = client.application.commands.cache.find(c => c.name === 'new');
fields.push({
name: getMessage('commands.slash.tickets.response.fields.closed.name'),
value: getMessage(`commands.slash.tickets.response.fields.closed.none.${ownOrOther}`, {
new: `</${newCommand.name}:${newCommand.id}>`,
user: member.user.toString(),
}),
});
} else {
fields.push({
name: getMessage('commands.slash.tickets.response.fields.closed.name'),
value: closed.slice(0, 10).map(ticket => { // max 10 rows
const topic = ticket.topic ? `- \`${decrypt(ticket.topic).replace(/\n/g, ' ').slice(0, 30)}\`` : '';
return `> ${ticket.category.name} #${ticket.number} ${topic}`;
}).join('\n'),
});
}
const embed = new ExtendedEmbedBuilder({
iconURL: interaction.guild.iconURL(),
text: settings.footer,
})
.setColor(settings.primaryColour)
.setAuthor({
iconURL: member.displayAvatarURL(),
name: member.displayName,
})
.setTitle(getMessage(`commands.slash.tickets.response.title.${ownOrOther}`, { displayName: member.displayName }))
.setFields(fields);
if (settings.archive && !client.config.overrides.disableArchives) {
const transcriptCommand = client.application.commands.cache.find(c => c.name === 'transcript');
embed.setDescription(getMessage('commands.slash.tickets.response.description', { transcript: `</${transcriptCommand.name}:${transcriptCommand.id}>` }));
}
return await interaction.editReply({ embeds: [embed] });
}
};

View File

@ -67,8 +67,8 @@ commands:
force-close:
confirm_multiple:
description: >
You are about to close **{count}** tickets that have been inactive for
more than `{time}`:
You are about to close **{count}** tickets that have been inactive
for more than `{time}`:
{tickets}
title: ❓ Are you sure?
@ -85,8 +85,7 @@ commands:
options:
category:
description: >-
Close all tickets in the specified category (can be used with
`time`)
Close all tickets in the specified category (can be used with `time`)
name: category
reason:
description: The reason for closing the ticket(s)
@ -166,11 +165,30 @@ commands:
name: tag
tickets:
description: List your own or someone else's tickets
fields:
name: tickets
not_staff:
description: Only staff members can view others' tickets.
title: ❌ Error
options:
member:
description: The member to list the tickets of
name: member
response:
description: Use {transcript} to download the transcript of a ticket.
fields:
closed:
name: Closed tickets
none:
other: "{user} hasn't made any tickets."
own: |
You haven't made any tickets.
Use {new} to open a ticket.
open:
name: Open tickets
title:
other: "{displayName}'s tickets"
own: Your tickets
topic:
description: Change the topic of a ticket
name: topic
@ -274,8 +292,8 @@ misc:
- ❌ You already have %d open tickets
missing_roles:
description: >-
You do not have the roles required to be able to create a ticket in this
category.
You do not have the roles required to be able to create a ticket in
this category.
title: ❌ Insufficient roles
no_categories:
description: No ticket categories have been configured.