Saltearse al contenido

Enviando Mensajes

La característica básica de los Bots de Discord es enviar mensajes en todo Discord. Y en Seyfert puedes enviarlos de la manera más fácil.

Primero que nada, tenemos que configurar un comando básico de Hola mundo.

src/commands/helloworld.ts
import {
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';
@
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
: 'helloworld',
description: string
description
: 'Envía un mensaje básico de hola mundo.',
})
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
) {}
}

Habiendo configurado nuestro comando básico de Hola mundo, estamos listos para enviar nuestro primer mensaje usando la función CommandContext.write().

src/commands/helloworld.ts
import {
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';
@
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
: 'helloworld',
description: string
description
: 'Envía un mensaje básico de hola mundo.',
})
export default class
class HelloWorldCommand
HelloWorldCommand
extends
class Command
Command
{
async
HelloWorldCommand.run(ctx: CommandContext): Promise<void | WebhookMessage>
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
) {
return
ctx: CommandContext<{}, never>
ctx
.
CommandContext<{}, never>.write<false>(body: InteractionCreateBodyRequest, withResponse?: false | undefined): Promise<void | WebhookMessage>
write
({
content?: string | undefined

The message contents (up to 2000 characters)

content
: 'Hola mundo 👋' });
}
}

La función CommandContext.write() responderá al comando.

EditOrReply

Pero, ¿qué pasa si queremos responder al comando o editar su respuesta en lugar de simplemente responder?

Podemos usar la función CommandContext.editOrReply(). Esta función se utiliza para responder al comando o, si la respuesta ya ha sido enviada, editarla.

Esta función es muy útil si queremos desarrollar un comando que responda al comando o, si el comando fue respondido, la respuesta será editada. Si solo estamos usando un CommandContext.write() simple, enviaremos una respuesta en todos los casos.

Aquí hay un ejemplo de cómo implementar esta función.

src/commands/helloworld.ts
import {
class Command
Command
, type
class CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>
interface CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>
CommandContext
} from 'seyfert';
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
) {
await
ctx: CommandContext<{}, never>
ctx
.
CommandContext<{}, never>.deferReply<false>(ephemeral?: boolean, withResponse?: false | undefined): Promise<undefined>
deferReply
();
// hacer algo que toma tiempo y es aburrido
await
ctx: CommandContext<{}, never>
ctx
.
CommandContext<{}, never>.editOrReply<false>(body: InteractionCreateBodyRequest | InteractionMessageUpdateBodyRequest, withResponse?: false | undefined): Promise<...>
editOrReply
({
content: string
content
: 'Hice cosas' });
}
}

Enviando mensajes sin una respuesta

Leyendo esta guía podrías haber pensado en la posibilidad de solo enviar un mensaje a un canal en lugar de responder a un comando.

Aquí estamos. Para enviar un mensaje simple a un canal específico, necesitamos recuperar su id y luego acceder a la propiedad BaseClient.messages y ejecutar la función write.

Aquí hay un ejemplo de cómo enviar ese mensaje sin responder a un comando:

src/commands/helloworld.ts
import {
class Command
Command
, type
class CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>
interface CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>
CommandContext
} from 'seyfert';
export default class
class HelloWorldCommand
HelloWorldCommand
extends
class Command
Command
{
async
HelloWorldCommand.run(ctx: CommandContext): Promise<Message>
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
) {
return
ctx: CommandContext<{}, never>
ctx
.
CommandContext<{}, never>.client: UsingClient
client
.
BaseClient.messages: MessageShorter
messages
.
MessageShorter.write(channelId: string, { files, ...body }: MessageCreateBodyRequest): Promise<MessageStructure>
write
(
ctx: CommandContext<{}, never>
ctx
.
CommandContext<{}, never>.channelId: string
channelId
, {
content?: string | undefined

The message contents (up to 2000 characters)

content
: 'Hola mundo 👋' });
}
}

Enviando Embeds

Discord añade la posibilidad de enviar mensajes incrustados dentro de un canal.

Para enviar esos mensajes incrustados con Seyfert, tendremos que construir el embed con el constructor de Embed. Para obtener más información sobre la personalización del mensaje incrustado, puedes consultar el constructor de Embed dentro de esta documentación.

Aquí hay un ejemplo de cómo enviar un embed con un título y descripción personalizados.

src/commands/helloworld.ts
import {
class Embed

Represents a message embed.

@example const embed = new Embed(); embed.setTitle('Seyfert'); embed.setDescription('Better than discord.js'); embed.setColor('Green'); const embedJSON = embed.json();

Embed
,
class Command
Command
, type
class CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>
interface CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>
CommandContext
} from 'seyfert';
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 embed: Embed
embed
= new
new Embed(data?: Partial<APIEmbed>): Embed

Creates a new instance of Embed.

@paramdata - The initial data for the embed.

@example const embed = new Embed({ title: 'Hello', description: 'This is an example embed' });

Embed
()
.
Embed.setTitle(title?: string): Embed

Sets the title of the embed.

@paramtitle - The title of the embed.

@returnsThe updated Embed instance.

@example embed.setTitle('This is the title');

setTitle
('Mi Embed Asombroso')
.
Embed.setDescription(desc?: string): Embed

Sets the description of the embed.

@paramdesc - The description of the embed.

@returnsThe updated Embed instance.

@example embed.setDescription('This is the description of the embed');

setDescription
('Hola mundo 👋');
await
ctx: CommandContext<{}, never>
ctx
.
CommandContext<{}, never>.write<false>(body: InteractionCreateBodyRequest, withResponse?: false | undefined): Promise<void | WebhookMessage>
write
({
ResolverProps.embeds?: Embed[] | APIEmbed[] | undefined
embeds
: [
const embed: Embed
embed
] });
}
}

Enviando componentes adjuntos al mensaje

Discord incluye la posibilidad de enviar componentes adjuntos al mensaje dentro de un ActionRow. Estos componentes pueden ser Buttons o SelectMenus.

Los componentes se almacenan en un ActionRow que puede contener hasta 5 botones diferentes y solo un menú de selección y no puede contener otro ActionRow en su interior.

En este ejemplo vamos a enviar dos filas de acciones dentro del mensaje. Cada fila va a tener un botón y un menú de selección de cadena adjuntos respectivamente.

src/commands/helloworld.ts
import {
class ActionRow<T extends BuilderComponents>

Represents an Action Row component in a message.

ActionRow
,
class Button

Represents a button component.

Button
,
class StringSelectMenu

Represents a Select Menu for selecting string options.

@example const stringSelectMenu = new StringSelectMenu(); stringSelectMenu.setCustomId("string-select"); stringSelectMenu.addOption(new StringSelectOption().setLabel("Option 1").setValue("option_1")); stringSelectMenu.setOptions([ { label: "Option 2", value: "option_2" }, { label: "Option 3", value: "option_3" }, ]);

StringSelectMenu
,
class StringSelectOption

Represents an individual option for a string select menu.

@example const option = new StringSelectOption().setLabel("Option 1").setValue("option_1");

StringSelectOption
,
class Command
Command
,
type
class CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>
interface CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>
CommandContext
} from 'seyfert';
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.

@paramdata - The initial data for the button.

Button
()
.
Button.setCustomId(id: string): Button

Sets the custom ID for the button.

@paramid - The custom ID to set.

@returnsThe modified Button instance.

setCustomId
('helloworld')
.
Button.setLabel(label: string): Button

Sets the label for the button.

@paramlabel - The label to set.

@returnsThe modified Button instance.

setLabel
('Hola mundo')
.
Button.setStyle(style: ButtonStyle): Button
setStyle
(ButtonStyle.
function (enum member) ButtonStyle.Primary = 1
Primary
);
const
const buttonRow: ActionRow<Button>
buttonRow
= new
new ActionRow<Button>({ components, ...data }?: Partial<APIActionRowComponent<APIActionRowComponentTypes>>): ActionRow<...>

Creates a new instance of the ActionRow class.

@paramdata - Optional data to initialize the Action Row.

@example const actionRow = new ActionRow({ components: [buttonRawJSON] });

ActionRow
<
class Button

Represents a button component.

Button
>().
ActionRow<Button>.addComponents(...component: RestOrArray<ButtonLink | ButtonID>): ActionRow<Button>

Adds one or more components to the Action Row.

@paramcomponent - The component(s) to add.

@returnsThe updated Action Row instance.

@example actionRow.addComponents(buttonComponent); actionRow.addComponents(buttonComponent1, buttonComponent2); actionRow.addComponents([buttonComponent1, buttonComponent2]);

addComponents
(
const button: Button
button
);
const
const menu: StringSelectMenu
menu
= new
new StringSelectMenu(data?: Partial<APIStringSelectComponent>): StringSelectMenu

Represents a Select Menu for selecting string options.

@example const stringSelectMenu = new StringSelectMenu(); stringSelectMenu.setCustomId("string-select"); stringSelectMenu.addOption(new StringSelectOption().setLabel("Option 1").setValue("option_1")); stringSelectMenu.setOptions([ { label: "Option 2", value: "option_2" }, { label: "Option 3", value: "option_3" }, ]);

StringSelectMenu
()
.
SelectMenu<APISelectMenuComponent, ComponentInteraction<boolean, APIMessageComponentInteraction>>.setCustomId(id: string): StringSelectMenu

Sets the custom ID for the select menu.

@paramid - The custom ID for the select menu.

@returnsThe current SelectMenu instance.

setCustomId
('select-helloworld')
.
StringSelectMenu.addOption(...options: RestOrArray<StringSelectOption>): StringSelectMenu

Adds options to the string select menu.

@paramoptions - Options to be added.

@returnsThe current StringSelectMenu instance.

addOption
(
new
new StringSelectOption(data?: Partial<APISelectMenuOption>): StringSelectOption

Represents an individual option for a string select menu.

@example const option = new StringSelectOption().setLabel("Option 1").setValue("option_1");

StringSelectOption
().
StringSelectOption.setLabel(label: string): StringSelectOption

Sets the label for the option. label - The label for the option.

@returnsThe current StringSelectOption instance.

setLabel
('Hello').
StringSelectOption.setValue(value: string): StringSelectOption

Sets the value for the option. value - The value for the option.

@returnsThe current StringSelectOption instance.

setValue
('option_1')
);
const
const menuRow: ActionRow<StringSelectMenu>
menuRow
= new
new ActionRow<StringSelectMenu>({ components, ...data }?: Partial<APIActionRowComponent<APIActionRowComponentTypes>>): ActionRow<...>

Creates a new instance of the ActionRow class.

@paramdata - Optional data to initialize the Action Row.

@example const actionRow = new ActionRow({ components: [buttonRawJSON] });

ActionRow
<
class StringSelectMenu

Represents a Select Menu for selecting string options.

@example const stringSelectMenu = new StringSelectMenu(); stringSelectMenu.setCustomId("string-select"); stringSelectMenu.addOption(new StringSelectOption().setLabel("Option 1").setValue("option_1")); stringSelectMenu.setOptions([ { label: "Option 2", value: "option_2" }, { label: "Option 3", value: "option_3" }, ]);

StringSelectMenu
>().
ActionRow<StringSelectMenu>.addComponents(...component: RestOrArray<StringSelectMenu>): ActionRow<StringSelectMenu>

Adds one or more components to the Action Row.

@paramcomponent - The component(s) to add.

@returnsThe updated Action Row instance.

@example actionRow.addComponents(buttonComponent); actionRow.addComponents(buttonComponent1, buttonComponent2); actionRow.addComponents([buttonComponent1, buttonComponent2]);

addComponents
(
const menu: StringSelectMenu
menu
);
await
ctx: CommandContext<{}, never>
ctx
.
CommandContext<{}, never>.write<false>(body: InteractionCreateBodyRequest, withResponse?: false | undefined): Promise<void | WebhookMessage>
write
({
content?: string | undefined

The message contents (up to 2000 characters)

content
: 'Hola mundo 👋',
ResolverProps.components?: APIActionRowComponent<APIMessageActionRowComponent>[] | ActionRow<BuilderComponents>[] | undefined
components
: [
const buttonRow: ActionRow<Button>
buttonRow
,
const menuRow: ActionRow<StringSelectMenu>
menuRow
] });
}
}