Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.cogniagent.ai/llms.txt

Use this file to discover all available pages before exploring further.

Telegram lets your flow live inside the world’s most popular messaging app. You create a bot with @BotFather, connect it once, and any DM sent to that bot becomes a conversation in your flow.

When to use Telegram

  • Consumer-facing support or assistant bots where your audience already lives in Telegram.
  • International / emerging-market audiences where Telegram has higher reach than Slack or Teams.
  • Lightweight bots that don’t need a website or login — just t.me/your_bot and people can chat.
  • Group-channel companions where the bot answers questions when DM’d.

Responder mode only

Telegram is a responder-only channel. The bot can reply to anyone who has messaged it, but it cannot cold-start a conversation with a user it has never met.
This is a Telegram platform restriction, not a CogniAgent one. Telegram’s Bot API does not expose a way to look up users by @username for DM purposes — bots can only send messages to chats they have already received a message in. The standard workaround is a deep link like t.me/your_bot?start=welcome, which a user clicks first; once they tap Start, your bot has their chat_id and can talk.
If you need a bot that proactively reaches out to users (a marketing blast, a scheduled reminder to a new lead), Telegram isn’t the right channel — use SMS, WhatsApp Business, or Email instead.

Before you start

You need two things:
  1. A bot token from @BotFather on Telegram.
  2. A builtin Composio Telegram connection in CogniAgent that holds the token.

Create the bot with @BotFather

1

Open @BotFather in Telegram

Search for @BotFather and start a chat. It’s the official bot for creating other bots.
2

Send /newbot

BotFather asks for:
  • A display name (what users see, e.g. “Acme Support”).
  • A username ending in bot (e.g. acme_support_bot).
3

Copy the token

BotFather replies with a token of the form 1234567890:ABCdef.... Keep this safe — anyone with the token can impersonate your bot.
4

(Optional) Configure the bot

While you’re in BotFather you can also set:
  • /setdescription — the “About” blurb users see before they start the chat.
  • /setuserpic — a profile photo.
  • /setprivacyDisable if you want the bot to read all messages in groups it’s added to (not just @mentions). Default is Enable (only sees @mentions).

Add the Telegram channel and connect the bot

The Telegram connection is created from inside the channel-add flow — there’s no separate trip to the Integrations page first.
1

Open the flow's Channels configuration

Go to Conversations → open the flow → ConfigurationChannels tab.
2

Add Channel → Telegram

Click Add Channel and pick Telegram from the channel picker.
3

Create (or pick) a Telegram connection

The channel form’s Connection field lets you either pick an existing Telegram connection or create a new one inline. When creating new, the form asks for an API Key — paste the BotFather token here. The form’s description text walks through the BotFather flow if you skipped it above.
4

Save and Deploy

Save the channel and deploy the flow. Within ~5 seconds your bot starts polling for new messages, and any DM to @your_bot creates a conversation.
Once created, the connection is reusable — you can pick it from the dropdown in any other flow’s Telegram channel configuration. Manage integration connections →

How conversations are scoped

Each conversation is keyed by chat_id : from_user_id — the chat the message arrived in and the user who sent it.
ScenarioConversation
Sarah DMs the botOne conversation (her chat_id == her user id)
Sarah DMs the bot again next weekSame conversation (subject to session timeout)
Mike DMs the same botA separate conversation
Bot is added to a group; Sarah and Mike both @mention itTwo separate conversations (one per user) inside the same group chat
This mirrors how Slack scoping works in DM mode.

Outbound formatting (MarkdownV2)

The bot sends replies with parse_mode: MarkdownV2. The flow’s actor prompt is auto-augmented to nudge the LLM toward MarkdownV2-safe output, but a few quirks are worth knowing:
  • Single-delimiter bold: *bold* (not **bold**).
  • Single-delimiter italic: _italic_.
  • Reserved characters must be backslash-escaped when used as literal text:
    _  *  [  ]  (  )  ~  `  >  #  +  -  =  |  {  }  .  !
    
    So a literal 1.5 should be written 1\.5, and https://example.com/path should escape the dot too.
  • Code spans use backticks. Triple backticks for fenced code blocks (with an optional language tag) work the same as GitHub.
If a reply ever fails to render (you see escape characters in the message), it usually means the LLM forgot to escape a reserved character. This is rare with Sonnet, but possible — re-asking (“please re-send escaped properly”) usually fixes it.
Keep messages short and chat-shaped. Telegram DMs are scanned on a phone — a wall of markdown looks worse than a few short paragraphs. The system prompt steers the actor this way already.

Rich content

ElementTelegram
Plain text
Bold / italic✓ (MarkdownV2)
Links
Bullet lists✓ (rendered as plain text with -)
Code blocks✓ (fenced)
Inline buttonsnot in v1
Images / attachmentslinks only in v1
Voice notes
Inline keyboards, photo uploads, and audio replies are on the roadmap but not in the initial release.

How polling works

There is no Telegram webhook to host — the platform polls Telegram’s getUpdates API every 5 seconds with an offset bookmark stored in Redis. Updates older than 24 hours that have never been claimed get garbage-collected by Telegram, so the worst-case delivery delay is bounded. If you previously set a webhook on the same bot (via setWebhook), Telegram refuses to serve getUpdates and returns HTTP 409. The poller logs this as a warning. To resolve, call https://api.telegram.org/bot<TOKEN>/deleteWebhook once and the poller resumes.

Per-user identity

Inbound messages carry the sender’s:
  • from_id — numeric Telegram user id.
  • from_username — the @handle, if set (optional in Telegram).
  • from_first_name / from_last_name — display name parts.
The flow sees a resolved participantName (e.g. "Sarah Lee" or "@sarah_lee" if no real name is set) which actors can reference in their prompts.

Limitations

  • Bots cannot DM users who haven’t started a chat with them. There is no “cold outreach” path on Telegram for bots.
  • Group chats: by default Telegram bots in groups only receive messages that @mention them. To see every message, toggle /setprivacy to Disable in BotFather — but expect higher inbound volume.
  • @username is not a stable destination identifier. Telegram only treats numeric chat_id as routable. The platform stores the numeric id internally.
  • A single bot token serves one bot. If you want a different persona, create a new bot in BotFather and a new connection in CogniAgent.

Troubleshooting

SymptomLikely cause
No conversations appear after deployThe bot hasn’t received any DMs yet. Send /start from your own account to @your_bot to trigger the first one.
Bot replies stop after a redeployA previously-set webhook is intercepting updates. Call deleteWebhook once.
Replies render as literal characters (\., \!)The model emitted text that doesn’t satisfy MarkdownV2 escaping. Usually self-corrects on the next turn; consider tightening the actor’s system prompt.
Multiple users in one group share statePrivacy mode is off but the actor wasn’t designed for group context. Either turn privacy back on (so the bot only hears @mentions) or have the actor handle the multi-speaker case explicitly.
New session created on every messageSession timeout is shorter than the gap between user messages. Increase it in Flow settings.

Next

Messaging channels

Slack and Teams — the closest cousins of Telegram.

Deploy a flow

Schedule the Telegram listener.