feat: handle and dispatch commands
This commit is contained in:
+127
-1
@@ -3,20 +3,26 @@ import path from 'path';
|
||||
|
||||
import {
|
||||
AutocompleteInteraction,
|
||||
BaseInteraction,
|
||||
ChatInputCommandInteraction,
|
||||
GuildMember,
|
||||
Interaction,
|
||||
Message,
|
||||
MessageFlags,
|
||||
PermissionFlagsBits,
|
||||
REST,
|
||||
Routes,
|
||||
SlashCommandOptionsOnlyBuilder,
|
||||
VoiceState
|
||||
} from 'discord.js';
|
||||
import { Logger } from './utils/log';
|
||||
import { Bot } from './bot';
|
||||
import { config } from './utils/config';
|
||||
import { Bot } from './bot';
|
||||
|
||||
export interface Command {
|
||||
name?: string;
|
||||
requiresAdmin: boolean;
|
||||
ownerOnly?: boolean;
|
||||
execute?: (interaction: ChatInputCommandInteraction) => Promise<void>;
|
||||
autocomplete?: (interaction: AutocompleteInteraction) => Promise<void>;
|
||||
messageListener?: (msg: Message) => Promise<void>;
|
||||
@@ -58,6 +64,18 @@ export class CommandManager {
|
||||
this.initialized = true;
|
||||
await this.populateCommands();
|
||||
this.registerSlashCommands();
|
||||
|
||||
const bot = Bot.get;
|
||||
|
||||
bot.on('interactionCreate', (interaction: Interaction) => {
|
||||
this.onInteraction(interaction);
|
||||
});
|
||||
bot.on('messageCreate', (message: Message) => {
|
||||
this.onMessage(message);
|
||||
});
|
||||
bot.on('voiceStateUpdate', (oldState: VoiceState, newState: VoiceState) => {
|
||||
this.onVoiceStateUpdate(oldState, newState);
|
||||
});
|
||||
}
|
||||
|
||||
public getCategories(): Array<CommandCategory> {
|
||||
@@ -194,4 +212,112 @@ export class CommandManager {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
interaction handling
|
||||
*/
|
||||
private async executeCommandInteraction(
|
||||
interaction: ChatInputCommandInteraction
|
||||
): Promise<void> {
|
||||
const cmdName = interaction.commandName;
|
||||
const command = this.get(cmdName);
|
||||
if (!command)
|
||||
return this.log.error(
|
||||
'Attempted to execute non-existing command (%s)',
|
||||
cmdName
|
||||
);
|
||||
|
||||
if (command.requiresAdmin) {
|
||||
const member = interaction.member as GuildMember;
|
||||
if (!member.permissions.has(PermissionFlagsBits.Administrator)) {
|
||||
await interaction.reply({
|
||||
content:
|
||||
"You don't have the permissions required to execute this command.",
|
||||
flags: MessageFlags.Ephemeral
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (command.ownerOnly) {
|
||||
const member = interaction.member as GuildMember;
|
||||
if (member.id != config.owner_id) {
|
||||
await interaction.reply({
|
||||
content: 'This command is restricted.',
|
||||
flags: MessageFlags.Ephemeral
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (command.execute) {
|
||||
try {
|
||||
await command.execute(interaction);
|
||||
} catch (error) {
|
||||
this.log.error(
|
||||
'Error occurred while executing command %s: %s',
|
||||
cmdName,
|
||||
error
|
||||
);
|
||||
}
|
||||
} else this.log.error('Command is missing execute method: %s', cmdName);
|
||||
}
|
||||
|
||||
private async autocompleteCommandInteraction(
|
||||
interaction: AutocompleteInteraction
|
||||
): Promise<void> {
|
||||
const cmdName = interaction.commandName;
|
||||
const command = this.get(cmdName);
|
||||
|
||||
if (!command)
|
||||
return this.log.error(
|
||||
'Attempted to execute unexisting command (%s)',
|
||||
cmdName
|
||||
);
|
||||
|
||||
if (command.autocomplete) {
|
||||
try {
|
||||
await command.autocomplete(interaction);
|
||||
} catch (error) {
|
||||
this.log.error(
|
||||
'Error occurred while autocompleting command %s: %s',
|
||||
cmdName,
|
||||
error
|
||||
);
|
||||
}
|
||||
} else
|
||||
this.log.error('Command is missing autocomplete method: %s', cmdName);
|
||||
}
|
||||
|
||||
/*
|
||||
event listeners
|
||||
*/
|
||||
private async onInteraction(interaction: BaseInteraction): Promise<void> {
|
||||
/*
|
||||
cmd execution
|
||||
*/
|
||||
if (interaction.isChatInputCommand())
|
||||
return this.executeCommandInteraction(interaction);
|
||||
|
||||
if (interaction.isAutocomplete())
|
||||
return this.autocompleteCommandInteraction(interaction);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
private async onMessage(message: Message<boolean>): Promise<void> {
|
||||
if (message.author.bot) return;
|
||||
|
||||
for (const cmd of this.getAll())
|
||||
if (cmd.messageListener) await cmd.messageListener(message);
|
||||
}
|
||||
|
||||
private async onVoiceStateUpdate(
|
||||
oldState: VoiceState,
|
||||
newState: VoiceState
|
||||
): Promise<void> {
|
||||
for (const cmd of this.getAll())
|
||||
if (cmd.voiceStateListener)
|
||||
await cmd.voiceStateListener(oldState, newState);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user