Message commands
Create a message command
The bot listens for the
MessageCreateEvent event. If the
message content begins with one of the bots prefixes and a command name
immediately following that, the bot will attempt to invoke the commands
callback.
Note
Yami converts type hints in your callbacks function signature for basic Python types automatically.
@bot.command("echo", aliases=["say"], invoke_with=True)
async def echo_cmd(ctx: yami.MessageContext, text: str) -> None:
"""Echos what you said back to you."""
await ctx.message.delete()
ctx.shared.message = await ctx.respond(text)
Create a message subcommand
Subcommands in Yami do not have a special class. The only designation
they receive is the is_subcommand and the
parent properties.
Note
The subcommand decorator should be used
as a method of the callback function of the parent command.
Subcommands must also pass each
Checkbound to its parent commands.
In this example the subcommand provides and optional interface to delete the message sent by the parent command.
# continued from above...
@echo_cmd.subcommand("-d", aliases=["--delete"])
async def echo_delete_cmd(
ctx: yami.MessageContext, _: str, timeout: float = 10.0
) -> None:
"""Optionally deletes the message after the given timeout."""
if m := ctx.shared.message:
await asyncio.sleep(timeout)
await ctx.rest.delete_message(ctx.channel_id, m)
else:
await ctx.respond("Something went wrong - no message to delete.")
Sub-subcommands
You can chain subcommands down as far as you would like. There is nothing holding you back :).
Warning
Chaining subcommands does have some side effects to be aware of.
The
allow_extra_argskwarg forBotis very helpful for allowing you to align the arguments of your subcommands.Yami disables the callback for all parent commands by default. This can be set using the
invoke_withkwarg in theyami.command,yami.Bot.command, andyami.MessageCommand.subcommanddecorators.Varying number and type for arguments in the command callbacks can cause failures. Pay close attention to what type hints and what argument positions you occupy in each callback, as well as what defaults you set.
yami.MessageContext.sharedcan be a powerful tool when used to share information between parent commands and their subcommands. Keep in mind that if something goes wrong in the first callback, you may receive aSharedNoneif you access an attribute that has not been set in a later subcommands callback.
@bot.command("config")
async def config_cmd(ctx: yami.MessageContext) -> None:
"""Configuration command."""
...
@config_cmd.subcommand("exp", aliases=["experience"])
async def exp_subcmd(ctx: yami.MessageContext) -> None:
"""Configures server experience gain."""
...
@exp_subcmd.subcommand("on")
async def exp_on_subcmd(ctx: yami.MessageContext) -> None:
"""Turns experience on."""
...
@exp_subcmd.subcommand("off")
async def exp_off_subcmd(ctx: yami.MessageContext) -> None:
"""Turns experience off."""
...