Skip to content

Commands

Using commands and events is the main way to interact with the bot.

Command argument detection

One of the most powerful features of NioBot is the command argument interpretation system. When you create a niobot command, the arguments are automatically detected, and their desired type is inferred from the type hints in the function signature.

This means that foo: str will always give you a string, bar: int will try to give you an integer, or throw an error if it cannot convert the user-given argument.

As of v1.2.0, you can take advantage of the keyword-only and positional args in Python. Normally, when you specify a function like async def mycommand(ctx, x: str), niobot will see that you want an argument, x, and will do just that. It will take the user's input, and give you the value for x. However, if the user specifies multiple words for x, it will only give the first one to the function, unless the user warps the argument in "quotes".

import niobot
bot = niobot.NioBot()

@bot.command()
async def mycommand(ctx, x: str):
    await ctx.respond(f"Your argument was: {x}")
If you ran !mycommand hello world, the bot would respond with Your argument was: hello.

With keyword-only arguments, you can make use of "greedy" arguments. While you could previously do this by manually constructing the niobot.Argument type, you can now do this with the * syntax in Python.

import niobot
bot = niobot.NioBot()

@bot.command()
async def mycommand(ctx, *, x: str):
    await ctx.respond(f"Your argument was: {x}")
If you ran !mycommand hello world, the bot would respond with Your argument was: hello world.

And, as for positional args, if you want to fetch a set of arguments, you can do so by specifying *args. This will give you a tuple containing every whitespace-delimited argument after the command.

import niobot
bot = niobot.NioBot()

@bot.command()
async def mycommand(ctx, *args: str):
    await ctx.respond(f"Your arguments were: {args}")
If you ran !mycommand hello world, the bot would respond with Your arguments were: ('hello', 'world').

Position & KW-Only args are final and strings!

If you specify a keyword or positional argument, you cannot have any arguments afterwards. Furthermore, (currently) both of these arguments are always strings. Trying to specify another type will throw an error.


Reference

Argument

Represents a command argument.

Example
from niobot import NioBot, command, Argument

bot = NioBot(...)

@bot.command("echo")
def echo(ctx: niobot.Context, message: str):
    await ctx.respond(message)

bot.run(...)

Parameters:

Name Type Description Default
name str

The name of the argument. Will be used to know which argument to pass to the command callback.

required
arg_type _T

The type of the argument (e.g. str, int, etc. or a custom type)

required
description Optional[str]

The description of the argument. Will be shown in the auto-generated help command.

None
default Any

The default value of the argument

...
required bool

Whether the argument is required or not. Defaults to True if default is ..., False otherwise.

...
parser Callable[[Context, Argument, str], Optional[_T]]

A function that will parse the argument. Defaults to the default parser.

...
greedy bool

When enabled, will attempt to match as many arguments as possible, without raising an error. If no arguments can be parsed, is merely empty, otherwise is a list of parsed arguments.

False

internal_parser staticmethod

internal_parser(
    _: Context, arg: Argument, value: str
) -> Optional[_T]

The default parser for the argument. Will try to convert the value to the argument type.

Command

Represents a command.

Example

Note

This example uses the command decorator, but you can also use the Command class directly, but you likely won't need to, unless you want to pass a custom command class.

All that the @command decorator does is create a Command instance and add it to the bot's commands, while wrapping the function its decorating.

from niobot import NioBot, command

bot = NioBot(...)

@bot.command("hello")
def hello(ctx: niobot.Context):
    await ctx.respond("Hello, %s!" % ctx.message.sender)

bot.run(...)

Parameters:

Name Type Description Default
name str

The name of the command. Will be used to invoke the command.

required
callback Callable

The callback to call when the command is invoked.

required
aliases Optional[list[str]]

The aliases of the command. Will also be used to invoke the command.

None
description Optional[str]

The description of the command. Will be shown in the auto-generated help command.

None
disabled bool

Whether the command is disabled or not. If disabled, the command will be hidden on the auto-generated help command, and will not be able to be invoked.

False
arguments Optional[list[Argument]]

A list of Argument instances. Will be used to parse the arguments given to the command. ctx is always the first argument, regardless of what you put here.

None
usage Optional[str]

A string representing how to use this command's arguments. Will be shown in the auto-generated help. Do not include the command name or your bot's prefix here, only arguments. For example: usage="<message> [times]" will show up as [p][command] <message> [times] in the help command.

None
hidden bool

Whether the command is hidden or not. If hidden, the command will be always hidden on the auto-generated help.

False
greedy bool

When enabled, CommandArgumentsError will not be raised if too many arguments are given to the command. This is useful for commands that take a variable amount of arguments, and retrieve them via Context.args.

False

display_usage property

display_usage: str

Returns the usage string for this command, auto-resolved if not pre-defined

autodetect_args staticmethod

autodetect_args(callback) -> list[Argument]

Attempts to auto-detect the arguments for the command, based on the callback's signature

Parameters:

Name Type Description Default
callback

The function to inspect

required

Returns:

Type Description
list[Argument]

A list of arguments. self, and ctx are skipped.

__eq__

__eq__(other)

Checks if another command's runtime ID is the same as this one's

can_run async

can_run(ctx: Context) -> bool

Checks if the current user passes all of the checks on the command.

If the user fails a check, CheckFailure is raised. Otherwise, True is returned.

parse_args async

parse_args(
    ctx: Context,
) -> Dict[Argument, Union[Any, List[Any]]]

Parses the arguments for the current command.

invoke async

invoke(ctx: Context) -> Coroutine

Invokes the current command with the given context

Parameters:

Name Type Description Default
ctx Context

The current context

required

Raises:

Type Description
CommandArgumentsError

Too many/few arguments, or an error parsing an argument.

CheckFailure

A check failed

construct_context

construct_context(
    client: NioBot,
    room: MatrixRoom,
    src_event: RoomMessageText,
    invoking_prefix: str,
    meta: str,
    cls: type = Context,
) -> Context

Constructs the context for the current command.

You will rarely need to do this, the library automatically gives you a Context when a command is run.

Parameters:

Name Type Description Default
client NioBot

The current instance of the client.

required
room MatrixRoom

The room the command was invoked in.

required
src_event RoomMessageText

The source event that triggered the command. Must be nio.RoomMessageText.

required
invoking_prefix str

The prefix that triggered the command.

required
meta str

The invoking string (usually the command name, however may be an alias instead)

required
cls type

The class to construct the context with. Defaults to Context.

Context

Returns:

Type Description
Context

The constructed Context.

Module

Represents a module.

A module houses a set of commands and events, and can be used to modularise your bot, and organise commands and their respective code into multiple files and classes for ease of use, development, and maintenance.

Attributes:

Name Type Description
bot

The bot instance this module is mounted to.

list_events

list_events() -> Generator[dict, None, None]

Lists all the @event listeners registered in this module.

This returns the functions themselves. You can get the event name via result.__nio_event__["name"].

__setup__

__setup__()

Setup function called once by NioBot.mount_module(). Mounts every command discovered.

.. warning: If you override this function, you should ensure that you call super().setup() to ensure that commands are properly registered.

__teardown__

__teardown__()

Teardown function called once by NioBot.unmount_module(). Removes any command that was mounted.

.. warning: If you override this function, you should ensure that you call super().teardown() to ensure that commands are properly unregistered.

command

command(name: Optional[str] = None, **kwargs) -> Callable

Allows you to register commands later on, by loading modules.

This differs from NioBot.command() in that commands are not automatically added, you need to load them with bot.mount_module

Parameters:

Name Type Description Default
name Optional[str]

The name of the command. Defaults to function.name

None
kwargs

Any key-words to pass to Command

{}

Returns:

Type Description
Callable

check

check(
    function: Callable[
        [Context], Union[bool, Coroutine[None, None, bool]]
    ]
) -> Callable

Allows you to register checks in modules.

@niobot.command()
@niobot.check(my_check_func)
async def my_command(ctx: niobot.Context):
    pass

Parameters:

Name Type Description Default
function Callable[[Context], Union[bool, Coroutine[None, None, bool]]]

The function to register as a check

required

Returns:

Type Description
Callable

The decorated function.

event

event(name: Optional[Union[str, Event]] = None) -> Callable

Allows you to register event listeners in modules.

Parameters:

Name Type Description Default
name Optional[Union[str, Event]]

the name of the event (no on_ prefix)

None

Returns:

Type Description
Callable