matrix-bridge-slack
A Matrix <-> Slack bridge written in Rust.
Maintainer: Palpo Team
Contact: chris@acroidea.com
Overview
- Rust-only implementation
- Matrix appservice + Slack bot bridge core
- Slack Socket Mode for inbound events
- Slack Web API for outbound messaging, edits, file uploads, and lookups
- HTTP endpoints for health/status/metrics and provisioning
- Database backends: PostgreSQL, SQLite, and MySQL (feature-gated)
Repository Layout
src/: bridge implementationconfig/config.sample.yaml: sample configurationDockerfile: multi-stage container build
Prerequisites
- Rust toolchain (Docker build uses Rust 1.93)
- A Matrix homeserver configured for appservices
- A Slack app with:
- bot token (
xoxb-...) - app token (
xapp-...) withconnections:write
- bot token (
- Database: PostgreSQL, SQLite, or MySQL
Quick Start (Local)
- Create your config file:
-
Set required values in
config.yaml:bridge.domainauth.bot_tokenauth.app_tokendatabase.url(ordatabase.conn_string/database.filename)- registration values via either:
registration.id,registration.as_token,registration.hs_token, orslack-registration.yamlnext to your config file, or- env vars (see Environment Overrides below)
-
Run:
- Verify:
Configure Slack (Step by Step)
-
Create a Slack app in your workspace:
-
Enable Socket Mode and create an App-Level Token:
- scope:
connections:write - token format:
xapp-...
- scope:
-
Add Bot Token Scopes under OAuth & Permissions (minimum recommended):
chat:writechannels:historychannels:readusers:readfiles:write- optional for private channels:
groups:history,groups:read - optional for username/icon customization:
chat:write.customize
-
Under Event Subscriptions, enable events and subscribe bot events as needed:
message.channels- optional:
message.groups,user_typing,user_change
-
Install/reinstall the app to your workspace and copy tokens:
- Bot User OAuth Token ->
auth.bot_token - App-Level Token ->
auth.app_token
- Bot User OAuth Token ->
-
Fill auth values in
config.yaml:
auth:
bot_token: "xoxb-..."
app_token: "xapp-..."
client_id: null
client_secret: null
Slack API/Spec References
This bridge implementation follows Slack official docs:
- Socket Mode overview: https://api.slack.com/apis/connections/socket
apps.connections.open: https://docs.slack.dev/reference/methods/apps.connections.open/chat.postMessage: https://docs.slack.dev/reference/methods/chat.postMessage/chat.update: https://docs.slack.dev/reference/methods/chat.update/users.info: https://docs.slack.dev/reference/methods/users.info/conversations.info: https://docs.slack.dev/reference/methods/conversations.info/- File upload flow:
- Message event scopes/events:
Configure Matrix / Palpo (Step by Step)
- In Palpo config (
palpo.toml), set server name and appservice registration directory:
= "example.com"
= "appservices"
-
Place your bridge registration file there, for example:
appservices/slack-registration.yaml
-
Ensure tokens are consistent between Palpo registration and bridge config:
as_tokenin registration == bridge appservice tokenhs_tokenin registration == bridge homeserver token
-
Ensure bridge homeserver fields point to Palpo:
bridge:
domain: "example.com"
homeserver_url: "http://127.0.0.1:6006"
Configure Matrix / Synapse (Step by Step)
Create slack-registration.yaml (or set REGISTRATION_PATH) and load it from Synapse:
id: "slack"
url: "http://127.0.0.1:9005"
as_token: "CHANGE_ME_AS_TOKEN"
hs_token: "CHANGE_ME_HS_TOKEN"
sender_localpart: "_slack_"
rate_limited: false
protocols:
namespaces:
users:
- exclusive: true
regex: "@_slack_.*:example.com"
aliases:
- exclusive: true
regex: "#_slack_.*:example.com"
rooms:
In homeserver.yaml:
app_service_config_files:
- /path/to/slack-registration.yaml
Docker
Build:
Run:
Environment Overrides
CONFIG_PATHREGISTRATION_PATHAPPSERVICE_SLACK_AUTH_BOT_TOKENAPPSERVICE_SLACK_AUTH_APP_TOKENAPPSERVICE_SLACK_AUTH_CLIENT_IDAPPSERVICE_SLACK_AUTH_CLIENT_SECRETAPPSERVICE_SLACK_REGISTRATION_IDAPPSERVICE_SLACK_REGISTRATION_AS_TOKENAPPSERVICE_SLACK_REGISTRATION_HS_TOKENAPPSERVICE_SLACK_REGISTRATION_SENDER_LOCALPART