users now cant create more than 3 tickets + ticket now closes and locks

This commit is contained in:
Danya H 2024-06-10 16:46:21 +01:00
parent a4a58f0d83
commit 637c2800d4
2 changed files with 62 additions and 19 deletions

View File

@ -9,8 +9,8 @@ import {
GuildTextThreadCreateOptions,
MessageCreateOptions,
Role,
roleMention,
userMention,
roleMention, ThreadChannel,
userMention
} from 'discord.js'
import { db, DBTableEnum } from '../../db'
@ -124,18 +124,36 @@ export class CreateTicketSystem {
return
}
const ticketRole = await db.get(DBTableEnum.TICKET_ROLE)
// prevent creating ticket for users with 3 or more tickets
const allThreads = await interaction.channel.threads.fetch()
const ownedThreads = allThreads.threads.reduce((total, thread) => {
if (thread.ownerId === interaction.user.id && (!thread.archived || !thread.locked)) total += 1
return total
}, 0)
if (ownedThreads >= 3 && interaction.user.id !== interaction.guild.ownerId) {
logger.action('Denied ticket creation', `User: ${interaction.user.username}(${interaction.user.id})\nActive tickets: ${ownedThreads}`)
await interaction.editReply('❌ You already have too many tickets')
return
}
// create ticket channel
const threadChannelSettings: GuildTextThreadCreateOptions<AllowedThreadTypeForTextChannel> =
{
name: `${interaction.user.username}`,
type: ChannelType.PrivateThread,
invitable: false,
}
const threadChannel = await interaction.channel.threads.create(
threadChannelSettings,
)
const ticketRole = await db.get(DBTableEnum.TICKET_ROLE)
let threadChannel: ThreadChannel<boolean>
try {
// create ticket channel
const threadChannelSettings: GuildTextThreadCreateOptions<AllowedThreadTypeForTextChannel> =
{
name: `${interaction.user.username}-${(new Date).toLocaleDateString().replaceAll('/', '-')}`,
type: ChannelType.PrivateThread,
invitable: false,
}
threadChannel = await interaction.channel.threads.create(
threadChannelSettings,
)
} catch (e) {
logger.error('Create ticket channel', e)
return
}
// welcoming message in ticket
const threadChannelMessage: MessageCreateOptions = {
@ -168,6 +186,8 @@ export class CreateTicketSystem {
await threadChannel.members.add(user)
await threadChannel.members.add(owner)
logger.action('Created ticket', `User: ${user.user.username}(${user.id})\nChannel: ${threadChannel.name}(${threadChannel.id})`)
// close interaction
await interaction.editReply({
embeds: [
@ -182,15 +202,32 @@ export class CreateTicketSystem {
@ButtonComponent({ id: 'close-btn' })
async closeBtn(interaction: ButtonInteraction): Promise<void> {
await interaction.deferReply()
if (!interaction.channel) {
logger.action('Ticket close attempt', `User: ${interaction.user.username}(${interaction.user.id})\nChannel: ${interaction.channel?.id}`)
if (!interaction.channel || !interaction.guild) {
await interaction.editReply('❌ Ticket channel does not exist')
return
}
if (interaction.channel.isThread() && !interaction.channel.archived) {
await interaction.editReply('Closing ticket..')
await interaction.channel.setArchived(true, `Archived by ${userMention(interaction.user.id)}(${interaction.user.id})`)
if (!interaction.channel.isThread() || interaction.channel.archived) {
return
}
await interaction.editReply('❌ Ticket is not a thread')
await interaction.editReply('Closing ticket..')
try {
// remove ticket owner if exists
const ticketOwner = interaction.channel.ownerId ? await interaction.guild.members.fetch(interaction.channel.ownerId) : null
ticketOwner ? await interaction.channel.members.remove(ticketOwner) : null
// lock + archive thread
await interaction.channel.setLocked(true, `Locked by ${userMention(interaction.user.id)}(${interaction.user.id})`)
await interaction.channel.setArchived(true, `Archived by ${userMention(interaction.user.id)}(${interaction.user.id})`)
} catch (e) {
logger.error('Closing ticket', e)
return
}
logger.action('Ticket close attempt successful', `User: ${interaction.user.username}(${interaction.user.id})\nChannel: ${interaction.channel?.id}`)
}
}

View File

@ -1,7 +1,7 @@
import c from 'chalk'
class Logger {
error(msg: string, err: string) {
error(msg: string, err: unknown) {
console.log(c.red.bold('Error: ') + c.red(msg) + '\n' + err + '\n')
}
@ -10,6 +10,12 @@ class Logger {
c.cyan.bold('Entry: ') + c.cyan(field) + '\n' + value + '\n',
)
}
action(msg: string, value: string) {
console.log(
c.blueBright.bold('Action: ') + c.blueBright(msg) + '\n' + value + '\n',
)
}
}
export const logger = new Logger()