# Matrix Bot Light
A lightweight, modern Erlang library for building Matrix bots with end-to-end encryption (E2E) support.
Connects to any Matrix homeserver, handles encrypted rooms via Megolm/Olm, and lets you plug in your own command handler.
[](https://hex.pm/packages/matrix_bot_light)
[](https://hexdocs.pm/matrix_bot_light)
[](LICENSE)
---
## Features
- **E2E encryption**: Full Megolm/Olm support — reads encrypted rooms transparently
- **Key backup**: Import session keys from server backup using your recovery key
- **Cross-signing**: Uploads and maintains cross-signing keys automatically
- **SAS verification**: Supports `m.sas.v1` emoji verification flow
- **Lightweight**: Minimal dependencies, no heavy frameworks
- **Flexible**: Plug in any module or fun as your command handler
---
## Dependencies
Add to your `rebar.config`:
```erlang
{matrix_bot_light, "0.1.2"}
```
Required dependencies (pulled automatically):
- `gun` — HTTP/WebSocket client
- `certifi` — CA certificates
- `keylara` — Entropy management (ALARA pool)
- `alara` — Distributed entropy
- `public_key` — comes with Erlang/OTP
---
## Environment Variables
The bot is configured entirely via environment variables. **No credentials are hardcoded.**
| Variable | Required | Description |
|---|---|---|
| `MATRIX_TOKEN` | ✅ | Matrix access token for the bot account |
| `MATRIX_HOMESERVER` | ✅ | Full URL of the homeserver, e.g. `https://matrix.example.com` |
| `MATRIX_BOT_PASSWORD` | ⚠️ | Bot account password — required only on first run to upload cross-signing keys via UIA |
| `MATRIX_BACKUP_KEY` | 💡 | Recovery key (base58 with spaces) — enables automatic import of backed-up Megolm sessions |
### Starting the shell
```bash
MATRIX_TOKEN="syt_..." \
MATRIX_HOMESERVER="https://matrix.example.com" \
MATRIX_BOT_PASSWORD="your_password" \
MATRIX_BACKUP_KEY="EsXX xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx" \
rebar3 shell
```
`MATRIX_BOT_PASSWORD` is only needed on the **first run** (or after a state reset) to authenticate the cross-signing key upload. It can be omitted once keys are uploaded.
`MATRIX_BACKUP_KEY` is optional but strongly recommended — without it, the bot cannot decrypt messages sent before it joined a session.
---
## Usage
### 1. Write a Command Handler
Create a module that exports `handle_message/4`:
```erlang
-module(my_bot_commands).
-export([handle_message/4]).
handle_message(<<"!ping">>, RoomId, _Sender, Token) ->
matrix_bot_light_client:send_message(RoomId, <<"Pong!">>, Token);
handle_message(<<"!hello">>, RoomId, Sender, Token) ->
Reply = <<"Hello, ", Sender/binary, "!">>,
matrix_bot_light_client:send_message(RoomId, Reply, Token);
handle_message(_, _, _, _) ->
ok.
```
### 2. Start the Bot
From your application supervisor or the shell:
```erlang
Token = os:getenv("MATRIX_TOKEN"),
Homeserver = os:getenv("MATRIX_HOMESERVER"),
{ok, _} = matrix_bot_light_client:start_link(
list_to_binary(Token),
Homeserver,
[{command_handler, my_bot_commands}]
).
```
### 3. Send Messages
```erlang
matrix_bot_light_client:send_message(RoomId, <<"Hello!">>, Token).
```
---
## E2E Key Management
### Importing backup keys manually
If the bot can't decrypt a message (session not yet known), you can trigger a manual backup import from the shell:
```erlang
matrix_e2e:fetch_backup_keys(<<"EsXX xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx">>).
```
### Re-uploading the device signature
Useful after a server-side key reset:
```erlang
matrix_e2e:reupload_device_sig().
```
### SAS emoji verification
To verify this device from another client (e.g. Element):
```erlang
matrix_e2e:verify_with(<<"@user:example.com">>, <<"DEVICEID">>).
```
---
## State File
The bot persists its cryptographic state (Olm account, Megolm sessions, cross-signing keys) in `matrix_e2e_state.bin` in the working directory.
- The Matrix token is **never written** to this file
- If the file is corrupt or missing, the bot creates a fresh identity automatically (old messages will not be decryptable)
- Keep this file secure — it contains private keys
---
## License
Licensed under the Apache License, Version 2.0. See the [LICENSE](LICENSE) file for details.
---
**Happy hacking!**
For questions or improvements, open an issue or PR on the repository.