Skip to main content

Telegram โ†” Mattermost transparent bridge. Messages appear native.

Project description

BridgeMost ๐Ÿ‘ป

CI

Telegram โ†” Mattermost Transparent Bridge

BridgeMost makes your Telegram messages appear natively in Mattermost โ€” as your real user, with your avatar and name. Bot responses relay back to Telegram instantly via WebSocket.

Unlike Matterbridge or webhooks that post with [User] prefixes, BridgeMost posts as your actual Mattermost account. Nobody in Mattermost can tell you're writing from Telegram.

โœจ Features

Feature Description
๐Ÿชช Transparent identity Posts as your real MM user (avatar, name, everything)
๐Ÿ“ Full media Photos, documents, audio, video, voice โ€” bidirectional
๐ŸŽค Voice-to-text Voice messages auto-transcribed via Whisper API
๐Ÿค– Multi-bot routing Talk to multiple bots; switch with /bot name
โšก Real-time WebSocket Responses arrive instantly (no polling)
โœ๏ธ Edit & delete sync Edits and deletes stay in sync both ways
๐Ÿ˜€ Reactions Emoji reactions synced between TG and MM
โŒจ๏ธ Typing indicator "Bot is typing..." shown in Telegram
๐Ÿ“ Markdown MM markdown โ†’ Telegram MarkdownV2 auto-conversion
๐Ÿ”’ Startup checks Validates tokens + discovers channels before starting
๐Ÿ’พ Persistent mapping SQLite store for message IDs (survives restarts)
๐Ÿฉบ Health endpoint HTTP /health on configurable port

| ๐Ÿ‘ฅ Multi-user | Multiple Telegram users, each with their own MM identity |

~55 MB RAM ยท ~250 ms latency ยท asyncio-based ยท Python 3.11+

Multi-user ready: Multiple people can use the same BridgeMost instance โ€” each with their own Telegram account, Mattermost identity, and bot routing. Add users to config.yaml and they appear as themselves in Mattermost. No shared accounts, no impersonation.


๐Ÿš€ Installation โ€” Step by Step

What you need before starting

# Item Where to get it
1 Mattermost server (self-hosted) You must be admin or have an admin enable PAT support
2 Telegram bot token Create via @BotFather โ†’ /newbot
3 Your Telegram user ID Send any message to @userinfobot โ€” it replies with your numeric ID
4 Python 3.11+ python3 --version to check
5 Git git --version to check

Step 1 โ€” Enable Personal Access Tokens on Mattermost

โš ๏ธ This step is REQUIRED. Without it, BridgeMost cannot post as your user.

Option A โ€” Via Mattermost UI (admin):

  1. Go to System Console โ†’ Authentication โ†’ Token Access
  2. Set Enable Personal Access Tokens to true
  3. Save

Option B โ€” Via command line (requires access to the server):

# If mmctl is available:
mmctl --local config set ServiceSettings.EnableUserAccessTokens true

# Or via REST API with admin token:
curl -X PUT http://localhost:8065/api/v4/config/patch \
  -H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"ServiceSettings": {"EnableUserAccessTokens": true}}'

Step 2 โ€” Clone and install

git clone https://github.com/JuanjoPM-Developer/BridgeMost.git
cd BridgeMost
python3 -m venv .venv
source .venv/bin/activate
pip install -e .

Step 3 โ€” Configure

Option A โ€” Interactive wizard (recommended):

python3 -m bridgemost setup

The wizard will:

  1. Connect to your Mattermost server
  2. Log you in (password is NOT stored)
  3. Auto-create a Personal Access Token for BridgeMost
  4. List all bots on the server โ€” you pick which ones to bridge
  5. Ask for your Telegram bot token and user ID
  6. Generate config.yaml automatically

Option B โ€” Manual configuration:

cp config.example.yaml config.yaml

Then edit config.yaml โ€” see the Configuration Reference below for each field.

Step 4 โ€” Run

# Foreground (for testing):
python3 -m bridgemost

# Or as a systemd service (recommended for production):
sudo cp bridgemost.service.example /etc/systemd/system/bridgemost.service
# Edit the service file โ€” update paths to match your installation
sudo systemctl daemon-reload
sudo systemctl enable --now bridgemost

Step 5 โ€” Test

  1. Open Telegram and send a message to your BridgeMost bot
  2. The message should appear in Mattermost as your real user
  3. When the MM bot responds, the response should appear in your Telegram chat

โš™๏ธ Configuration Reference

Minimal config.yaml

telegram:
  bot_token: "123456:ABC-DEF..."        # From @BotFather

mattermost:
  url: "http://localhost:8065"           # Your MM server URL (http or https)
  bot_token: "abc123..."                 # Any bot's access token (for WebSocket)
  bot_user_id: "a1b2c3d4..."            # User ID of that bot

users:
  - telegram_id: 123456789              # Your numeric Telegram user ID
    telegram_name: "Your Name"           # Display name (for logs only)
    mm_user_id: "x1y2z3..."             # Your Mattermost user ID
    mm_token: "your-pat-here"           # Your Personal Access Token
    bots:
      - name: "mybot"                   # Friendly name (used with /bot command)
        mm_bot_id: "bot-user-id-here"   # The bot's Mattermost user ID
        mm_dm_channel: ""               # Leave empty โ€” auto-discovered at startup
        default: true                   # First bot to talk to when bridge starts

How to find each value

Field How to get it
telegram.bot_token @BotFather โ†’ /newbot โ†’ copy the token
telegram_id Send any message to @userinfobot
mattermost.url The URL you use to open Mattermost in your browser
mattermost.bot_token MM โ†’ Integrations โ†’ Bot Accounts โ†’ pick any bot โ†’ copy token. Or ask your admin.
mattermost.bot_user_id Run: mmctl user search <botname> โ†’ copy the id field. Or: curl http://YOUR_MM/api/v4/users/username/<botname> -H "Authorization: Bearer TOKEN" โ†’ "id" field
mm_user_id Same as above but with your own username instead of the bot's
mm_token (PAT) MM โ†’ click your avatar โ†’ Profile โ†’ Security โ†’ Personal Access Tokens โ†’ Create. Or the setup wizard creates it for you.
mm_bot_id Same method as bot_user_id โ€” the Mattermost user ID of the bot you want to talk to
mm_dm_channel Leave empty โ€” BridgeMost discovers it automatically. Only fill in if auto-discovery fails (check logs).

Optional sections

# Voice-to-text transcription (requires a Whisper-compatible API)
voice_to_text:
  url: "http://localhost:9000"          # Whisper endpoint
  api_key: ""                           # For OpenAI/Groq; empty for local Whisper
  model: "large-v3"                     # large-v3, whisper-1, whisper-large-v3-turbo
  language: ""                          # "es", "en", or "" for auto-detect
  keep_audio: true                      # Also attach audio file alongside transcript

# Health monitoring endpoint
health:
  port: 9191                            # HTTP health check on this port

# Message persistence
storage:
  data_dir: ""                          # SQLite DB location; empty = working directory

# Logging
logging:
  level: "INFO"                         # DEBUG, INFO, WARNING, ERROR
  file: ""                              # Log file path, or "" for stdout only

๐Ÿค– Telegram Commands

Command Description
/bot List all available bots and show which one is active
/bot name Switch to a different bot
/bots Show all bots with live ๐ŸŸข/โšซ online status
/status Detailed info about the active bot (state, last message, store stats)

Just type normally to send messages โ€” commands are only for bot management.


๐ŸŽค Voice-to-Text

When voice_to_text is configured, voice messages are transcribed before posting:

๐ŸŽค Hello, this is what I said in the voice message

If keep_audio: true, the original audio file is also attached.

Compatible APIs:


๐Ÿ“Š Health Endpoint

curl http://localhost:9191/health
{
  "status": "ok",
  "version": "0.9.5",
  "transport": "websocket",
  "uptime": "2h15m30s",
  "messages": { "tg_to_mm": 42, "mm_to_tg": 38, "errors": 0 },
  "store": { "persistent_mappings": 156 }
}

๐Ÿ—๏ธ Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Telegram โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚  BridgeMost  โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚  Mattermost  โ”‚
โ”‚  (User)  โ”‚  Bot API     โ”‚   (Bridge)   โ”‚  REST + WS   โ”‚  (Bots)      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
  1. TG โ†’ MM: User sends via Telegram โ†’ BridgeMost posts to MM using the user's PAT (appears as real user)
  2. MM โ†’ TG: Bot responds โ†’ WebSocket delivers event instantly โ†’ BridgeMost relays to Telegram
  3. Edits/Deletes/Reactions: Tracked via bidirectional message ID mapping (SQLite-backed, 30-day TTL)

๐Ÿ”ง Troubleshooting

Problem Solution
FATAL: Token validation FAILED Your PAT is invalid or expired. Create a new one in MM โ†’ Profile โ†’ Security โ†’ Personal Access Tokens. Also verify EnableUserAccessTokens is true in System Console.
โš ๏ธ Tu token de Mattermost ha expirado (Telegram alert) Same as above โ€” renew the PAT and update mm_token in config.yaml, then restart.
Zero DM channels discovered BridgeMost couldn't find any DM channel with the configured bots. Make sure you have sent at least one DM to each bot in Mattermost before starting. The mm_bot_id values must be correct user IDs (26 alphanumeric characters).
WS auth rejected (CLOSE on connect) The mattermost.bot_token is invalid. Get a valid bot token from Integrations โ†’ Bot Accounts.
OSError: [Errno 98] address already in use (health port) Another process is using the health port (default 9191). Change health.port in config or stop the conflicting service.
Messages arrive but with [BotName] prefix This is normal in multi-bot mode โ€” it identifies which bot sent the response. With a single bot, no prefix is added.
Voice messages not transcribed Check that voice_to_text.url is reachable: curl http://YOUR_WHISPER_URL/asr. For OpenAI/Groq, verify api_key is set.
EnableUserAccessTokens keeps turning off Something (another admin, a script, or a bot) is toggling it. Set it permanently and check who has access to System Console.
Bridge starts but no messages relay Check logs (journalctl -u bridgemost -f). Common causes: wrong telegram_id (messages from unknown users are silently ignored), bot not yet DM'd in MM, or firewall blocking MM API.

๐Ÿ›ก๏ธ Security Notes

  • config.yaml contains secrets โ€” it's in .gitignore, never commit it
  • Personal Access Tokens have your full user permissions โ€” use a dedicated account if concerned
  • Health endpoint binds to 127.0.0.1 by default (not exposed externally)
  • Only Telegram users whose telegram_id is in config can use the bridge
  • Message ID mappings stored in SQLite (local disk only, 30-day auto-prune)

๐Ÿ“‹ Changelog

Version Date Feature
v0.9.5 2026-03-25 Fix NameError in whisper.py finally block (GitHub #1), version alignment
v0.9.4 2026-03-25 Smart MMโ†’TG file relay with MIME dispatch (photo/gif/audio/voice/video)
v0.9.3 2026-03-24 Audit fix: 3 bugs in sticker/location/poll handlers
v0.9.2 2026-03-24 Stickers, locations, venues, polls โ€” TGโ†’MM
v0.9.1 2026-03-25 Multi-user highlighted in README, unit tests added
v0.9.0 2026-03-24 README rewrite, improved config.example.yaml with inline docs
v0.8.3 2026-03-24 Code audit cleanup (dead code, unused imports, version alignment)
v0.8.2 2026-03-24 Remove /ping (ghost typing fix), typing timeout 300โ†’60s
v0.8.1 2026-03-24 /bots and /status Telegram commands
v0.8.0 2026-03-24 SQLite persistent store, WS reconnect jitter, TG rate limiter
v0.7.0 2026-03-24 7-bug audit fix (voice handler, file leak, typing timeout, PAT expiry)
v0.6.0 2026-03-24 Interactive setup wizard (bridgemost setup)
v0.5.0 2026-03-24 Startup resilience โ€” token validation, DM retry, zero-channel abort
v0.4.0 2026-03-24 Voice-to-text via Whisper API
v0.3.1 2026-03-24 Synthetic typing indicator
v0.3.0 2026-03-24 Multi-bot routing with /bot command
v0.2.0 2026-03-24 Emoji/reaction relay
v0.1.1 2026-03-24 Edit and delete sync (bidirectional)
v0.1.0 2026-03-24 WebSocket transport (replaced polling)
v0.0.5 2026-03-24 First public release

๐Ÿ“„ License

MIT โ€” see LICENSE

๐Ÿ™ Built with

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bridgemost-1.0.0.tar.gz (45.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bridgemost-1.0.0-py3-none-any.whl (39.3 kB view details)

Uploaded Python 3

File details

Details for the file bridgemost-1.0.0.tar.gz.

File metadata

  • Download URL: bridgemost-1.0.0.tar.gz
  • Upload date:
  • Size: 45.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for bridgemost-1.0.0.tar.gz
Algorithm Hash digest
SHA256 0a47051168b695e9f986273df3c802a2cb73ca0c8a6747b45bddb91bbcb42577
MD5 8210b160a5e1a5a652f1c2e05dd6fb31
BLAKE2b-256 3ccc4134f1025b218cb308ebad90527d3a2d9b433642574a1365154dcaeb2d2a

See more details on using hashes here.

File details

Details for the file bridgemost-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: bridgemost-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 39.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for bridgemost-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d60da01f4781bc867d1c9aef9fdcde844d606501ff94477b859f51efc188fdd7
MD5 66793c43e087eadbbcc8775c231ea8f9
BLAKE2b-256 c09490dea46a50f50b8d1d750436942e151dc2b2c1210fb060c0838d19c02695

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page