(interaction, client)
| 88 | const createTicketHandler = { |
| 89 | name: 'create_ticket', |
| 90 | async execute(interaction, client) { |
| 91 | try { |
| 92 | if (!(await ensureGuildContext(interaction))) return; |
| 93 | |
| 94 | const rateLimitKey = `${interaction.user.id}:create_ticket`; |
| 95 | const allowed = await checkRateLimit(rateLimitKey, 3, 60000); |
| 96 | if (!allowed) { |
| 97 | await replyUserError(interaction, { type: ErrorTypes.RATE_LIMIT, message: 'You are creating tickets too quickly. Please wait a minute and try again.' }); |
| 98 | return; |
| 99 | } |
| 100 | |
| 101 | const config = await getGuildConfig(client, interaction.guildId); |
| 102 | const maxTicketsPerUser = config.maxTicketsPerUser || 3; |
| 103 | |
| 104 | const { getUserTicketCount } = await import('../services/ticket.js'); |
| 105 | const currentTicketCount = await getUserTicketCount(interaction.guildId, interaction.user.id); |
| 106 | |
| 107 | if (currentTicketCount >= maxTicketsPerUser) { |
| 108 | return await replyUserError(interaction, { type: ErrorTypes.UNKNOWN, message: 'You have reached the maximum number of open tickets (${maxTicketsPerUser}).\n\nPlease close your existing tickets before creating a new one.\n\n**Current Tickets:** ${currentTicketCount}/${maxTicketsPerUser}' }); |
| 109 | } |
| 110 | |
| 111 | const modal = new ModalBuilder() |
| 112 | .setCustomId('create_ticket_modal') |
| 113 | .setTitle('Create a Ticket'); |
| 114 | |
| 115 | const reasonInput = new TextInputBuilder() |
| 116 | .setCustomId('reason') |
| 117 | .setLabel('Why are you creating this ticket?') |
| 118 | .setStyle(TextInputStyle.Paragraph) |
| 119 | .setPlaceholder('Describe your issue...') |
| 120 | .setRequired(true) |
| 121 | .setMaxLength(1000); |
| 122 | |
| 123 | const actionRow = new ActionRowBuilder().addComponents(reasonInput); |
| 124 | modal.addComponents(actionRow); |
| 125 | |
| 126 | await interaction.showModal(modal); |
| 127 | } catch (error) { |
| 128 | logger.error('Error creating ticket modal:', error); |
| 129 | if (!interaction.replied && !interaction.deferred) { |
| 130 | await replyUserError(interaction, { type: ErrorTypes.UNKNOWN, message: 'Could not open ticket creation form.' }); |
| 131 | } |
| 132 | } |
| 133 | } |
| 134 | }; |
| 135 | |
| 136 | const createTicketModalHandler = { |
nothing calls this directly
no test coverage detected