mirror of
https://github.com/tiramisulabs/seyfert.git
synced 2025-07-04 05:56:09 +00:00
245 lines
8.7 KiB
TypeScript
245 lines
8.7 KiB
TypeScript
import { ApplicationCommandType, InteractionType, type APIInteraction } from 'discord-api-types/v10';
|
|
import {
|
|
BaseCommand,
|
|
CommandContext,
|
|
MenuCommandContext,
|
|
OptionResolver,
|
|
type RegisteredMiddlewares,
|
|
type Command,
|
|
type ContextMenuCommand,
|
|
type ContextOptionsResolved,
|
|
type UsingClient,
|
|
} from '../commands';
|
|
import type {
|
|
ChatInputCommandInteraction,
|
|
ComponentInteraction,
|
|
MessageCommandInteraction,
|
|
ModalSubmitInteraction,
|
|
UserCommandInteraction,
|
|
__InternalReplyFunction,
|
|
} from '../structures';
|
|
import { AutocompleteInteraction, BaseInteraction } from '../structures';
|
|
import { ComponentContext, ModalContext } from '../components';
|
|
|
|
export async function onInteractionCreate(
|
|
self: UsingClient,
|
|
body: APIInteraction,
|
|
shardId: number,
|
|
__reply?: __InternalReplyFunction,
|
|
) {
|
|
self.debugger?.debug(`[${InteractionType[body.type] ?? body.type}] Interaction received.`);
|
|
switch (body.type) {
|
|
case InteractionType.ApplicationCommandAutocomplete:
|
|
{
|
|
const parentCommand = self.commands?.values.find(x => {
|
|
if (body.data.guild_id) {
|
|
return x.guildId?.includes(body.data.guild_id) && x.name === body.data.name;
|
|
}
|
|
return x.name === body.data.name;
|
|
});
|
|
const optionsResolver = new OptionResolver(
|
|
self,
|
|
body.data.options ?? [],
|
|
parentCommand as Command,
|
|
body.guild_id,
|
|
body.data.resolved as ContextOptionsResolved,
|
|
);
|
|
const interaction = new AutocompleteInteraction(self, body, optionsResolver, __reply);
|
|
const command = optionsResolver.getAutocomplete();
|
|
|
|
// idc, is a YOU problem
|
|
if (!command?.autocomplete)
|
|
return self.logger.warn(
|
|
`${optionsResolver.fullCommandName} ${command?.name} command does not have 'autocomplete' callback`,
|
|
);
|
|
try {
|
|
try {
|
|
await command.autocomplete(interaction);
|
|
} catch (error) {
|
|
if (!command.onAutocompleteError)
|
|
return self.logger.error(
|
|
`${optionsResolver.fullCommandName} ${command.name} just threw an error, ${
|
|
error ? (typeof error === 'object' && 'message' in error ? error.message : error) : 'Unknown'
|
|
}`,
|
|
);
|
|
await command.onAutocompleteError(interaction, error);
|
|
}
|
|
} catch (error) {
|
|
try {
|
|
await optionsResolver.getCommand()?.onInternalError?.(self, optionsResolver.getCommand()!, error);
|
|
} catch {
|
|
// supress error
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case InteractionType.ApplicationCommand:
|
|
{
|
|
switch (body.data.type) {
|
|
case ApplicationCommandType.Message:
|
|
case ApplicationCommandType.User:
|
|
{
|
|
const command = self.commands?.values.find(x => {
|
|
if (body.data.guild_id) {
|
|
return x.guildId?.includes(body.data.guild_id) && x.name === body.data.name;
|
|
}
|
|
return x.name === body.data.name;
|
|
}) as ContextMenuCommand;
|
|
const interaction = BaseInteraction.from(self, body, __reply) as
|
|
| UserCommandInteraction
|
|
| MessageCommandInteraction;
|
|
// idc, is a YOU problem
|
|
if (!command?.run)
|
|
return self.logger.warn(`${command.name ?? 'Unknown'} command does not have 'run' callback`);
|
|
const context = new MenuCommandContext(self, interaction, shardId, command);
|
|
const extendContext = self.options?.context?.(interaction) ?? {};
|
|
Object.assign(context, extendContext);
|
|
try {
|
|
if (command.botPermissions && interaction.appPermissions) {
|
|
const permissions = interaction.appPermissions.missings(
|
|
...interaction.appPermissions.values([command.botPermissions]),
|
|
);
|
|
if (!interaction.appPermissions.has('Administrator') && permissions.length) {
|
|
return command.onBotPermissionsFail(context, interaction.appPermissions.keys(permissions));
|
|
}
|
|
}
|
|
const resultRunGlobalMiddlewares = await BaseCommand.__runMiddlewares(
|
|
context,
|
|
(self.options?.globalMiddlewares ?? []) as keyof RegisteredMiddlewares,
|
|
true,
|
|
);
|
|
if (resultRunGlobalMiddlewares.pass) {
|
|
return;
|
|
}
|
|
if ('error' in resultRunGlobalMiddlewares) {
|
|
return command.onMiddlewaresError(context, resultRunGlobalMiddlewares.error ?? 'Unknown error');
|
|
}
|
|
|
|
const resultRunMiddlewares = await BaseCommand.__runMiddlewares(
|
|
context,
|
|
command.middlewares as keyof RegisteredMiddlewares,
|
|
false,
|
|
);
|
|
if (resultRunMiddlewares.pass) {
|
|
return;
|
|
}
|
|
if ('error' in resultRunMiddlewares) {
|
|
return command.onMiddlewaresError(context, resultRunMiddlewares.error ?? 'Unknown error');
|
|
}
|
|
|
|
try {
|
|
await command.run(context);
|
|
await command.onAfterRun?.(context, undefined);
|
|
} catch (error) {
|
|
await command.onRunError(context, error);
|
|
await command.onAfterRun?.(context, error);
|
|
}
|
|
} catch (error) {
|
|
try {
|
|
await command.onInternalError(self, error);
|
|
} catch {
|
|
// supress error
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case ApplicationCommandType.ChatInput:
|
|
{
|
|
const parentCommand = self.commands?.values.find(x => {
|
|
if (body.data.guild_id) {
|
|
return x.guildId?.includes(body.data.guild_id) && x.name === body.data.name;
|
|
}
|
|
return x.name === body.data.name;
|
|
});
|
|
const optionsResolver = new OptionResolver(
|
|
self,
|
|
body.data.options ?? [],
|
|
parentCommand as Command,
|
|
body.guild_id,
|
|
body.data.resolved as ContextOptionsResolved,
|
|
);
|
|
const interaction = BaseInteraction.from(self, body, __reply) as ChatInputCommandInteraction;
|
|
const command = optionsResolver.getCommand();
|
|
if (!command?.run)
|
|
return self.logger.warn(`${optionsResolver.fullCommandName} command does not have 'run' callback`);
|
|
const context = new CommandContext(self, interaction, optionsResolver, shardId, command);
|
|
const extendContext = self.options?.context?.(interaction) ?? {};
|
|
Object.assign(context, extendContext);
|
|
try {
|
|
if (command.botPermissions && interaction.appPermissions) {
|
|
const permissions = interaction.appPermissions.missings(
|
|
...interaction.appPermissions.values([command.botPermissions]),
|
|
);
|
|
if (!interaction.appPermissions.has('Administrator') && permissions.length) {
|
|
return command.onBotPermissionsFail?.(context, interaction.appPermissions.keys(permissions));
|
|
}
|
|
}
|
|
const [erroredOptions, result] = await command.__runOptions(context, optionsResolver);
|
|
if (erroredOptions) {
|
|
return command.onOptionsError?.(context, result);
|
|
}
|
|
const resultRunGlobalMiddlewares = await command.__runGlobalMiddlewares(context);
|
|
if (resultRunGlobalMiddlewares.pass) {
|
|
return;
|
|
}
|
|
if ('error' in resultRunGlobalMiddlewares) {
|
|
return command.onMiddlewaresError?.(context, resultRunGlobalMiddlewares.error ?? 'Unknown error');
|
|
}
|
|
const resultRunMiddlewares = await command.__runMiddlewares(context);
|
|
if (resultRunMiddlewares.pass) {
|
|
return;
|
|
}
|
|
if ('error' in resultRunMiddlewares) {
|
|
return command.onMiddlewaresError?.(context, resultRunMiddlewares.error ?? 'Unknown error');
|
|
}
|
|
|
|
try {
|
|
await command.run(context);
|
|
await command.onAfterRun?.(context, undefined);
|
|
} catch (error) {
|
|
await command.onRunError?.(context, error);
|
|
await command.onAfterRun?.(context, error);
|
|
}
|
|
} catch (error) {
|
|
try {
|
|
await command.onInternalError?.(self, context.command, error);
|
|
} catch {
|
|
// supress error
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case InteractionType.ModalSubmit:
|
|
{
|
|
const interaction = BaseInteraction.from(self, body, __reply) as ModalSubmitInteraction;
|
|
if (self.components?.hasModal(interaction)) {
|
|
await self.components.onModalSubmit(interaction);
|
|
} else {
|
|
const context = new ModalContext(self, interaction);
|
|
const extended = self.options?.context?.(interaction) ?? {};
|
|
Object.assign(context, extended);
|
|
await self.components?.executeModal(context);
|
|
}
|
|
}
|
|
break;
|
|
case InteractionType.MessageComponent:
|
|
{
|
|
const interaction = BaseInteraction.from(self, body, __reply) as ComponentInteraction;
|
|
if (self.components?.hasComponent(body.message.id, interaction.customId)) {
|
|
await self.components.onComponent(body.message.id, interaction);
|
|
} else {
|
|
//@ts-expect-error
|
|
const context = new ComponentContext(self, interaction);
|
|
const extended = self.options?.context?.(interaction) ?? {};
|
|
Object.assign(context, extended);
|
|
await self.components?.executeComponent(context);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|