Back to blog
· Julian Lindner

How We Built Real-Time Streaming for Telegram Bots

When you chat with ChatGPT on the web, you see the response stream in word by word. But most Telegram bots? You stare at “typing…” for 10-30 seconds, then get a wall of text.

We wanted Lenno’s agents to feel as responsive as web-based AI. Here’s how we did it.

The Challenge

Telegram’s Bot API doesn’t have a native streaming endpoint. The standard approach is:

  1. Send “typing” indicator
  2. Wait for AI to finish
  3. Send the complete message

This works, but it feels sluggish. Users don’t know if the bot is thinking, stuck, or dead.

Our Solution: sendMessageDraft

Telegram Bot API 9.5 introduced sendMessageDraft — a method that shows a draft bubble in the chat, exactly like when a real person is typing a message. The key insight: you can update this draft repeatedly as tokens stream in.

Our implementation batches tokens into sentence-sized chunks every 1500ms, then sends a draft update. The user sees the response form in real-time, just like watching someone type.

The Technical Details

The tricky part was the process architecture. Our orchestrator spawns mode execution in a Task.Supervisor.async_nolink — a separate process from the one handling the Telegram webhook. We use an Agent process (Elixir’s Agent, not our AI agents) to share streaming state across the process boundary.

Rate limiting was another challenge. Telegram limits editMessageText to ~20 calls per minute per chat. But sendMessageDraft has no such limit — another reason to prefer it.

The result: responses that feel alive, not robotic.