Skip to main content

Settings: Telegram channel connection and toggles

The Settings → Channels → Telegram page (/settings/channels/telegram) is the tenant-owned surface that manages the Telegram channel itself: which bot is attached, whether you are on the shared test bot or your own BotFather bot, and the health of the live connection. This guide walks that page end to end. It is deliberately separate from two other documents you may already have open:
  • Telegram onboarding — the ordered first-time path from empty channel to a working bot, including the curl calls. That guide is the “how do I get set up” walkthrough.
  • Telegram channel reference — the capability reference (message shapes, metadata, token handling, ownership disputes). That page is the “what can the channel do” specification.
This page is the operator’s console you return to after onboarding: checking state, swapping test ↔ production, recovering from a dead token, and exercising the channel from inside the dashboard.

1. How a Telegram bot becomes a first-party channel on Orbit

A Telegram bot is a first-party Orbit channel the moment Orbit holds three things for it:
  • The BotFather token — the credential Telegram issues when you create a bot with @BotFather. Orbit stores it in an encrypted credential vault; the token is never shown back to you after you paste it.
  • An active webhook registration — Orbit calls Telegram’s setWebhook against https://api.orbit.devotel.io/api/v1/webhooks/inbound/telegram the moment you connect, so Telegram starts pushing updates to Orbit immediately. No inbound polling is involved.
  • A verifiable webhook signature — every inbound update is validated against the per-bot secret_token Orbit rotates on connect. Telegram presents it in the X-Telegram-Bot-Api-Secret-Token header; an update that does not present the right value is rejected before it reaches your routing pipeline.
With those three in place, Telegram joins the same omnichannel routing surface as SMS, WhatsApp, and so on — inbound updates arrive as message.received events, outbound sends go through the unified Messaging API, and the channel respects your tenant-owned opt-in/opt-out routing. Telegram’s opt-in model is inverter-of-default compared to SMS: a user starts the conversation by messaging your bot (or pressing a deep-link start button), which is the consent signal. When that user later blocks the bot, Telegram stops delivering to them — see §5 for how Orbit surfaces a block.

2. Connection modes: webhook vs polling

Orbit only supports webhook mode for Telegram. Telegram offers two transports (setWebhook for push, getUpdates for pull); Orbit registers the webhook on connect and never polls getUpdates. This is a deliberate choice, not a gap: Opractical consequence for you: connecting a bot to Orbit claims the webhook exclusively. If you previously had the same bot wired to another service via setWebhook, Orbit overwrites that registration on connect; if the other service uses getUpdates, Telegram’s one-consumer rule kicks in and only one of you will see updates. The rule of thumb matches the per-channel connection modes guide: pick one live consumer per channel, and let Orbit be it.

3. Channel setup on this page, step by step

Open Settings → Channels → Telegram. The page renders one of five exclusive states, and you move between them by acting on the page:
  1. Not connected — pick a path: stay on the shared test bot (recommended for evaluation) or connect your own BotFather bot. This is the only state where both choices are presented side by side.
  2. Verifying (test path only) — Orbit shows a deep link (https://t.me/<shared_bot>?start=<token>) plus a QR code. Open the link in Telegram on the device you want to test from, and the page polls every 3 s until the link confirms. Verification is what moves you to test-active.
  3. Test-active — you are on the shared bot in demo posture. The page shows your linked chat, your remaining daily test quota, and a “Manage in production” CTA. Test sends route through Devotel’s shared bot under its branding, not yours.
  4. BYO setup — the production path: a single-token form. Paste the token BotFather gave you; Orbit validates it against Telegram’s getMe, claims the webhook, and flips the channel to production in one step. One org owns one bot: if another Orbit organization already holds the bot_id, the connect call returns 409 TELEGRAM_BOT_ALREADY_CONNECTED and the form surfaces it — see the ownership-disputes recovery path on the channel reference.
  5. Production — your own bot is connected. See §4 for the toggle surface this state exposes.
The page is owner/admin only — bot tokens are credentials, and the rest of the workspace should not see them. RoleGuard blocks viewer/member/developer seats from the whole surface, not just the token form.

4. The production-state toggle surface

Once your own bot is connected, the page becomes a status-and-actions card. Every row below is a tenant-owned control; none of them need a Telethon call or a support ticket.

Bot identity

Actions

The card also embeds the feature matrix panel, which renders the capability matrix for the current mode (test vs production) so you can compare what each posture includes without leaving the page. Telegram does not expose rate-cap, template, or recipient-list toggles on this page — those controls exist on channels whose provider requires them (WhatsApp templates, RCS sender agents). Telegram’s flood-control is enforced by Telegram itself; see TELEGRAM_RATE_LIMITED in the onboarding error reference for how the 429 flows back to your send call. If you need a recipient allow-list for a compliance-locked deployment, do it at your own send-side router rather than here.

5. The two failure loops this page exists to break

Loop A — bot token is invalid

Symptom. Status flips to the red Invalid token badge. The most common cause: someone ran /revoke or /token in BotFather and rotated the token without re-pasting it into Orbit, or the token was never re-pasted after an environment copy. Recovery. Click Reconnect. You land back on the BYO setup form; paste the current token; Orbit re-claims the webhook. History and your channel configuration survive because they key off bot_id, not the token itself. Prevention. Treat the BotFather token as a single-writer credential. If your team also rotates it via automation, have the automation call POST /api/v1/telegram/connect-bot with the new value as part of the same runbook, so Orbit is never holding a dead token.

Loop B — webhook verify returns a Telegram 401, or the bot is blocked

Two distinct failures share a symptom: inbound messages silently stop arriving.
  • Webhook verify 401 — Telegram’s setWebhook re-handshake is rejected because the bot token Orbit holds is no longer valid. The periodic probe catches this and flips Status to invalid_token; the fix is Loop A above.
  • Bot blocked by the user (bot was blocked by the user) — a Telegram-side state, not an Orbit one. Telegram returns 403 Forbidden: bot was blocked by the user on your send and stops delivering inbound from that user. Orbit surfaces this as a delivery failure on the message record and the channel stays Active — the block is user-scoped, not bot-scoped.
Distinguishing them. A 401 on the webhook verify is a credential problem: every inbound update stops, and the page’s Invalid token banner is the tell. A user-level block is a delivery-scoped problem: that one user’s thread stops, everyone else continues, and the block surfaces on the per-message delivery.failed event. What a WebhookPause looks like. When Telegram cannot reach the Orbit webhook (a network partition, a cert error, or a 5xx storm on our side), Telegram retries with its own exponential backoff and eventually stops delivering. Our probe detects the stall and raises the invalid-token/disabled surface on this page even though the token itself is fine — the page treats an unreachable webhook as a not-healthy channel, because from your users’ perspective it is. Reconnecting the bot re-runs setWebhook and un-pauses the pipe.

6. Smoke-test the channel from the sandbox

Before you point real traffic at the bot, exercise it through the sandbox:
The sandbox uses test-mode keys (dv_test_sk_...) and the X-Test-Mode header; no credits are spent and no Telegram flood-control is incurred. Once that loop is green, flip to your production key and the connected production bot — the same endpoint shape routes through your own bot, so a green sandbox loop is a green production path. The full matrix of sandbox magic numbers and simulate-inbound tooling is in the sandbox guide.

7. What this page is not — and where the other two documents live

  • This page is the operator console for a channel you already have. It is not the first-time walkthrough — for that, start with the onboarding guide, which assumes nothing is connected and walks the whole path linearly. Re-open this page whenever you want to check state, rotate a token, or recover from a failure.
  • This page is the dashboard surface, not the capability reference. Message shapes, parse_mode values, keyboard conventions, edit/delete limits, ownership-dispute recovery, and the error-code table all live on the Telegram channel reference. The settings page links out to that reference where those topics come up.
  • The onboarding guide and this page target the same channel, but the guide is API-shaped (endpoint-by-endpoint) and this page is operator-shaped (state-by-state). They cross-link at every hand-off so following either gets you to the same place.