diff --git a/src/handlers/handle-interaction-creation.ts b/src/handlers/handle-interaction-creation.ts new file mode 100644 index 00000000..be605c51 --- /dev/null +++ b/src/handlers/handle-interaction-creation.ts @@ -0,0 +1,21 @@ +import type { Interaction } from 'discord.js'; + +import { createLobby } from '../create-lobby'; + +export const handleInteractionCreation = async (interaction: Interaction): Promise => { + if ( + !interaction.isCommand() || + !interaction.inGuild() || + !interaction.isChatInputCommand() || + interaction.commandName !== 'voice-on-demand' + ) { + return; + } + + if (interaction.options.getSubcommand(true) !== 'create') { + await interaction.reply('Unknown subcommand'); + return; + } + + await createLobby(interaction); +}; diff --git a/src/handlers/handle-voice-channel-deletion.ts b/src/handlers/handle-voice-channel-deletion.ts index a89ccd10..1d07dd5d 100644 --- a/src/handlers/handle-voice-channel-deletion.ts +++ b/src/handlers/handle-voice-channel-deletion.ts @@ -1,8 +1,15 @@ -import type { VoiceChannel } from 'discord.js'; +import type { DMChannel, NonThreadGuildBasedChannel } from 'discord.js'; +import { ChannelType } from 'discord.js'; import { cache } from '../helpers/cache'; -export const handleVoiceChannelDeletion = async (channel: VoiceChannel): Promise => { +export const handleVoiceChannelDeletion = async ( + channel: DMChannel | NonThreadGuildBasedChannel +): Promise => { + if (channel.type !== ChannelType.GuildVoice) { + return; + } + const lobbyId = await cache.get('lobbyId'); const { guild, id } = channel; diff --git a/src/handlers/voice-state-handlers.ts b/src/handlers/handle-voice-state-update.ts similarity index 60% rename from src/handlers/voice-state-handlers.ts rename to src/handlers/handle-voice-state-update.ts index 05f9c820..c5b4719a 100644 --- a/src/handlers/voice-state-handlers.ts +++ b/src/handlers/handle-voice-state-update.ts @@ -6,13 +6,13 @@ import { cache } from '../helpers/cache'; type CheckedVoiceState = SetNonNullable; -export const isJoinState = (newState: VoiceState): newState is CheckedVoiceState => +const isJoinState = (newState: VoiceState): newState is CheckedVoiceState => newState.channel !== null && newState.channelId !== null && newState.member !== null; -export const isLeaveState = (oldDate: VoiceState): oldDate is CheckedVoiceState => +const isLeaveState = (oldDate: VoiceState): oldDate is CheckedVoiceState => oldDate.channel !== null && oldDate.channelId !== null && oldDate.member !== null; -export const handleJoin = async (state: CheckedVoiceState, lobbyId: string): Promise => { +const handleJoin = async (state: CheckedVoiceState, lobbyId: string): Promise => { if (state.channelId !== lobbyId) { return; } @@ -21,7 +21,7 @@ export const handleJoin = async (state: CheckedVoiceState, lobbyId: string): Pro await state.member.voice.setChannel(channel); }; -export const handleLeave = async (state: CheckedVoiceState): Promise => { +const handleLeave = async (state: CheckedVoiceState): Promise => { const channels = await cache.get('channels', []); const { channel } = state; @@ -35,3 +35,21 @@ export const handleLeave = async (state: CheckedVoiceState): Promise => { await cache.set('channels', filtered); } }; + +export const handleVoiceStateUpdate = async ( + oldState: VoiceState, + newState: VoiceState +): Promise => { + const lobbyId = await cache.get('lobbyId'); + if (lobbyId === undefined) { + return; + } + + if (isLeaveState(oldState)) { + await handleLeave(oldState); + } + + if (isJoinState(newState)) { + await handleJoin(newState, lobbyId); + } +}; diff --git a/src/main.ts b/src/main.ts index 22bd45c7..b3e873af 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,17 +1,11 @@ -import { ChannelType, Client, REST, Routes } from 'discord.js'; +import { Client, REST, Routes } from 'discord.js'; +import { voiceOnDemandCommand } from './commands'; import { config } from './config'; -import { createLobby } from './create-lobby'; import { deleteExistingCommands } from './delete-existing-commands'; +import { handleInteractionCreation } from './handlers/handle-interaction-creation'; import { handleVoiceChannelDeletion } from './handlers/handle-voice-channel-deletion'; -import { - handleJoin, - handleLeave, - isJoinState, - isLeaveState, -} from './handlers/voice-state-handlers'; -import { cache } from './helpers/cache'; -import { voiceOnDemandCommand } from './commands'; +import { handleVoiceStateUpdate } from './handlers/handle-voice-state-update'; const { discord } = config; @@ -36,42 +30,15 @@ const client = new Client({ await bootstrap(client); client.on('channelDelete', async (channel) => { - if (channel.type === ChannelType.GuildVoice) { - await handleVoiceChannelDeletion(channel); - } + await handleVoiceChannelDeletion(channel); }); client.on('voiceStateUpdate', async (oldState, newState) => { - const lobbyId = await cache.get('lobbyId'); - if (lobbyId === undefined) { - return; - } - - if (isLeaveState(oldState)) { - await handleLeave(oldState); - } - - if (isJoinState(newState)) { - await handleJoin(newState, lobbyId); - } + await handleVoiceStateUpdate(oldState, newState); }); client.on('interactionCreate', async (interaction) => { - if ( - !interaction.isCommand() || - !interaction.inGuild() || - !interaction.isChatInputCommand() || - interaction.commandName !== 'voice-on-demand' - ) { - return; - } - - if (interaction.options.getSubcommand(true) !== 'create') { - await interaction.reply('Unknown subcommand'); - return; - } - - await createLobby(interaction); + await handleInteractionCreation(interaction); }); const rest = new REST({ version: '10' }).setToken(discord.token);