Skip to content

Client

NioBot

Bases: AsyncClient

The main client for NioBot.

Forcing an initial sync is slow

(for the force_initial_sync parameter) By default, nio-bot stores what the last sync token was, and will resume from that next time it starts. This allows you to start up near instantly, and makes development easier and faster.

However, in some cases, especially if you are missing some metadata such as rooms or their members, you may need to perform an initial (sometimes referred to as "full") sync. An initial sync will fetch ALL the data from the server, rather than just what has changed since the last sync.

This initial sync can take several minutes, especially the larger your bot gets, and should only be used if you are missing aforementioned data that you need.

Parameters:

Name Type Description Default
homeserver str

The homeserver to connect to. e.g. https://matrix-client.matrix.org

required
user_id str

The user ID to log in as. e.g. @user:matrix.org

required
device_id str

The device ID to log in as. e.g. nio-bot

'nio-bot'
store_path Optional[str]

The path to the store file. Defaults to ./store. Must be a directory.

None
command_prefix Union[str, Pattern, Iterable[str]]

The prefix to use for commands. e.g. !. Can be a string, a list of strings, or a regex pattern.

required
case_insensitive bool

Whether to ignore case when checking for commands. If True, this casefold()s incoming messages for parsing.

True
global_message_type Literal['m.text', 'm.notice']

The message type to default to. Defaults to m.notice

'm.notice'
ignore_old_events bool

Whether to simply discard events before the bot's login.

True
auto_join_rooms bool

Whether to automatically join rooms the bot is invited to.

True
auto_read_messages bool

Whether to automatically update read recipts

True
owner_id Optional[str]

The user ID of the bot owner. If set, only this user can run owner-only commands, etc.

None
max_message_cache int

The maximum number of messages to cache. Defaults to 1000.

1000
ignore_self bool

Whether to ignore messages sent by the bot itself. Defaults to False. Useful for self-bots.

True
import_keys Tuple[PathLike, Optional[str]]

A key export file and password tuple. These keys will be imported at startup.

None
startup_presence Literal['online', 'unavailable', 'offline', False, None]

The presence to set on startup. False disables presence altogether, and None is automatic based on the startup progress.

None
default_parse_mentions bool

Whether to parse mentions in send_message by default to make them intentional.

True
force_initial_sync bool

Forcefully perform a full initial sync at startup.

False
use_fallback_replies bool

Whether to force the usage of deprecated fallback replies. Not recommended outside of compatibility reasons.

False

supported_server_versions property

supported_server_versions: List[Tuple[int, int, int]]

Returns the supported server versions as a list of major, minor, patch tuples.

The only time patch is >0 is when the server is using a deprecated r release. All stable releases (v1) will have patch as 0.

This property returns [(1, 1, 0)] if no server info is available.

commands property

commands: dict[str, Command]

Returns the internal command register.

Warning

Modifying any values here will update the internal register too.

Note

Aliases of commands are treated as their own command instance. You will see the same command show up as a value multiple times if it has aliases.

You can check if two commands are identical by comparing them (command1instance == command2instance)

modules property

modules: dict[Type, Module]

Returns the internal module register.

Warning

Modifying any values here will update the internal register too.

server_supports

server_supports(
    version: Union[Tuple[int, int], Tuple[int, int, int]]
) -> bool

Checks that the server supports at least this matrix version.

mxc_to_http async

mxc_to_http(
    mxc: str, homeserver: Optional[str] = None
) -> Optional[str]

Converts an mxc:// URI to a downloadable HTTP URL.

This function is identical the nio.AsyncClient.mxc_to_http() function, however supports matrix 1.10 and below's unauthenticated media automatically.

Parameters:

Name Type Description Default
mxc str

The mxc URI

required
homeserver Optional[str]

The homeserver to download this through (defaults to the bot's homeserver)

None

Returns:

Type Description
Optional[str]

an MXC URL, if applicable

latency staticmethod

latency(
    event: Event, *, received_at: Optional[float] = None
) -> float

Returns the latency for a given event in milliseconds

Parameters:

Name Type Description Default
event Event

The event to measure latency with

required
received_at Optional[float]

The optional time the event was received at. If not given, uses the current time.

None

Returns:

Type Description
float

The latency in milliseconds

dispatch

dispatch(event_name: Union[str, Event], *args, **kwargs)

Dispatches an event to listeners

is_old

is_old(event: Event) -> bool

Checks if an event was sent before the bot started. Always returns False when ignore_old_events is False

update_read_receipts async

update_read_receipts(
    room: Union[str, MatrixRoom], event: Event
)

Moves the read indicator to the given event in the room.

This is automatically done for you.

Whenever a message is received, this is automatically called for you. As such, your read receipt will always be the most recent message. You rarely need to call this function.

Parameters:

Name Type Description Default
room Union[str, MatrixRoom]

The room to update the read receipt in.

required
event Event

The event to move the read receipt to.

required

Returns:

Type Description

Nothing

process_message async

process_message(
    room: MatrixRoom, event: RoomMessage
) -> None

Processes a message and runs the command it is trying to invoke if any.

is_owner

is_owner(user_id: str) -> bool

Checks whether a user is the owner of the bot.

Parameters:

Name Type Description Default
user_id str

The user ID to check.

required

Returns:

Type Description
bool

Whether the user is the owner.

mount_module

mount_module(import_path: str) -> Optional[list[Command]]

Mounts a module including all of its commands.

Must be a subclass of niobot.commands.Module, or else this function will not work.

There may not be an event loop running when this function is called.

If you are calling this function before you call bot.run(), it is entirely possible that you don't have a running asyncio event loop. If you use the event loop in Module.__init__, you will get an error, and the module will fail the mount.

You can get around this by deferring mounting your modules until the ready event is fired, at which point not only will the first full sync have completed (meaning the bot has all of its caches populated), but the event loop will be running.

Parameters:

Name Type Description Default
import_path str

The import path (such as modules.file), which would be ./modules/file.py in a file tree.

required

Returns:

Type Description
Optional[list[Command]]

Optional[list[Command]] - A list of commands mounted. None if the module's setup() was called.

Raises:

Type Description
ImportError

The module path is incorrect of there was another error while importing

TypeError

The module was not a subclass of Module.

ValueError

There was an error registering a command (e.g. name conflict)

unmount_module

unmount_module(module: Module) -> None

Does the opposite of mounting the module. This will remove any commands that have been added to the bot from the given module.

Parameters:

Name Type Description Default
module Module

The module to unmount

required

get_command

get_command(name: str) -> Optional[Command]

Attempts to retrieve an internal command

Parameters:

Name Type Description Default
name str

The name of the command to retrieve

required

Returns:

Type Description
Optional[Command]

The command, if found. None otherwise.

add_command

add_command(command: Command) -> None

Adds a command to the internal register

if a name or alias is already registered, this throws a ValueError. Otherwise, it returns None.

remove_command

remove_command(command: Command) -> None

Removes a command from the internal register.

If the command is not registered, this is a no-op.

command

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

Registers a command with the bot.

on_event

on_event(
    event_type: Optional[Union[str, Type[Event]]] = None
)

Wrapper that allows you to register an event handler.

Event handlers must be async.

if event_type is None, the function name is used as the event type.

Please note that if you pass a Event, you are responsible for capturing errors.

set_room_nickname async

set_room_nickname(
    room: Union[str, MatrixRoom],
    new_nickname: str = None,
    user: Optional[Union[str, MatrixUser]] = None,
) -> RoomPutStateResponse

Changes the user's nickname in the given room.

Parameters:

Name Type Description Default
room Union[str, MatrixRoom]

The room to change the nickname in.

required
new_nickname str

The new nickname. If None, defaults to the user's display name.

None
user Optional[Union[str, MatrixUser]]

The user to update. Defaults to the bot's user.

None

Returns:

Type Description
RoomPutStateResponse

The response from the server.

get_cached_message

get_cached_message(
    event_id: str,
) -> Optional[Tuple[MatrixRoom, RoomMessage]]

Fetches a message from the cache.

This returns both the room the message was sent in, and the event itself.

If the message is not in the cache, this returns None.

fetch_message async

fetch_message(room_id: str, event_id: str)

Fetches a message from the server.

wait_for_message async

wait_for_message(
    room_id: Optional[str] = None,
    sender: Optional[str] = None,
    check: Optional[
        Callable[[MatrixRoom, RoomMessageText], Any]
    ] = None,
    *,
    timeout: Optional[float] = None,
    msg_type: Type[RoomMessage] = RoomMessageText
) -> Optional[Tuple[MatrixRoom, RoomMessage]]

Waits for a message, optionally with a filter.

If this function times out, asyncio.TimeoutError is raised.

Parameters:

Name Type Description Default
room_id Optional[str]

The room ID to wait for a message in. If None, waits for any room.

None
sender Optional[str]

The user ID to wait for a message from. If None, waits for any sender.

None
check Optional[Callable[[MatrixRoom, RoomMessageText], Any]]

A function to check the message with. If the function returns False, the message is ignored.

None
timeout Optional[float]

The maximum time to wait for a message. If None, waits indefinitely.

None
msg_type Type[RoomMessage]

The type of message to wait for. Defaults to nio.RoomMessageText.

RoomMessageText

Returns:

Type Description
Optional[Tuple[MatrixRoom, RoomMessage]]

The room and message that was received.

markdown_to_html async staticmethod

markdown_to_html(text: str) -> str

Converts markdown to HTML.

Parameters:

Name Type Description Default
text str

The markdown to render as HTML

required

Returns:

Type Description
str

the rendered HTML

generate_mx_reply

generate_mx_reply(
    room: MatrixRoom, event: RoomMessageText
) -> str

Fallback replies have been removed by MSC2781. Do not use this anymore.

get_dm_rooms async

get_dm_rooms() -> Dict[str, List[str]]
get_dm_rooms(user: Union[MatrixUser, str]) -> List[str]
get_dm_rooms(
    user: Optional[Union[MatrixUser, str]] = None
) -> Union[Dict[str, List[str]], List[str]]

Gets DM rooms, optionally for a specific user.

If no user is given, this returns a dictionary of user IDs to lists of rooms.

Parameters:

Name Type Description Default
user Optional[Union[MatrixUser, str]]

The user ID or object to get DM rooms for.

None

Returns:

Type Description
Union[Dict[str, List[str]], List[str]]

A dictionary of user IDs to lists of rooms, or a list of rooms.

create_dm_room async

create_dm_room(
    user: Union[MatrixUser, str]
) -> RoomCreateResponse

Creates a DM room with a given user.

Parameters:

Name Type Description Default
user Union[MatrixUser, str]

The user to create a DM room with.

required

Returns:

Type Description
RoomCreateResponse

The response from the server.

send_message async

send_message(
    room: Union[MatrixRoom, MatrixUser, str],
    content: Optional[str] = None,
    file: Optional[BaseAttachment] = None,
    reply_to: Optional[Union[RoomMessage, str]] = None,
    message_type: Optional[str] = None,
    *,
    content_type: Literal[
        "plain", "markdown", "html", "html.raw"
    ] = "markdown",
    override: Optional[dict] = None,
    mentions: Union[Mentions, Literal[False], None] = None
) -> RoomSendResponse

Sends a message. Doesn't get any more simple than this.

DMs

As of v1.1.0, you can now send messages to users (either a nio.MatrixUser or a user ID string), and a direct message room will automatically be created for you if one does not exist, using an existing one if it does.

Content Type

Separate to message_type, content_type controls what sort of parsing and formatting will be applied to the provided content. This is useful for sending messages that are not markdown, or for sending HTML. Before, all content was assumed to be markdown, and was parsed as such. However, this may cause undesirable effects if you are sending messages that are not markdown.

  • plain - No parsing or formatting is applied, and the content is sent as-is.
  • markdown - The content is parsed as markdown and rendered as HTML, with a fallback plain text body. This is the default.
  • html - The content is sent as HTML, with no fallback to plain text. If BeautifulSoup is installed, the provided content will be sanitised and pretty-printed before sending. ** html.raw - The content is sent as HTML, with no fallback to plain text, nor sanitising or formatting.

Parameters:

Name Type Description Default
room Union[MatrixRoom, MatrixUser, str]

The room or to send this message to

required
content Optional[str]

The content to send. Cannot be used with file.

None
file Optional[BaseAttachment]

A file to send, if any. Cannot be used with content.

None
reply_to Optional[Union[RoomMessage, str]]

A message to reply to.

None
message_type Optional[str]

The message type to send. If none, defaults to NioBot.global_message_type, which itself is m.notice by default.

None
override Optional[dict]

A dictionary containing additional properties to pass to the body. Overrides existing properties.

None
content_type Literal['plain', 'markdown', 'html', 'html.raw']

The type of content to send. Defaults to "markdown".

'markdown'
mentions Union[Mentions, Literal[False], None]

Intentional mentions to send with the message. If not provided, or False, then auto-detected.

None

Returns:

Type Description
RoomSendResponse

The response from the server.

Raises:

Type Description
MessageException

If the message fails to send, or if the file fails to upload.

ValueError

You specified neither file nor content.

RuntimeError

An internal error occured. A room was created, but is not in the bot room list.

edit_message async

edit_message(
    room: Union[MatrixRoom, str],
    message: Union[Event, str],
    content: str,
    *,
    message_type: Optional[str] = None,
    content_type: Literal[
        "plain", "markdown", "html", "html.raw"
    ] = "markdown",
    mentions: Optional[Mentions] = None,
    override: Optional[dict] = None
) -> RoomSendResponse

Edit an existing message. You must be the sender of the message.

You also cannot edit messages that are attachments.

Parameters:

Name Type Description Default
room Union[MatrixRoom, str]

The room the message is in.

required
message Union[Event, str]

The message to edit.

required
content str

The new content of the message.

required
message_type Optional[str]

The new type of the message (i.e. m.text, m.notice. Defaults to client.global_message_type)

None
override Optional[dict]

A dictionary containing additional properties to pass to the body. Overrides existing properties.

None
content_type Literal['plain', 'markdown', 'html', 'html.raw']

The type of content to send. Defaults to "markdown".

'markdown'

Raises:

Type Description
RuntimeError

If you are not the sender of the message.

TypeError

If the message is not text.

delete_message async

delete_message(
    room: Union[MatrixRoom, str],
    message_id: Union[RoomMessage, str],
    reason: Optional[str] = None,
) -> RoomRedactResponse

Delete an existing message. You must be the sender of the message.

Parameters:

Name Type Description Default
room Union[MatrixRoom, str]

The room the message is in.

required
message_id Union[RoomMessage, str]

The message to delete.

required
reason Optional[str]

The reason for deleting the message.

None

Raises:

Type Description
RuntimeError

If you are not the sender of the message.

MessageException

If the message fails to delete.

add_reaction async

add_reaction(
    room: Union[MatrixRoom, str],
    message: Union[RoomMessage, str],
    emoji: str,
) -> RoomSendResponse

Adds an emoji "reaction" to a message.

Parameters:

Name Type Description Default
room Union[MatrixRoom, str]

The room the message is in.

required
message Union[RoomMessage, str]

The event ID or message object to react to.

required
emoji str

The emoji to react with (e.g. = ❌)

required

Returns:

Type Description
RoomSendResponse

The response from the server.

Raises:

Type Description
MessageException

If the message fails to react.

redact_reaction async

redact_reaction(
    room: Union[MatrixRoom, str],
    reaction: Union[RoomSendResponse, str],
)

Alias for NioBot.delete_message, but more appropriately named for reactions.

start async

start(
    password: Optional[str] = None,
    access_token: Optional[str] = None,
    sso_token: Optional[str] = None,
) -> None

Starts the bot, running the sync loop.

run

run(
    *,
    password: Optional[str] = None,
    access_token: Optional[str] = None,
    sso_token: Optional[str] = None
) -> None

Runs the bot, blocking the program until the event loop exists. This should be the last function to be called in your script, as once it exits, the bot will stop running.

Note: This function is literally just asyncio.run(NioBot.start(...)), so you won't have much control over the asyncio event loop. If you want more control, you should use await NioBot.start(...) instead.

Parameters:

Name Type Description Default
password Optional[str]

The password to log in with.

None
access_token Optional[str]

An existing login token.

None
sso_token Optional[str]

An SSO token to sign in with.

None

Returns:

Type Description
None

get_account_data async

get_account_data(
    key: str, *, room_id: str = None
) -> Union[dict, list, None]

Gets account data for the currently logged in account

Parameters:

Name Type Description Default
key str

the key to get

required
room_id str

The room ID to get account data from. If not provided, defaults to user-level.

None

Returns:

Type Description
Union[dict, list, None]

The account data, or None if it doesn't exist

set_account_data async

set_account_data(
    key: str, data: dict, *, room_id: str = None
) -> None

Sets account data for the currently logged in account

Parameters:

Name Type Description Default
key str

the key to set

required
data dict

the data to set

required
room_id str

The room ID to set account data in. If not provided, defaults to user-level.

None

join async

join(
    room_id: str, reason: str = None, is_dm: bool = False
) -> Union[JoinResponse, JoinError]

Joins a room. room_id must be a room ID, not alias

Parameters:

Name Type Description Default
room_id str

The room ID or alias to join

required
reason str

The reason for joining the room, if any

None
is_dm bool

Manually marks this room as a direct message.

False

room_leave async

room_leave(
    room_id: str, reason: str = None
) -> Union[RoomLeaveError, RoomLeaveResponse]

Leaves a room. room_id must be an ID, not alias