Commands

Warning

This page is still a work in progress.

Discm has 2 base types of commands:

  • text
  • slash

Text Commands

Text commands read messages and determine if that is a valid command for your bot.

Warning

Text commands are not recommended because it can make your bot slow and they are not developer or user friendly.

Lets make a basic ping text command, which responds with “Pong!” and the websocket heartbeat.

Make a file called ping.js or ping.ts (depending on what language your using) in your commands directory.

// filename: commands/ping.ts
import { DiscmCommand } from 'discm.js';

export default new DiscmCommand({
    type: 'text',
    description: 'Replies with "Pong!"',
    run({ client, message }) {
        message.reply(`Pong! Websocket heatbeat: \`${client.ws.ping}ms\``);
    }
});
// filename: commands/ping.js
const { DiscmCommand } = require('discm.js');

module.exports = new DiscmCommand({
    type: 'text',
    description: 'Replies with "Pong!"',
    run({ client, message }) {
        message.reply(`Pong! Websocket heatbeat: \`${client.ws.ping}ms\``);
    }
});

The callback passes in one argument, which is an object.

This allows you to destruct the object to get the arguments you need, in no particular order.

The object includes the client, message, and a set of parsed options.

The options object is made to mimic interaction.options.

Text command options are automatically parsed for you.

Options can be 1 of 3 types:

  • string: A one word option. Supports choices.
  • number: Any numeric number. Does not support choices.
  • boolean: Either true or false. Does not support choices.

Choices are a set list of acceptable values. Each choice should be defined with a name property and a value property.

The name property is the acceptable value.

The value property is what is returned when that option is retrieved.

If the value is not a valid choice, the entire argument is determined invalid.

Let’s make a math command which performs simple arithmatic (addition, subtraction, multiplication, division) between 2 numbers.

The process will be a string option and will determine which operation to use.

Then the following arguments number1 and number2 will be number options and determine which numbers to use for the arithmatic.

// filename: commands/math.ts
import { DiscmCommand } from 'discm.js';

export default new DiscmCommand({
    type: 'text',
    description: 'Does math.',
    options: [
        {
            name: 'process',
            description: 'The process to use.',
            type: 'string',
            choices: [
                {
                    name: 'add',
                    value: '+'
                },
                {
                    name: 'subtract',
                    value: '-'
                },
                {
                    name: 'multiply',
                    value: '*'
                },
                {
                    name: 'divide',
                    value: '/'
                }
            ]
        },
        {
            name: 'number1',
            description: 'The first number to use in the operation.',
            type: 'number'
        },
        {
            name: 'number2',
            description: 'The second number to use in the operation',
            type: 'number'
        }
    ],
    run({ message, options }) {
        const process = options.getString('process');
        const number1 = options.getNumber('number1');
        const number2 = options.getNumber('number2');

        const equation = `${number1}${process}${number2}`;

        message.reply(
            `The result of your equation (\`${equation}\`) is \`${eval(
                equation
            )}\`.`
        );
    }
});
// filename: commands/math.js
const { DiscmCommand } = require('discm.js');

module.exports = new DiscmCommand({
    type: 'text',
    description: 'Does math.',
    options: [
        {
            name: 'process',
            description: 'The process to use.',
            type: 'string',
            choices: [
                {
                    name: 'add',
                    value: '+'
                },
                {
                    name: 'subtract',
                    value: '-'
                },
                {
                    name: 'multiply',
                    value: '*'
                },
                {
                    name: 'divide',
                    value: '/'
                }
            ]
        },
        {
            name: 'number1',
            description: 'The first number to use in the operation.',
            type: 'number'
        },
        {
            name: 'number2',
            description: 'The second number to use in the operation',
            type: 'number'
        }
    ],
    run({ message, options }) {
        const process = options.getString('process');
        const number1 = options.getNumber('number1');
        const number2 = options.getNumber('number2');

        const equation = `${number1}${process}${number2}`;

        message.reply(
            `The result of your equation (\`${equation}\`) is \`${eval(
                equation
            )}\`.`
        );
    }
});

Slash Commands

Slash commands are the new era of discord commands.

They improve speed, are more developer friendly, and more user friendly.

Learn more

Lets make a basic ping slash command, which responds with “Pong!” and the websocket heartbeat.

Make a file called ping.js or ping.ts (depending on what language your using) in your commands directory.

// filename: commands/ping.ts
import { DiscmCommand } from 'discm.js';

export default new DiscmCommand({
    type: 'slash',
    description: 'Replies with "Pong!"',
    run({ client, interaction }) {
        interaction.reply({
            content: `Pong! Websocket heatbeat: \`${client.ws.ping}ms\``,
            ephemeral: true
        });
    }
});
// filename: commands/ping.js
const { DiscmCommand } = require('discm.js');

module.exports = new DiscmCommand({
    type: 'slash',
    description: 'Replies with "Pong!"',
    run({ client, interaction }) {
        interaction.reply({
            content: `Pong! Websocket heatbeat: \`${client.ws.ping}ms\``,
            ephemeral: true
        });
    }
});

Like text commands, the callback passes in one argument, which is an object.

This allows you to destruct the object to get the arguments you need, in no particular order.

The object includes the client and the interaction that invoked the command.

The options property is uploaded directly to discord.

To set an option type, discm exports CommandOptionType enum, which is a copy of ApplicationCommandOptionType from discord.js (defined in discord-api-types)

Let’s make a math command which performs simple arithmatic (addition, subtraction, multiplication, division) between 2 numbers.

// filename: commands/math.ts
import { CommandOptionType, DiscmCommand } from 'discm.js';

export default new DiscmCommand({
    type: 'slash',
    description: 'Does math.',
    options: [
        {
            name: 'process',
            description: 'The process to use.',
            type: CommandOptionType.String,
            choices: [
                {
                    name: 'add',
                    value: '+'
                },
                {
                    name: 'subtract',
                    value: '-'
                },
                {
                    name: 'multiply',
                    value: '*'
                },
                {
                    name: 'divide',
                    value: '/'
                }
            ],
            required: true
        },
        {
            name: 'number1',
            description: 'The first number to use in the operation.',
            type: CommandOptionType.Integer
        },
        {
            name: 'number2',
            description: 'The second number to use in the operation',
            type: CommandOptionType.Integer
        }
    ],
    run({ interaction }) {
        const process = interaction.options.getString('process');
        const number1 = interaction.options.getInteger('number1');
        const number2 = interaction.options.getInteger('number2');

        const equation = `${number1}${process}${number2}`;

        interaction.reply({
            content: `The result of your equation (\`${equation}\`) is \`${eval(
                equation
            )}\`.`,
            ephemeral: true
        });
    }
});
// filename: commands/math.js
const { CommandOptionType, DiscmCommand } = require('discm.js');

module.exports = new DiscmCommand({
    type: 'slash',
    description: 'Does math.',
    options: [
        {
            name: 'process',
            description: 'The process to use.',
            type: CommandOptionType.String,
            choices: [
                {
                    name: 'add',
                    value: '+'
                },
                {
                    name: 'subtract',
                    value: '-'
                },
                {
                    name: 'multiply',
                    value: '*'
                },
                {
                    name: 'divide',
                    value: '/'
                }
            ],
            required: true
        },
        {
            name: 'number1',
            description: 'The first number to use in the operation.',
            type: CommandOptionType.Integer
        },
        {
            name: 'number2',
            description: 'The second number to use in the operation',
            type: CommandOptionType.Integer
        }
    ],
    run({ interaction }) {
        const process = interaction.options.getString('process');
        const number1 = interaction.options.getInteger('number1');
        const number2 = interaction.options.getInteger('number2');

        const equation = `${number1}${process}${number2}`;

        interaction.reply({
            content: `The result of your equation (\`${equation}\`) is \`${eval(
                equation
            )}\`.`,
            ephemeral: true
        });
    }
});

Subcommands

To make a subcommand, make a directory inside the commands directory, name it what you want the command to be named.

Then, make a file, name it what you want the subcommand to be named.

All subcommands must be a slash command, or else discm will throw a CommandError.

Overloading

Command overloading is a discm feature that allows you to make 2 commands with the same name, one is a text command and the other is a slash command.

Ideally, the commands would accomplish the same task, but this is not required.

You cannot overload a subcommand.

To make a command overload, create a file in your commands directory and name it command-name.overload.ts or command-name.overload.js, replacing command-name with the name of the command you wish to overload.

Make sure a file without the .overload in the name exists or discm will throw an error.

When parsed, discm combines these two commands into one.

/** * A parsed overload command (slash and text). */ export interface ParsedOverloadCommand { /** * Specifies that this command has data for both a slash and text command. */ type: 'overload'; /** * The name of the command. */ name: string; /** * The description of the command. */ description: string; /** * The options the text command uses. Slash command options are only in data. */ options: AnyCommandTextOption[]; /** * Overload commands do not permit plugins yet. */ plugins: []; /** * The data of the command deployed to discord. */ data: RESTPostAPIApplicationCommandsJSONBody; /** * Whether to delay the deployment of this command. */ delayedDeploy: boolean; /** * The callback for the slash version of this command. * @param client The client of this command. * @param interaction The interaction that called this command. */ slashRun: ( client: DiscmClient, interaction: ChatInputCommandInteraction ) => Awaitable<void>; /** * The callback for the text version of command. * @param client The client of this command. * @param message The message that called the command. * @param options The options the command uses. */ textRun: ( client: DiscmClient, message: Message, options: CommandTextOptionResults ) => Awaitable<void>; }
typescript
undefined

Deployment

Discm automatically deploys all commands for you when client.login is called.

You can delay the deployment of all commands by setting client.delayDeploy to true.

You can also delay the deployment of individual commands by setting DiscmCommand#delayDeploy to true.

Note

These commands will not deploy until manually done so. The deploy function is exposed by client.deploy, however, its not recommended to use this command unless all commands deployment has been delayed. Use client.deployCommand for individual commands.