From 7eee44a71b127068ae93c717a1fdde0015c96182 Mon Sep 17 00:00:00 2001 From: chandler05 <66492208+chandler05@users.noreply.github.com> Date: Fri, 9 Jul 2021 23:56:34 -0500 Subject: [PATCH 1/6] Reject exact duplicate requests --- config/default.yml | 1 + src/BotConfig.ts | 2 ++ src/events/request/RequestEventHandler.ts | 26 ++++++++++++++++++++++- src/util/RequestsUtil.ts | 12 ++++++++++- 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/config/default.yml b/config/default.yml index 27241077..ac0b7721 100644 --- a/config/default.yml +++ b/config/default.yml @@ -28,6 +28,7 @@ projects: request: invalidTicketEmoji: ⏸ noLinkEmoji: ⛔ + duplicateRequestEmoji: '🔁' warningLifetime: 5000 waitingEmoji: ⌛ diff --git a/src/BotConfig.ts b/src/BotConfig.ts index 83f01337..249e4327 100644 --- a/src/BotConfig.ts +++ b/src/BotConfig.ts @@ -23,6 +23,7 @@ export class RequestConfig { public invalidTicketEmoji: string; public noLinkEmoji: string; + public duplicateRequestEmoji: string; public warningLifetime: number; public invalidRequestJql: string; public waitingEmoji: string; @@ -48,6 +49,7 @@ export class RequestConfig { this.invalidTicketEmoji = config.get( 'request.invalidTicketEmoji' ); this.noLinkEmoji = config.get( 'request.noLinkEmoji' ); + this.duplicateRequestEmoji = config.get( 'duplicateRequestEmoji' ); this.warningLifetime = config.get( 'request.warningLifetime' ); this.invalidRequestJql = config.get( 'request.invalidRequestJql' ); this.waitingEmoji = config.get( 'request.waitingEmoji' ); diff --git a/src/events/request/RequestEventHandler.ts b/src/events/request/RequestEventHandler.ts index a3ce70d2..2ed7052e 100644 --- a/src/events/request/RequestEventHandler.ts +++ b/src/events/request/RequestEventHandler.ts @@ -64,7 +64,7 @@ export default class RequestEventHandler implements EventHandler<'message'> { return; } - if ( BotConfig.request.invalidRequestJql ) { + if ( BotConfig.request.invalidTicketEmoji && BotConfig.request.invalidRequestJql ) { if ( !await RequestsUtil.checkTicketValidity( tickets ) ) { try { await origin.react( BotConfig.request.invalidTicketEmoji ); @@ -88,6 +88,30 @@ export default class RequestEventHandler implements EventHandler<'message'> { const internalChannelId = this.internalChannels.get( origin.channel.id ); const internalChannel = await DiscordUtil.getChannel( internalChannelId ); + if ( BotConfig.request.duplicateRequestEmoji ) { + const match = RequestsUtil.findExactMatchInPendingRequests( origin, internalChannel ); + + if ( match != origin ) { + const parent = await RequestsUtil.getOriginMessage( match ); + + try { + await origin.react( BotConfig.request.duplicateRequestEmoji ); + } catch ( error ) { + this.logger.error( error ); + } + + try { + const warning = await origin.channel.send( `${ origin.author }, your request (<${ origin.url }>) has already been requested at <${ parent.url }>.` ); + + const timeout = BotConfig.request.warningLifetime; + await warning.delete( { timeout } ); + } catch ( error ) { + this.logger.error( error ); + } + return; + } + } + if ( requestLimit && requestLimit >= 0 && internalChannel instanceof TextChannel ) { const internalChannelUserMessages = internalChannel.messages.cache .filter( message => message.embeds.length > 0 && message.embeds[0].author.name == origin.author.tag ) diff --git a/src/util/RequestsUtil.ts b/src/util/RequestsUtil.ts index fbf94808..042a95a6 100644 --- a/src/util/RequestsUtil.ts +++ b/src/util/RequestsUtil.ts @@ -1,4 +1,4 @@ -import { EmbedField, Message, TextChannel, User } from 'discord.js'; +import { Channel, EmbedField, Message, TextChannel, User } from 'discord.js'; import * as log4js from 'log4js'; import BotConfig from '../BotConfig'; import DiscordUtil from './DiscordUtil'; @@ -145,4 +145,14 @@ export class RequestsUtil { return content.replace( /([[\]\\])/gm, '\\$1' ) .replace( regex, '[$$](https://bugs.mojang.com/browse/$$$)' ); } + + public static findExactMatchInPendingRequests( origin: Message, internalChannel: Channel ): Message { + const matcher = this.replaceTicketReferencesWithRichLinks( origin.content ); + if ( internalChannel instanceof TextChannel ) { + const matches = internalChannel.messages.cache.filter( message => message.embeds[0].description == matcher ); + return matches.size > 0 ? matches[0] : origin; + } else { + return origin; + } + } } From ea3bc34daacb28640699d9e133cacc485ab39a44 Mon Sep 17 00:00:00 2001 From: chandler05 <66492208+chandler05@users.noreply.github.com> Date: Sat, 10 Jul 2021 00:14:28 -0500 Subject: [PATCH 2/6] Fix a few issues --- config/default.yml | 4 ++-- src/BotConfig.ts | 2 +- src/util/RequestsUtil.ts | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/config/default.yml b/config/default.yml index ac0b7721..01d68c5e 100644 --- a/config/default.yml +++ b/config/default.yml @@ -28,8 +28,8 @@ projects: request: invalidTicketEmoji: ⏸ noLinkEmoji: ⛔ - duplicateRequestEmoji: '🔁' - warningLifetime: 5000 + duplicateRequestEmoji: 🔁 + warningLifetime: 7500 waitingEmoji: ⌛ invalidRequestJql: created > -24h diff --git a/src/BotConfig.ts b/src/BotConfig.ts index 249e4327..f23e6860 100644 --- a/src/BotConfig.ts +++ b/src/BotConfig.ts @@ -49,7 +49,7 @@ export class RequestConfig { this.invalidTicketEmoji = config.get( 'request.invalidTicketEmoji' ); this.noLinkEmoji = config.get( 'request.noLinkEmoji' ); - this.duplicateRequestEmoji = config.get( 'duplicateRequestEmoji' ); + this.duplicateRequestEmoji = config.get( 'request.duplicateRequestEmoji' ); this.warningLifetime = config.get( 'request.warningLifetime' ); this.invalidRequestJql = config.get( 'request.invalidRequestJql' ); this.waitingEmoji = config.get( 'request.waitingEmoji' ); diff --git a/src/util/RequestsUtil.ts b/src/util/RequestsUtil.ts index 042a95a6..f78f0ec7 100644 --- a/src/util/RequestsUtil.ts +++ b/src/util/RequestsUtil.ts @@ -149,8 +149,8 @@ export class RequestsUtil { public static findExactMatchInPendingRequests( origin: Message, internalChannel: Channel ): Message { const matcher = this.replaceTicketReferencesWithRichLinks( origin.content ); if ( internalChannel instanceof TextChannel ) { - const matches = internalChannel.messages.cache.filter( message => message.embeds[0].description == matcher ); - return matches.size > 0 ? matches[0] : origin; + const matches = internalChannel.messages.cache.filter( message => message.embeds.length > 0 && message.embeds[0].description == matcher); + return matches.size > 0 ? matches.first() : origin; } else { return origin; } From a873a15fa8d014a60c687254f322667cfd05986a Mon Sep 17 00:00:00 2001 From: chandler05 <66492208+chandler05@users.noreply.github.com> Date: Sat, 10 Jul 2021 00:16:35 -0500 Subject: [PATCH 3/6] Add space --- src/util/RequestsUtil.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/RequestsUtil.ts b/src/util/RequestsUtil.ts index f78f0ec7..c2bcbb50 100644 --- a/src/util/RequestsUtil.ts +++ b/src/util/RequestsUtil.ts @@ -149,7 +149,7 @@ export class RequestsUtil { public static findExactMatchInPendingRequests( origin: Message, internalChannel: Channel ): Message { const matcher = this.replaceTicketReferencesWithRichLinks( origin.content ); if ( internalChannel instanceof TextChannel ) { - const matches = internalChannel.messages.cache.filter( message => message.embeds.length > 0 && message.embeds[0].description == matcher); + const matches = internalChannel.messages.cache.filter( message => message.embeds.length > 0 && message.embeds[0].description == matcher ); return matches.size > 0 ? matches.first() : origin; } else { return origin; From f2dc863a1500d02428be9596ae95186372825481 Mon Sep 17 00:00:00 2001 From: chandler05 <66492208+chandler05@users.noreply.github.com> Date: Tue, 21 Sep 2021 13:44:31 -0500 Subject: [PATCH 4/6] Update RequestEventHandler.ts --- src/events/request/RequestEventHandler.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/events/request/RequestEventHandler.ts b/src/events/request/RequestEventHandler.ts index ee598e76..340a6294 100644 --- a/src/events/request/RequestEventHandler.ts +++ b/src/events/request/RequestEventHandler.ts @@ -98,9 +98,7 @@ export default class RequestEventHandler implements EventHandler<'message'> { try { const warning = await origin.channel.send( `${ origin.author }, your request (<${ origin.url }>) has already been requested at <${ parent.url }>.` ); - - const timeout = BotConfig.request.warningLifetime; - await warning.delete( { timeout } ); + await DiscordUtil.deleteWithDelay( warning, BotConfig.request.warningLifetime ); } catch ( error ) { this.logger.error( error ); } From 3420965773ce7f19e23dd6c6f55be90ac777a9e6 Mon Sep 17 00:00:00 2001 From: chandler05 <66492208+chandler05@users.noreply.github.com> Date: Tue, 21 Sep 2021 13:47:05 -0500 Subject: [PATCH 5/6] Update RequestsUtil.ts --- src/util/RequestsUtil.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util/RequestsUtil.ts b/src/util/RequestsUtil.ts index ba519c4a..8c02ec1a 100644 --- a/src/util/RequestsUtil.ts +++ b/src/util/RequestsUtil.ts @@ -1,4 +1,4 @@ -import { EmbedField, Message, PartialMessage, Snowflake, TextChannel, User } from 'discord.js'; +import { EmbedField, Message, PartialMessage, Snowflake, TextChannel, User, TextBasedChannels } from 'discord.js'; import * as log4js from 'log4js'; import BotConfig from '../BotConfig'; import DiscordUtil from './DiscordUtil'; @@ -146,7 +146,7 @@ export class RequestsUtil { .replace( regex, '[$$](https://bugs.mojang.com/browse/$$$)' ); } - public static findExactMatchInPendingRequests( origin: Message, internalChannel: Channel ): Message { + public static findExactMatchInPendingRequests( origin: Message, internalChannel: TextBasedChannels ): Message { const matcher = this.replaceTicketReferencesWithRichLinks( origin.content ); if ( internalChannel instanceof TextChannel ) { const matches = internalChannel.messages.cache.filter( message => message.embeds.length > 0 && message.embeds[0].description == matcher ); From 42ca31b929e898da137d5e0b5ca768789cd0d7c0 Mon Sep 17 00:00:00 2001 From: chandler05 <66492208+chandler05@users.noreply.github.com> Date: Tue, 21 Sep 2021 13:52:25 -0500 Subject: [PATCH 6/6] Update RequestEventHandler.ts --- src/events/request/RequestEventHandler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/events/request/RequestEventHandler.ts b/src/events/request/RequestEventHandler.ts index 340a6294..8c27680e 100644 --- a/src/events/request/RequestEventHandler.ts +++ b/src/events/request/RequestEventHandler.ts @@ -84,7 +84,7 @@ export default class RequestEventHandler implements EventHandler<'message'> { const internalChannelId = this.internalChannels.get( origin.channel.id ); const internalChannel = await DiscordUtil.getChannel( internalChannelId ); - if ( BotConfig.request.duplicateRequestEmoji ) { + if ( BotConfig.request.duplicateRequestEmoji && internalChannel instanceof TextChannel ) { const match = RequestsUtil.findExactMatchInPendingRequests( origin, internalChannel ); if ( match != origin ) {