# Discourse-Telegram chat bridge

**URL:** https://meta.discourse.org/t/discourse-telegram-chat-bridge/406959
**Category:** Plugin
**Tags:** chat-integration, chat
**Created:** [July 7, 2026, 6:09am UTC](https://meta.discourse.org/t/discourse-telegram-chat-bridge/406959 "2026-07-07T06:09:03Z")
**Posts on this page:** 1
**Showing post:** 1

<div class="post-metadata">

### Author: ![Babylai](https://avatars.discourse-cdn.com/v4/letter/b/b19c9b/32.png) [@Babylai](https://meta.discourse.org/u/Babylai)
#### Post date: [July 7, 2026, 6:09am UTC](https://meta.discourse.org/t/discourse-telegram-chat-bridge/406959/1 "2026-07-07T06:09:03Z")

</div>

| | |
| --- | --- |
| ℹ **Summary** | Real-time, two-way bridge between Discourse Chat and Telegram, with first-class support for Telegram forum topics |
| 🛠 **Repository Link** | [GitHub - babylai/discourse-telegram-chat-bridge: Real-time two-way bridge between Discourse Chat and Telegram (design phase / POC) · GitHub](https://github.com/babylai/discourse-telegram-chat-bridge) |
| 📖 **Install Guide** | [How to install plugins in Discourse](https://meta.discourse.org/t/install-plugins-in-discourse/19157) |

## Features

Each Discourse chat channel is mapped to a Telegram chat — either a plain group, or a **specific topic in a supergroup with Topics enabled**. A message posted on one side shows up on the other within a second or two.

| | Discourse → Telegram | Telegram → Discourse |
| --- | --- | --- |
| Text (with formatting) | ✅ real HTML formatting | ✅ entities → Markdown |
| Emojis | ✅ | ✅ |
| Replies | ✅ | ✅ |
| Edits | ✅ | ✅ |
| Deletions | ✅ | ❌ (Bot API limitation, see below) |
| Photos | ✅ photos & albums | ✅ downloaded and re-uploaded |
| Other files | ✅ | ✅ documents, video, audio, voice |
| Stickers | — | ✅ static as image; animated degrade to their emoji |

- **Author attribution:** bots can’t impersonate users on either platform, so messages carry the author as a bold prefix — ` **Maria:** hello` in Discourse, **maria:** in Telegram.
- **Loop-safe:** messages posted by the bridge itself are never relayed back.
- **Idempotent jobs:** retries and webhook redeliveries never produce duplicate messages.
- **Rate-limit aware:** on HTTP 429 the job re-enqueues after exactly the wait Telegram asks for.
- **Graceful degradation:** files over the Bot API limits (20 MB download / 50 MB upload) become an `[file omitted: name (size)]` note; unsupported formatting degrades to plain text.
- **`/id` setup command:** type `/id` in any group or topic the bot can see and it replies with the ids plus a ready-to-paste mapping line.

### Known limitations

- **Deletions in Telegram are not synced to Discourse** — the Telegram Bot API has no deletion event. This is a platform limitation, not a configuration issue.
- Telegram only lets bots edit their own messages for 48 hours; Discourse edits of older messages are not reflected on the Telegram side.
- Reactions are not bridged.
- Discourse chat _threads_ are not mapped to Telegram topics; thread replies are bridged flat.

## Configuration

**1. Create the Telegram bot**

1. Create a bot via [@BotFather](https://t.me/BotFather) and copy the token.
2. **Disable privacy mode** (`/setprivacy` → Disable), or the bot only sees `/commands`. ⚠ If the bot is already in a group, remove and re-add it — the change doesn’t apply to existing memberships otherwise.
3. Add the bot to your group as an **admin** (it needs _Delete messages_ for deletion sync).
4. To bridge into specific topics, enable **Topics** in the group settings.

**2. Configure the site settings** (Admin → Plugins → Telegram Bridge): enable the plugin, paste the bot token, and set a random webhook secret (e.g. `openssl rand -hex 24`).

**3. Register the webhook** — easiest through the plugin’s own client, which sets the correct `allowed_updates` for you:

```bash
cd /var/discourse
./launcher enter app
rails runner "puts DiscourseTelegramChatBridge::TelegramClient.new.set_webhook(
  url: 'https://YOUR-SITE/telegram-bridge/webhook',
  secret_token: SiteSetting.telegram_bridge_webhook_secret)"

```

⚠ `allowed_updates` lives in the webhook registration stored at Telegram, not in the plugin code. If you register manually and omit `edited_message`, Telegram silently never delivers edits.

**4. Map channels** — type `/id` in each group/topic, then add one line per bridged channel to `telegram_bridge_mappings`:

```plaintext
chat_channel_id:telegram_chat_id:telegram_thread_id

```

The Discourse channel id is the number at the end of the channel URL (`/chat/c/<slug>/<id>`); leave the thread id blank for the General topic or a plain group. On every boot and mapping change the plugin logs one `active mappings` summary line you can grep to confirm what is bridged.

**5. Verify** — send a message in each direction. If nothing happens, check in order: the `active mappings` log line, the webhook info (`get_webhook_info`), and privacy mode.

## Settings

| Name | Description |
| --- | --- |
| `telegram_bridge_enabled` | Master on/off switch for the bridge. |
| `telegram_bridge_bot_token` | Telegram Bot API token, issued by @BotFather (secret). |
| `telegram_bridge_webhook_secret` | Secret validated against Telegram’s `X-Telegram-Bot-Api-Secret-Token` header on incoming webhook requests (secret). |
| `telegram_bridge_mappings` | Channel mappings, one per line: `chat_channel_id:telegram_chat_id:telegram_thread_id` (thread id optional). |

> 🔒 **Privacy note:** content from bridged channels leaves your Discourse instance and is stored with Telegram (and vice versa). Only channels explicitly listed in the mappings are ever bridged — but do tell the members of those channels.
> 
> ![Skærmbillede 2026-07-07 kl. 08.07.05](https://global.discourse-cdn.com/meta/original/4X/3/c/c/3ccee989d2b6a86628201c99265537004860e313.png)

---

_[View the full topic](https://meta.discourse.org/t/discourse-telegram-chat-bridge/406959)._
