Collectors
Ahora que has aprendido a manejar componentes de manera estática, podrías haberte preguntado cómo obtener más contexto sobre lo que sucedió antes de enviar el componente.
Seyfert incluye colectores de componentes de mensajes
, que son una manera fácil de manejar esas interacciones recibidas de un mensaje específico y te permiten obtener más contexto sobre lo que sucedió antes de enviar el componente.
Construcción de colectores
Los colectores se construyen utilizando el método createComponentCollector
en un mensaje, el cual es heredado por BaseMessage
. Este método devuelve un objeto que representa un colector.
Aquí tienes un ejemplo de cómo construir un colector simple después de enviar un mensaje con un botón adjunto en un comando de hola mundo
.
import { class Button
Represents a button component.
Button, class ActionRow<T extends BuilderComponents>
Represents an Action Row component in a message.
ActionRow, class Command
Command, function Declare(declare: CommandDeclareOptions): <T extends { new (...args: any[]): object;}>(target: T) => { new (...args: any[]): { name: string; nsfw: boolean | undefined; props: ExtraProps | undefined; contexts: InteractionContextType[]; integrationTypes: ApplicationIntegrationType[]; defaultMemberPermissions: bigint | undefined; botPermissions: bigint | undefined; description: string; type: ApplicationCommandType; guildId?: string[]; ignore?: IgnoreCommand; aliases?: string[]; handler?: EntryPointCommandHandlerType; };} & T
Declare, type class CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>interface CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>
CommandContext,} from 'seyfert';
import { enum ButtonStyle
ButtonStyle } from 'seyfert/lib/types';
@function Declare(declare: CommandDeclareOptions): <T extends { new (...args: any[]): object;}>(target: T) => { new (...args: any[]): { name: string; nsfw: boolean | undefined; props: ExtraProps | undefined; contexts: InteractionContextType[]; integrationTypes: ApplicationIntegrationType[]; defaultMemberPermissions: bigint | undefined; botPermissions: bigint | undefined; description: string; type: ApplicationCommandType; guildId?: string[]; ignore?: IgnoreCommand; aliases?: string[]; handler?: EntryPointCommandHandlerType; };} & T
Declare({ name: string
name: 'hello', description: string
description: 'I will send you a hello world message',})export default class class HelloWorldCommand
HelloWorldCommand extends class Command
Command { async HelloWorldCommand.run(ctx: CommandContext): Promise<void>
run(ctx: CommandContext<{}, never>
ctx: class CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>interface CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>
CommandContext) { const const button: Button
button = new new Button(data?: Partial<APIButtonComponent>): Button
Creates a new Button instance.
Button() .Button.setCustomId(id: string): Button
Sets the custom ID for the button.
setCustomId('hello') .Button.setLabel(label: string): Button
Sets the label for the button.
setLabel('Hello') .Button.setStyle(style: ButtonStyle): Button
setStyle(enum ButtonStyle
ButtonStyle.function (enum member) ButtonStyle.Primary = 1
Primary);
const const row: ActionRow<Button>
row = new new ActionRow<Button>({ components, ...data }?: Partial<APIActionRowComponent<APIActionRowComponentTypes>>): ActionRow<...>
Creates a new instance of the ActionRow class.
ActionRow<class Button
Represents a button component.
Button>().ActionRow<Button>.setComponents(component: (ButtonLink | ButtonID)[]): ActionRow<Button>
Sets the components of the Action Row.
setComponents([const button: Button
button]);
// Para obtener el mensaje al que se le adjunta un botón, puedes configurar la fetchReply en "true". const const message: WebhookMessage
message = await ctx: CommandContext<{}, never>
ctx.CommandContext<{}, never>.write<true>(body: InteractionCreateBodyRequest, withResponse?: true | undefined): Promise<WebhookMessage>
write( { content?: string | undefined
The message contents (up to 2000 characters)
content: 'Do you want a hello world? Click the button below.', ResolverProps.components?: APIActionRowComponent<APIMessageActionRowComponent>[] | ActionRow<BuilderComponents>[] | undefined
components: [const row: ActionRow<Button>
row], }, true );
const const collector: CreateComponentCollectorResult
collector = const message: WebhookMessage
message.BaseMessage.createComponentCollector(options?: ListenerOptions): CreateComponentCollectorResult
createComponentCollector(); }}
Manejo de interacciones dentro de un colector
Una vez creado el colector a partir de un mensaje, vamos a manejar la interacción del botón con la función run
del colector.
Aquí tienes un ejemplo:
import { class Button
Represents a button component.
Button, class ActionRow<T extends BuilderComponents>
Represents an Action Row component in a message.
ActionRow, class Command
Command, function Declare(declare: CommandDeclareOptions): <T extends { new (...args: any[]): object;}>(target: T) => { new (...args: any[]): { name: string; nsfw: boolean | undefined; props: ExtraProps | undefined; contexts: InteractionContextType[]; integrationTypes: ApplicationIntegrationType[]; defaultMemberPermissions: bigint | undefined; botPermissions: bigint | undefined; description: string; type: ApplicationCommandType; guildId?: string[]; ignore?: IgnoreCommand; aliases?: string[]; handler?: EntryPointCommandHandlerType; };} & T
Declare, type class CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>interface CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>
CommandContext,} from 'seyfert';
import { enum ButtonStyle
ButtonStyle } from 'seyfert/lib/types';
@function Declare(declare: CommandDeclareOptions): <T extends { new (...args: any[]): object;}>(target: T) => { new (...args: any[]): { name: string; nsfw: boolean | undefined; props: ExtraProps | undefined; contexts: InteractionContextType[]; integrationTypes: ApplicationIntegrationType[]; defaultMemberPermissions: bigint | undefined; botPermissions: bigint | undefined; description: string; type: ApplicationCommandType; guildId?: string[]; ignore?: IgnoreCommand; aliases?: string[]; handler?: EntryPointCommandHandlerType; };} & T
Declare({ name: string
name: 'hello', description: string
description: 'I will send you a hello world message',})export default class class HelloWorldCommand
HelloWorldCommand extends class Command
Command { async HelloWorldCommand.run(ctx: CommandContext): Promise<void>
run(ctx: CommandContext<{}, never>
ctx: class CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>interface CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>
CommandContext) { const const button: Button
button = new new Button(data?: Partial<APIButtonComponent>): Button
Creates a new Button instance.
Button() .Button.setCustomId(id: string): Button
Sets the custom ID for the button.
setCustomId('hello') .Button.setLabel(label: string): Button
Sets the label for the button.
setLabel('Hello') .Button.setStyle(style: ButtonStyle): Button
setStyle(enum ButtonStyle
ButtonStyle.function (enum member) ButtonStyle.Primary = 1
Primary);
const const row: ActionRow<Button>
row = new new ActionRow<Button>({ components, ...data }?: Partial<APIActionRowComponent<APIActionRowComponentTypes>>): ActionRow<...>
Creates a new instance of the ActionRow class.
ActionRow<class Button
Represents a button component.
Button>().ActionRow<Button>.setComponents(component: (ButtonLink | ButtonID)[]): ActionRow<Button>
Sets the components of the Action Row.
setComponents([const button: Button
button]);
const const message: WebhookMessage
message = await ctx: CommandContext<{}, never>
ctx.CommandContext<{}, never>.write<true>(body: InteractionCreateBodyRequest, withResponse?: true | undefined): Promise<WebhookMessage>
write( { content?: string | undefined
The message contents (up to 2000 characters)
content: 'Do you want a hello world? Click the button below.', ResolverProps.components?: APIActionRowComponent<APIMessageActionRowComponent>[] | ActionRow<BuilderComponents>[] | undefined
components: [const row: ActionRow<Button>
row], }, true );
const const collector: CreateComponentCollectorResult
collector = const message: WebhookMessage
message.BaseMessage.createComponentCollector(options?: ListenerOptions): CreateComponentCollectorResult
createComponentCollector();
// estamos colocando el ID personalizado que hemos establecido en el botón como primer parámetro de la función. const collector: CreateComponentCollectorResult
collector.CreateComponentCollectorResult.run<CollectorInteraction>(customId: UserMatches, callback: ComponentCallback<CollectorInteraction>): any
run('hello', async (i: CollectorInteraction
i) => { if (i: CollectorInteraction
i.BaseInteraction<FromGuild extends boolean = boolean, Type extends APIInteraction = APIInteraction>.isButton(): this is ButtonInteraction
isButton()) return i: ButtonInteraction
i.Interaction<boolean, APIMessageComponentInteraction>.write<false>(body: InteractionCreateBodyRequest, withResponse?: false | undefined): Promise<void>
write({ content?: string | undefined
The message contents (up to 2000 characters)
content: 'Hello World 👋' }); }); }}
Filtrando interacciones
Podrías haber pensado en filtrar la interacción recibida en la función run para limitar, por ejemplo, al usuario que está interactuando con el botón.
Habrías añadido una condición dentro de la función run de esta manera:
if (i.user.id === ctx.author.id) return i.write({ content: 'Do not touch the button' });
Esto limitará el uso del botón solo al usuario que ejecutó el comando.
Pero Seyfert implementa simplemente una opción de filter
al crear el colector, que espera una función de retorno que devuelva un booleano.
Vamos a implementar el filtro para filtrar al usuario que ejecutó la interacción y filtrar la interacción solo para las interacciones de botón.
import { class Button
Represents a button component.
Button, class ActionRow<T extends BuilderComponents>
Represents an Action Row component in a message.
ActionRow, class Command
Command, function Declare(declare: CommandDeclareOptions): <T extends { new (...args: any[]): object;}>(target: T) => { new (...args: any[]): { name: string; nsfw: boolean | undefined; props: ExtraProps | undefined; contexts: InteractionContextType[]; integrationTypes: ApplicationIntegrationType[]; defaultMemberPermissions: bigint | undefined; botPermissions: bigint | undefined; description: string; type: ApplicationCommandType; guildId?: string[]; ignore?: IgnoreCommand; aliases?: string[]; handler?: EntryPointCommandHandlerType; };} & T
Declare, type class CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>interface CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>
CommandContext,} from 'seyfert';
import { enum ButtonStyle
ButtonStyle } from 'seyfert/lib/types';
@function Declare(declare: CommandDeclareOptions): <T extends { new (...args: any[]): object;}>(target: T) => { new (...args: any[]): { name: string; nsfw: boolean | undefined; props: ExtraProps | undefined; contexts: InteractionContextType[]; integrationTypes: ApplicationIntegrationType[]; defaultMemberPermissions: bigint | undefined; botPermissions: bigint | undefined; description: string; type: ApplicationCommandType; guildId?: string[]; ignore?: IgnoreCommand; aliases?: string[]; handler?: EntryPointCommandHandlerType; };} & T
Declare({ name: string
name: 'hello', description: string
description: 'I will send you a hello world message',})export default class class HelloWorldCommand
HelloWorldCommand extends class Command
Command { async HelloWorldCommand.run(ctx: CommandContext): Promise<void>
run(ctx: CommandContext<{}, never>
ctx: class CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>interface CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>
CommandContext) { const const button: Button
button = new new Button(data?: Partial<APIButtonComponent>): Button
Creates a new Button instance.
Button() .Button.setCustomId(id: string): Button
Sets the custom ID for the button.
setCustomId('hello') .Button.setLabel(label: string): Button
Sets the label for the button.
setLabel('Hello') .Button.setStyle(style: ButtonStyle): Button
setStyle(enum ButtonStyle
ButtonStyle.function (enum member) ButtonStyle.Primary = 1
Primary);
const const row: ActionRow<Button>
row = new new ActionRow<Button>({ components, ...data }?: Partial<APIActionRowComponent<APIActionRowComponentTypes>>): ActionRow<...>
Creates a new instance of the ActionRow class.
ActionRow<class Button
Represents a button component.
Button>().ActionRow<Button>.setComponents(component: (ButtonLink | ButtonID)[]): ActionRow<Button>
Sets the components of the Action Row.
setComponents([const button: Button
button]);
const const message: WebhookMessage
message = await ctx: CommandContext<{}, never>
ctx.CommandContext<{}, never>.write<true>(body: InteractionCreateBodyRequest, withResponse?: true | undefined): Promise<WebhookMessage>
write( { content?: string | undefined
The message contents (up to 2000 characters)
content: 'Do you want a hello world? Click the button below.', ResolverProps.components?: APIActionRowComponent<APIMessageActionRowComponent>[] | ActionRow<BuilderComponents>[] | undefined
components: [const row: ActionRow<Button>
row], }, true );
const const collector: CreateComponentCollectorResult
collector = const message: WebhookMessage
message.BaseMessage.createComponentCollector(options?: ListenerOptions): CreateComponentCollectorResult
createComponentCollector({ ListenerOptions.filter?: ComponentFilterCallback<ComponentInteraction<boolean, APIMessageComponentInteraction>>
filter: (i: ComponentInteraction<boolean, APIMessageComponentInteraction>
i) => i: ComponentInteraction<boolean, APIMessageComponentInteraction>
i.BaseInteraction<boolean, APIMessageComponentInteraction>.user: User
user.DiscordBase<APIUser>.id: string
id === ctx: CommandContext<{}, never>
ctx.CommandContext<{}, never>.author: User
author.DiscordBase<APIUser>.id: string
id && i: ComponentInteraction<boolean, APIMessageComponentInteraction>
i.BaseInteraction<boolean, APIMessageComponentInteraction>.isButton(): this is ButtonInteraction
isButton(), });
const collector: CreateComponentCollectorResult
collector.CreateComponentCollectorResult.run<CollectorInteraction>(customId: UserMatches, callback: ComponentCallback<CollectorInteraction>): any
run('hello', async (i: CollectorInteraction
i) => { return i: CollectorInteraction
i.Interaction<FromGuild extends boolean = boolean, Type extends APIInteraction = APIInteraction>.write<false>(body: InteractionCreateBodyRequest, withResponse?: false | undefined): Promise<void>
write({ content?: string | undefined
The message contents (up to 2000 characters)
content: 'Hello World 👋' }); }); }}
Manejo del evento onStop del colector
Un colector podría detenerse, lo que significa que no recogerá más interacciones del mensaje. Para manejar la detención, debemos pasar una función de retorno a la opción onStop
al crear el colector.
La función de retorno tomará dos parámetros:
-
reason
. Un texto que indica la razón por la cual el colector se ha detenido. Lo más común estimeout
oidle
si hemos agregado la propiedad de tiempo de espera o inactividad a nuestro colector. Puedes establecer la razón cuando detienes manualmente el colector dentro de la funcióncollector.stop()
. -
refresh
. Una función que puedes ejecutar para refrescar el colector, haciendo que vuelva a recoger interacciones como lo hacía antes.
Aquí tienes un ejemplo de cómo añadimos un tiempo de inactividad al colector de 1000ms y luego, cada vez que entra en la función de retorno onStop
, lo refrescamos.
import { class Button
Represents a button component.
Button, class ActionRow<T extends BuilderComponents>
Represents an Action Row component in a message.
ActionRow, class Command
Command, function Declare(declare: CommandDeclareOptions): <T extends { new (...args: any[]): object;}>(target: T) => { new (...args: any[]): { name: string; nsfw: boolean | undefined; props: ExtraProps | undefined; contexts: InteractionContextType[]; integrationTypes: ApplicationIntegrationType[]; defaultMemberPermissions: bigint | undefined; botPermissions: bigint | undefined; description: string; type: ApplicationCommandType; guildId?: string[]; ignore?: IgnoreCommand; aliases?: string[]; handler?: EntryPointCommandHandlerType; };} & T
Declare, type class CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>interface CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>
CommandContext,} from 'seyfert';
import { enum ButtonStyle
ButtonStyle } from 'seyfert/lib/types';
@function Declare(declare: CommandDeclareOptions): <T extends { new (...args: any[]): object;}>(target: T) => { new (...args: any[]): { name: string; nsfw: boolean | undefined; props: ExtraProps | undefined; contexts: InteractionContextType[]; integrationTypes: ApplicationIntegrationType[]; defaultMemberPermissions: bigint | undefined; botPermissions: bigint | undefined; description: string; type: ApplicationCommandType; guildId?: string[]; ignore?: IgnoreCommand; aliases?: string[]; handler?: EntryPointCommandHandlerType; };} & T
Declare({ name: string
name: 'hello', description: string
description: 'I will send you a hello world message',})export default class class HelloWorldCommand
HelloWorldCommand extends class Command
Command { async HelloWorldCommand.run(ctx: CommandContext): Promise<void>
run(ctx: CommandContext<{}, never>
ctx: class CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>interface CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>
CommandContext) { const const button: Button
button = new new Button(data?: Partial<APIButtonComponent>): Button
Creates a new Button instance.
Button() .Button.setCustomId(id: string): Button
Sets the custom ID for the button.
setCustomId('hello') .Button.setLabel(label: string): Button
Sets the label for the button.
setLabel('Hello') .Button.setStyle(style: ButtonStyle): Button
setStyle(enum ButtonStyle
ButtonStyle.function (enum member) ButtonStyle.Primary = 1
Primary);
const const row: ActionRow<Button>
row = new new ActionRow<Button>({ components, ...data }?: Partial<APIActionRowComponent<APIActionRowComponentTypes>>): ActionRow<...>
Creates a new instance of the ActionRow class.
ActionRow<class Button
Represents a button component.
Button>().ActionRow<Button>.setComponents(component: (ButtonLink | ButtonID)[]): ActionRow<Button>
Sets the components of the Action Row.
setComponents([const button: Button
button]);
const const message: WebhookMessage
message = await ctx: CommandContext<{}, never>
ctx.CommandContext<{}, never>.write<true>(body: InteractionCreateBodyRequest, withResponse?: true | undefined): Promise<WebhookMessage>
write( { content?: string | undefined
The message contents (up to 2000 characters)
content: 'Do you want a hello world? Click the button below.', ResolverProps.components?: APIActionRowComponent<APIMessageActionRowComponent>[] | ActionRow<BuilderComponents>[] | undefined
components: [const row: ActionRow<Button>
row], }, true );
const const collector: CreateComponentCollectorResult
collector = const message: WebhookMessage
message.BaseMessage.createComponentCollector(options?: ListenerOptions): CreateComponentCollectorResult
createComponentCollector({ ListenerOptions.filter?: ComponentFilterCallback<ComponentInteraction<boolean, APIMessageComponentInteraction>>
filter: (i: ComponentInteraction<boolean, APIMessageComponentInteraction>
i) => i: ComponentInteraction<boolean, APIMessageComponentInteraction>
i.BaseInteraction<boolean, APIMessageComponentInteraction>.user: User
user.DiscordBase<APIUser>.id: string
id === ctx: CommandContext<{}, never>
ctx.CommandContext<{}, never>.author: User
author.DiscordBase<APIUser>.id: string
id && i: ComponentInteraction<boolean, APIMessageComponentInteraction>
i.BaseInteraction<boolean, APIMessageComponentInteraction>.isButton(): this is ButtonInteraction
isButton(), ListenerOptions.onStop?: ComponentStopCallback
onStop(reason: "idle" | "messageDelete" | "channelDelete" | "guildDelete" | "timeout" | (string & {}) | undefined
reason, refresh: ComponentRefreshCallback
refresh) { //this will refresh the collector everytime it stops by timeout if (reason: "idle" | "messageDelete" | "channelDelete" | "guildDelete" | "timeout" | (string & {}) | undefined
reason === 'idle') return refresh: () => any
refresh(); }, ListenerOptions.idle?: number
idle: 1e3, //1000ms });
const collector: CreateComponentCollectorResult
collector.CreateComponentCollectorResult.run<CollectorInteraction>(customId: UserMatches, callback: ComponentCallback<CollectorInteraction>): any
run('hello', async (i: CollectorInteraction
i) => { return i: CollectorInteraction
i.Interaction<FromGuild extends boolean = boolean, Type extends APIInteraction = APIInteraction>.write<false>(body: InteractionCreateBodyRequest, withResponse?: false | undefined): Promise<void>
write({ content?: string | undefined
The message contents (up to 2000 characters)
content: 'Hello World 👋' }); }); }}
Manejo de Modales con colectores
Dado que los modales no son componentes de mensajes, no es posible crear un colector de componentes de mensajes
, pero Seyfert introduce la posibilidad de crearlo utilizando el método run
dentro del constructor de modales, que espera una función de retorno que manejará las interacciones.
Aquí tienes un ejemplo utilizando run
dentro del constructor de modales:
import { class Modal<T extends ModalBuilderComponents = TextInput>
Represents a modal for user interactions.
Modal, class Command
Command, function Declare(declare: CommandDeclareOptions): <T extends { new (...args: any[]): object;}>(target: T) => { new (...args: any[]): { name: string; nsfw: boolean | undefined; props: ExtraProps | undefined; contexts: InteractionContextType[]; integrationTypes: ApplicationIntegrationType[]; defaultMemberPermissions: bigint | undefined; botPermissions: bigint | undefined; description: string; type: ApplicationCommandType; guildId?: string[]; ignore?: IgnoreCommand; aliases?: string[]; handler?: EntryPointCommandHandlerType; };} & T
Declare, type class ModalSubmitInteraction<FromGuild extends boolean = boolean>interface ModalSubmitInteraction<FromGuild extends boolean = boolean>
ModalSubmitInteraction, type class CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>interface CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>
CommandContext,} from 'seyfert';
@function Declare(declare: CommandDeclareOptions): <T extends { new (...args: any[]): object;}>(target: T) => { new (...args: any[]): { name: string; nsfw: boolean | undefined; props: ExtraProps | undefined; contexts: InteractionContextType[]; integrationTypes: ApplicationIntegrationType[]; defaultMemberPermissions: bigint | undefined; botPermissions: bigint | undefined; description: string; type: ApplicationCommandType; guildId?: string[]; ignore?: IgnoreCommand; aliases?: string[]; handler?: EntryPointCommandHandlerType; };} & T
Declare({ name: string
name: 'hello', description: string
description: 'I will send you a hello world message',})export default class class HelloWorldCommand
HelloWorldCommand extends class Command
Command { async HelloWorldCommand.run(ctx: CommandContext): Promise<void>
run(ctx: CommandContext<{}, never>
ctx: class CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>interface CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>
CommandContext) { const const modal: Modal<TextInput>
modal = new new Modal<TextInput>(data?: Partial<APIModalInteractionResponseCallbackData>): Modal<TextInput>
Creates a new Modal instance.
Modal() .Modal<TextInput>.setCustomId(id: string): Modal<TextInput>
Sets the custom ID of the modal.
setCustomId('hello') .Modal<TextInput>.setTitle(title: string): Modal<TextInput>
Sets the title of the modal.
setTitle('Hello') .Modal<TextInput>.run(func: ModalSubmitCallback): Modal<TextInput>
Sets the callback function to be executed when the modal is submitted.
run(this.HelloWorldCommand.handleModal(i: ModalSubmitInteraction): Promise<void>
handleModal);
await ctx: CommandContext<{}, never>
ctx.CommandContext<{}, never>.interaction: ChatInputCommandInteraction<boolean>
interaction.Interaction<boolean, APIChatInputApplicationCommandInteraction>.modal(body: ModalCreateBodyRequest): Promise<undefined>
modal(const modal: Modal<TextInput>
modal); }
async HelloWorldCommand.handleModal(i: ModalSubmitInteraction): Promise<void>
handleModal(i: ModalSubmitInteraction<boolean>
i: class ModalSubmitInteraction<FromGuild extends boolean = boolean>interface ModalSubmitInteraction<FromGuild extends boolean = boolean>
ModalSubmitInteraction) { return i: ModalSubmitInteraction<boolean>
i.write<false>(body: InteractionCreateBodyRequest, withResponse?: false | undefined): Promise<void>
write({ content?: string | undefined
The message contents (up to 2000 characters)
content: 'Hello World 👋' }); }}