Skip to main content

Telegram

Orbit’s Telegram channel wraps the Telegram Bot API so you can send and receive messages, photos, documents, inline keyboards, and callbacks from the same unified Messaging surface used for every other channel. Each Orbit organization can attach one bot; webhook delivery is automatic.

Send a message

The message text goes in the top-level body field. Per-message options — the send type (text (default), photo, video, document, location), parse_mode, and keyboards — are passed under metadata, whose values are all strings. Supply inline_keyboard (and reply_keyboard) as a JSON-stringified button[][] array, exactly as shown above.

Response

Capabilities

  • Text + media — text (with HTML / MarkdownV2 formatting), photo, video, document, and location. Set the send type in metadata; a photo, video, or document send needs mediaUrl, and a location send needs latitude / longitude.
  • Inline + reply keyboardsinline_keyboard, reply_keyboard, plus force_reply and remove_keyboard.
  • Callbacks — inline-keyboard button presses arrive as Telegram callback_query updates. Orbit ingests each press as an inbound message (the button’s callback_data becomes the message body), so it lands in the conversation timeline and fans out on the standard message.received webhook — the same event as any other inbound Telegram message. There is no separate telegram.callback event type to subscribe to.
  • Chat actionstyping, upload_photo, etc., either via the API or auto-emitted by Orbit when a long-running send is in flight.
  • Edit + delete (Orbit-side only)PATCH /messages/:id edits the body and/or scheduled_at of a message that is still scheduled (not yet dispatched); once the message has been sent the edit returns 409 MESSAGE_NOT_EDITABLE. DELETE /messages/:id soft-deletes the Orbit message record and syncs that removal across your dashboards. Neither endpoint calls Telegram’s editMessageText / deleteMessage, so a message already delivered to the chat is not edited or removed in Telegram itself.
  • Bot commands + deep links — registered via the bot setup wizard; /start deep-links land on your conversation routing rules.
  • Webhook security — Telegram’s secret_token header is validated against the per-bot secret stored in Orbit’s encrypted credential vault.

Onboarding flow

  1. Talk to @BotFather and create a bot. Save the token it returns.
  2. From the dashboard, navigate to Channels → Telegram → Add bot and paste the token.
  3. Orbit auto-registers the webhook URL https://api.orbit.devotel.io/api/v1/webhooks/inbound/telegram and rotates the secret_token header value.
  4. Optional: configure the bot command list directly from the channel detail page.

Token handling — your responsibility

Telegram bot tokens are bearer credentials. Anyone who has the token can read every message sent to your bot, send messages on its behalf, and — until the token is revoked via BotFather — pose as your bot to your users. Orbit encrypts the token at rest with an enc:v1: envelope and never echoes it back through any API response, but the token’s safety upstream of Orbit (in your password manager, your laptop, your CI/CD variables, your screenshots) is yours to protect:
  • Never commit a bot token to git, public or private. GitHub and GitLab both surface tokens to search; bots have scraped them in seconds.
  • Never paste a token into a chat, ticket, screenshot, or screen-share. Use the dashboard paste field, which masks the value after submit.
  • Rotate immediately via /revoke in BotFather if you believe a token has been exposed. Old tokens stop working the moment a new one is issued; reconnect in Orbit with the new value and the existing conversation history is preserved (we key history by bot_id, not by the token).
  • Scope each environment to its own bot. Use distinct BotFather bots for dev / staging / production so a leaked dev token doesn’t compromise customer conversations.

Ownership disputes

Orbit identifies a bot by its bot_id (the numeric prefix of the token) and enforces a single-tenant claim: once an Orbit organization connects a bot, the same bot cannot be connected to a second Orbit organization until the first one disconnects. The dashboard surfaces TELEGRAM_BOT_ALREADY_CONNECTED (HTTP 409) when a second tenant attempts the same bot. Connecting a bot to Orbit proves you have the bot’s token. It does NOT prove you are the BotFather owner of the bot. If a token leaks (see “Token handling” above) and a hostile actor claims it on their own Orbit tenant before you do, you will see a 409 on your own connect attempt — your bot is locked to someone else’s Orbit organization. Two recovery paths, in order of preference:
  1. Revoke the token via BotFather (you, as the bot’s BotFather owner). Open @BotFather, select the bot, and run /revoke. BotFather issues a new token; the leaked token immediately stops working. The hostile tenant’s webhook registration is now dead — Telegram refuses every send / receive against the old token. Once the hostile claim is functionally inert, contact Orbit support (see step 2) to release the bot_id claim so you can connect with the new token.
  2. Open an ownership-dispute ticket with Orbit support. Email support@devotel.io with subject Telegram bot ownership dispute — <bot_username> and include:
    • The bot’s @username and numeric bot_id (the digits before the colon in any token you’ve held).
    • Proof of BotFather ownership — a screenshot of the /mybots list in BotFather showing the bot under your Telegram account, OR a fresh token rotation timestamp from BotFather that we can correlate against Telegram’s getMe response on the live token.
    • The Orbit organization you want the bot claim transferred to.
    Support will verify your BotFather ownership against Telegram’s API, force-disconnect the hostile tenant’s row (revoking their webhook registration in the process), and unblock the bot_id so you can connect from your own Orbit organization. Median response time is one business day; security-sensitive disputes are escalated to on-call.
To prevent this class of incident: keep bot tokens out of every code path that touches the public internet, rotate on any whiff of exposure, and connect the bot to Orbit yourself the moment BotFather hands you a fresh token — the small window between issuance and Orbit-claim is the entire attack surface.

Common errors

A failed send returns a JSON error envelope whose error.code is one of the values below.

Blocked recipients

When a user blocks the bot, leaves a chat, deactivates their account, or the chat id is gone, Telegram returns a 403. Orbit does not raise an error for this — the message record is marked failed with error_code set to TELEGRAM_USER_BLOCKED. Treat that recipient as undeliverable: mark the contact opted-out and skip future sends rather than retrying, because the condition is permanent until the user re-engages the bot.

Pricing

The Telegram Bot API itself is free. Orbit charges a flat per-1M platform fee for delivery and webhook fan-in. See the pricing page.