diff --git a/examples/command_bot.py b/examples/command_bot.py
new file mode 100644
index 0000000..4f9da59
--- /dev/null
+++ b/examples/command_bot.py
@@ -0,0 +1,130 @@
+"""
+This example implements Matrix bot that can execute some commands.
+
+It uses environment variables to specify authorization data. Use Ctrl+C to stop
+the bot.
+"""
+
+import asyncio
+import time
+import html
+import os
+import traceback
+import logging
+
+from mab import *
+
+from _environment import check_environment
+
+async def on_help_command(ctx: EventContext) -> None:
+ """!help"""
+ HELP_MESSAGE = (
+ "Here is the list of the commands:
"
+ "
!help - this help message!time - get UNIX timestamp!raise - raise RuntimeError()!assert - perform assert that will fail!mul A B [C] [D]... - multiply A, B... and so on!args arg1 [arg2] ... [arg5] - command that takes 1..5 argumentsraise RuntimeError()..."
+ )
+ raise RuntimeError()
+
+async def on_assert_command(ctx: EventContext) -> None:
+ """!assert"""
+ await ctx.bot.send_text(
+ ctx.room,
+ "Executing assert False..."
+ )
+ assert False
+
+async def on_mul_command(ctx: EventContext) -> None:
+ """!mul"""
+ try:
+ numbers = [float(v) for v in ctx[CTX_CMD_ARGS]]
+ v = numbers[0]
+ for n in numbers[1:]:
+ v *= n
+ response = " * ".join(html.escape("%.2f" % n) for n in numbers)
+ response += f" = {html.escape(str(v))}"
+ await ctx.bot.send_text(ctx.room, response)
+ except Exception as e:
+ await ctx.bot.send_text(ctx.room, f"Could not process the command: {e}")
+
+async def on_args_command(ctx: EventContext) -> None:
+ """!args"""
+ try:
+ response = (
+ f"Prefix: {ctx[CTX_CMD_PREFIX]}{ctx[CTX_CMD_VERB]}{len(ctx[CTX_CMD_ARGS])}{html.escape(arg)}!help")
+
+
+async def main() -> None:
+ """Application entry point"""
+ logging.basicConfig(level=logging.INFO)
+ logging.getLogger("nio").setLevel(logging.CRITICAL+1)
+ check_environment()
+
+ config = MatrixBotConfig(
+ matrix_homeserver_url=os.environ["MATRIX_HOMESERVER"],
+ matrix_username_localpart=os.environ["MATRIX_USERNAME"],
+ storage_directory="session_storage"
+ )
+ bot = MatrixBot(config)
+
+ COMMANDS = {
+ on_help_command: BodyCommandFilter(["help", "?"]),
+ on_time_command: BodyCommandFilter("time"),
+ on_raise_command: BodyCommandFilter("raise"),
+ on_assert_command: BodyCommandFilter("assert"),
+ on_mul_command: BodyCommandFilter("mul", min_args=2),
+ on_args_command: BodyCommandFilter("args", min_args=1, max_args=5),
+ }
+ for callback, filter in COMMANDS.items():
+ f = ~SenderIsBotFilter() & filter
+ bot.add_callback(f, callback)
+ bot.add_callback(~SenderIsBotFilter() & NewMessageFilter(), invalid_usage)
+
+ # run until Ctrl+C
+ try:
+ await bot.run()
+ except asyncio.CancelledError:
+ pass
+
+if __name__ == "__main__":
+ asyncio.run(main())
\ No newline at end of file