This repository has been archived by the owner on Sep 3, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat!: Extracted handling of interactions into separate files
- Loading branch information
1 parent
8e9cb30
commit 780e20d
Showing
7 changed files
with
166 additions
and
153 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { AutocompleteInteraction } from 'discord.js'; | ||
import loggerModule from '../services/logger'; | ||
|
||
const logger = loggerModule.child({ | ||
source: 'interactionCutocompleteHandler.ts', | ||
module: 'handler', | ||
name: 'interactionAutocompleteHandler' | ||
}); | ||
|
||
export const handleAutocomplete = async (interaction: AutocompleteInteraction, executionId: string) => { | ||
const autocompleteModule = await import(`../interactions/autocomplete/${interaction.commandName}.js`); | ||
const { default: autocomplete } = autocompleteModule; | ||
|
||
logger.debug('Executing autocomplete interaction.'); | ||
await autocomplete.execute({ interaction, executionId }); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { ChatInputCommandInteraction } from 'discord.js'; | ||
import { Command, ExtendedClient } from '../types/clientTypes'; | ||
import { cannotSendMessageInChannel } from '../utils/validation/permissionValidator'; | ||
import loggerModule from '../services/logger'; | ||
|
||
const logger = loggerModule.child({ | ||
source: 'interactionCommandHandler.ts', | ||
module: 'handler', | ||
name: 'interactionCommandHandler' | ||
}); | ||
|
||
export const handleCommand = async ( | ||
interaction: ChatInputCommandInteraction, | ||
client: ExtendedClient, | ||
executionId: string | ||
) => { | ||
await interaction.deferReply(); | ||
logger.debug('Interaction deferred.'); | ||
|
||
const command = client.commands?.get(interaction.commandName) as Command; | ||
if (!command) { | ||
logger.warn(`Interaction created but command '${interaction.commandName}' was not found.`); | ||
return; | ||
} | ||
|
||
if (await cannotSendMessageInChannel({ interaction, executionId })) { | ||
return Promise.resolve(); | ||
} | ||
|
||
logger.debug('Executing command interaction.'); | ||
await command.execute({ interaction, client, executionId }); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { MessageComponentInteraction } from 'discord.js'; | ||
import loggerModule from '../services/logger'; | ||
|
||
const logger = loggerModule.child({ | ||
source: 'interactionComponentHandler.js', | ||
module: 'handler', | ||
name: 'interactionComponentHandler' | ||
}); | ||
|
||
export const handleComponent = async (interaction: MessageComponentInteraction, executionId: string) => { | ||
await interaction.deferReply(); | ||
logger.debug('Interaction deferred.'); | ||
|
||
const componentId = interaction.customId.split('_')[0]; | ||
const referenceId = interaction.customId.split('_')[1]; | ||
|
||
logger.debug(`Parsed componentId: ${componentId}`); | ||
|
||
const componentModule = await import(`../interactions/components/${componentId}.js`); | ||
const { default: component } = componentModule; | ||
|
||
logger.debug('Executing component interaction.'); | ||
await component.execute({ interaction, referenceId, executionId }); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import config from 'config'; | ||
import { ChatInputCommandInteraction, EmbedBuilder, Interaction, MessageComponentInteraction } from 'discord.js'; | ||
import { BotOptions, EmbedOptions } from '../types/configTypes'; | ||
import loggerModule from '../services/logger'; | ||
import { CustomError } from '../types/interactionTypes'; | ||
|
||
const embedOptions: EmbedOptions = config.get('embedOptions'); | ||
const botOptions: BotOptions = config.get('botOptions'); | ||
|
||
const logger = loggerModule.child({ | ||
source: 'interactionErrorHandler.ts', | ||
module: 'handler', | ||
name: 'interactionErrorHandler' | ||
}); | ||
|
||
export const handleError = async ( | ||
interaction: Interaction, | ||
error: CustomError, | ||
interactionIdentifier: string, | ||
executionId: string | ||
) => { | ||
const errorReply = { | ||
embeds: [ | ||
new EmbedBuilder() | ||
.setDescription( | ||
`**${embedOptions.icons.error} Uh-oh... _Something_ went wrong!**\nThere was an unexpected error while trying to perform this action. You can try again.\n\n_If this problem persists, please submit a bug report in the **[support server](${botOptions.serverInviteUrl})**._` | ||
) | ||
.setColor(embedOptions.colors.error) | ||
.setFooter({ text: `Execution ID: ${executionId}` }) | ||
] | ||
}; | ||
|
||
logger.error(error, `Error handling interaction '${interactionIdentifier}'`); | ||
|
||
if (interaction instanceof ChatInputCommandInteraction && interaction.deferred) { | ||
switch (interaction.replied) { | ||
case true: | ||
logger.warn(error, `Interaction '${interaction.id}' threw an error but has already been replied to.`); | ||
return; | ||
case false: | ||
logger.debug('Responding with error embed'); | ||
return await interaction.editReply(errorReply); | ||
} | ||
} else if (interaction instanceof MessageComponentInteraction && interaction.deferred) { | ||
switch (interaction.replied) { | ||
case true: | ||
logger.warn(error, `Interaction '${interaction.id}' threw an error but has already been replied to.`); | ||
return; | ||
case false: | ||
logger.debug('Responding with error embed'); | ||
return await interaction.editReply(errorReply); | ||
} | ||
} else { | ||
logger.warn( | ||
'Interaction threw an error but was not deferred or replied to, or was an autocomplete interaction. Cannot send error reply.' | ||
); | ||
|
||
if ( | ||
error.code === 'InteractionCollectorError' || | ||
error.message === 'Collector received no interactions before ending with reason: time' | ||
) { | ||
logger.debug('Interaction response timed out.'); | ||
return; | ||
} | ||
|
||
logger.fatal(error, 'Unhandled error while awaiting or handling component interaction.'); | ||
return; | ||
} | ||
}; |
Oops, something went wrong.