Skip to main content
This guide builds an AI agent on Telegram, first on Flow’s sandbox bot and then on your own bot, with the same code.
TypeScript

1. Try it on the sandbox bot

  1. Get a test key, with no account: curl -X POST https://api.flow.engineer/v1/sandbox/keys (or npx @flow-engineer/messaging init). Set its key as FLOW_MESSAGING_KEY. It allows 1 contact and 50 messages for 7 days; sign in to get more (Keys and sign-in).
  2. GET /v1/senders?channel=telegram lists the sandbox bot. Its address.link is https://t.me/<bot>?start=<code>, with your join code in it. (npx @flow-engineer/messaging init prints it too.)
  3. Open the link and tap Start. That’s it, you’ve joined.
  4. Run the code above and send the bot a message.
If the link can’t be used (for example you found the bot by searching for it), send the bot the sender’s join_code instead, for example join wild-otter-04508705.

2. Your own Telegram bot

Telegram is the fastest channel to go live on: bring a bot token and it is connected at once.
  1. In Telegram, open @BotFather, send /newbot, and copy the token.
  2. Put the token in an environment variable on your server or in your terminal, and connect it with a live key (FLOW_MESSAGING_KEY=fk_live_...):
curl
Flow checks the token, keeps it encrypted, points the bot’s webhook at Flow and answers with the sender active. The token is never returned. With FLOW_MESSAGING_KEY set to the live key, your agent now answers on your bot.
The bot token controls your bot. Never paste it into a chat with an AI assistant (including your coding agent), and never commit it. Keep it in an environment variable and send it from your own server or terminal, as above.
To disconnect the bot, call DELETE /v1/senders/{sender_id} with your live key: Flow removes the bot’s webhook, deletes its token and retires the sender (banned). If Telegram rejects the token (you revoked it in @BotFather), the sender turns flagged: new sends answer 403 permission and queued messages are held. Send the new token the same way (POST /v1/senders) and the same sender becomes active again and sends them. A held message waits at most 72 hours after Flow accepted it; after that it fails with outside_window (channel_code queued_too_long) in message.failed instead of going out late.
A bot can have only one webhook. Connecting a bot to Flow replaces any webhook it had, so do not keep another server polling or receiving updates for the same bot.

3. Inline keyboards

buttons content shows as an inline keyboard (1 to 10 buttons). Taps arrive as button_reply with the button’s id. URL buttons open a link and send nothing back.
TypeScript

4. Edit and unsend

Telegram lets bots edit their messages and delete them within 48 hours:
TypeScript

5. What Telegram supports

6. Telegram rules worth knowing

  • People must start your bot first. Telegram does not let a bot message someone who has never pressed Start.
  • Commands are messages. /start and other commands arrive as text content; your agent decides what to answer.
  • Contacts have no phone number. A Telegram contact is identified by address.telegram_user_id and maybe address.username.