Skip to content

Prefix Commands

Prefix Configuration

Seyfert handles not only application commands but also prefix commands. They are not enabled by default, but you can enable them by configuring an option within ClientOptions. We have access to the command option where we can specify a suboption called prefix. This option expects a callback that returns an array of possible prefixes for that command. Since the callback returns a Message, we have access to the command option where we can specify a suboption called prefix. This option expects a callback returning an array of possible prefixes for that command. As the callback returns a Message property inside CommandContext, it is quite simple to handle different prefixes per server.

Here’s an example where we configure multiple prefixes for all commands.

import { Client } from 'seyfert';
const client = new Client({
commands: {
prefix: (msg) => {
// here you can handle whatever prefixes you want depending on the message data.
return ['!', '?', '.']
}
}
});

Handling Prefix Commands

After configuring our prefixes for commands, it’s time to make them work.

Fortunately, handling them works the same way as application commands. The only difference is that we receive an optional Message property inside the CommandContext.

To make this property appear in our CommandContext, all we need to do is declare the Seyfert module and set the withPrefix property inside InternalOptions to true. You can see this detailed example.

In this example, we are going to create a command that crossposts the message sent in an announcement channel.

import {
Command,
CommandContext,
Declare
} from 'seyfert';
@Declare({
name: 'crosspost',
description: 'Crosspost an announcement message.'
})
export default class CrosspostCommand extends Command {
async run(ctx: CommandContext){
if(ctx.message) await ctx.message.crosspost();
return ctx.write({ content: 'I have crossposted your announcement.'});
}
};

Ignoring Commands

You can decide whether a command should ignore being a slash command or a text command.

import {
Command,
CommandContext,
Declare,
IgnoreCommand
} from 'seyfert';
@Declare({
name: 'crosspost',
description: 'Crosspost an announcement message.',
ignore: IgnoreCommand.Slash
})
export default class CrosspostCommand extends Command {
async run(ctx: CommandContext){
if(ctx.message) await ctx.message.crosspost();
return ctx.write({ content: 'I have crossposted your announcement.'});
}
};

Responding to Prefix Commands

By default, when you use the write or editOrReply function, it will only send a message to the channel where the command was triggered. To make the command respond, you need to configure the reply suboption within the command option in the client options. This option is a callback whose first parameter is the CommandContext and expects a boolean to be returned: if true, it will reply to the command; if not, it will just send a message.

Here’s a detailed example of what your client will look like with all the modifications mentioned in this guide:

import { Client } from 'seyfert';
const client = new Client({
commands: {
prefix: (msg) => {
// here you can handle whatever prefixes you want depending on the message data.
return ['!', '?', '.']
},
reply: (ctx) => true
}
});

Prefix Command Options

Just like with application commands, you can configure options for prefix commands. The only thing you need to do is declare them as you do with application commands. They are parsed with a regex that indicates that options will be split when followed by -. You can replace the parser with your own parser in the argsParser suboption within the commands options in the client options. This is a callback whose parameters are content, the message content, and command, the command that was executed, and expects an object whose keys are the options and values are the option values.

Here’s a short template showing how options work in prefix commands.

Prefix Command Template
!command -option value_option -option2 value_option2

Here you can see how we modify the previous command, but instead of crossposting the current message, we crosspost another message by getting its ID, which will be provided in the options.

import {
Command,
CommandContext,
Declare,
Options,
createStringOption
} from 'seyfert';
const options = {
id: createStringOption({
description: 'The ID of the message we are going to crosspost',
required: true
})
};
@Declare({
name: 'crosspost',
description: 'Crosspost an announcement message.'
})
@Options(options)
export default class CrosspostCommand extends Command {
async run(ctx: CommandContext<typeof options>){
await ctx.client.messages.crosspost(ctx.options.id, ctx.channelId);
return ctx.write({ content: 'I have crossposted your announcement.'});
}
};

Deferring Response with Prefix Commands

Just like with application commands, you can defer the response of a command. By default, if you use the CommandContext.deferReply() function, it will defer the response by showing a Loading... message. If we want the deferred response to be customized, we need to check the commands option in the client options again, as we need to create a callback for deferReplyResponse that expects the content to send during the deferral.

Here is an example of how we modify the client options and make the command response deferred using the previous example.

import { Client } from 'seyfert';
const client = new Client({
commands: {
prefix: (msg) => {
// here you can handle whatever prefixes you want depending on the message data.
return ['!', '?', '.']
},
reply: (ctx) => true,
deferReplyResponse: (ctx) => ({ content: 'Please wait, processing your request...' })
}
});