Building Telegram Bots with LLMs: A Practical Guide

Building Telegram Bots with LLMs: A Practical Guide

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:

  1. Webhook receiver — listens for Telegram updates
  2. LLM client — sends messages to Claude/GPT and streams the response
  3. Context store — keeps per-user conversation history
  4. 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:

``python 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.userdata (that's in-memory only) For persistent storage I use PostgreSQL with a simple schema: `python 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): 1. Push code to GitHub 2. Create a new Web Service on Render 3. Set environment variables: TELEGRAMTOKEN, ANTHROPICAPIKEY 4. 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. `python 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.

Valdas

Valdas

Vibe Coder · AI Product Builder based in Prague. I turn ideas into working AI products in days — Telegram bots, web apps, automation tools. Reach me on Telegram or follow on Medium.

Comments (0)

Be the first to leave a comment.

Leave a Comment

Comments are moderated and appear after review. No email required.