DEV Community

Apollo
Apollo

Posted on

The fastest way to build a Telegram Bot natively

The Fastest Way to Build a Telegram Bot Natively

Building a Telegram bot natively using Python and the python-telegram-bot library is one of the most efficient ways to create a fully functional bot with minimal overhead. This guide will walk you through setting up a bot, handling commands, and deploying it efficiently.

Prerequisites

  • Python 3.8+
  • A Telegram account (to create the bot via @BotFather)
  • python-telegram-bot library (pip install python-telegram-bot)

Step 1: Obtain Your Bot Token

  1. Open Telegram and search for @botfather.
  2. Send /newbot and follow the prompts to get your API token.

Step 2: Set Up the Bot

We’ll use the python-telegram-bot library (v20+) which supports asynchronous operations.

Basic Bot Structure

from telegram import Update
from telegram.ext import Application, CommandHandler, ContextTypes

BOT_TOKEN = "YOUR_BOT_TOKEN_HERE"

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    await update.message.reply_text("Hello! I'm your Telegram bot.")

if __name__ == "__main__":
    app = Application.builder().token(BOT_TOKEN).build()
    app.add_handler(CommandHandler("start", start))
    app.run_polling()
Enter fullscreen mode Exit fullscreen mode

This minimal bot responds to /start with a greeting.

Step 3: Add More Functionality

Let’s extend the bot with:

  • Echo command
  • Inline buttons
  • Error handling

Echo Command

async def echo(update: Update, context: ContextTypes.DEFAULT_TYPE):
    text = " ".join(context.args) if context.args else "Nothing to echo!"
    await update.message.reply_text(text)

# Add to main():
app.add_handler(CommandHandler("echo", echo))
Enter fullscreen mode Exit fullscreen mode

Inline Buttons

from telegram import InlineKeyboardButton, InlineKeyboardMarkup

async def buttons(update: Update, context: ContextTypes.DEFAULT_TYPE):
    keyboard = [
        [InlineKeyboardButton("Option 1", callback_data="1")],
        [InlineKeyboardButton("Option 2", callback_data="2")]
    ]
    reply_markup = InlineKeyboardMarkup(keyboard)
    await update.message.reply_text("Choose:", reply_markup=reply_markup)

async def button_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query
    await query.answer()
    await query.edit_message_text(f"Selected: {query.data}")

# Add to main():
app.add_handler(CommandHandler("buttons", buttons))
app.add_handler(CallbackQueryHandler(button_callback))
Enter fullscreen mode Exit fullscreen mode

Error Handling

async def error_handler(update: object, context: ContextTypes.DEFAULT_TYPE):
    print(f"Update {update} caused error {context.error}")

# Add to main():
app.add_error_handler(error_handler)
Enter fullscreen mode Exit fullscreen mode

Step 4: Optimize for Performance

Use Webhooks (For Production)

If deploying on a server (e.g., AWS, Heroku), use webhooks instead of polling:

from telegram.ext import ApplicationBuilder

app = (
    ApplicationBuilder()
    .token(BOT_TOKEN)
    .webhook_url("https://yourdomain.com/webhook")
    .build()
)

# For Flask integration:
from flask import Flask, request

server = Flask(__name__)

@server.route("/webhook", methods=["POST"])
def webhook():
    update = Update.de_json(request.get_json(force=True), app.bot)
    app.process_update(update)
    return "OK"

if __name__ == "__main__":
    app.run_server(port=8443)
Enter fullscreen mode Exit fullscreen mode

Rate Limiting

Telegram imposes rate limits (~30 messages/sec). Use @rate_limited decorator if needed:

import time

def rate_limited(max_per_second):
    min_interval = 1.0 / max_per_second
    def decorator(func):
        last_time = [0.0]
        async def wrapper(*args, **kwargs):
            elapsed = time.time() - last_time[0]
            wait = min_interval - elapsed
            if wait > 0:
                time.sleep(wait)
            last_time[0] = time.time()
            return await func(*args, **kwargs)
        return wrapper
    return decorator

@rate_limited(5)  # 5 calls per second max
async def safe_reply(update: Update, text: str):
    await update.message.reply_text(text)
Enter fullscreen mode Exit fullscreen mode

Step 5: Deploy the Bot

Option 1: Local Polling (Development)

python bot.py  # Runs with polling  
Enter fullscreen mode Exit fullscreen mode

Option 2: Webhook Deployment (Production)

  1. Set up HTTPS (Telegram requires it).
  2. Use NGINX or AWS API Gateway to route /webhook.
  3. Run with Gunicorn (for Flask) or ASGI (FastAPI).
gunicorn -w 4 -b 0.0.0.0:8443 app:server  # For Flask
Enter fullscreen mode Exit fullscreen mode

Final Thoughts

This setup ensures low-latency, scalable, and maintainable Telegram bots. For advanced features, explore:

  • ConversationHandler for multi-step interactions
  • PTB’s JobQueue for scheduled tasks
  • Custom Filters for message filtering

By following these steps, you’ll have a high-performance native Telegram bot in minutes! 🚀


Stop Reinventing The Wheel

If you want to skip the boilerplate and launch your app today, check out my Ultimate AI Micro-SaaS Boilerplate ($49). It includes full Stripe integration, Next.js, and an external API suite.

Or, let my AI teardown your existing funnels at Apollo Roaster.

Top comments (0)