Skip to content

Create your first Message Command

Message Commands Overview

What are Message Commands?

Message commands are the primary type of commands. Unlike their sisters, they are not used with a forward slash (/) but with a prefix defined in Installation. They offer a basic method of sending commands to bots, and are considered by many users like deprecated.

Importance of Message Commands

Message commands are crucial for enhancing user experience by creating most sophisticated and private commands. They are not also widespread as slash commands but you can find an use for them.

Implementing Message Commands (with ban.js)

To define the ban command, start by importing necessary elements from the umbrae library and setting up the command structure with CommandBuilder. For the example below, we created the command with the path ./commands/[dir]/ban.js.

Warning

In this path [dir] represents a mid-level directory situated between the root commands directory and the specific command file (ban.js). This structure helps organize commands into categorically relevant directories for better manageability and clarity.

js
import { CommandBuilder, Permissions} from 'umbrae';

export default CommandBuilder(
    {
        slash: false,
        name: 'ban',
        description: 'Ban a member',
        permissions: [Permissions.BanMembers, Permissions.ManageMessages],
        cooldown: 5,
        args: [
            {
                name: 'user',
                type: 'User',
                description: 'The user to ban',
            },
            {
                name: 'reason',
                type: 'String',
                description: 'The reason for the ban',
            }
        ]
    },
    async (message, app, args) => {
        
        const user = args.getUser('user');
        if (!user) return message.reply({ content: 'Please mention the user to ban.' });

        const member = message.guild.members.cache.get(user.id);
        const appMember = message.guild.members.cache.get(app.user.id);
        const reason = args.list[1] // user is args.list[0]
        
        if (appMember.permissions.has(Permissions.BanMembers) && (appMember.roles.highest.position > (member.roles.highest.position as number))
        && member.manageable) {
            try {
                await member.ban({ reason });
                await message.reply({ content: 'Sucefully banned '+` **${user.globalName}** (`+"`"+user.id+"`"+')' });
            } catch (e) {
                console.error(e);
                await message.reply({ content: 'An error occured while banning '+` **${user.globalName}** (`+"`"+user.id+"`"+')' });
            }
        }
    }
)
ts
import { CommandBuilder, Permissions, MessageCommandBuilderOptions } from 'umbrae';

export default CommandBuilder<MessageCommandBuilderOptions>(
    {
        name: 'ban',
        description: 'Ban a member',
        permissions: [Permissions.BanMembers, Permissions.ManageMessages],
        cooldown: 5,
        args: [
            {
                name: 'user',
                type: 'User',
                description: 'The user to ban',
            },
            {
                name: 'reason',
                type: 'String',
                description: 'The reason for the ban',
            }
        ]
    },
    async (message, app, data) => {
        
        const user = args.getUser('user');
        if (!user) return message.reply({ content: 'Please mention the user to ban.' });

        const member = message.guild?.members.cache.get((user.id as string));
        const appMember = message.guild?.members.cache.get((app.user?.id as string));
        const reason = args.list[1] // user is args.list[0];
        
        if (appMember?.permissions.has(Permissions.BanMembers) && (appMember.roles.highest.position > (member?.roles.highest.position as number))
        && member?.manageable) {
            try {
                await member?.ban({ reason });
                await message.reply({ content: 'Sucefully banned '+` **${user.globalName}** (`+"`"+user.id+"`"+')' });
            } catch (e) {
                console.error(e);
                await message.reply({ content: 'An error occured while banning '+` **${user.globalName}** (`+"`"+user.id+"`"+')' });
            }
        }
    }
)

Warning

The option slash set to false or not defined is required to build a MessageCommand otherwise you are building a SlashCommand.

Key Features of the CommandBuilder 1.0.3

  • Simplicity and Clarity: The CommandBuilder function simplifies the definition and setup of commands by encapsulating options and logic in a single function call.
  • Permission Handling: It easily integrates permission checks to ensure that only authorized users can execute sensitive commands like banning.
  • Argument Handling: This setup enables the command to handle user inputs efficiently, providing auto-complete options for reasons, and requiring necessary arguments.

CommandBuilderOptions

If you are using TypeScript to build your project, you should opt for MessageCommandBuilderOptions instead of creating a standard CommandBuilder function. However, you should also review this section to ensure that you are creating commands correctly.

ts
type Permissions = BitFieldResolvable<keyof typeof PermissionFlagsBits, bigint>;
type ArgType = 'Attachment' | 'User' | 'Channel' | 'Role' | 'Mentionable' | 'String' | 'Integer' | 'Number' | 'Boolean' | 'Subcommand' | 'SubcommandGroup';

interface Choice {
    name: string;
    value: string | number;
}

interface Arg {
    name: string;
    description: string;
    type: ArgType;
    choices?: Choice[];
    required?: boolean;
}


interface CommandBuilderOptionsBase {
    name: string;
    description: string;
    cooldown?: number;
    permissions: Permissions[];
    args?: Arg[];
}

interface MessageCommandBuilderOptions extends CommandBuilderOptionsBase {
    slash?: false;
}

Callback Message Commands

The callback of CommandBuilder for MessageCommandBuilderOptions is a way different from CommandBuilder for SlashCommandBuilderOptions.

You always have 3 arguments but they have different use cases:

  • message: The message received for this command.
  • app : the application receiving the command.
  • args: an instance of our Args class.

Args

For enhancing users experience we introduce the Args class to provide you many additional possibilities with Message Command. Here is a quick example.

js
export default CommandBuilder(
    {
        ...,
        args: [
            {
                name: 'myRole',
                description: 'My awesome role',
                type: 'Role'
            },
            {
                name: 'secondRole',
                description: 'My awesome role',
                type: 'Role'
            },
            {
                name: 'logs',
                description: 'The channel logs',
                type: 'Channel'
            },
            {
                name: 'me',
                description: 'Myself',
                type: 'User'
            }
        ]
    },
    async (message, app, args) => {
        
        const role = args.getRole('myRole'); // get the role by your role option name.
        const secondRole = args.getRole('secondRole'); // get the second role by your role option name.


        const channel = args.getChannel('logs')
        if (channel) message.reply({ content: 'Successfully tried this example !'});

        const user =  args.getUser('me'); 

        console.log(args.list) // Output : ['<@&192020220210>', '<@&19202303210>', '<#292010202202>', '<@198202922902>', 'beautiful', 'test']
        console.log(args.list[4]) // Output : beautiful
    }
)

:::