Skip to main content

Registering Context Commands

Context Menu Commands are another kind of application command. They show up, as the name implies, in the context menus of either messages or users when you right click them.

Message Context MenuUser Context Menu
warning

There's a lot of overlap with the previous Registering Chat Input Commands section, including important information that isn't repeated here, so please skim that first!

To register a Message or User Context Command, implement the registerApplicationCommands method for the Command class. The method's parameter will be the command's pre-defined ApplicationCommandRegistry, on which you can call registerContextMenuCommand to register your application command.

A brief breakdown of registerContextMenuCommand

This method is responsible for describing how a Message or User Context Menu Command will be registered. It takes two parameters:

How to register a Message Context Menu Command

Register a Message Context Menu Command by calling the registerContextMenuCommand method on the registry with the type specified in .setType(), this looks like:

const { Command } = require('@sapphire/framework');
const { ApplicationCommandType } = require('discord.js');

class SlashCommand extends Command {
constructor(context, options) {
super(context, {
...options,
description: 'Delete message and ban author.'
});
}

registerApplicationCommands(registry) {
registry.registerContextMenuCommand((builder) =>
builder //
.setName(this.name)
.setType(ApplicationCommandType.Message)
);
}

contextMenuRun(interaction) {
// ...
}
}
module.exports = {
SlashCommand
};

It should be noted that unlike Registering Chat Input Commands, it's not possible for Context Menu Commands to hold a description. This is why we recommend using the ContextMenuCommandBuilder here for input verificiation instead of alternatives such as writing the ApplicationCommandData JSON yourself.

warning

The registerContextMenuCommand method, similar to the registerChatInputCommand method in the previous section, takes in a second options parameter. Please see Chat Input Command Registry Options, since there are important details not repeated here.

How to register a User Context Menu Command

Registering a User Context Menu is done in the same way, with the only difference being a different type specified in .setType():

const { Command } = require('@sapphire/framework');
const { ApplicationCommandType } = require('discord.js');

class SlashCommand extends Command {
constructor(context, options) {
super(context, {
...options,
description: 'Ban user.'
});
}

registerApplicationCommands(registry) {
registry.registerContextMenuCommand((builder) =>
builder //
.setName(this.name)
.setType(ApplicationCommandType.User)
);
}

contextMenuRun(interaction) {
// ...
}
}
module.exports = {
SlashCommand
};
warning

Just like the Message Context Menu Command, the registerContextMenuCommand method takes in a second options parameter. Please see Chat Input Command Registry Options, since there are important details not repeated here.

Implementing a Context Menu Command

Now that we've covered registering a Message or User Context Menu Command, the last step is to implement the contextMenuRun method for the Command class so your bot can respond! The example here is the second User Context Menu Command started above:

const { Command } = require('@sapphire/framework');
const { ApplicationCommandType, userMention, GuildMember } = require('discord.js');

class SlashCommand extends Command {
constructor(context, options) {
super(context, {
...options,
description: 'Ban user.'
});
}

registerApplicationCommands(registry) {
registry.registerContextMenuCommand((builder) =>
builder //
.setName(this.name)
.setType(ApplicationCommandType.User)
);
}

async contextMenuRun(interaction) {
// Use isUserContextMenu() to ensure this command was executed as a User Context Menu Command
if (interaction.isUserContextMenu() && interaction.targetMember instanceof GuildMember) {
await interaction.targetMember.ban({
days: 8,
reason: 'Banned for for breaking the rules.'
});

const userToGreetMention = userMention(interaction.targetMember.id);

return interaction.reply({
content: `${userToGreetMention} has been successfully banned`,
allowedMentions: {
users: [interaction.targetMember.id]
}
});
}
}
}
module.exports = {
SlashCommand
};
info

Since contextMenuRun runs both kind of context commands, we recommend using either isMessageContextMenu() or isUserContextMenu() to ensure the correct kind of context menu application command is executing your command.