Sending Messages
The basic feature of Discord Bots is sending messages across Discord. That’s why here we will see how to send messages with Seyfert.
First of all, we need to set up a basic Hello World
command.
Having set up our basic Hello World
command, we are now ready to send our first message using the CommandContext.write()
function.
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: 'Sends a basic hello world message.',})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: 'Hello world 👋' }); }}
The CommandContext.write()
function will respond to the command.
EditOrReply
But what if we want to respond to the command or edit its response instead of just replying?
We can use the CommandContext.editOrReply()
function. This function is used to reply to the command, or if a reply has already been sent, it will edit it.
This function is very useful if we want to develop a command that responds to the command or, if the command has been answered, edits the response. If we are only using a simple CommandContext.write()
, a response will be sent in all cases.
Here’s an example of how to implement this function.
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();
// do something that takes time and is boring
await ctx: CommandContext<{}, never>
ctx.CommandContext<{}, never>.editOrReply<false>(body: InteractionCreateBodyRequest | InteractionMessageUpdateBodyRequest, withResponse?: false | undefined): Promise<...>
editOrReply({ content: string
content: 'I did some stuff' }); }}
Sending Messages Without a Response
While reading this guide, you may have thought about the possibility of simply sending a message to a channel instead of responding to a command.
Here we are. To send a simple message to a specific channel, we need to get its ID and then access the BaseClient.messages
property and use the write
function.
Here’s an example of how to send that message without replying to a command:
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: 'Hello world 👋' }); }}
Sending Embeds
Discord adds the ability to send embedded messages within a channel.
To send these embedded messages with Seyfert, we need to construct the embed using the Embed builder. For more information about customizing the embedded message, you can check out the Embed builder within this documentation.
Here’s an example of how to send an embed with a custom title and description.
import { class Embed
Represents a message embed.
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.
Embed() .Embed.setTitle(title?: string): Embed
Sets the title of the embed.
setTitle('My Amazing Embed') .Embed.setDescription(desc?: string): Embed
Sets the description of the embed.
setDescription('Hello world 👋');
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] }); }}
Sending Components Attached to the Message
Discord includes the ability to send components attached to a message within an ActionRow
. These components can be Buttons
or SelectMenus
.
Components are stored in an ActionRow
, which can contain up to 5 different buttons and only one select menu and cannot contain another ActionRow inside.
In this example, we are going to send two action rows within the message. Each row will have a button and a string select menu attached, respectively.
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.
StringSelectMenu, class StringSelectOption
Represents an individual option for a string select menu.
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';import { enum ButtonStyle
ButtonStyle } from 'seyfert/lib/types'
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('helloworld') .Button.setLabel(label: string): Button
Sets the label for the button.
setLabel('Hello World') .Button.setStyle(style: ButtonStyle): Button
setStyle(enum ButtonStyle
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.
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.
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.
StringSelectMenu() .SelectMenu<APISelectMenuComponent, ComponentInteraction<boolean, APIMessageComponentInteraction>>.setCustomId(id: string): StringSelectMenu
Sets the custom ID for the select menu.
setCustomId('select-helloworld') .StringSelectMenu.addOption(...options: RestOrArray<StringSelectOption>): StringSelectMenu
Adds options to the string select menu.
addOption( new new StringSelectOption(data?: Partial<APISelectMenuOption>): StringSelectOption
Represents an individual option for a string select menu.
StringSelectOption().StringSelectOption.setLabel(label: string): StringSelectOption
Sets the label for the option.
label - The label for the option.
setLabel('Hello').StringSelectOption.setValue(value: string): StringSelectOption
Sets the value for the option.
value - The value for the option.
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.
ActionRow<class StringSelectMenu
Represents a Select Menu for selecting string options.
StringSelectMenu>().ActionRow<StringSelectMenu>.addComponents(...component: RestOrArray<StringSelectMenu>): ActionRow<StringSelectMenu>
Adds one or more components to the Action Row.
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: 'Hello world 👋', ResolverProps.components?: APIActionRowComponent<APIMessageActionRowComponent>[] | ActionRow<BuilderComponents>[] | undefined
components: [const buttonRow: ActionRow<Button>
buttonRow, const menuRow: ActionRow<StringSelectMenu>
menuRow] }); }}