How to Create a Telegram Bot with Python: Complete Example with Code
Introduction: Why Telegram Bots Matter
Telegram bots have become an essential part of modern business. They automate customer support, send notifications, manage orders, and perform hundreds of other tasks. According to Telegram statistics, over 10 billion messages pass through bots daily.
But before you can configure any bot — whether it's for order notifications or server monitoring — you need to know the Chat ID of your group or channel. This identifier is what you specify in your bot's configuration.
In this tutorial, we'll create a practically useful bot: add it to a group chat, and it sends the Chat ID to your private messages. Simple but indispensable tool for any Telegram bot developer.
What you'll learn:
- How to get a Telegram Bot Token via BotFather
- Basics of working with Telegram Bot API
- Complete working code in Python with python-telegram-bot library
- How to deploy your bot to a server
Time required: 20 minutes
Prerequisites
Before starting, make sure you have:
- Python 3.10+ — a modern Python version
- pip — Python package manager
- Telegram account — to create the bot
- Text editor — VS Code, PyCharm, or any other
We'll use the python-telegram-bot library — the most popular and well-documented library for working with Telegram Bot API in Python.
Step 1: Getting Your Telegram Bot Token
A Telegram Bot Token is a unique key that identifies your bot. Without a token, the bot cannot interact with the Telegram API.
Creating a Bot via BotFather
-
Open Telegram and find @BotFather — this is Telegram's official bot for creating other bots
-
Send the /newbot command
-
Enter your bot name — this is the display name, e.g., "Chat ID Helper"
-
Enter the bot username — must end with bot, e.g., chatid_helper_bot
-
BotFather will send you a token like:
1234567890:ABCdefGHIjklMNOpqrsTUVwxyz
Secure Token Storage
Never store tokens in your code! Use environment variables:
export BOT_TOKEN="your_token_here"
$env:BOT_TOKEN="your_token_here"
Or create a .env file:
BOT_TOKEN=1234567890:ABCdefGHIjklMNOpqrsTUVwxyz
And add .env to .gitignore to keep the token out of your repository.
Step 2: Telegram Bot API Basics
How Telegram Bot API Works
Telegram Bot API is an HTTP interface for bots to interact with Telegram servers. Each bot sends requests to the API and receives responses.
Key concepts:
- Update — an incoming event (new message, button click, being added to a group)
- Chat — a conversation (private chat, group, supergroup, channel)
- Message — a message with text, media, or service information
Long Polling vs Webhooks
There are two ways to receive updates:
Long Polling — the bot periodically asks Telegram "anything new?":
- Easier to set up
- Works behind NAT and firewalls
- Suitable for development and small bots
Webhooks — Telegram sends updates to your server:
- Requires HTTPS and public IP
- More efficient for high-load bots
- Used in production
In this tutorial, we'll use Long Polling — it's simpler to start with.
Why python-telegram-bot
The python-telegram-bot library (also known as py telegram bot api) is the best choice for Python developers:
- Complete Telegram Bot API coverage
- Asynchronous architecture (asyncio)
- Excellent documentation
- Active community
- Python 3.8+ support
Installation:
pip install python-telegram-bot
Step 3: Writing the Chat ID Bot — Complete Example
Now let's create a bot that:
- On
/start command in DM — explains how to use it
- When added to a group — sends the Chat ID to private messages
- On
/chatid command — shows the current chat's ID
This is a classic telegram bot example that demonstrates core development patterns.
Complete Bot Code
Create a file chatid_bot.py:
"""
Chat ID Bot — Telegram bot for getting chat IDs
Add the bot to a group, and it will send you the Chat ID in private messages.
Usage:
1. Send /start to the bot in private messages
2. Add the bot to the desired group
3. Receive the Chat ID in private messages
"""
import os
import logging
from telegram import Update
from telegram.ext import (
Application,
CommandHandler,
MessageHandler,
filters,
ContextTypes,
)
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO
)
logger = logging.getLogger(__name__)
TOKEN = os.getenv("BOT_TOKEN")
if not TOKEN:
raise ValueError(
"Bot token not found! "
"Set the BOT_TOKEN environment variable"
)
async def start_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""
Handler for /start command
Sends a welcome message with instructions
"""
user = update.effective_user
welcome_text = (
f"Hi, {user.first_name}!\n\n"
"I'll help you get the Chat ID of any group or channel.\n\n"
"**How to use:**\n"
"1. Add me to the desired group\n"
"2. I'll send you the Chat ID in private messages\n\n"
"**Commands:**\n"
"/chatid — get the current chat's ID\n"
"/help — show this help"
)
await update.message.reply_text(welcome_text, parse_mode="Markdown")
logger.info(f"User {user.id} ({user.username}) started the bot")
async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""
Handler for /help command
"""
await start_command(update, context)
async def chatid_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""
Handler for /chatid command
Shows the current chat's ID
"""
chat = update.effective_chat
user = update.effective_user
chat_types = {
"private": "Private chat",
"group": "Group",
"supergroup": "Supergroup",
"channel": "Channel"
}
chat_type = chat_types.get(chat.type, "Unknown type")
if chat.type == "private":
response = (
f"**{chat_type}**\n\n"
f"Your User ID: `{user.id}`"
)
else:
response = (
f"**{chat_type}:** {chat.title}\n\n"
f"Chat ID: `{chat.id}`\n\n"
"_Copy the ID and use it to configure your bots_"
)
await update.message.reply_text(response, parse_mode="Markdown")
logger.info(f"Chat ID requested: {chat.id} ({chat.type})")
async def handle_new_chat_members(
update: Update,
context: ContextTypes.DEFAULT_TYPE
) -> None:
"""
Handler for new members being added to a chat
If our bot was added — send Chat ID to DM
"""
chat = update.effective_chat
user = update.effective_user
new_members = update.message.new_chat_members
bot_was_added = any(
member.id == context.bot.id
for member in new_members
)
if not bot_was_added:
return
logger.info(
f"Bot added to chat '{chat.title}' (ID: {chat.id}) "
f"by user {user.id}"
)
try:
private_message = (
f"You added me to a chat!\n\n"
f"**Name:** {chat.title}\n"
f"**Chat ID:** `{chat.id}`\n\n"
"_Copy this ID to configure your bots_"
)
await context.bot.send_message(
chat_id=user.id,
text=private_message,
parse_mode="Markdown"
)
await update.message.reply_text(
f"{user.first_name}, Chat ID sent to your private messages!"
)
except Exception as e:
logger.warning(f"Couldn't send DM to user {user.id}: {e}")
await update.message.reply_text(
f"{user.first_name}, I can't send you a message.\n\n"
f"Please send me /start in private messages first, "
f"then add me to the group again.\n\n"
f"Or use the /chatid command right here."
)
async def handle_my_chat_member(
update: Update,
context: ContextTypes.DEFAULT_TYPE
) -> None:
"""
Handler for bot status changes in a chat
Fires when bot is added/removed/promoted/demoted
"""
my_chat_member = update.my_chat_member
chat = my_chat_member.chat
user = my_chat_member.from_user
old_status = my_chat_member.old_chat_member.status
new_status = my_chat_member.new_chat_member.status
logger.info(
f"Bot status changed in '{chat.title}' ({chat.id}): "
f"{old_status} -> {new_status}"
)
def main() -> None:
"""
Entry point — starts the bot
"""
application = Application.builder().token(TOKEN).build()
application.add_handler(CommandHandler("start", start_command))
application.add_handler(CommandHandler("help", help_command))
application.add_handler(CommandHandler("chatid", chatid_command))
application.add_handler(
MessageHandler(
filters.StatusUpdate.NEW_CHAT_MEMBERS,
handle_new_chat_members
)
)
logger.info("Bot started. Press Ctrl+C to stop.")
application.run_polling(allowed_updates=Update.ALL_TYPES)
if __name__ == "__main__":
main()
Code Breakdown
Let's examine the key parts:
Imports and setup:
from telegram import Update
from telegram.ext import Application, CommandHandler, MessageHandler, filters
The python-telegram-bot library uses an asynchronous approach. Application is the main class for managing the bot.
The /start handler:
async def start_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
user = update.effective_user
await update.message.reply_text(f"Hi, {user.first_name}!")
All handlers are async functions. update contains the incoming event, context — additional data and methods.
Tracking when added to a group:
application.add_handler(
MessageHandler(
filters.StatusUpdate.NEW_CHAT_MEMBERS,
handle_new_chat_members
)
)
The NEW_CHAT_MEMBERS filter fires when someone is added to a chat, including the bot itself.
Sending a DM:
await context.bot.send_message(
chat_id=user.id,
text="Message",
parse_mode="Markdown"
)
The bot can only send messages to users who have previously started a dialogue via /start.
Step 4: Running and Testing
Installing Dependencies
Create a requirements.txt file:
python-telegram-bot>=20.0
python-dotenv>=1.0.0
Install:
pip install -r requirements.txt
Running the Bot
export BOT_TOKEN="your_token"
python chatid_bot.py
Testing
- Find your bot in Telegram by its username
- Send
/start
- Add the bot to a test group
- Verify that the Chat ID arrived in your private messages
- In the group, enter
/chatid — it should show the ID
Step 5: Deploying the Bot to a Server
For the bot to run continuously, you need a server. Let's look at a simple setup with systemd on Linux.
Server Preparation
mkdir -p /opt/chatid-bot
cd /opt/chatid-bot
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
Systemd Service
Create the file /etc/systemd/system/chatid-bot.service:
[Unit]
Description=Chat ID Telegram Bot
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/chatid-bot
Environment=BOT_TOKEN=your_token_here
ExecStart=/opt/chatid-bot/venv/bin/python chatid_bot.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
Starting:
sudo systemctl daemon-reload
sudo systemctl enable chatid-bot
sudo systemctl start chatid-bot
sudo systemctl status chatid-bot
sudo journalctl -u chatid-bot -f
Docker (Optional)
Create a Dockerfile:
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY chatid_bot.py .
CMD ["python", "chatid_bot.py"]
Running:
docker build -t chatid-bot .
docker run -d \
--name chatid-bot \
-e BOT_TOKEN=your_token \
--restart unless-stopped \
chatid-bot
Troubleshooting: Common Issues
Bot Doesn't Send DMs
Problem: When added to a group, the bot can't send the Chat ID to private messages.
Cause: Telegram doesn't allow bots to initiate conversations. The user must write to the bot first.
Solution: Instruct users to start the bot via /start first, then add it to groups.
"Unauthorized" Error
Problem: The bot won't start with a 401 Unauthorized error.
Cause: Invalid or revoked token.
Solution:
- Verify the token is correct
- Get a new token via @BotFather using the
/token command
- Make sure the token doesn't contain extra spaces
Bot Doesn't Respond to Commands in Groups
Problem: In a group, the bot ignores commands.
Cause: By default, bots don't receive messages in groups.
Solution: Disable Privacy Mode via @BotFather:
/mybots
- Select your bot
- Bot Settings → Group Privacy → Turn off
Rate Limiting
Problem: The bot stops responding for a while.
Cause: Telegram limits requests — 30 messages per second to a single chat.
Solution: Add delays between sends or use message queues.
FAQ
How do I get a Telegram Bot Token?
Open @BotFather in Telegram, send the /newbot command, and follow the instructions. BotFather will provide a token in the format 1234567890:ABCdefGHIjklMNOpqrsTUVwxyz.
Which Python library should I use for Telegram bots?
We recommend python-telegram-bot (py telegram bot api) — it has complete Telegram Bot API coverage, great documentation, and an active community. An alternative is aiogram for those who prefer more low-level control.
How do I get a Telegram group's Chat ID?
Use our bot: add it to the group, and it will send the Chat ID to your private messages. Or use the /chatid command directly in the group.
Is the Telegram bot free?
Yes, the Telegram Bot API is completely free. You only pay for hosting the bot (server). You can use free tiers from cloud providers.
How do I make a bot a group admin?
In group settings → Administrators → Add Administrator → Select the bot. This is only needed if the bot requires additional permissions (delete messages, ban users).
Can I create a bot for downloading music?
Technically yes — the Telegram Bot API supports sending audio files. But consider copyright laws. A telegram bot for music should use legal content.
What's the difference between a group and a supergroup?
A supergroup is an enhanced version of a group supporting up to 200,000 members, pinned messages, and admin permissions. When a group exceeds 200 members, it automatically becomes a supergroup. Note that the Chat ID changes when this happens!
Conclusion
We've created a full-featured Telegram bot in Python that solves a practical problem — getting Chat IDs for groups. This telegram bot example demonstrates core development patterns:
- Working with Telegram Bot API
- Handling commands and events
- Sending messages to private chats
- Logging and error handling
The bot code is available for use and modification. Use it as a foundation for your own projects.
Next steps:
- Add inline buttons for convenience
- Implement history saving to a database
- Set up uptime monitoring
Need a Professional Telegram Bot?
Building a simple bot like this takes a few hours. But a production-ready bot for business — with payments, CRM integration, analytics, and 99.5% uptime — requires serious development expertise.
What we build:
- Order and booking bots for restaurants, salons, clinics
- E-commerce bots with catalog, cart, and Telegram Payments
- Customer support automation with AI
- Telegram Mini Apps — full web apps inside Telegram
Telegram Bot Development Services →
Custom bots from $900. Delivery in 2-4 weeks. 6 months support included.
Related services: