diff --git a/src/commands/ping.ts b/src/commands/ping.ts new file mode 100644 index 000000000..30c975323 --- /dev/null +++ b/src/commands/ping.ts @@ -0,0 +1,21 @@ +import { SlashCommandBuilder } from 'discord.js'; +import cmdName from '../core/interaction/cmdName.js'; +import { CommandRegistry } from '../events/interactionCreate.js'; + +export default { + inProduction: true, + inDevelopment: true, + inPublic: true, + handlesInteraction: true, + + command: new SlashCommandBuilder() + .setName(cmdName('ping')) + .setDescription('Check if the bot is alive'), + + async execute(interaction) { + const executionStart = new Date().getTime(); + await interaction.editReply('Pong 🏓'); + const executionTime = new Date().getTime() - executionStart; + interaction.editReply(`Pong 🏓 - ${executionTime}ms`); + }, +} satisfies CommandRegistry; diff --git a/src/events/interactionCreate.ts b/src/events/interactionCreate.ts index 047a38ad3..295dc05f4 100644 --- a/src/events/interactionCreate.ts +++ b/src/events/interactionCreate.ts @@ -19,6 +19,7 @@ import eligible from '../commands/eligible.js'; import help from '../commands/help.js'; import inactive from '../commands/inactive.js'; import ownedtanks from '../commands/ownedtanks.js'; +import ping from '../commands/ping.js'; import playerachievements from '../commands/playerachievements.js'; import playerinfo from '../commands/playerinfo.js'; import searchclans from '../commands/searchclans.js'; @@ -40,17 +41,25 @@ import { handleError } from './error.js'; export type CommandReturnable = EmbedBuilder | ButtonBuilder | JSX.Element; export type RichCommandReturnable = CommandReturnable | CommandReturnable[]; -export interface CommandRegistry { +export type CommandRegistry = { inDevelopment: boolean; inProduction: boolean; inPublic: boolean; command: Omit; - execute: ( - interaction: ChatInputCommandInteraction, - ) => RichCommandReturnable | Promise; autocomplete?: (interaction: AutocompleteInteraction) => void; -} +} & ( + | { + handlesInteraction?: false; + execute: ( + interaction: ChatInputCommandInteraction, + ) => RichCommandReturnable | Promise; + } + | { + handlesInteraction: true; + execute: (interaction: ChatInputCommandInteraction) => void; + } +); const rest = new REST().setToken(DISCORD_TOKEN); @@ -70,6 +79,7 @@ const commands = ( tankstats, today, verify, + ping, ] as CommandRegistry[] ).reduce>((accumulator, registry) => { return { ...accumulator, [registry.command.name]: registry }; @@ -161,6 +171,9 @@ export default async function interactionCreate( try { const result = await command.execute(interaction); + + if (command.handlesInteraction) return; + const normalizedResult = Array.isArray(result) ? result : [result]; const reply: InteractionEditReplyOptions = {}; @@ -182,7 +195,7 @@ export default async function interactionCreate( reply.components[0] as ActionRowBuilder ).addComponents(item); } else { - const image = await render(item); + const image = await render(item!); if (!reply.files) reply.files = []; reply.files.push(image); }