matrix-bridge-teams 0.1.0

A bridge between Matrix and Microsoft Teams written in Rust
matrix-bridge-teams-0.1.0 is not a library.

matrix-bridge-teams

A Matrix <-> Microsoft Teams bridge written in Rust.

中文文档

Maintainer: Palpo Team
Contact: chris@acroidea.com

Overview

  • Rust-only implementation for Matrix <-> Microsoft Teams bridging
  • Matrix appservice + Microsoft Graph API integration
  • HTTP endpoints for health/status/metrics and provisioning
  • Database backends: PostgreSQL, SQLite, and MySQL (feature-gated)
  • Dockerfile for local build and container runtime

Repository Layout

  • src/: bridge implementation
  • config/config.sample.yaml: sample configuration
  • migrations/: database migrations
  • Dockerfile: multi-stage container build

Prerequisites

  • Rust toolchain (compatible with the project; Docker build uses Rust 1.93)
  • A Matrix homeserver configured for appservices
  • Microsoft Teams tenant and app registration
  • Database: PostgreSQL, SQLite, or MySQL

Quick Start (Local)

  1. Create your config file:
cp config/config.sample.yaml config.yaml
  1. Set the required values in config.yaml:

    • bridge.domain
    • auth.tenant_id, auth.client_id, auth.client_secret
    • database.url (or database.conn_string / database.filename)
    • registration values via either:
      • registration.id, registration.as_token, registration.hs_token, or
      • teams-registration.yaml next to your config file, or
      • env vars (see Environment Overrides below)
  2. Run:

cargo check -p matrix-bridge-teams
cargo test -p matrix-bridge-teams --no-run
cargo run -p matrix-bridge-teams
  1. Verify:
curl http://127.0.0.1:9006/health
curl http://127.0.0.1:9006/status

Configure Microsoft Teams (Step by Step)

  1. Go to https://portal.azure.com/ and create a new App Registration:

    • Navigate to Azure Active Directory > App registrations > New registration
    • Name: "Matrix Bridge Teams"
    • Supported account types: Choose based on your needs
    • Redirect URI: http://localhost:8080/callback (for initial setup)
  2. After registration, copy:

    • Application (client) ID (for auth.client_id)
    • Directory (tenant) ID (for auth.tenant_id)
  3. Create a client secret:

    • Go to Certificates & secrets > New client secret
    • Copy the secret value (for auth.client_secret)
  4. Configure API permissions:

    • Go to API permissions > Add a permission
    • Select Microsoft Graph > Application permissions
    • Add these permissions:
      • Chat.Read.All or Chat.ReadWrite.All
      • ChannelMessage.Read.All or ChannelMessage.ReadWrite.All
      • Team.ReadBasic.All
      • User.Read.All
    • Grant admin consent for your organization
  5. Fill the auth section in config.yaml:

auth:
  tenant_id: "YOUR_TENANT_ID"
  client_id: "YOUR_CLIENT_ID"
  client_secret: "YOUR_CLIENT_SECRET"
  1. To bridge a specific Teams channel, collect IDs from:
    • Team ID and Channel ID from the Teams URL or API

Configure Matrix / Palpo (Step by Step)

  1. In Palpo config (palpo.toml), set your server name and appservice registration directory:
server_name = "example.com"
appservice_registration_dir = "appservices"
  1. Place your bridge registration file under that directory, for example:
    • appservices/teams-registration.yaml
  2. Ensure tokens are consistent between Palpo registration and bridge config:
    • as_token in registration == bridge appservice token
    • hs_token in registration == bridge homeserver token
  3. Ensure bridge homeserver fields point to Palpo:
bridge:
  domain: "example.com"
  homeserver_url: "http://127.0.0.1:6006" # Replace with your Palpo URL
  1. Start Palpo, then start this bridge.
  2. Confirm connectivity both ways:
    • Palpo must reach bridge registration url (for appservice transactions)
    • Bridge must reach bridge.homeserver_url (your Palpo endpoint)

Notes:

  • If Palpo and bridge run in different containers/hosts, do not use loopback addresses unless they are in the same network namespace.
  • For Docker Desktop, host.docker.internal is often useful when bridge container needs to reach host Palpo.

Configure Matrix / Synapse (Step by Step)

  1. Set your Matrix-facing values in config.yaml:
bridge:
  domain: "example.com"
  homeserver_url: "https://matrix.example.com"
  bind_address: "0.0.0.0"
  port: 9006
  1. Create teams-registration.yaml next to config.yaml (or set REGISTRATION_PATH):
id: "teams"
url: "http://127.0.0.1:9006"
as_token: "CHANGE_ME_AS_TOKEN"
hs_token: "CHANGE_ME_HS_TOKEN"
sender_localpart: "_teams_"
rate_limited: false
protocols: ["msteams"]
namespaces:
  users:
    - exclusive: true
      regex: "@_teams_.*:example.com"
  aliases:
    - exclusive: true
      regex: "#_teams_.*:example.com"
  rooms: []
  1. In Synapse homeserver.yaml, add:
app_service_config_files:
  - /path/to/teams-registration.yaml
  1. Ensure the registration url is reachable by Synapse.
    • Same host: http://127.0.0.1:9006 is fine.
    • Different host/container: use a routable address.
  2. Restart Synapse, then start this bridge.

Notes:

  • bridge.domain should match your Matrix server domain (right side of MXIDs).
  • bridge.homeserver_url should be the real homeserver URL (preferably public HTTPS if Teams needs to fetch media).
  • If registration fields are missing in config.yaml, values are loaded from teams-registration.yaml.

Docker

Build:

docker build -t ghcr.io/palpo-im/matrix-bridge-teams:main -f Dockerfile .

Run (expects /data/config.yaml in the mounted directory):

docker run --rm \
  -p 9006:9006 \
  -v "$(pwd)/config:/data" \
  -e CONFIG_PATH=/data/config.yaml \
  ghcr.io/palpo-im/matrix-bridge-teams:main

Notes:

  • Container listens on 0.0.0.0:9006 by default.
  • Health check endpoint: GET /health
  • Default registration file path is teams-registration.yaml resolved relative to CONFIG_PATH.

Database Configuration

The bridge auto-detects DB type from connection string prefix:

  • postgres:// or postgresql:// -> PostgreSQL
  • sqlite:// -> SQLite
  • mysql:// or mariadb:// -> MySQL / MariaDB
  • anything else -> PostgreSQL fallback

MySQL backend note:

  • Build with the mysql feature enabled, e.g. cargo run -p matrix-bridge-teams --features mysql
  • Install libmysqlclient (or MariaDB Connector/C) so mysqlclient-sys can link

Examples:

database:
  url: "postgresql://user:password@localhost:5432/matrix_bridge"
  max_connections: 10
  min_connections: 1
database:
  url: "sqlite://./data/matrix-bridge.db"
database:
  url: "mysql://user:password@localhost:3306/matrix_bridge"
  max_connections: 10
  min_connections: 1

Environment Overrides

The following environment variables are supported:

  • CONFIG_PATH
  • REGISTRATION_PATH
  • APPSERVICE_TEAMS_AUTH_TENANT_ID
  • APPSERVICE_TEAMS_AUTH_CLIENT_ID
  • APPSERVICE_TEAMS_AUTH_CLIENT_SECRET
  • APPSERVICE_TEAMS_REGISTRATION_ID
  • APPSERVICE_TEAMS_REGISTRATION_AS_TOKEN
  • APPSERVICE_TEAMS_REGISTRATION_HS_TOKEN
  • APPSERVICE_TEAMS_REGISTRATION_SENDER_LOCALPART

Features

Current Features

  • Basic Matrix AppService integration
  • Microsoft Teams Graph API integration
  • Message bridging (Matrix <-> Teams)
  • User synchronization
  • Room/Channel mapping
  • File/Attachment handling
  • Edit/Delete message support
  • Typing notifications
  • Read receipts
  • Presence synchronization

Planned Features

  • Thread support
  • Reaction bridging
  • Rich text formatting
  • Mentions (@user)
  • End-to-end encryption support
  • Multi-tenant support

Development

Building

cargo build

Testing

cargo test

Linting

cargo clippy
cargo fmt -- --check

Contributing

Contributions are welcome! Please read our contributing guidelines before submitting PRs.

License

Apache-2.0

Acknowledgments

Support