A Telegram bot that relays user messages to an LLM and streams responses back using Telegram's sendMessageDraft API for real-time typing animation.
- Long-polling for incoming messages
- LLM response streaming via RubyLLM
- Real-time draft updates with cursor animation (
▌) viasendMessageDraft - Supports OpenAI, Anthropic, and Gemini providers
- Ruby 3.4 (managed via mise)
- A Telegram bot token
- An API key for at least one LLM provider
- Open Telegram and search for @BotFather
- Send
/newbotand follow the prompts (choose a name and username) - BotFather will reply with your bot token — copy it into
TELEGRAM_BOT_TOKENin your.env
cp .env.example .env
# Edit .env with your credentials
bundle install| Variable | Required | Default | Description |
|---|---|---|---|
TELEGRAM_BOT_TOKEN |
Yes | — | Bot token from @BotFather |
OPENAI_API_KEY |
One required | — | OpenAI API key |
ANTHROPIC_API_KEY |
One required | — | Anthropic API key |
GEMINI_API_KEY |
One required | — | Gemini API key |
LLM_MODEL |
No | gpt-4o-mini |
Model to use (e.g. claude-sonnet-4-5) |
ruby bot.rbSend any message to your bot and it will stream back an AI-generated response.
- Bot polls for updates via Telegram's
getUpdates - On receiving a message, creates a RubyLLM chat session and calls
askwith a streaming block - As chunks arrive, accumulated text is sent every ~400ms via
sendMessageDraft(samedraft_id→ Telegram animates the update) - Once streaming completes, the full response is sent via
sendMessage, replacing the draft