Production-ready Telegram bot template using python-telegram-bot
A complete, production-ready starter template for building Telegram bots using the official python-telegram-bot library. Built with async/await, this template includes command handlers, inline keyboards, callback handling, and database integration.
- ✅ python-telegram-bot v20+ - Latest async library
- ✅ Command Handlers - /start, /help, custom commands
- ✅ Inline Keyboards - Interactive buttons
- ✅ Callback Handlers - Button press handling
- ✅ Conversation Handler - Multi-step interactions
- ✅ Media Support - Send/receive images, documents, audio
- ✅ MongoDB Integration - Store user data and conversations
- ✅ Error Handling - Comprehensive error management
- ✅ Logging - Structured logging system
- ✅ Docker Support - Easy deployment
- ✅ Production Ready - Battle-tested patterns
- Python 3.9 or higher
- Telegram Bot Token (from @BotFather)
- MongoDB (local or cloud)
git clone https://github.com/botdev-community/telegram-bot-starter.git
cd telegram-bot-starter# Create virtual environment
python -m venv venv
# Activate virtual environment
# On Windows:
venv\Scripts\activate
# On macOS/Linux:
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt- Open Telegram and search for @BotFather
- Send
/newbotcommand - Follow the prompts to create your bot
- Copy the bot token provided
Create a .env file:
# Telegram Bot Configuration
TELEGRAM_BOT_TOKEN=your_bot_token_here
# MongoDB Configuration
MONGODB_URL=mongodb://localhost:27017
MONGODB_DB_NAME=telegram_bot
# Application Configuration
ENVIRONMENT=development
LOG_LEVEL=INFO
# Optional
ADMIN_USER_IDS=123456789,987654321python bot.pyYour bot is now running! Open Telegram and send /start to your bot.
telegram-bot-starter/
├── bot.py # Main bot file
├── config.py # Configuration management
├── handlers/
│ ├── __init__.py
│ ├── start.py # /start command
│ ├── help.py # /help command
│ ├── commands.py # Custom commands
│ ├── callbacks.py # Button callbacks
│ └── conversation.py # Multi-step conversations
├── services/
│ ├── __init__.py
│ ├── database.py # Database operations
│ └── message_builder.py # Message formatting
├── utils/
│ ├── __init__.py
│ ├── logger.py # Logging configuration
│ └── decorators.py # Helper decorators
├── deployment/
│ ├── Dockerfile
│ └── docker-compose.yml
├── .env.example
├── .gitignore
├── requirements.txt
└── README.md
/start- Start the bot and see welcome message/help- Display help information/menu- Show interactive menu/settings- User settings/stats- Bot statistics/about- About the bot
/echo <text>- Echo back your message/poll- Create a quick poll/reminder- Set a reminder
from telegram import Update
from telegram.ext import ContextTypes
async def hello_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Handle /hello command"""
await update.message.reply_text("Hello! 👋")from telegram import InlineKeyboardButton, InlineKeyboardMarkup
keyboard = [
[
InlineKeyboardButton("Option 1", callback_data="opt_1"),
InlineKeyboardButton("Option 2", callback_data="opt_2")
],
[InlineKeyboardButton("Cancel", callback_data="cancel")]
]
reply_markup = InlineKeyboardMarkup(keyboard)
await update.message.reply_text(
"Choose an option:",
reply_markup=reply_markup
)async def button_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Handle button presses"""
query = update.callback_query
await query.answer()
if query.data == "opt_1":
await query.edit_message_text("You chose Option 1!")await update.message.reply_photo(
photo="https://example.com/image.jpg",
caption="Here's your image!"
)await update.message.reply_document(
document=open("file.pdf", "rb"),
filename="document.pdf"
)| Variable | Description | Required | Default |
|---|---|---|---|
TELEGRAM_BOT_TOKEN |
Bot token from @BotFather | Yes | - |
MONGODB_URL |
MongoDB connection URL | No | mongodb://localhost:27017 |
MONGODB_DB_NAME |
Database name | No | telegram_bot |
ENVIRONMENT |
Environment (dev/prod) | No | development |
LOG_LEVEL |
Logging level | No | INFO |
ADMIN_USER_IDS |
Admin user IDs (comma-separated) | No | - |
- Create a new handler in
handlers/:
# handlers/mycommand.py
from telegram import Update
from telegram.ext import ContextTypes
async def my_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Handle /mycommand"""
await update.message.reply_text("My custom command!")- Register it in
bot.py:
from handlers.mycommand import my_command
application.add_handler(CommandHandler("mycommand", my_command))from telegram.ext import ConversationHandler
# Define states
CHOOSING, TYPING_REPLY = range(2)
# Create conversation handler
conv_handler = ConversationHandler(
entry_points=[CommandHandler("start", start)],
states={
CHOOSING: [MessageHandler(filters.TEXT, regular_choice)],
TYPING_REPLY: [MessageHandler(filters.TEXT, received_information)]
},
fallbacks=[CommandHandler("cancel", cancel)]
)# Build and run
docker-compose up -d
# View logs
docker-compose logs -f
# Stop
docker-compose down# Build image
docker build -t telegram-bot .
# Run container
docker run -d \
--name telegram-bot \
--env-file .env \
telegram-botnpm install -g @railway/cli
railway login
railway init
railway upheroku create your-bot-name
heroku config:set TELEGRAM_BOT_TOKEN=your_token
git push heroku main# Install dependencies
sudo apt update
sudo apt install python3 python3-pip python3-venv
# Clone and setup
git clone your-repo
cd telegram-bot-starter
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
# Create systemd service
sudo nano /etc/systemd/system/telegram-bot.serviceService file:
[Unit]
Description=Telegram Bot
After=network.target
[Service]
Type=simple
User=your_user
WorkingDirectory=/path/to/bot
ExecStart=/path/to/venv/bin/python bot.py
Restart=always
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable telegram-bot
sudo systemctl start telegram-bot# Run tests
pytest
# Run with coverage
pytest --cov=. tests/
# Run specific test
pytest tests/test_handlers.py- ✅ Text messages
- ✅ Photos
- ✅ Videos
- ✅ Documents
- ✅ Audio files
- ✅ Voice messages
- ✅ Stickers
- ✅ Location
- ✅ Contact
- ✅ Inline keyboards
- ✅ Reply keyboards
- ✅ Inline queries
- ✅ Callback queries
- ✅ Poll creation
- ✅ Multi-step conversations
- ✅ User state management
- ✅ Rate limiting
- ✅ Error handling
- ✅ Admin commands
- ✅ Database integration
- ✅ Scheduled tasks
- Never commit your bot token - Use environment variables
- Validate user input - Always sanitize inputs
- Rate limiting - Prevent spam/abuse
- Admin checks - Verify user permissions
- Error handling - Don't expose internal errors
- HTTPS only - Use webhooks with SSL in production
- Check bot token is correct
- Verify bot is running
- Check logs for errors
- Ensure network connectivity
- Verify MongoDB is running
- Check connection string
- Ensure database exists
- Check user permissions
- Check handler is registered
- Verify command format
- Check for errors in logs
- Test with simple command first
We welcome contributions! See CONTRIBUTING.md for guidelines.
This project is maintained by BotDev Community.
This project is licensed under the MIT License - see the LICENSE file for details.
- python-telegram-bot library by Leandro Toledo
- Telegram Bot API by Telegram
- BotDev Community contributors
Built with ❤️ by BotDev Community