Telegram
Telegram · Telegram bot API for AI agents · Telegram AI agent · Telegram LLM bot · connect ChatGPT to Telegram · Telegram bot with OpenAI · Telegram chatbot APITry the sandbox bot, then connect your own Telegram sender.
Try your agent on the Telegram sandbox, then connect your own bot without changing its message handler.
// npm install @flow-engineer/messaging openaiimport OpenAI from "openai";import { FlowMessaging, contentText } from "@flow-engineer/messaging";
const flow = new FlowMessaging();const openai = new OpenAI();
for await (const event of flow.events.stream({ types: ["message.received"] })) { await event.conversation.reply( openai.chat.completions.create({ model: "gpt-4.1-mini", stream: true, messages: [{ role: "user", content: contentText(event.data.message.content) }], }), );}1. Try it on the sandbox bot
Section titled “1. Try it on the sandbox bot”- Get a test key, with no account:
curl -X POST https://api.flow.engineer/v0/sandbox/keys(ornpx @flow-engineer/messaging init). Set itskeyasFLOW_MESSAGING_KEY. It allows 1 contact and 50 messages for 7 days; sign in to get more (Keys and sign-in). GET /v0/senders?channel=telegramlists the sandbox bot. Itsaddress.linkishttps://t.me/<bot>?start=<code>, with your join code in it. (npx @flow-engineer/messaging initprints it too.)- Open the link and tap Start. That’s it, you’ve joined: your app gets
conversation.started, then/startas your firstmessage.received. - 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, as it is, for example Hi Sandbox app (ref wild-otter-04508705).
2. Your own Telegram bot
Section titled “2. Your own Telegram bot”Telegram is the fastest channel to go live on: bring a bot token and it is connected at once.
- In Telegram, open @BotFather, send
/newbot, and copy the token. - 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_...):
export TELEGRAM_BOT_TOKEN=... # the token from BotFather; never commit it
curl https://api.flow.engineer/v0/senders \ -H "Authorization: Bearer $FLOW_MESSAGING_KEY" \ -H "Content-Type: application/json" \ -d "{\"channel\": \"telegram\", \"telegram_bot_token\": \"$TELEGRAM_BOT_TOKEN\"}"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.
To disconnect the bot, call DELETE /v0/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 /v0/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.
3. Inline keyboards
Section titled “3. Inline keyboards”A buttons message 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. Telegram has no list or carousel: those answer 422 unsupported_content, and the hint says what to send instead (for a carousel, a basic message, then one buttons message with an image header per card).
import { buttons } from "@flow-engineer/messaging";
await event.conversation.send(buttons("Pick a size", ["Small", "Medium", "Large"]));4. Edit and unsend
Section titled “4. Edit and unsend”Telegram lets bots edit their messages at any time and unsend them within 48 hours of sending:
const [msg] = await event.conversation.reply("Checking stock...");await flow.messages.edit(msg.id, "In stock: 12 left.");await flow.messages.unsend(msg.id);An unsend more than 48 hours after sending is refused at once with 422 unsupported_content and channel_code unsend_window_closed; send a new message instead. A 200 means accepted: wait for message.sent (or message.failed) for the unsend. See Edit and unsend limits.
5. What Telegram supports
Section titled “5. What Telegram supports”| Kind | Telegram |
|---|---|
Text (basic) | yes, sent as written; style it with Telegram’s own HTML or MarkdownV2 in telegram.parse_mode |
| Photos, video, audio, voice notes | yes |
| Documents | yes, sent (up to 50 MB) and received; malware-scanned before Flow keeps them (an upload that fails answers 422 file_blocked) |
| Buttons | inline keyboard, up to 10; no lists or carousels |
| Reactions, typing | yes; reactions only with Telegram’s reaction emoji |
| Read receipts | no: bots cannot send them (422 unsupported_content, param kind) |
| Edit, unsend | yes: edits with no time limit, unsends within 48 hours (otherwise 422 unsupported_content, unsend_window_closed) |
| Starting a conversation | only with people who started your bot (to.telegram_user_id) |
6. Telegram rules worth knowing
Section titled “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.
/startand other commands arrive asbasicmessages; your agent decides what to answer. - Contacts have no phone number. A Telegram contact is identified by
address.telegram_user_idand maybeaddress.username.
Related
Section titled “Related”Thanks, we read every comment.