Command Groups#
Slash commands can be organized into command groups, creating a hierarchy. Nesting is supported, but only one level deep, meaning that a top-level group may contain groups, but the subgroups must contain subcommands.
Examples of supported nesting configurations
VALID
group
│
├─ subcommand
│
└─ subcommand
----
VALID
group
│
├─ subgroup
│ │
│ └─ subcommand
│
└─ subgroup
│
└─ subcommand
----
VALID
group
│
├─ subgroup
│ │
│ └─ subcommand
│
└─ subcommand
-------
INVALID
Subgroups cannot contain subgroups
group
│
├─ subgroup
│ │
│ └─ subgroup
│
└─ subgroup
│
└─ subgroup
----
INVALID
Subcommands cannot contain subgroups
group
│
├─ subcommand
│ │
│ └─ subgroup
│
└─ subcommand
│
└─ subgroup
Caution
Using subcommands or subcommand groups will make your top-level group unusable. You can't send the base /permissions
as a valid command if you also have /permissions add | remove
as subcommands or subcommand groups.
For example, if you're developing a moderation bot, you may want to create a /permissions
command that can:
- Get the guild permissions for a user or a role
- Get the permissions for a user or a role on a specific channel
- Change the guild permissions for a user or a role
- Change the permissions for a user or a role on a specific channel
We'll start by defining the top-level SlashGroup
. This is a special type of "command" that has no
callback, and acts as a sort of "folder" to add other commands to. A slash group can be added via Client.include_slash_group()
(or Plugin.include_slash_group()
, if working with a plugin).
permissions = client.include_slash_group("permissions", "Get or edit permissions for a user or role")
Next, you can define subgroups that this group will contain via SlashGroup.include_subgroup
:
user = permissions.include_subgroup("user", "Get or edit permissions for a user")
role = permissions.include_subgroup("role", "Get or edit permissions for a role")
Finally, you can simply @include
the commands in the group:
@user.include
@arc.slash_subcommand("get", "Get permissions for a user")
async def perms_user_get(ctx: arc.GatewayContext) -> None:
...
@user.include
@arc.slash_subcommand("edit", "Edit permissions for a user")
async def perms_user_edit(ctx: arc.GatewayContext) -> None:
...
@role.include
@arc.slash_subcommand("get", "Get permissions for a role")
async def perms_role_get(ctx: arc.GatewayContext) -> None:
...
@role.include
@arc.slash_subcommand("edit", "Edit permissions for a role")
async def perms_role_edit(ctx: arc.GatewayContext) -> None:
...
@user.include
@arc.slash_subcommand("get", "Get permissions for a user")
async def perms_user_get(ctx: arc.RESTContext) -> None:
...
@user.include
@arc.slash_subcommand("edit", "Edit permissions for a user")
async def perms_user_edit(ctx: arc.RESTContext) -> None:
...
@role.include
@arc.slash_subcommand("get", "Get permissions for a role")
async def perms_role_get(ctx: arc.RESTContext) -> None:
...
@role.include
@arc.slash_subcommand("edit", "Edit permissions for a role")
async def perms_role_edit(ctx: arc.RESTContext) -> None:
...
Subcommands can be included in either top-level groups or subgroups.
Warning
Slash subcommands must use the @arc.slash_subcommand
decorator
instead of the @arc.slash_command
decorator.
With the following setup, you should get something similar to this:
You can then proceed adding options to the subcommands and develop your command logic.
Other Limitations#
Only top-level commands & groups can have the following defined:
default_permissions
is_nsfw
is_dm_enabled
guilds
Subcommands & subgroups inherit these settings from the parent group. This is due to how Discord represents subcommands & subgroups in the API.