05 / Messaging channels

Telegram channel

On this page 18

Module id: telegram · Kind: channel · Configured by: TELEGRAM_ENABLED=true and a public https address (APP_URL, or TELEGRAM_WEBHOOK_BASE_URL when that differs) · Healthy when: the same — this module does not probe Telegram · Capability: channel_telegram

The same assistant, the same knowledge base, the same model policy — in a private Telegram chat. Unlike WhatsApp, there is no installation-wide token: each person connects a bot they created in BotFather. Synaplan stores that token encrypted, registers the webhook itself, and answers only that person. Off by default.

The channel overview is on Messaging channels. This page is the module view: what an administrator sets, and how a user finishes the connection.


What it adds#

  • The inbound webhook POST /api/v1/webhooks/telegram/{botKey}. Synaplan calls Telegram's setWebhook when a user connects a bot, including the secret and the "/" menu. Nobody pastes a callback URL into BotFather.
  • Manage → Channels → Inbound → Telegram in the web app: paste a bot token, open the pairing link, and disconnect from the same card.
  • A private chat with that bot. Text, photos, files, voice messages, videos, locations and polls are answered the way the web chat would answer them. Created images, videos, audio and documents are sent back. The thread appears in Synaplan history with the origin Telegram, and received files are stored with the person's files. Usage counts toward the same limits.

Without it#

The Telegram card on Inbound is absent. There is no placeholder and no "how to enable" notice — the surface exists only once the module is configured. WhatsApp, e-mail, the widget, Synamail, Desktop and MCP are independent and unaffected.

When the module is absent and its gate is on (GATE_TELEGRAM, pin FEATURE_MODULES_GATE_TELEGRAM), the channel routes answer 404 feature_not_configured with "docs": "modules/telegram". That covers the status, connect, pairing and disconnect routes and the inbound webhook.


How to enable#

An administrator does this once. People on the installation then connect their own bots; they never see these variables.

1. A public https address#

Telegram's servers must be able to call your instance over HTTPS. APP_URL is that address on a normal installation. When the public origin differs from APP_URL (a TLS-terminating proxy, or a tunnel in front of a dev machine), set TELEGRAM_WEBHOOK_BASE_URL to the public origin instead. Synaplan rejects localhost, private IPs and plain http — the card stays hidden until the address is one Telegram can reach.

2. Environment#

Add to the backend environment (backend/.env, or deploy/.env for the production contract) and restart backend and worker. Both services read these variables.

shell
TELEGRAM_ENABLED=true
# TELEGRAM_WEBHOOK_BASE_URL=https://synaplan.example.com   # only when APP_URL is not the public origin
# TELEGRAM_API_BASE_URL=https://api.telegram.org           # only for a proxy or the test stub
# TELEGRAM_ALLOW_LOCAL_WEBHOOK=false                       # development only; see below

3. Confirm the card#

Operate → Feature Status should show Telegram channel as Available / Telegram channel enabled. Manage → Channels → Inbound then shows the Telegram card. A user connects a bot from there — the next section.


Connect a bot#

Each Synaplan account connects one bot, and a bot belongs to one account. The token is a user credential. It is stored encrypted and is never shown again.

1. Create the bot in BotFather#

In Telegram, open @BotFather and send /newbot. Choose a display name and a username that ends in bot. BotFather replies with a token that looks like 123456789:AAH…. Copy it.

2. Paste the token#

Web app → Manage → Channels → Inbound → Telegram. Paste the token and choose Connect.

Synaplan checks the token with Telegram, stores it, and points the bot's webhook at https://<your-domain>/api/v1/webhooks/telegram/<botKey>.

The card shows Open Telegram. That link has the form https://t.me/<bot>?start=<code> and works for 30 minutes. In Telegram, tap Start. The Inbound page updates on its own once the bot is paired; the toast says Telegram is connected.

The first message from your Telegram account is what pairs the bot. Until then it answers with a sentence asking you to finish connecting, and nothing is saved.

  • Create new link — the code expired. You do not paste the token again.
  • Cancel — wrong bot, or you want to stop. The token is removed from Synaplan.

Send a message. The reply also appears under that chat in Synaplan, and Open chat on the card jumps there.


Who can use the bot#

The bot answers private chats with its owner. A group, a channel, or anyone else's private chat gets one sentence (this bot only answers its owner, or only answers private chats) and nothing is stored. Connecting the same bot to a second Synaplan account is refused until it is disconnected from the first.

What you can send#

You send What happens
Text The assistant replies in Telegram and in your Synaplan chat.
A photo, video, voice message, file, location or poll Same, with the file saved in your Synaplan files. Voice messages are transcribed when a speech-to-text model is available.
An edited message The bot answers again.
/help What the bot can do. This is the only command in Telegram's "/" menu.
/pic …, /vid …, /tts … Create an image, a video, or spoken audio. The file comes back in Telegram when it is ready, and stays in the Synaplan chat.
/search …, /docs … Search the web, or search your files in Synaplan.

Under each answer: Again, Other model and Not correct. Files larger than 20 MB never reach the bot — Telegram does not hand those to bots; upload them in Synaplan instead.

Disconnect#

Disconnect on the same card. The bot stops replying and the webhook is removed. Your chat history stays in Synaplan, under History, with the origin Telegram. Paste a new token to connect again.

Blocking the bot in Telegram pauses it. Unblock it and send a message, and it answers again without a new token.


Check it works#

  • Operate → Feature Status → Telegram channel:
    • Available / Telegram channel enabled.
    • Not installed / Missing: TELEGRAM_ENABLED — the switch is off.
    • Not installed / Missing: a public https APP_URL or TELEGRAM_WEBHOOK_BASE_URL that Telegram can reach — enabled, but the address is empty, http, localhost or a private IP.
    • There is no Needs setup state. This module does not call Telegram until a user connects a bot.
  • The Telegram card is on Manage → Channels → Inbound.
  • After pairing, /help in the bot lists the commands, and a message shows up in Synaplan history.
  • docker compose logs -f backend worker shows the inbound update.

Configuration reference#

Variable Default Meaning
TELEGRAM_ENABLED false Master switch. Required, together with a public https address, for configured and healthy.
TELEGRAM_WEBHOOK_BASE_URL empty (use APP_URL) Public origin Telegram calls. Set this when APP_URL is not that origin.
TELEGRAM_API_BASE_URL https://api.telegram.org Bot API base. Override for an egress proxy, or for the test stub.
TELEGRAM_ALLOW_LOCAL_WEBHOOK false Development only. A localhost or private address then counts as public. Telegram's servers still cannot call it; see below.

The bot token, pairing code and webhook secret are per user and live in the database. They are not environment variables.

Local development#

A real bot needs a public https origin. Put a tunnel in front of the dev stack and set TELEGRAM_WEBHOOK_BASE_URL to that https:// address, then restart backend and worker.

TELEGRAM_ALLOW_LOCAL_WEBHOOK=true only relaxes Synaplan's own check so a localhost APP_URL can configure the module. Use it with the test stub (TELEGRAM_API_BASE_URL=http://telegram-stub:3998 on backend and worker), not with a live BotFather bot.


Troubleshooting#

  • The Telegram card is missing. The module is not configured. Feature Status names the missing piece: TELEGRAM_ENABLED, or a public https address. Restart backend and worker after changing the environment.
  • Connect says the installation is not set up yet. Same cause, seen by a user: Telegram is not set up on this installation yet. Ask your administrator.
  • That bot token was not accepted. Copy it again from BotFather. A token looks like 123456789:AAH….
  • This bot is already connected to another Synaplan account. Disconnect it there, or create a new bot in BotFather.
  • The bot could not be connected. Check the public address. Telegram refused setWebhook. The origin must be https and reachable from the internet; a localhost URL fails here even when the card is visible.
  • Telegram no longer accepts this bot token. Create a new token for that bot in BotFather and connect again.
  • You blocked this bot. Unblock it in Telegram and send a message. It connects again; no new token is required.
  • The reply could not be sent to Telegram. Your message is saved in the Synaplan chat. The card shows the error and offers a new token or Disconnect.
  • Voice messages are not understood. Transcription needs a speech-to-text model: local Whisper, or a cloud speech-to-text model from one of your providers.
  • A file was not sent back. Telegram limits outbound files. The file stays in the Synaplan chat, and the bot says so.