Telegram Chatbot Mobile Development
A Telegram chatbot for mobile users comes in several flavors: a simple command bot with menus, a conversational bot with NLP, or a full-featured Mini App with a React/Vue interface inside Telegram. Your architectural choice defines the entire stack.
Telegram Bot API: Webhooks vs Polling
Two methods receive updates from Telegram: long polling (getUpdates) and webhooks. For production — webhooks only: Telegram sends a POST to your HTTPS endpoint on each message, and your bot responds immediately. Long polling — for development and local testing via ngrok.
A webhook requires a valid TLS certificate (Let's Encrypt) and port 443, 80, 88, or 8443. Telegram verifies the certificate — self-signed won't pass without explicit upload via setWebhook with the certificate parameter.
# aiogram 3.x: webhook registration
from aiogram import Bot, Dispatcher
from aiogram.webhook.aiohttp_server import SimpleRequestHandler
bot = Bot(token=BOT_TOKEN)
dp = Dispatcher()
async def on_startup():
await bot.set_webhook(
url=f"https://yourserver.com/webhook/{BOT_TOKEN}",
drop_pending_updates=True # Ignore accumulated messages on restart
)
drop_pending_updates=True is important on bot restart: without it, the bot processes all accumulated messages, causing a flood when deploying.
Inline Keyboards and Dialog State
Buttons beneath a message (InlineKeyboardMarkup) are a Telegram bot's primary UI. Each button carries callback_data up to 64 bytes. With complex states, these 64 bytes quickly become a constraint.
Solution: store state in Redis with a short callback_id:
import uuid, redis
r = redis.Redis()
async def create_callback(data: dict) -> str:
callback_id = str(uuid.uuid4())[:8]
r.setex(f"cb:{callback_id}", 3600, json.dumps(data)) # TTL 1 hour
return callback_id
async def resolve_callback(callback_id: str) -> dict | None:
raw = r.get(f"cb:{callback_id}")
return json.loads(raw) if raw else None
FSM (Finite State Machine) is standard for multi-step dialogs: registration, form filling, setup wizards. In aiogram — StatesGroup; in python-telegram-bot — ConversationHandler.
Mini App: Full Web UI Inside Telegram
A Telegram Mini App is a web application in a WebView within Telegram. The window.Telegram.WebApp object provides:
-
initDataandinitDataUnsafe— user data (id, username) -
MainButton— large button at the bottom of the screen -
sendData()— send data to the bot -
openLink(),openTelegramLink()
For mobile UX, a Mini App should follow Telegram's colorScheme (dark/light theme) and use CSS variables like --tg-theme-bg-color, --tg-theme-text-color, etc.
const tg = window.Telegram.WebApp;
tg.ready();
tg.expand(); // Expand to full screen
// Action button
tg.MainButton.setText("Confirm Order");
tg.MainButton.show();
tg.MainButton.onClick(() => {
tg.sendData(JSON.stringify({ action: "confirm", orderId: currentOrderId }));
});
// Colors from Telegram theme
document.documentElement.style.setProperty(
'--bg', tg.themeParams.bg_color || '#ffffff'
);
Deploy the Mini App as static assets on a CDN or server-side rendered on your server. HTTPS is mandatory.
Authorization and initData Verification
initData is a string with an HMAC signature from Telegram. On the server, verify the signature before trusting user data:
import hmac, hashlib
def verify_telegram_init_data(init_data: str, bot_token: str) -> bool:
secret_key = hmac.new(b"WebAppData", bot_token.encode(), hashlib.sha256).digest()
data_check_string = "\n".join(
f"{k}={v}" for k, v in sorted(parse_qs(init_data).items()) if k != "hash"
)
computed_hash = hmac.new(secret_key, data_check_string.encode(), hashlib.sha256).hexdigest()
provided_hash = parse_qs(init_data).get("hash", [""])[0]
return hmac.compare_digest(computed_hash, provided_hash)
Without this check, anyone can forge a Telegram user ID in requests to your API.
Development Process
Defining scenarios: command bot, FSM dialog, or Mini App. Choosing server framework (aiogram, grammy, python-telegram-bot). Configuring webhook with TLS. Implementing dialog flows. For Mini App: developing a web interface with Telegram theme support. Verifying initData on the backend. Deployment and monitoring.
Timeline Estimates
A command bot with menus and basic FSM — 1–2 weeks. A Mini App with full UI, authentication, and server API — 4–8 weeks.







