Command mentions
Mention a slash command in your bot's messages, so a reader clicks it rather than retyping it. Covers the route keys, what an entry holds, why a command in two servers has no mention, when the list fills during startup, and context menu commands.
Discord turns </role remove:1287> into a clickable mention that runs the command. The number is the id Discord assigned when your bot deployed it, so writing that string by hand means fetching the id first.
Your bot already received that id at startup. You read it from Commands.
import {
Commands,
SlashHandler,
SlashRoute
} from '@seedcord/gateway';
@SlashRoute('role/add')
export class RoleAdd extends SlashHandler<'role/add'> {
public async execute(): Promise<void> {
const member = this.options.getUser('member');
const role = this.options.getRole('role');
await this.reply(
`Gave ${role.name} to ${member.username}. ` +
`Undo with ${Commands['role/remove'].mention}.`
);
}
}The keys are your routes
Commands is keyed by the routes seedcord codegen wrote, the same strings your handlers name. ping is a valid identifier so it takes a dot. role/add has a slash in it and needs brackets.
const ping = Commands.ping.mention; // '</ping:1234>'
const addRole = Commands['role/add'].mention; // '</role add:1287>'</role add:1287> up there is the whole path with a space in it, which is the form Discord reads.
Typing the dot lists the routes that take one. These are the commands this guide uses in its examples.
Commands.- award
- ban
- feed
- history
- kick
- leaderboard
- maintenance
- ping
- probe
- roles
- search
- whoami
What an entry holds
| field | what it holds |
|---|---|
mention | The clickable string, or plain /role add when the id did not resolve |
id | The deployed command id. Absent for a command in two or more servers |
route | The full route, role/add |
description | The description on that route. A nested route takes it from the subcommand |
Commands holds every route you registered, so a help command can read them all.
const const listing: string[]listing = var Object: ObjectConstructorObject.ObjectConstructor.values<CommandInfo>(o: {
[s: string]: CommandInfo;
} | ArrayLike<CommandInfo>): CommandInfo[] (+1 overload)
values(const Commands: InjectedCommandMapCommands).Array<CommandInfo>.map<string>(callbackfn: (value: CommandInfo, index: number, array: CommandInfo[]) => string, thisArg?: any): string[]map(
(command: CommandInfocommand) => `${command: CommandInfocommand.CommandInfo.mention: stringmention} ${command: CommandInfocommand.CommandInfo.description: stringdescription}`
);A command in two servers has no mention
Discord gives a guild command its own id in every server it deploys to, so no single id stands for it. id comes back undefined and mention falls back to plain text.
const id = Commands.ping.id;Your bot logs it once per command at startup.
ping is deployed to multiple guilds, falling back to plain text (not clickable).A global command has one id everywhere, so it always gets a clickable mention.
Commands fills during startup
Your bot sends its commands to Discord after it connects, then Commands fills from what comes back. A read before that throws.
Commands.ping has no value yet. Commands fills during startup, and a read at the top of a file runs before that.A ready event handler is early too, since the deploy runs after the client connects.
Tip
seedcord publishes a commandsDeployed bus event right after Commands fills. Subscribe to it to run something the moment your commands are live. It fires again every time a hot reload redeploys them.
Context menu commands
Discord doesn't give a right-click command any mention syntax, so ContextMenus carries the id and the name. The two kinds keep separate registries, the same way Discord scopes name uniqueness per kind.
import { ContextMenus } from '@seedcord/gateway';
const profile = ContextMenus.user['View Profile'].id;
const report = ContextMenus.message['Report Message'].id;A context menu deployed to two or more servers comes back with id undefined, the same as a slash command.