diff --git a/src/commands/info/help.ts b/src/commands/info/help.ts index 327c1a4b..2334f456 100644 --- a/src/commands/info/help.ts +++ b/src/commands/info/help.ts @@ -1,7 +1,7 @@ import config from 'config'; import { EmbedOptions } from '../../types/configTypes'; const embedOptions: EmbedOptions = config.get('embedOptions'); -const botOptions = config.get('botOptions'); +const botOptions: BotOptions = config.get('botOptions'); import { SlashCommandBuilder, EmbedBuilder } from 'discord.js'; import loggerModule from '../../services/logger'; diff --git a/src/commands/player/filters.ts b/src/commands/player/filters.ts index 9047e09f..ea981cf6 100644 --- a/src/commands/player/filters.ts +++ b/src/commands/player/filters.ts @@ -1,7 +1,7 @@ import config from 'config'; import { EmbedOptions } from '../../types/configTypes'; const embedOptions: EmbedOptions = config.get('embedOptions'); -const ffmpegFilterOptions = config.get('ffmpegFilterOptions'); +const ffmpegFilterOptions: FFmpegFilterOptions = config.get('ffmpegFilterOptions'); import { notInVoiceChannel, notInSameVoiceChannel } from '../../utils/validation/voiceChannelValidator'; import { queueDoesNotExist, queueNoCurrentTrack } from '../../utils/validation/queueValidator'; import { diff --git a/src/commands/player/loop.ts b/src/commands/player/loop.ts index 4dce11fe..181eec5e 100644 --- a/src/commands/player/loop.ts +++ b/src/commands/player/loop.ts @@ -1,7 +1,7 @@ import config from 'config'; import { EmbedOptions } from '../../types/configTypes'; const embedOptions: EmbedOptions = config.get('embedOptions'); -const botOptions = config.get('botOptions'); +const botOptions: BotOptions = config.get('botOptions'); import { notInVoiceChannel, notInSameVoiceChannel } from '../../utils/validation/voiceChannelValidator'; import { queueDoesNotExist } from '../../utils/validation/queueValidator'; import{ SlashCommandBuilder, EmbedBuilder } from 'discord.js'; diff --git a/src/commands/player/nowplaying.ts b/src/commands/player/nowplaying.ts index d73beee4..9a2923de 100644 --- a/src/commands/player/nowplaying.ts +++ b/src/commands/player/nowplaying.ts @@ -1,7 +1,7 @@ import config from 'config'; import { EmbedOptions } from '../../types/configTypes'; const embedOptions: EmbedOptions = config.get('embedOptions'); -const playerOptions = config.get('playerOptions'); +const playerOptions: PlayerOptions = config.get('playerOptions'); import { notInVoiceChannel, notInSameVoiceChannel } from '../../utils/validation/voiceChannelValidator'; import { queueDoesNotExist, queueNoCurrentTrack } from '../../utils/validation/queueValidator'; import { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder } from 'discord.js'; diff --git a/src/commands/player/play.ts b/src/commands/player/play.ts index 47d08f99..74180af4 100644 --- a/src/commands/player/play.ts +++ b/src/commands/player/play.ts @@ -1,7 +1,7 @@ import config from 'config'; const embedOptions: EmbedOptions = config.get('embedOptions'); -const botOptions = config.get('botOptions'); -const playerOptions = config.get('playerOptions'); +const botOptions: BotOptions = config.get('botOptions'); +const playerOptions: PlayerOptions = config.get('playerOptions'); import { notInVoiceChannel, notInSameVoiceChannel } from '../../utils/validation/voiceChannelValidator'; import { cannotJoinVoiceOrTalk } from '../../utils/validation/permissionValidator'; import { transformQuery } from '../../utils/validation/searchQueryValidator'; diff --git a/src/commands/player/queue.ts b/src/commands/player/queue.ts index 83da8308..dd570a96 100644 --- a/src/commands/player/queue.ts +++ b/src/commands/player/queue.ts @@ -1,7 +1,7 @@ import config from 'config'; import { EmbedOptions } from '../../types/configTypes'; const embedOptions: EmbedOptions = config.get('embedOptions'); -const playerOptions = config.get('playerOptions'); +const playerOptions: PlayerOptions = config.get('playerOptions'); import { notInVoiceChannel, notInSameVoiceChannel } from '../../utils/validation/voiceChannelValidator'; import{ SlashCommandBuilder, EmbedBuilder } from 'discord.js'; import { useQueue } from 'discord-player'; diff --git a/src/events/client/debug.ts b/src/events/client/debug.ts index 34a80d91..d3afd14b 100644 --- a/src/events/client/debug.ts +++ b/src/events/client/debug.ts @@ -6,7 +6,7 @@ module.exports = { name: Events.Debug, isDebug: true, once: false, - execute: async (message) => { + execute: async (message: string) => { const executionId = uuidv4(); const logger = loggerModule.child({ source: 'debug.js', diff --git a/src/events/client/disconnect.ts b/src/events/client/disconnect.ts index ffb9e4b3..d125b2e0 100644 --- a/src/events/client/disconnect.ts +++ b/src/events/client/disconnect.ts @@ -1,36 +1,39 @@ import { v4 as uuidv4 } from 'uuid'; import config from 'config'; -import { EmbedOptions } from '../../types/configTypes'; +import { EmbedOptions, SystemOptions } from '../../types/configTypes'; const embedOptions: EmbedOptions = config.get('embedOptions'); -const systemOptions = config.get('systemOptions'); -import { EmbedBuilder } from 'discord.js'; +const systemOptions: SystemOptions = config.get('systemOptions'); +import { BaseGuildTextChannel, EmbedBuilder } from 'discord.js'; import loggerModule from '../../services/logger'; +import { ExtendedClient } from '../../types/clientTypes'; module.exports = { name: 'disconnect', isDebug: false, once: false, - execute: async (client) => { + execute: async (client: ExtendedClient) => { const executionId = uuidv4(); const logger = loggerModule.child({ source: 'disconnect.js', module: 'event', name: 'clientDisconnect', executionId: executionId, - shardId: client.shard.ids[0] + shardId: client.shard?.ids[0] }); - logger.warn(`${client.user.tag} lost connection to Discord APIs. Disconnected.`); + logger.warn(`${client.user?.tag} lost connection to Discord APIs. Disconnected.`); // send message to system message channel for event if (systemOptions.systemMessageChannelId && systemOptions.systemUserId) { - const channel = await client.channels.cache.get(systemOptions.systemMessageChannelId); + const channel = (await client.channels.cache.get( + systemOptions.systemMessageChannelId + )) as BaseGuildTextChannel; if (channel) { await channel.send({ embeds: [ new EmbedBuilder() .setDescription( - `${embedOptions.icons.warning} **${client.user.tag}** is **\`disconnected\`**!` + + `${embedOptions.icons.warning} **${client.user?.tag}** is **\`disconnected\`**!` + `\n\n<@${systemOptions.systemUserId}>` ) .setColor(embedOptions.colors.warning) diff --git a/src/events/client/error.ts b/src/events/client/error.ts index cf1bfc18..bbf97f46 100644 --- a/src/events/client/error.ts +++ b/src/events/client/error.ts @@ -6,7 +6,7 @@ module.exports = { name: Events.Error, isDebug: false, once: false, - execute: async (error) => { + execute: async (error: Error) => { const executionId = uuidv4(); const logger = loggerModule.child({ source: 'error.js', diff --git a/src/events/client/guildCreate.ts b/src/events/client/guildCreate.ts index 4e3c9c37..14d28367 100644 --- a/src/events/client/guildCreate.ts +++ b/src/events/client/guildCreate.ts @@ -1,4 +1,4 @@ -import { Events } from 'discord.js'; +import { Events, Guild } from 'discord.js'; import { v4 as uuidv4 } from 'uuid'; import loggerModule from '../../services/logger'; @@ -6,7 +6,7 @@ module.exports = { name: Events.GuildCreate, isDebug: false, once: false, - execute: async (guild) => { + execute: async (guild: Guild) => { const executionId = uuidv4(); const logger = loggerModule.child({ source: 'guildCreate.js', diff --git a/src/events/client/guildDelete.ts b/src/events/client/guildDelete.ts index faf6b9ad..c380f255 100644 --- a/src/events/client/guildDelete.ts +++ b/src/events/client/guildDelete.ts @@ -1,4 +1,4 @@ -import { Events } from 'discord.js'; +import { Events, Guild } from 'discord.js'; import { v4 as uuidv4 } from 'uuid'; import loggerModule from '../../services/logger'; @@ -6,7 +6,7 @@ module.exports = { name: Events.GuildDelete, isDebug: false, once: false, - execute: async (guild) => { + execute: async (guild: Guild) => { const executionId = uuidv4(); const logger = loggerModule.child({ source: 'guildDelete.js', diff --git a/src/events/client/ready.ts b/src/events/client/ready.ts index a2c59982..76c17e75 100644 --- a/src/events/client/ready.ts +++ b/src/events/client/ready.ts @@ -1,42 +1,43 @@ import config from 'config'; -import { EmbedOptions } from '../../types/configTypes'; +import { EmbedOptions, LoadTestOptions, SystemOptions } from '../../types/configTypes'; const embedOptions: EmbedOptions = config.get('embedOptions'); -const systemOptions = config.get('systemOptions'); -const presenceStatusOptions = config.get('presenceStatusOptions'); -const loadTestOptions = config.get('loadTestOptions'); +const systemOptions: SystemOptions = config.get('systemOptions'); +const presenceStatusOptions: PresenceData = config.get('presenceStatusOptions'); +const loadTestOptions: LoadTestOptions = config.get('loadTestOptions'); import { postBotStats } from '../../utils/other/postBotStats'; import { startLoadTest } from '../../utils/other/startLoadTest'; -import { Events, EmbedBuilder } from 'discord.js'; +import { Events, EmbedBuilder, PresenceData, BaseGuildTextChannel } from 'discord.js'; import { v4 as uuidv4 } from 'uuid'; import loggerModule from '../../services/logger'; +import { ExtendedClient } from '../../types/clientTypes'; module.exports = { name: Events.ClientReady, isDebug: false, once: false, - execute: async (client) => { + execute: async (client: ExtendedClient) => { const executionId = uuidv4(); const logger = loggerModule.child({ source: 'ready.js', module: 'event', name: 'clientReady', executionId: executionId, - shardId: client.shard.ids[0] + shardId: client.shard?.ids[0] }); - logger.debug('Client \'ready\' event received after \'allShardsReady\' event.'); - await client.user.setPresence(presenceStatusOptions); + logger.debug("Client 'ready' event received after 'allShardsReady' event."); + await client.user?.setPresence(presenceStatusOptions); if (loadTestOptions.enabled) { // Only call function from shard with id 0 // The function uses broadcastEval() to call itself on all shards - if (client.shard.ids[0] === 0) { + if (client.shard?.ids[0] === 0) { logger.info('Initiating load test for bot client.'); await startLoadTest({ client, executionId }); } } - const channel = await client.channels.cache.get(systemOptions.systemMessageChannelId); + const channel = (await client.channels.cache.get(systemOptions.systemMessageChannelId)) as BaseGuildTextChannel; // Check if the channel exists in curent shard and send a message if (channel) { @@ -45,7 +46,7 @@ module.exports = { embeds: [ new EmbedBuilder() .setDescription( - `**${embedOptions.icons.success} All shards ready**\n**${client.user.tag}** is now **\`online\`**!` + `**${embedOptions.icons.success} All shards ready**\n**${client.user?.tag}** is now **\`online\`**!` ) .setColor(embedOptions.colors.success) ] diff --git a/src/events/client/reconnecting.ts b/src/events/client/reconnecting.ts index 1ec97975..3c7d7985 100644 --- a/src/events/client/reconnecting.ts +++ b/src/events/client/reconnecting.ts @@ -1,23 +1,24 @@ import { v4 as uuidv4 } from 'uuid'; import config from 'config'; -import { EmbedOptions } from '../../types/configTypes'; +import { EmbedOptions, SystemOptions } from '../../types/configTypes'; const embedOptions: EmbedOptions = config.get('embedOptions'); -const systemOptions = config.get('systemOptions'); -import { EmbedBuilder } from 'discord.js'; +const systemOptions: SystemOptions = config.get('systemOptions'); +import { BaseGuildTextChannel, EmbedBuilder } from 'discord.js'; import loggerModule from '../../services/logger'; +import { ExtendedClient } from '../../types/clientTypes'; module.exports = { name: 'reconnecting', isDebug: false, once: false, - execute: async (client) => { + execute: async (client: ExtendedClient) => { const executionId = uuidv4(); const logger = loggerModule.child({ source: 'reconnecting.js', module: 'event', name: 'clientReconnecting', executionId: executionId, - shardId: client.shard.ids[0] + shardId: client.shard?.ids[0] }); logger.warn('Client is reconnecting to Discord APIs.'); @@ -25,13 +26,15 @@ module.exports = { // send message to system message channel for event if (systemOptions.systemMessageChannelId && systemOptions.systemUserId) { if (systemOptions.systemMessageChannelId && systemOptions.systemUserId) { - const channel = await client.channels.cache.get(systemOptions.systemMessageChannelId); + const channel = (await client.channels.cache.get( + systemOptions.systemMessageChannelId + )) as BaseGuildTextChannel; if (channel) { await channel.send({ embeds: [ new EmbedBuilder() .setDescription( - `${embedOptions.icons.warning} **${client.user.tag}** is **\`reconnecting\`**!` + + `${embedOptions.icons.warning} **${client.user?.tag}** is **\`reconnecting\`**!` + `\n\n<@${systemOptions.systemUserId}>` ) .setColor(embedOptions.colors.warning) diff --git a/src/events/client/warn.ts b/src/events/client/warn.ts index 0390cb6e..64fc42d5 100644 --- a/src/events/client/warn.ts +++ b/src/events/client/warn.ts @@ -6,7 +6,7 @@ module.exports = { name: Events.Warn, isDebug: false, once: false, - execute: async (warning) => { + execute: async (warning: string) => { const executionId = uuidv4(); const logger = loggerModule.child({ source: 'warn.js', diff --git a/src/events/interactions/interactionCreate.ts b/src/events/interactions/interactionCreate.ts index cb282bb3..1327c79e 100644 --- a/src/events/interactions/interactionCreate.ts +++ b/src/events/interactions/interactionCreate.ts @@ -1,125 +1,143 @@ import config from 'config'; -import { EmbedOptions } from '../../types/configTypes'; +import { BotOptions, EmbedOptions } from '../../types/configTypes'; const embedOptions: EmbedOptions = config.get('embedOptions'); -const botOptions = config.get('botOptions'); +const botOptions: BotOptions = config.get('botOptions'); import { cannotSendMessageInChannel } from '../../utils/validation/permissionValidator'; -import { Events, EmbedBuilder } from 'discord.js'; +import { Events, EmbedBuilder, Interaction, StringSelectMenuInteraction } from 'discord.js'; import { v4 as uuidv4 } from 'uuid'; import loggerModule from '../../services/logger'; +import { ExtendedClient, Command } from '../../types/clientTypes'; module.exports = { name: Events.InteractionCreate, isDebug: false, - execute: async (interaction, { client }) => { + execute: async (interaction: Interaction, { client }: { client: ExtendedClient }) => { const executionId = uuidv4(); const logger = loggerModule.child({ source: 'interactionCreate.js', module: 'event', name: 'interactionCreate', executionId: executionId, - shardId: interaction.guild.shardId, - guildId: interaction.guild.id + shardId: interaction.guild?.shardId, + guildId: interaction.guild?.id }); if (interaction.isMessageComponent()) { - logger.debug( - `Message component interaction created for id ${interaction.customId}${ - interaction.values ? ' and values ' + interaction.values : '' - }.` - ); - return; - } + if (interaction instanceof StringSelectMenuInteraction) { + logger.debug( + `Message component interaction created for id ${interaction.customId}${ + interaction.values ? ' and values ' + interaction.values : '' + }.` + ); + } - const command = client.commands.get(interaction.commandName); - if (!command) { - logger.warn(`Interaction created but command '${interaction.commandName}' was not found.`); return; } - if (interaction.isAutocomplete()) { - logger.debug('Autocomplete interaction created.'); - try { - await command.autocomplete({ interaction, executionId }); - } catch (error) { - if ( - error.message === 'Unknown interaction' || - error.message === 'Interaction has already been acknowledged.' - ) { - logger.debug( - 'Autocomplete failed to be responded to, unknown interaction or already acknowledged.' - ); - return; - } else { - logger.warn(error, 'Autocomplete failed to execute.'); - } - return; - } - } else if (interaction.isChatInputCommand()) { - logger.debug(`Chat input command interaction created for '${interaction.commandName}'.`); - try { - await interaction.deferReply(); + if (interaction.isChatInputCommand() || interaction.isAutocomplete()) { + const command = client.commands?.get(interaction.commandName) as Command; - if (await cannotSendMessageInChannel({ interaction, executionId })) { + if (interaction.isChatInputCommand()) { + if (!command) { + logger.warn(`Interaction created but command '${interaction.commandName}' was not found.`); return; } + logger.debug(`Chat input command interaction created for '${interaction.commandName}'.`); + try { + await interaction.deferReply(); + + if (await cannotSendMessageInChannel({ interaction, executionId })) { + return; + } - const inputTime = new Date(); + const inputTime: number = new Date().getTime(); - await command.execute({ interaction, client, executionId }); + await command.execute({ interaction, client, executionId }); - const outputTime = new Date(); - const executionTime = outputTime - inputTime; + const outputTime: number = new Date().getTime(); + const executionTime: number = outputTime - inputTime; - logger.info(`Command '${interaction}' executed in ${executionTime} ms.`); - } catch (error) { - logger.warn( - error, - `Command '${interaction}' throwed an unhandled error and might have failed to execute properly.` - ); + logger.info(`Command '${interaction}' executed in ${executionTime} ms.`); + } catch (error) { + if (error instanceof Error) { + logger.warn( + error, + `Command '${interaction}' throwed an unhandled error and might have failed to execute properly.` + ); - if ( - error.message === 'Unknown interaction' || - error.message === 'Interaction has already been acknowledged.' - ) { - logger.debug('Command failed to be responded to, unknown interaction or already acknowledged.'); - return; - } else { - if (!interaction.deferred || !interaction.replied) { - logger.warn('Interaction was not deferred or replied to, and an error was thrown.'); - return; - } + if ( + error.message === 'Unknown interaction' || + error.message === 'Interaction has already been acknowledged.' + ) { + logger.debug( + 'Command failed to be responded to, unknown interaction or already acknowledged.' + ); + return; + } else { + if (!interaction.deferred || !interaction.replied) { + logger.warn('Interaction was not deferred or replied to, and an error was thrown.'); + return; + } - if (interaction.replied) { - // If the interaction has already been replied to, most likely command executed successfully or error is already handled. + if (interaction.replied) { + // If the interaction has already been replied to, most likely command executed successfully or error is already handled. + return; + } else if (interaction.deferred) { + logger.info('Interaction was deferred, editing reply and sending Uh-oh message.'); + await interaction.editReply({ + embeds: [ + new EmbedBuilder() + .setDescription( + `**${embedOptions.icons.error} Uh-oh... _Something_ went wrong!**\nThere was an unexpected error while trying to execute this command.\n\nYou can try to perform the command 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}` }) + ] + }); + } else { + logger.info( + 'Interaction was not deferred or replied, sending new reply with Uh-oh message.' + ); + await interaction.reply({ + embeds: [ + new EmbedBuilder() + .setDescription( + `**${embedOptions.icons.error} Uh-oh... _Something_ went wrong!**\nThere was an unexpected error while trying to execute this command.\n\nYou can try to perform the command 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}` }) + ] + }); + } + } + } else { + throw error; + } + } + } else if (interaction.isAutocomplete()) { + logger.debug('Autocomplete interaction created.'); + try { + command?.autocomplete && (await command?.autocomplete({ interaction, executionId })); + } catch (error) { + if (error instanceof Error) { + if ( + error.message === 'Unknown interaction' || + error.message === 'Interaction has already been acknowledged.' + ) { + logger.debug( + 'Autocomplete failed to be responded to, unknown interaction or already acknowledged.' + ); + return; + } else { + logger.warn(error, 'Autocomplete failed to execute.'); + } return; - } else if (interaction.deferred) { - logger.info('Interaction was deferred, editing reply and sending Uh-oh message.'); - await interaction.editReply({ - embeds: [ - new EmbedBuilder() - .setDescription( - `**${embedOptions.icons.error} Uh-oh... _Something_ went wrong!**\nThere was an unexpected error while trying to execute this command.\n\nYou can try to perform the command 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}` }) - ] - }); } else { - logger.info('Interaction was not deferred or replied, sending new reply with Uh-oh message.'); - await interaction.reply({ - embeds: [ - new EmbedBuilder() - .setDescription( - `**${embedOptions.icons.error} Uh-oh... _Something_ went wrong!**\nThere was an unexpected error while trying to execute this command.\n\nYou can try to perform the command 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}` }) - ] - }); + throw error; } } } - } else { + logger.warn(interaction, 'Interaction created but was not a chat input or autocomplete interaction.'); } } diff --git a/src/events/player/generalDebug.ts b/src/events/player/generalDebug.ts index 61085939..10306dd0 100644 --- a/src/events/player/generalDebug.ts +++ b/src/events/player/generalDebug.ts @@ -5,7 +5,7 @@ module.exports = { name: 'debug', isDebug: true, isPlayerEvent: false, - execute: async (message) => { + execute: async (message: string) => { const executionId = uuidv4(); const logger = loggerModule.child({ source: 'generalDebug.js', diff --git a/src/events/player/generalError.ts b/src/events/player/generalError.ts index b9f247a7..3ffaed67 100644 --- a/src/events/player/generalError.ts +++ b/src/events/player/generalError.ts @@ -1,31 +1,32 @@ import config from 'config'; -import { EmbedOptions } from '../../types/configTypes'; +import { BotOptions, EmbedOptions, SystemOptions } from '../../types/configTypes'; const embedOptions: EmbedOptions = config.get('embedOptions'); -const botOptions = config.get('botOptions'); -const systemOptions = config.get('systemOptions'); -import { EmbedBuilder } from 'discord.js'; +const botOptions: BotOptions = config.get('botOptions'); +const systemOptions: SystemOptions = config.get('systemOptions'); +import { BaseGuildTextChannel, EmbedBuilder } from 'discord.js'; import { v4 as uuidv4 } from 'uuid'; import loggerModule from '../../services/logger'; +import { ExtendedGuildQueuePlayerNode } from '../../types/eventTypes'; // Emitted when the player queue encounters error (general error with queue) module.exports = { name: 'error', isDebug: false, isPlayerEvent: true, - execute: async (queue, error) => { + execute: async (queue: ExtendedGuildQueuePlayerNode, error: Error) => { const executionId = uuidv4(); const logger = loggerModule.child({ source: 'generalError.js', module: 'event', name: 'playerGeneralError', executionId: executionId, - shardId: queue.metadata.client.shard.ids[0], - guildId: queue.metadata.channel.guild.id + shardId: queue.metadata?.client.shard?.ids[0], + guildId: queue.metadata?.channel.guild.id }); - logger.error(error, 'player.events.on(\'error\'): Player queue encountered error event'); + logger.error(error, "player.events.on('error'): Player queue encountered error event"); - await queue.metadata.channel.send({ + await queue.metadata?.channel.send({ embeds: [ new EmbedBuilder() .setDescription( @@ -37,7 +38,9 @@ module.exports = { }); if (systemOptions.systemMessageChannelId && systemOptions.systemUserId) { - const channel = await queue.metadata.client.channels.cache.get(systemOptions.systemMessageChannelId); + const channel = (await queue.metadata?.client.channels.cache.get( + systemOptions.systemMessageChannelId + )) as BaseGuildTextChannel; if (channel) { await channel.send({ embeds: [ diff --git a/src/events/player/playerDebug.ts b/src/events/player/playerDebug.ts index 8ee6a389..e30906db 100644 --- a/src/events/player/playerDebug.ts +++ b/src/events/player/playerDebug.ts @@ -5,7 +5,7 @@ module.exports = { name: 'error', isDebug: true, isPlayerEvent: true, - execute: async (message) => { + execute: async (message: string) => { const executionId = uuidv4(); const logger = loggerModule.child({ source: 'playerDebug.js', diff --git a/src/events/player/playerError.ts b/src/events/player/playerError.ts index 75a9c86b..d1ed1f3d 100644 --- a/src/events/player/playerError.ts +++ b/src/events/player/playerError.ts @@ -1,31 +1,32 @@ import config from 'config'; -import { EmbedOptions } from '../../types/configTypes'; +import { BotOptions, EmbedOptions, SystemOptions } from '../../types/configTypes'; const embedOptions: EmbedOptions = config.get('embedOptions'); -const botOptions = config.get('botOptions'); -const systemOptions = config.get('systemOptions'); -import { EmbedBuilder } from 'discord.js'; +const botOptions: BotOptions = config.get('botOptions'); +const systemOptions: SystemOptions = config.get('systemOptions'); +import { BaseGuildTextChannel, EmbedBuilder } from 'discord.js'; import { v4 as uuidv4 } from 'uuid'; import loggerModule from '../../services/logger'; +import { ExtendedGuildQueuePlayerNode } from '../../types/eventTypes'; // Emitted when the player encounters an error while streaming audio track module.exports = { name: 'error', isDebug: false, isPlayerEvent: true, - execute: async (queue, error) => { + execute: async (queue: ExtendedGuildQueuePlayerNode, error: Error) => { const executionId = uuidv4(); const logger = loggerModule.child({ source: 'playerError.js', module: 'event', name: 'playerError', executionId: executionId, - shardId: queue.metadata.client.shard.ids[0], - guildId: queue.metadata.channel.guild.id + shardId: queue.metadata?.client.shard?.ids[0], + guildId: queue.metadata?.channel.guild.id }); - logger.error(error, 'player.events.on(\'playerError\'): Player error while streaming track'); + logger.error(error, "player.events.on('playerError'): Player error while streaming track"); - await queue.metadata.channel.send({ + await queue.metadata?.channel.send({ embeds: [ new EmbedBuilder() .setDescription( @@ -37,7 +38,9 @@ module.exports = { }); if (systemOptions.systemMessageChannelId && systemOptions.systemUserId) { - const channel = await queue.metadata.client.channels.cache.get(systemOptions.systemMessageChannelId); + const channel = (await queue.metadata?.client.channels.cache.get( + systemOptions.systemMessageChannelId + )) as BaseGuildTextChannel; if (channel) { await channel.send({ embeds: [ diff --git a/src/events/player/playerSkip.ts b/src/events/player/playerSkip.ts index 6baed0c5..8213e587 100644 --- a/src/events/player/playerSkip.ts +++ b/src/events/player/playerSkip.ts @@ -1,31 +1,33 @@ import config from 'config'; -import { EmbedOptions } from '../../types/configTypes'; +import { BotOptions, EmbedOptions, SystemOptions } from '../../types/configTypes'; const embedOptions: EmbedOptions = config.get('embedOptions'); -const botOptions = config.get('botOptions'); -const systemOptions = config.get('systemOptions'); -import { EmbedBuilder } from 'discord.js'; +const botOptions: BotOptions = config.get('botOptions'); +const systemOptions: SystemOptions = config.get('systemOptions'); +import { BaseGuildTextChannel, EmbedBuilder } from 'discord.js'; import { v4 as uuidv4 } from 'uuid'; import loggerModule from '../../services/logger'; +import { Track } from 'discord-player'; +import { ExtendedGuildQueuePlayerNode } from '../../types/eventTypes'; // Emitted when the audio player fails to load the stream for a track module.exports = { name: 'playerSkip', isDebug: false, isPlayerEvent: true, - execute: async (queue, track) => { + execute: async (queue: ExtendedGuildQueuePlayerNode, track: Track) => { const executionId = uuidv4(); const logger = loggerModule.child({ source: 'playerSkip.js', module: 'event', name: 'playerSkip', executionId: executionId, - shardId: queue.metadata.client.shard.ids[0], - guildId: queue.metadata.channel.guild.id + shardId: queue.metadata?.client.shard?.ids[0], + guildId: queue.metadata?.channel.guild.id }); logger.error(`player.events.on('playerSkip'): Failed to play '${track.url}'.`); - await queue.metadata.channel.send({ + await queue.metadata?.channel.send({ embeds: [ new EmbedBuilder() .setDescription( @@ -37,7 +39,9 @@ module.exports = { }); if (systemOptions.systemMessageChannelId && systemOptions.systemUserId) { - const channel = await queue.metadata.client.channels.cache.get(systemOptions.systemMessageChannelId); + const channel = (await queue.metadata?.client.channels.cache.get( + systemOptions.systemMessageChannelId + )) as BaseGuildTextChannel; if (channel) { await channel.send({ embeds: [ diff --git a/src/events/player/playerStart.ts b/src/events/player/playerStart.ts index 06f24ca0..3ce24a1a 100644 --- a/src/events/player/playerStart.ts +++ b/src/events/player/playerStart.ts @@ -1,19 +1,21 @@ import { v4 as uuidv4 } from 'uuid'; import loggerModule from '../../services/logger'; +import { Track } from 'discord-player'; +import { ExtendedGuildQueuePlayerNode } from '../../types/eventTypes'; module.exports = { name: 'playerStart', isDebug: false, isPlayerEvent: true, - execute: async (queue, track) => { + execute: async (queue: ExtendedGuildQueuePlayerNode, track: Track) => { const executionId = uuidv4(); const logger = loggerModule.child({ source: 'playerStart.js', module: 'event', name: 'playerStart', executionId: executionId, - shardId: queue.metadata.client.shard.ids[0], - guildId: queue.metadata.channel.guild.id + shardId: queue.metadata?.client.shard?.ids[0], + guildId: queue.metadata?.channel.guild.id }); logger.debug(`playerStart event: Started playing '${track.url}'.`); diff --git a/src/events/process/uncaughtException.ts b/src/events/process/uncaughtException.ts index 0041f591..b6822a11 100644 --- a/src/events/process/uncaughtException.ts +++ b/src/events/process/uncaughtException.ts @@ -4,7 +4,7 @@ import loggerModule from '../../services/logger'; module.exports = { name: 'uncaughtException', isDebug: false, - execute: async (error) => { + execute: async (error: Error) => { const executionId = uuidv4(); const logger = loggerModule.child({ source: 'uncaughtException.js', diff --git a/src/events/process/unhandledRejection.ts b/src/events/process/unhandledRejection.ts index a33a34a0..66634a75 100644 --- a/src/events/process/unhandledRejection.ts +++ b/src/events/process/unhandledRejection.ts @@ -4,7 +4,7 @@ import loggerModule from '../../services/logger'; module.exports = { name: 'unhandledRejection', isDebug: false, - execute: async (error) => { + execute: async (error: Error) => { const executionId = uuidv4(); const logger = loggerModule.child({ source: 'unhandledRejection.js', diff --git a/src/services/logger.ts b/src/services/logger.ts index 5bdf4a54..65f3e9e6 100644 --- a/src/services/logger.ts +++ b/src/services/logger.ts @@ -2,7 +2,7 @@ import pino from 'pino'; import config from 'config'; // Retrieve logger options from config -const loggerOptions = config.get('loggerOptions'); +const loggerOptions: LoggerOptions = config.get('loggerOptions'); const targets = [ { diff --git a/src/types/clientTypes.ts b/src/types/clientTypes.ts index 74fb2739..2429adb5 100644 --- a/src/types/clientTypes.ts +++ b/src/types/clientTypes.ts @@ -2,7 +2,15 @@ import { Client, Collection } from 'discord.js'; type RegisterClientCommandsFunction = (params: { client: Client; executionId: string }) => void; +export interface Command { + isNew: boolean; + isBeta: boolean; + data: object; + execute: (params: { interaction: object; client: ExtendedClient | undefined; executionId: string }) => void; + autocomplete?: (params: { interaction: object; executionId: string }) => void; +} + export interface ExtendedClient extends Client { registerClientCommands?: RegisterClientCommandsFunction; - commands?: Collection; + commands?: Collection; } diff --git a/src/types/eventTypes.ts b/src/types/eventTypes.ts index 38cdd281..5e48e385 100644 --- a/src/types/eventTypes.ts +++ b/src/types/eventTypes.ts @@ -1,3 +1,16 @@ +import { GuildQueuePlayerNode } from 'discord-player'; +import { ExtendedClient } from './clientTypes'; +import { BaseGuildTextChannel } from 'discord.js'; + export type ClientEventArguments = unknown[]; export type ProcessEventArguments = unknown[]; export type PlayerEventArguments = unknown[]; + +export interface ExtendedGuildQueuePlayerNode extends GuildQueuePlayerNode { + metadata: + | undefined + | { + client: ExtendedClient; + channel: BaseGuildTextChannel; + }; +}