Building Telegram Bots with LLMs: A Practical Guide
Telegram bots are the fastest distribution channel for AI products. No app store approval, no complex onboarding — just share a link and users are talking to your product.
This is how I build them.
Why Telegram?
Before we get into code, the strategic case:
- Instant reach: every Telegram user can click a link and start a conversation
- No frontend needed: the chat UI is already built
- Async friendly: users expect asynchronous communication
- Group support: your bot can serve teams, not just individuals
The downside: you're limited to text, images, files, and voice. No custom UI. For many use cases, that's fine.
Architecture
A minimal LLM-powered Telegram bot needs:
- Webhook receiver — listens for Telegram updates
- LLM client — sends messages to Claude/GPT and streams the response
- Context store — keeps per-user conversation history
- Rate limiter — prevents abuse
I use Python with python-telegram-bot (v20+, async-first) and FastAPI for the webhook.
Core Code
Here's the minimal setup:
from telegram import Update
from telegram.ext import Application, MessageHandler, filters, ContextTypes
from anthropic import Anthropic
client = Anthropic()
async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
user_id = update.effective_user.id
text = update.message.text
# Get or init conversation history
history = context.user_data.get('history', [])
history.append({"role": "user", "content": text})
# Stream response from Claude
response_text = ""
msg = await update.message.reply_text("...")
with client.messages.stream(
model="claude-opus-4-6",
max_tokens=1024,
system="You are a helpful assistant.",
messages=history,
) as stream:
for chunk in stream.text_stream:
response_text += chunk
await msg.edit_text(response_text)
history.append({"role": "assistant", "content": response_text})
context.user_data['history'] = history[-20:] # keep last 10 turns
Context Management
The biggest mistake I see: no context limit. Claude and GPT have context windows, but they're not infinite, and costs scale linearly with tokens.
My rules:
- Keep the last N turns (I use 10 by default)
- Summarize long conversations instead of truncating
- Store conversation state server-side, not in
context.user_data(that's in-memory only)
For persistent storage I use PostgreSQL with a simple schema:
CREATE TABLE conversations (
user_id BIGINT NOT NULL,
role TEXT NOT NULL, -- 'user' | 'assistant'
content TEXT NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX ON conversations(user_id, created_at);
Deployment
I deploy on Render (free tier for small bots, $7/month for always-on):
- Push code to GitHub
- Create a new Web Service on Render
- Set environment variables:
TELEGRAM_TOKEN,ANTHROPIC_API_KEY - Register the webhook:
https://api.telegram.org/bot{TOKEN}/setWebhook?url=https://yourapp.onrender.com/webhook
Done. The bot is live.
Rate Limiting
Without rate limiting, a single malicious user can burn your API credits in minutes.
from datetime import datetime, timedelta
from collections import defaultdict
rate_limits = defaultdict(list)
def check_rate_limit(user_id: int, max_per_hour: int = 20) -> bool:
now = datetime.now()
hour_ago = now - timedelta(hours=1)
# Clean old entries
rate_limits[user_id] = [t for t in rate_limits[user_id] if t > hour_ago]
if len(rate_limits[user_id]) >= max_per_hour:
return False
rate_limits[user_id].append(now)
return True
In production, replace defaultdict with Redis for persistence across restarts.
What Makes a Good Bot
After a dozen bots, the patterns that matter:
Clear system prompt. The system prompt is your bot's personality and constraints. Spend time on it. A vague system prompt produces a vague bot.
/start onboarding. Tell users what the bot does and how to use it in the first message. Users won't read documentation.
Error messages. When the LLM fails or rate limit hits, tell the user clearly. "An error occurred" is useless. "You've sent 20 messages in the last hour — try again in a few minutes" is actionable.
Group chat handling. If your bot is in a group, it should only respond when mentioned (@botname). Use filters.MENTION to filter.
Conclusion
Telegram bots are underrated as a delivery mechanism for AI products. Low friction for users, fast to build, easy to iterate.
If you want to build one but don't know where to start — message me on Telegram. I can have a working bot deployed for you in 24-48 hours.
Comments (0)
Be the first to leave a comment.
Leave a Comment