From ae72266b82174e7ac0d4d59462ce975d54851f09 Mon Sep 17 00:00:00 2001 From: Isaac Date: Sat, 6 Aug 2022 22:50:28 +0100 Subject: [PATCH] Ticket creation rate limiting + fixes --- src/i18n/en-GB.yml | 3 ++ src/lib/tickets/manager.js | 49 ++++++++++++++----- src/routes/api/admin/guilds/[guild]/panels.js | 7 ++- 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/src/i18n/en-GB.yml b/src/i18n/en-GB.yml index f8eb71d..2836cec 100644 --- a/src/i18n/en-GB.yml +++ b/src/i18n/en-GB.yml @@ -163,6 +163,9 @@ misc: no_categories: description: No ticket categories have been configured. title: ❌ There are no ticket categories + ratelimited: + description: Try again in a few seconds. + title: 🐢 Slow down unknown_category: description: Please try a different category. title: ❌ That ticket category doesn't exist \ No newline at end of file diff --git a/src/lib/tickets/manager.js b/src/lib/tickets/manager.js index 4431fd0..ea1600f 100644 --- a/src/lib/tickets/manager.js +++ b/src/lib/tickets/manager.js @@ -27,7 +27,6 @@ module.exports = class TicketManager { }) { const cacheKey = `cache/category+guild+questions:${categoryId}`; let category = await this.client.keyv.get(cacheKey); - if (!category) { category = await this.client.prisma.category.findUnique({ include: { @@ -47,19 +46,47 @@ module.exports = class TicketManager { }; } const getMessage = this.client.i18n.getLocale(settings.locale); + const embed = new EmbedBuilder() + .setColor(settings.errorColour) + .setTitle(getMessage('misc.unknown_category.title')) + .setDescription(getMessage('misc.unknown_category.description')); + if (settings.footer) { + embed.setFooter({ + iconURL: interaction.guild?.iconURL(), + text: settings.footer, + }); + } return await interaction.reply({ - embeds: [ - new EmbedBuilder() - .setColor(settings.errorColour) - .setTitle(getMessage('misc.unknown_category.title')) - .setDescription(getMessage('misc.unknown_category.description')) - .setFooter(settings.footer), - ], + embeds: [embed], + ephemeral: true, }); } this.client.keyv.set(cacheKey, category, ms('5m')); } + const getMessage = this.client.i18n.getLocale(category.guild.locale); + + const rlKey = `ratelimits/guild-user:${interaction.guild.id}-${interaction.user.id}`; + const rl = await this.client.keyv.get(rlKey); + if (rl) { + const embed = new EmbedBuilder() + .setColor(category.guild.errorColour) + .setTitle(getMessage('misc.ratelimited.title')) + .setDescription(getMessage('misc.ratelimited.description')); + if (category.guild.footer) { + embed.setFooter({ + iconURL: interaction.guild.iconURL(), + text: category.guild.footer, + }); + } + return await interaction.reply({ + embeds: [embed], + ephemeral: true, + }); + } else { + this.client.keyv.set(rlKey, true, ms('10s')); + } + // TODO: if member !required roles -> stop // TODO: if discordCategory has 50 channels -> stop @@ -70,11 +97,6 @@ module.exports = class TicketManager { // TODO: if cooldown -> stop - // TODO: if 10s ratelimit -> stop - - - const getMessage = this.client.i18n.getLocale(category.guild.locale); - if (category.questions.length >= 1) { await interaction.showModal( new ModalBuilder() @@ -86,6 +108,7 @@ module.exports = class TicketManager { .setTitle(category.name) .setComponents( category.questions + .filter(q => q.type === 'TEXT') // TODO: remove this when modals support select menus .sort((a, b) => a.order - b.order) .map(q => { if (q.type === 'TEXT') { diff --git a/src/routes/api/admin/guilds/[guild]/panels.js b/src/routes/api/admin/guilds/[guild]/panels.js index c1d928a..e60c02b 100644 --- a/src/routes/api/admin/guilds/[guild]/panels.js +++ b/src/routes/api/admin/guilds/[guild]/panels.js @@ -58,11 +58,14 @@ module.exports.post = fastify => ({ const embed = new EmbedBuilder() .setColor(settings.primaryColour) - .setTitle(data.title) - .setFooter({ + .setTitle(data.title); + + if (settings.footer) { + embed.setFooter({ iconURL: guild.iconURL(), text: settings.footer, }); + } if (data.description) embed.setDescription(data.description); if (data.image) embed.setImage(data.image);