README
¶
mmupdatebot
A lightweight Go bot that listens to a Mattermost channel and executes a local command whenever a new message is posted.
Features
- Connects to Mattermost via WebSocket for real-time event streaming
- Authenticates using a personal access token or login/password
- Filters messages by channel and optionally by author
- Runs a configurable local command on each matching post
- Automatic reconnection with exponential backoff on WebSocket drops
- Graceful shutdown on
SIGINT/SIGTERM
Requirements
- Go 1.24+
- A Mattermost account (bot or regular user)
Installation
go install codeberg.org/oschwand/mmupdatebot@latest
Configuration
Copy the example environment file to .env (or use the systemd setup below) and fill in the values:
cp .env.example .env
| Variable | Required | Description |
|---|---|---|
MMUPDATEBOT_MATTERMOST_URL |
yes | Mattermost server URL (e.g. https://mattermost.example.com) |
MMUPDATEBOT_MATTERMOST_TEAM |
yes | Team name |
MMUPDATEBOT_MATTERMOST_CHANNEL |
yes | Channel to listen on |
MMUPDATEBOT_MATTERMOST_TOKEN |
no* | Personal access token |
MMUPDATEBOT_MATTERMOST_LOGIN |
no* | Login email or username |
MMUPDATEBOT_MATTERMOST_PASSWORD |
no* | Account password |
MMUPDATEBOT_MATTERMOST_AUTHOR |
no | Restrict triggers to posts by this user ID |
MMUPDATEBOT_COMMAND |
yes | Absolute path to the executable to run on each post |
MMUPDATEBOT_WORKDIR |
no | Change working directory before running commands |
* You must provide either MMUPDATEBOT_MATTERMOST_TOKEN or both MMUPDATEBOT_MATTERMOST_LOGIN and MMUPDATEBOT_MATTERMOST_PASSWORD.
Finding the author ID
The MMUPDATEBOT_MATTERMOST_AUTHOR variable expects a Mattermost user ID (not a username). To find it, run the bot without MMUPDATEBOT_MATTERMOST_AUTHOR set and post a message in the monitored channel. The log will show:
[<post-id>] <username/user-id> <message>
Copy the user-id part and set it as MMUPDATEBOT_MATTERMOST_AUTHOR.
Usage
./mmupdatebot watch
The bot connects, logs the authenticated user and monitored channel, then waits for posts. Press Ctrl+C to stop.
Use --help to see all available commands.
systemd user service
A template unit file is provided to run the bot as a systemd user service. The @ placeholder allows running multiple instances with different configurations.
- Install the binary to
~/bin/mmupdatebot - Copy the service file:
mkdir -p ~/.config/systemd/user
cp mmupdatebot@.service ~/.config/systemd/user/
- Create an environment file for each instance (e.g.
mybot):
mkdir -p ~/.config/mmupdatebot
cp .env.example ~/.config/mmupdatebot/mybot.env
- Enable and start the service:
systemctl --user daemon-reload
systemctl --user enable --now mmupdatebot@mybot
View logs with:
journalctl --user -u mmupdatebot@mybot -f
How It Works
- Reads configuration from
.envand/or environment variables - Changes working directory
- Authenticates with the Mattermost server (token or credentials)
- Opens a WebSocket connection for real-time events
- Filters incoming
postedevents for the configured channel (and author if set) - Executes the configured command in a goroutine for each matching post
Reconnection
Periodic WebSocket disconnections are normal and expected. Many Mattermost deployments sit behind a reverse proxy (nginx, Caddy, a load balancer, or a CDN) that closes idle WebSocket connections after a fixed timeout — often as short as 60 seconds. When this happens you will see log lines like:
ERRO websocket disconnected err="...close 1006 (abnormal closure): unexpected EOF"
INFO websocket connected
The bot handles this transparently:
- It detects the drop (either via the WebSocket read loop or the 65 s ping timeout watchdog) and reconnects automatically.
- Reconnection uses an exponential backoff (starting at 1 s, capped at 60 s) to avoid hammering the server during an outage.
- The backoff resets to 1 s after each successful connection.
- A short gap of a few seconds between the disconnect and the reconnect is expected, but no messages are recovered for that window — the bot only sees posts that arrive while it is connected.
So a disconnect/reconnect cycle every minute is harmless: it just means a proxy in front of the server is enforcing its idle timeout. The bot keeps running and stays in sync. If the cycles become very frequent or the backoff grows large, that points to a sustained network or server issue rather than a normal idle drop.
License
This project is licensed under the MIT License.
Documentation
¶
There is no documentation for this package.