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.

Convertible types: int bool float complex bytes

@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 Check bound 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_args kwarg for Bot is 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_with kwarg in the yami.command, yami.Bot.command, and yami.MessageCommand.subcommand decorators.

  • 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.shared can 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 a SharedNone if 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."""
    ...