Skip to content

A TypeScript-based bridge that seamlessly forwards messages between channels on different Mattermost instances. Features profile picture sync, file attachments, MFA support, and domain filtering. Uses regular user accounts - no bot setup required. Multi-arch Docker images available.

License

Notifications You must be signed in to change notification settings

cln-io/mattermost-bridge

Repository files navigation

Mattermost Bridge

A TypeScript-based bridge that forwards messages between channels on different Mattermost instances. Uses regular user accounts for authentication - no bot setup required!

This project was vibe coded with Claude Opus 4

Screenshots

The left mattermost (the one we want to monitor messages on) has a user posting a message:

example

The bridge will mirror the message to the right mattermost (the destination mattermost)

example

The console / app log

console

Built-in Status Monitoring

The bridge includes a built-in status channel that provides real-time monitoring of bridge activity and logs. When enabled with STATS_CHANNEL_UPDATES=logs, it creates a dedicated #mattermost-bridge-status channel that continuously updates with:

  • Event summaries - Message counts and bridge activity
  • Live log feed - Last 30 log lines updated every 10 minutes (respects TIMEZONE setting)
  • Single message updates - No channel spam, just one continuously updated status message

status channel

This gives you an always up-to-date view of your bridge health without needing to check Docker logs or the console.

How It Works

The bridge listens for messages on a source channel and forwards them to a target channel on a different Mattermost instance, preserving:

  • User avatars
  • File attachments
  • Message formatting
  • Original context (timestamp, channel, server)

Features

  • Cross-server messaging - Bridge channels between any two Mattermost instances
  • Profile picture sync - Downloads and re-uploads user avatars with intelligent caching
  • File attachment support - Seamlessly forwards all file attachments
  • MFA/2FA support - Works with multi-factor authentication enabled accounts
  • Email domain filtering - Exclude messages from specific email domains
  • Minimal attachments - Clean, baby blue message formatting with profile pictures
  • Message catch-up - Automatically recover missed messages when bridge restarts (with Docker volume persistence)

Quick Start

# Clone and setup
git clone <repository-url>
cd mattermost-bridge
npm install

# Run quick setup
./quick-start.sh

Configuration

The bridge uses environment variables for configuration. You can set these in a .env file or as environment variables in your deployment environment.

Quick Configuration Example

# Required: Mattermost Instances
MATTERMOST_LEFT_NAME=SourceServer
MATTERMOST_LEFT_SERVER=https://mattermost.source.com
MATTERMOST_LEFT_USERNAME=[email protected]
MATTERMOST_LEFT_PASSWORD_B64=<base64-encoded-password>
MATTERMOST_LEFT_TEAM=team-name

MATTERMOST_RIGHT_NAME=TargetServer
MATTERMOST_RIGHT_SERVER=https://mattermost.target.com
MATTERMOST_RIGHT_USERNAME=[email protected]
MATTERMOST_RIGHT_PASSWORD_B64=<base64-encoded-password>

# Required: Channel IDs
SOURCE_CHANNEL_ID=abc123def456...  # Single channel
# or
SOURCE_CHANNEL_ID=abc123,def456,ghi789  # Multiple channels (comma-separated)
TARGET_CHANNEL_ID=xyz789uvw012...

Environment Variables Reference

Variable Description Required Default Example
Left Mattermost (Source)
MATTERMOST_LEFT_NAME Display name for the source server - SourceServer
MATTERMOST_LEFT_SERVER URL of the source Mattermost server - https://mattermost.source.com
MATTERMOST_LEFT_USERNAME Username for authentication - [email protected]
MATTERMOST_LEFT_PASSWORD_B64 Base64-encoded password - cGFzc3dvcmQxMjMh
MATTERMOST_LEFT_TEAM Team name (for generating message links) - team-name
MATTERMOST_LEFT_MFA_SEED MFA/2FA seed (if MFA enabled) - JBSWY3DPEHPK3PXP
Right Mattermost (Target)
MATTERMOST_RIGHT_NAME Display name for the target server - TargetServer
MATTERMOST_RIGHT_SERVER URL of the target Mattermost server - https://mattermost.target.com
MATTERMOST_RIGHT_USERNAME Username for authentication - [email protected]
MATTERMOST_RIGHT_PASSWORD_B64 Base64-encoded password - cGFzc3dvcmQxMjMh
MATTERMOST_RIGHT_TEAM Team name (for message links) - team-name
MATTERMOST_RIGHT_MFA_SEED MFA/2FA seed (if MFA enabled) - GEZDGNBVGY3TQOJQ
Bridge Configuration
SOURCE_CHANNEL_ID ID of the channel(s) to monitor. Can be a single ID or comma-separated list - abc123def456... or abc123,def456,ghi789
TARGET_CHANNEL_ID ID of the channel to post to - xyz789uvw012...
Logging & Display
LOG_LEVEL Logging verbosity level info debug, info, warn, error
DEBUG_WEBSOCKET_EVENTS Enable detailed WebSocket event logging false true
EVENT_SUMMARY_INTERVAL_MINUTES How often to log event summaries 10 5
STATS_CHANNEL_UPDATES What to post to #mattermost-bridge-status none summary, logs
none = disable status channel, summary = post event summaries, logs = combined summaries + last 30 log lines (updates single message)
DISABLE_EMOJI Disable emojis in console output false true
TIMEZONE Timezone for timestamp formatting UTC Europe/Brussels, CET
Message Filtering
DONT_FORWARD_FOR Comma-separated email domains to exclude - @excluded.com,@internal.org
DRY_RUN Log messages without posting to target false true
Monitoring
HEARTBEAT_URL URL for uptime monitoring - https://heartbeat.uptimerobot.com/...
HEARTBEAT_INTERVAL_MINUTES How often to send heartbeat pings 15 5
Message Catch-Up
ENABLE_CATCH_UP Enable catch-up mode to recover missed messages when bridge was offline false true
CATCH_UP_PERSISTENCE_PATH Path to store message tracking state (Docker volume recommended) /data/tracking/message-state.json /custom/path/state.json
MAX_MESSAGES_TO_RECOVER Maximum number of messages to recover per channel on startup 100 50, 200
Appearance
FOOTER_ICON Custom icon URL for message footers - https://example.com/icon.png
LEFT_MESSAGE_EMOJI Emoji to add to original message after bridging - envelope_with_arrow, white_check_mark

Password Encoding

node encode-password.js "your-password-here"

Docker

# Pull and run
docker pull clnio/mattermost-bridge:latest
docker run --env-file .env clnio/mattermost-bridge:latest

# Or use docker-compose
docker-compose up -d

Docker images support both AMD64 and ARM64 architectures.

Docker with Message Catch-Up

To enable message catch-up functionality, mount a volume for persistence:

# Create a named volume
docker volume create mattermost-bridge-data

# Run with catch-up enabled
docker run --env-file .env \
  -e ENABLE_CATCH_UP=true \
  -v mattermost-bridge-data:/data \
  clnio/mattermost-bridge:latest

Or in docker-compose.yml:

version: '3.8'
services:
  mattermost-bridge:
    image: clnio/mattermost-bridge:latest
    env_file: .env
    environment:
      - ENABLE_CATCH_UP=true
    volumes:
      - mattermost-bridge-data:/data
    restart: unless-stopped

volumes:
  mattermost-bridge-data:

The bridge will automatically track forwarded messages and catch up on missed messages when restarted.

Local Development

# Set up local test environment
./local-env-setup.sh

# Start development
npm run dev

# Run tests
npm test

Local URLs

Troubleshooting

Authentication Failed

  • Verify base64 encoded passwords
  • Check MFA seed if using 2FA
  • Ensure user has channel access

Channel Not Found

  • Verify channel IDs are correct
  • Use mmctl channel search "channel-name" --team "team-name"

Debug Mode

LOG_LEVEL=debug
DEBUG_WEBSOCKET_EVENTS=true

Scripts

  • npm start - Start the bridge
  • npm run dev - Development mode
  • npm test - Run tests
  • ./build.sh - Build Docker image
  • ./push-live.sh - Push to Docker Hub
  • ./local-env-setup.sh - Set up local test environment

Contributing

  1. Fork the repository
  2. Create your feature branch
  3. Commit your changes
  4. Push to the branch
  5. Open a Pull Request

License

MIT License - see the LICENSE file for details.

About

A TypeScript-based bridge that seamlessly forwards messages between channels on different Mattermost instances. Features profile picture sync, file attachments, MFA support, and domain filtering. Uses regular user accounts - no bot setup required. Multi-arch Docker images available.

Topics

Resources

License

Stars

Watchers

Forks

Contributors 2

  •  
  •