Skip to content

Commit

Permalink
feat: add ticket claiming
Browse files Browse the repository at this point in the history
  • Loading branch information
eartharoid committed Oct 28, 2022
1 parent 15318df commit 77216ba
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 8 deletions.
12 changes: 11 additions & 1 deletion src/buttons/claim.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,15 @@ module.exports = class ClaimButton extends Button {
});
}

async run (id, interaction) {}
/**
* @param {*} id
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async run(id, interaction) {
/** @type {import("client")} */
const client = this.client;

await interaction.deferReply({ ephemeral: false });
await client.tickets.claim(interaction);
}
};
12 changes: 11 additions & 1 deletion src/buttons/unclaim.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,15 @@ module.exports = class UnclaimButton extends Button {
});
}

async run(id, interaction) { }
/**
* @param {*} id
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async run(id, interaction) {
/** @type {import("client")} */
const client = this.client;

await interaction.deferReply({ ephemeral: false });
await client.tickets.release(interaction);
}
};
9 changes: 8 additions & 1 deletion src/commands/slash/claim.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,14 @@ module.exports = class ClaimSlashCommand extends SlashCommand {
});
}

/**
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async run(interaction) {
// tickets/manager.js
/** @type {import("client")} */
const client = this.client;

await interaction.deferReply({ ephemeral: false });
await client.tickets.claim(interaction);
}
};
11 changes: 10 additions & 1 deletion src/commands/slash/release.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,14 @@ module.exports = class ReleaseSlashCommand 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: false });
await client.tickets.release(interaction);
}
};
4 changes: 3 additions & 1 deletion src/i18n/en-GB.yml
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@ commands:
description: Release (unclaim) a ticket
name: release
remove:
removed: ⬅️ {removed} has been removed by {by}.
description: Remove a member from a ticket
name: remove
not_staff:
Expand All @@ -164,6 +163,7 @@ commands:
ticket:
description: The ticket to remove the member from
name: ticket
removed: ⬅️ {removed} has been removed by {by}.
success:
description: "{member} has been removed from {ticket}."
title: ✅ Added
Expand Down Expand Up @@ -332,6 +332,8 @@ modals:
ticket:
answers:
no_value: "*No response*"
claimed: 🙌 {user} has claimed this ticket.
released: ♻️ {user} has released this ticket.
created:
description: "Your ticket channel has been created: {channel}."
title: ✅ Ticket created
Expand Down
171 changes: 168 additions & 3 deletions src/lib/tickets/manager.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable no-underscore-dangle */
/* eslint-disable max-lines */
const TicketArchiver = require('./archiver');
const {
Expand Down Expand Up @@ -344,15 +345,15 @@ module.exports = class TicketManager {
id: guild.roles.everyone,
},
{
allow: allow,
allow,
id: this.client.user.id,
},
{
allow: allow,
allow,
id: creator.id,
},
...category.staffRoles.map(id => ({
allow: allow,
allow,
id,
})),
],
Expand Down Expand Up @@ -635,6 +636,170 @@ module.exports = class TicketManager {
}
}

/**
* @param {import("discord.js").ChatInputCommandInteraction|import("discord.js").ButtonInteraction} interaction
*/
async claim(interaction) {
const ticket = await this.client.prisma.ticket.findUnique({
include: {
_count: { select: { questionAnswers: true } },
category: true,
guild: true,
},
where: { id: interaction.channel.id },
});
const getMessage = this.client.i18n.getLocale(ticket.guild.locale);

await interaction.channel.permissionOverwrites.edit(interaction.user, { 'ViewChannel': true }, `Ticket claimed by ${interaction.user.tag}`);

for (const role of ticket.category.staffRoles) await interaction.channel.permissionOverwrites.edit(role, { 'ViewChannel': false }, `Ticket claimed by ${interaction.user.tag}`);

await this.client.prisma.ticket.update({
data: {
claimedBy: {
connectOrCreate: {
create: { id: interaction.user.id },
where: { id: interaction.user.id },
},
},
},
where: { id: interaction.channel.id },
});

const openingMessage = await interaction.channel.messages.fetch(ticket.openingMessageId);

if (openingMessage && openingMessage.components.length !== 0) {
const components = new ActionRowBuilder();

if (ticket.topic || ticket._count.questionAnswers !== 0) {
components.addComponents(
new ButtonBuilder()
.setCustomId(JSON.stringify({ action: 'edit' }))
.setStyle(ButtonStyle.Secondary)
.setEmoji(getMessage('buttons.edit.emoji'))
.setLabel(getMessage('buttons.edit.text')),
);
}

if (ticket.guild.claimButton && ticket.category.claiming) {
components.addComponents(
new ButtonBuilder()
.setCustomId(JSON.stringify({ action: 'unclaim' }))
.setStyle(ButtonStyle.Secondary)
.setEmoji(getMessage('buttons.unclaim.emoji'))
.setLabel(getMessage('buttons.unclaim.text')),
);
}

if (ticket.guild.closeButton) {
components.addComponents(
new ButtonBuilder()
.setCustomId(JSON.stringify({ action: 'close' }))
.setStyle(ButtonStyle.Danger)
.setEmoji(getMessage('buttons.close.emoji'))
.setLabel(getMessage('buttons.close.text')),
);
}

await openingMessage.edit({ components: [components] });
}

await interaction.editReply({
embeds: [
new ExtendedEmbedBuilder()
.setColor(ticket.guild.primaryColour)
.setDescription(getMessage('ticket.claimed', { user: interaction.user.toString() })),
],
});

logTicketEvent(this.client, {
action: 'claim',
target: {
id: ticket.id,
name: interaction.channel.toString(),
},
userId: interaction.user.id,
});
}

/**
* @param {import("discord.js").ChatInputCommandInteraction|import("discord.js").ButtonInteraction} interaction
*/
async release(interaction) {
const ticket = await this.client.prisma.ticket.findUnique({
include: {
category: true,
guild: true,
},
where: { id: interaction.channel.id },
});
const getMessage = this.client.i18n.getLocale(ticket.guild.locale);

await interaction.channel.permissionOverwrites.delete(interaction.user, `Ticket released by ${interaction.user.tag}`);

for (const role of ticket.category.staffRoles) await interaction.channel.permissionOverwrites.edit(role, { 'ViewChannel': true }, `Ticket released by ${interaction.user.tag}`);

await this.client.prisma.ticket.update({
data: { claimedBy: { disconnect: true } },
where: { id: interaction.channel.id },
});

const openingMessage = await interaction.channel.messages.fetch(ticket.openingMessageId);

if (openingMessage && openingMessage.components.length !== 0) {
const components = new ActionRowBuilder();

if (ticket.topic || ticket._count.questionAnswers !== 0) {
components.addComponents(
new ButtonBuilder()
.setCustomId(JSON.stringify({ action: 'edit' }))
.setStyle(ButtonStyle.Secondary)
.setEmoji(getMessage('buttons.edit.emoji'))
.setLabel(getMessage('buttons.edit.text')),
);
}

if (ticket.guild.claimButton && ticket.category.claiming) {
components.addComponents(
new ButtonBuilder()
.setCustomId(JSON.stringify({ action: 'claim' }))
.setStyle(ButtonStyle.Secondary)
.setEmoji(getMessage('buttons.claim.emoji'))
.setLabel(getMessage('buttons.claim.text')),
);
}

if (ticket.guild.closeButton) {
components.addComponents(
new ButtonBuilder()
.setCustomId(JSON.stringify({ action: 'close' }))
.setStyle(ButtonStyle.Danger)
.setEmoji(getMessage('buttons.close.emoji'))
.setLabel(getMessage('buttons.close.text')),
);
}

await openingMessage.edit({ components: [components] });
}

await interaction.editReply({
embeds: [
new ExtendedEmbedBuilder()
.setColor(ticket.guild.primaryColour)
.setDescription(getMessage('ticket.released', { user: interaction.user.toString() })),
],
});

logTicketEvent(this.client, {
action: 'unclaim',
target: {
id: ticket.id,
name: interaction.channel.toString(),
},
userId: interaction.user.id,
});
}


/**
* @param {import("discord.js").ChatInputCommandInteraction|import("discord.js").ButtonInteraction} interaction
Expand Down

0 comments on commit 77216ba

Please sign in to comment.