Trinity is an experimental bot framework written in Rust and using matrix-rust-sdk, as well as commands / modules compiled to WebAssembly, with convenient developer features like modules hot-reload.
This started as a fun weekend project where I've written a new generic Matrix bot framework. It is written in Rust from scratch using the fantastic matrix-rust-sdk crate.
Bot commands can be implemented as WebAssembly components, using Wasmtime as the WebAssembly virtual machine, and wit-bindgen for conveniently implementing interfaces between the host and wasm modules.
See for instance the uuid
and horsejs
modules.
Make sure to install the required tools (as of this writing, wit-bindgen
and wasm-tools
)
to be able to build wasm components. We're using a pinned revision of this that can automatically
be installed with ./modules/install-tools.sh
at the moment; we hope to lift that
limitation in the future.
Modules can be hot-reloaded, making it trivial to deploy new modules, or replace existing modules already running on a server. It is also nice during development iterations on modules. Basically one can do the following to see changes in close to real-time:
- run trinity with
cargo run
cd modules/ && cargo watch -x "component build --target=wasm32-unknown-unknown --release"
in another terminal
The overall generic design is inspired from my previous bot, botzilla, that was written in JavaScript and was very specialized for Mozilla needs.
At this point I expect this to be more of a weekend project, so I won't commit to any of those, but here's my ideas of things to implement in the future. If you feel like implementing some of these ideas, please go ahead :)
- fetch and cache user names
- make it possible to answer privately / to the full room / as a reply to the original message / as a thread reply.
- add ability to set emojis on specific messages (? this was useful for the admin module in botzilla)
- moonshot: JS host so one can test the chat modules on a Web browser, without requiring a matrix
account
- marsshot: existing modules built from CI and pushed to a simple Web app on github-pages that allows selecting an individual module and trying it.
- seek other
TODO
in code :p
- post on twitter. Example:
!tweet Inflammatory take that will receive millions of likes and quote-tweets
- same requirements as mastodon, likely
- gitlab auto-link to issues/merge requests: e.g. if someone types
!123
, post a link tohttps://{GITLAB_REPO_URL}/-/issues/123
.- would require the room to be configured with a gitlab repository
- same for github would be sweet
- ask what's the weather in some city, is it going to rain in the next hour, etc.
- YOUR BILLION DOLLARS IDEA HERE
If you want, you can use the image published on Docker (bnjbvr/trinity) -- it might be lagging behind by a few commits -- or build the Docker image yourself:
docker build -t bnjbvr/trinity .
Then start it with the right environment variables (see also .env.example
):
docker run -e HOMESERVER="matrix.example.com" \
-e BOT_USER_ID="@trinity:example.com" \
-e BOT_PWD="hunter2" \
-e ADMIN_USER_ID="@admin:example.com" \
-v /host/path/to/data/directory:/opt/trinity/data \
-ti bnjbvr/trinity
Data is saved in the /opt/trinity/data
directory, and it is recommended to make it a volume so as
to be able to decrypt messages over multiple sessions and so on.
If you want, you can specify a custom modules directory using the MODULES_PATHS
environment
variable and adding another data volume for it. This can be useful for hacking modules only without
having to compile the host runtime. Here's an example using Docker:
docker run -e HOMESERVER="matrix.example.com" \
-e BOT_USER_ID="@trinity:example.com" \
-e BOT_PWD="hunter2" \
-e ADMIN_USER_ID="@admin:example.com" \
-e MODULES_PATH="/wasm-modules" \
-v /host/path/to/data/directory:/opt/trinity/data \
-v /host/path/to/modules:/wasm-modules \
-ti bnjbvr/trinity
Trinity can be configured via config file. The config file can be passed in from the command line:
cargo run -- config.toml
Or it can be placed in $XDG_CONFIG_HOME
, typically ~/.config/trinity/config.toml
on XDG
compliant systems. Configuration lives in the document root, for example:
home_server = "matrix.example.com"
user_id = "@trinity:example.com"
password = "hunter2"
matrix_store_path = "/path/to/store"
redb_path = "/path/to/redb"
admin_user_id = "@admin:example.com"
modules_path = ["/wasm-modules"]
It's also possible to pass arbitrary configuration down to specific modules in the config file. For example:
[modules_config.pun]
format = "image"
This passes the object {"format": "image"}
to the pun
module's init
function. It's
up to specific modules to handle this configuration.
Yes.
We welcome community contributions to this project.
This is a Matrix bot, coded in Rust and WebAssembly, forming a holy trinity of technologies I love. And, Trinity is also a bad-ass character from the Matrix movie franchise.