- Go 91.6%
- Makefile 8.4%
Relays Forgejo events (issues, PRs, comments, reviews, pushes, releases, forks) to a configured Mattermost channel via plugin. |
||
|---|---|---|
| server | ||
| .gitignore | ||
| go.mod | ||
| go.sum | ||
| Makefile | ||
| plugin.json | ||
| README.md | ||
Forgejo Bot — Mattermost Plugin
Relays Forgejo webhook events (issues, pull requests, comments, reviews, pushes, releases) into a Mattermost channel. Runs inside Mattermost — no external relay service needed.
How it works
Forgejo (webhook) ──POST──► Mattermost plugin (ServeHTTP) ──CreatePost──► target channel
- A Forgejo repository fires a webhook on an event (issue opened, PR merged, comment posted, etc.)
- The webhook POSTs a JSON payload to the plugin's HTTP endpoint on the Mattermost server
- The plugin verifies the HMAC-SHA256 signature and skips duplicate deliveries
- The plugin formats a Markdown message and posts it to the configured channel using the bot user
Event types handled
| Event | Example message |
|---|---|
issues |
alice opened issue #42 Fix login in org/repo |
pull_request |
bob merged PR #18 Add cache in org/repo |
issue_comment |
carol commented on issue #42 Fix login:\n> Looks good, ... |
pull_request_review |
dave approved PR #18 Add cache in org/repo |
pull_request_review_comment |
dave commented on PR #18 Add cache:\n> Nice approach, ... |
push |
eve pushed to main in org/repo |
create |
eve created refs/heads/feature-x in org/repo |
delete |
eve deleted refs/heads/feature-x in org/repo |
fork |
frank forked org/repo |
release |
grace released v1.3.0 in org/repo |
Installation on a self-hosted Mattermost instance
Prerequisites
- Mattermost server 7.1+ (for
EnsureBotUserAPI) - Go 1.21+ for building
- Admin access to the Mattermost server filesystem and System Console
Step 1: Build the plugin
git clone <this-repo> forgejo-bot
cd forgejo-bot
make package
This produces forgejo-bot.tar.gz with the plugin binary and manifest.
If you don't have Go installed on the Mattermost host, cross-compile on your dev machine:
# From your dev machine:
make build
# Copy server/dist/ and plugin.json to the Mattermost host
Step 2: Install the plugin
Copy the tarball to the Mattermost server and extract it into the plugins directory:
# On the Mattermost server:
cd /opt/mattermost
mkdir -p plugins/cool.bonsai.forgejo-bot
tar -xzf /path/to/forgejo-bot.tar.gz -C plugins/cool.bonsai.forgejo-bot
# Ensure correct permissions:
chown -R mattermost:mattermost plugins/cool.bonsai.forgejo-bot
chmod +x plugins/cool.bonsai.forgejo-bot/server/dist/plugin-linux-amd64
Step 3: Enable and configure the plugin
- Go to System Console → Plugins → Plugin Management
- Find "Forgejo Bot" and click Enable
- Go to System Console → Plugins → Forgejo Bot
- Fill in the settings:
| Setting | Value |
|---|---|
| Webhook Secret | A random string, e.g. openssl rand -hex 32. Keep a copy for Forgejo. |
| Target Team | The Mattermost team URL name, e.g. main-team |
| Target Channel | The channel name, e.g. git-activity |
Step 4: Verify the bot user exists
After enabling the plugin, check that the bot user was created:
- Go to System Console → Users
- You should see a user named "forgejo" with type "Bot"
If not, disable and re-enable the plugin to trigger OnActivate again.
Step 5: Configure the webhook in Forgejo
For each repository (or at the organization level):
- Go to Settings → Webhooks (
/:username/:reponame/settings/hooks) - Click Add Webhook, choose Forgejo
- Fill in:
| Field | Value |
|---|---|
| Target URL | https://mattermost.example.com/plugins/cool.bonsai.forgejo-bot |
| HTTP Method | POST |
| POST Content Type | application/json |
| Secret | The same secret you set in the plugin config |
| Trigger On | Select custom events: Issues, Pull Request, Issue Comments, Pull Request Reviews, Pull Request Review Comments, Push, Create, Delete, Fork, Release |
| Active | Checked |
- Click Add Webhook, then click Test Delivery to verify
If the test delivery succeeds, you should see a message appear in the target Mattermost channel.
Docker installation
For Mattermost instances running in Docker (official mattermost/mattermost-team-edition image).
Step 1: Build the plugin
On your dev machine:
git clone <this-repo> forgejo-bot
cd forgejo-bot
make package
Step 2: Extract plugin into the host's plugins volume
# Create the plugin directory on the Docker host
mkdir -p /opt/mattermost/plugins/cool.bonsai.forgejo-bot
# Extract the tarball
tar -xzf forgejo-bot.tar.gz -C /opt/mattermost/plugins/cool.bonsai.forgejo-bot
# Ensure correct ownership (container runs as UID 2000 by default)
chown -R 2000:2000 /opt/mattermost/plugins/cool.bonsai.forgejo-bot
chmod +x /opt/mattermost/plugins/cool.bonsai.forgejo-bot/server/dist/plugin-linux-amd64
Step 2 (alternative): Copy into running container
# Extract on the host first
mkdir -p /tmp/forgejo-bot-plugin
tar -xzf forgejo-bot.tar.gz -C /tmp/forgejo-bot-plugin
# Copy into the container
docker cp /tmp/forgejo-bot-plugin/. mattermost:/mattermost/plugins/cool.bonsai.forgejo-bot/
# Fix ownership inside the container (UID 2000)
docker exec mattermost chown -R 2000:2000 /mattermost/plugins/cool.bonsai.forgejo-bot
docker exec mattermost chmod +x /mattermost/plugins/cool.bonsai.forgejo-bot/server/dist/plugin-linux-amd64
docker-compose setup
If using docker-compose.yml, mount a plugins directory so the plugin survives container restarts:
services:
mattermost:
image: mattermost/mattermost-team-edition:latest
volumes:
- ./volumes/app/mattermost/config:/mattermost/config:rw
- ./volumes/app/mattermost/data:/mattermost/data:rw
- ./volumes/app/mattermost/logs:/mattermost/logs:rw
- ./volumes/app/mattermost/plugins:/mattermost/plugins:rw
- ./volumes/app/mattermost/client/plugins:/mattermost/client/plugins:rw
After adding the plugin to ./volumes/app/mattermost/plugins/, restart the container:
docker compose restart mattermost
Step 3: Enable and configure
Same as bare-metal installation steps 3-5 above.
Note: If the plugin doesn't appear in System Console after restart, run
docker exec mattermost ls /mattermost/plugins/to verify it was extracted correctly.
Troubleshooting
No messages appearing:
- Check Mattermost server logs:
journalctl -u mattermost -for/opt/mattermost/logs/mattermost.log - Verify the secret matches exactly between Forgejo and the plugin config
- Verify the team and channel names match exactly (case-sensitive)
- Check that the bot user exists in System Console → Users
- Check the Forgejo webhook delivery history at the webhook settings page
"channel not found" in logs:
- The team or channel name in plugin config doesn't match. Team name is the URL slug (lowercase, hyphens), not the display name.
- The bot user must be a member of the team (Mattermost auto-adds bots to teams, but verify in System Console → Teams).
"unauthorized" in logs:
- The webhook secret is empty or doesn't match between Forgejo and the plugin.
Architecture notes
Plugin endpoint
The plugin listens at GET/POST /plugins/cool.bonsai.forgejo-bot. Only POST with a valid HMAC signature and X-Forgejo-Event header is processed. GET returns 405.
Idempotency
Duplicate deliveries (same X-Forgejo-Delivery UUID) are detected via the KV store and silently dropped. The KV store lives in the Mattermost database, so it survives plugin restarts.
Configuration
Settings are stored in the Mattermost PluginKeyValueStore via the System Console. The ForgejoSecret field is marked secret: true, so it's masked in the UI and API responses.
Bot user
A bot named forgejo is created on plugin activation. All messages are posted as this bot, keeping activity distinct from real users. The bot ID is persisted in the KV store for efficiency.
Building from source
# First time: download the Mattermost server dependency and generate go.sum
go mod tidy
# Then build
make build # compile for all platforms
make package # build + tar.gz
make clean # remove build artifacts
License
MIT