#[command]Expand description
This macro transforms plain functions into poise bot commands.
Documentation comments are used as help text. The first line is a single-line description,
displayed in listings of your bot’s commands (i.e. ~help). Following paragraphs are detailed explanations,
for example for command-specific help (i.e. ~help command_name). Escape newlines with \
§Macro arguments
#[poise::command] accepts a number of arguments to configure the command:
§Command types
prefix_command: Generate a prefix commandslash_command: Generate a slash commandcontext_menu_command: Generate a context menu command
§Meta properties
subcommands: List of subcommandssubcommands("foo", "bar", "baz")name_localized: Adds localized name of the parametername_localized("locale", "new_name")(slash-only)description_localized: Adds localized description of the parameterdescription_localized("locale", "Description")(slash-only)rename: Choose an alternative command name instead of the function name- Useful if your command name is a Rust keyword, like
move
- Useful if your command name is a Rust keyword, like
aliases: Command name aliases (only applies to prefix commands)category: Category of this command which affects placement in the help commandcustom_data: Arbitrary expression that will be boxed and stored inCommand::custom_dataidentifying_name: Optionally, a unique identifier for this command for your personal usageinstall_context: Installation contexts where this command is available (slash-only)interaction_context: Interaction contexts where this command is available (slash-only)
§Checks
required_permissions: Permissions which the command caller needs to haverequired_bot_permissions: Permissions which the bot is known to needdefault_member_permissions: Likerequired_permissions, but checked server-side (slash only)- Due to being checked server-side, users without the required permissions are prevented from executing the command in the first place, which is a better experience
- However,
default_member_permissionshas no effect on subcommands, which always inherit their permissions from the top-level command - Also, guild owners can freely change the required permissions for any bot command for their guild
owners_only: Restricts command callers to a configurable list of owners (see FrameworkOptions)guild_only: Restricts command callers to only run on a guilddm_only: Restricts command callers to only run on a DMnsfw_only: Restricts command callers to only run on a NSFW channelsubcommand_required: Requires a subcommand to be specified (prefix only)check: Path to a function which is invoked for every invocation. If the function returns false, the command is not executed (can be used multiple times)
§Help-related arguments
hide_in_help: Hide this command in help menushelp_text_fn: Path to a string-returning function which is used for command help text instead of documentation comments- Useful if you have many commands with very similar help messages: you can abstract the common parts into a function
§Edit tracking (prefix only)
track_edits: Shorthand forinvoke_on_edit,track_deletion, andreuse_response(prefix only)invoke_on_edit: Reruns the command if an existing invocation message is edited (prefix only)track_deletion: Deletes the bot response to a command if the command message is deleted (prefix only)reuse_response: After the first response, post subsequent responses as edits to the initial message (prefix only)
§Cooldown
manual_cooldowns: Allows overriding the framework’s built-in cooldowns tracking without affecting other commands.global_cooldown: Minimum duration in seconds between invocations, globallyuser_cooldown: Minimum duration in seconds between invocations, per userguild_cooldown: Minimum duration in seconds between invocations, per guildchannel_cooldown: Minimum duration in seconds between invocations, per channelmember_cooldown: Minimum duration in seconds between invocations, per guild member
§Other
on_error: Error handling functionbroadcast_typing: Trigger a typing indicator while command runs (prefix only)discard_spare_arguments: Don’t throw an error if the user supplies too many arguments (prefix only)ephemeral: Make bot responses ephemeral if possible (slash only)- Only poise’s functions, like
poise::send_reply, respect this preference
- Only poise’s functions, like
§Function parameters
Context is the first parameter of all command functions. It’s an enum over either PrefixContext or
SlashContext, which contain a variety of context data each. Context provides some utility methods to
access data present in both PrefixContext and SlashContext, like author() or created_at().
All following parameters are inputs to the command. You can use all types that implement poise::PopArgument, serenity::ArgumentConvert or std::str::FromStr.
You can also wrap types in Option or Vec to make them optional or variadic. In addition, there
are multiple attributes you can use on parameters:
§Meta properties
#[description = ""]: Sets description of the parameter (slash-only)#[description_localized("locale", "Description")]: Adds localized description of the parameter (slash-only)#[name_localized("locale", "new_name")]: Adds localized name of the parameter (slash-only)#[autocomplete = "callback()"]: Sets the autocomplete callback (slash-only)#[rename = "new_name"]: Changes the user-facing name of the parameter (slash-only)
§Input filter (slash only)
#[channel_types("", "")]: For channel parameters, restricts allowed channel types (slash-only)#[min = 0]: Minimum value for this number parameter (slash-only)#[max = 0]: Maximum value for this number parameter (slash-only)#[min_length = 0]: Minimum length for this string parameter (slash-only)#[max_length = 1]: Maximum length for this string parameter (slash-only)
§Parser settings (prefix only)
#[rest]: Use the entire rest of the message for this parameter (prefix-only)#[lazy]: Can be used on Option and Vec parameters and is equivalent to regular expressions’ laziness (prefix-only)#[flag]: Can be used on a bool parameter to set the bool to true if the user typed the parameter name literally (prefix-only)- For example with
async fn my_command(ctx: Context<'_>, #[flag] my_flag: bool),~my_commandwould set my_flag to false, and~my_command my_flagwould set my_flag to true
- For example with
§Help text
Documentation comments are used as command help text. The first paragraph is the command
description (Command::description) and all following paragraphs are the multiline help text
(Command::help_text).
In the multiline help text, put \ at the end of a line to escape the newline.
Example:
/// This is the description of my cool command, it can span multiple
/// lines if you need to
///
/// Here in the following paragraphs, you can give information on how \
/// to use the command that will be shown in your command's help.
///
/// You could also put example invocations here:
/// `~coolcommand test`
#[poise::command(slash_command)]
pub async fn coolcommand(ctx: Context<'_>, s: String) -> Result<(), Error> { ... }results in
poise::Command {
description: Some("This is the description of my cool command, it can span multiple lines if you need to".into()),
help_text: Some("Here in the following paragraphs, you can give information on how to use the command that will be shown in your command's help.\n\nYou could also put example invocations here:\n`~coolcommand test`".into()),
...
}§Internals
Internally, this attribute macro generates a function with a single poise::Command
return type, which contains all data about this command. For example, it transforms a function of
this form:
/// This is a command
#[poise::command(slash_command, prefix_command)]
async fn my_command(ctx: Context<'_>) -> Result<(), Error> {
// code
}into something like
fn my_command() -> poise::Command<Data, Error> {
async fn inner(ctx: Context<'_>) -> Result<(), Error> {
// code
}
poise::Command {
name: "my_command",
description: "This is a command",
prefix_action: Some(|ctx| Box::pin(async move {
inner(ctx.into()).await
})),
slash_action: Some(|ctx| Box::pin(async move {
inner(ctx.into()).await
})),
context_menu_action: None,
// ...
}
}If you’re curious, you can use cargo expand to see the
exact desugaring