Telegram โ Mattermost transparent bridge. Messages appear native.
Project description
BridgeMost ๐ป
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.yamland 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):
- Go to System Console โ Authentication โ Token Access
- Set Enable Personal Access Tokens to
true - 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:
- Connect to your Mattermost server
- Log you in (password is NOT stored)
- Auto-create a Personal Access Token for BridgeMost
- List all bots on the server โ you pick which ones to bridge
- Ask for your Telegram bot token and user ID
- Generate
config.yamlautomatically
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
- Open Telegram and send a message to your BridgeMost bot
- The message should appear in Mattermost as your real user
- 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:
- OpenAI Whisper API (
whisper-1) - Groq Whisper (
whisper-large-v3-turboโ free tier) - faster-whisper-server (self-hosted, any model)
- Any endpoint accepting
POSTwithmultipart/form-dataand returning{"text": "..."}
๐ 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) โ
โโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ
- TG โ MM: User sends via Telegram โ BridgeMost posts to MM using the user's PAT (appears as real user)
- MM โ TG: Bot responds โ WebSocket delivers event instantly โ BridgeMost relays to Telegram
- 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.yamlcontains 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.1by default (not exposed externally) - Only Telegram users whose
telegram_idis 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bridgemost-2.0.0.tar.gz.
File metadata
- Download URL: bridgemost-2.0.0.tar.gz
- Upload date:
- Size: 44.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
48336c055c81e58c4cea6050c474eef5e8e824a16f14a01adda58ffe31f780a1
|
|
| MD5 |
7c8bb88dcd3cde7ec3cc2ecc0011449e
|
|
| BLAKE2b-256 |
fd7c40aaf87f81086ea5810ada8759e13d0cdfadcc8ed9a67e874cb5b766bac2
|
File details
Details for the file bridgemost-2.0.0-py3-none-any.whl.
File metadata
- Download URL: bridgemost-2.0.0-py3-none-any.whl
- Upload date:
- Size: 39.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bad48ec69960de3b7a6fbe04e9f0ddb16c4f9031b386af47e0f279a04f8836f2
|
|
| MD5 |
9a0f2466b1246cd8eda21df3018f06e8
|
|
| BLAKE2b-256 |
c35d31025ff05fdd3da5bcdb124a43ab0f19fbd9142288c4c3c98ea8bff3e141
|