How Telegram Bots Work Using Python and SQLite3

Building Your First Telegram Bot with Python and SQLite3: A Step-by-Step Guide
Ever wanted to create your own automated assistant on Telegram? Telegram bots can automate tasks, provide information, play games, and much more. Python, with its rich ecosystem and straightforward syntax, is a fantastic language for bot development. Combined with SQLite3, a lightweight, built-in Python database module, you can easily store and manage user data or bot state.
This guide will walk you through creating a simple Telegram bot using the python-telegram-bot
library and SQLite3 for basic data persistence. We'll cover everything from setting up your environment to handling user messages and storing information.
What You'll Need:
- Python 3.x installed.
- A Telegram account.
- Basic understanding of Python programming.
Let's get started!
Step 1: Project Initialization and Setup
First, we need to set up our project directory and install the necessary library.
-
Install the Library: Open your terminal or command prompt and install the
python-telegram-bot
library:Bashpip install python-telegram-bot
(Note:
sqlite3
is included with Python, so no separate installation is needed.) -
Create Project Structure: Organize your files logically. A good structure might be:
Plaintexttelegram_bot/ |-- main.py # Main bot application logic |-- database.py # Functions for database interaction (SQLite3) |-- config.py # Stores your API token and potentially other settings |-- bot_database.db # The SQLite database file (will be created automatically)
Step 2: Register Your Bot on Telegram
To interact with the Telegram API, your bot needs an identity and an API token.
- Talk to BotFather: Open Telegram and search for "BotFather" (it's the official bot for managing bots).
- Create a New Bot: Send the
/newbot
command to BotFather. - Choose Name & Username: Follow the prompts to give your bot a display name (e.g., "My Test Bot") and a unique username (must end in "bot", e.g., "my_test_xyz_bot").
- Get Your Token: BotFather will provide you with an API Token. This is crucial – treat it like a password!
- Store the Token: Create the
config.py
file in your project directory and save your token there:Python# config.py API_TOKEN = "YOUR_ACTUAL_API_TOKEN_HERE"
Step 3: Setting Up the SQLite3 Database
We'll use SQLite3 to store basic information about users who interact with our bot.
Create the database.py
file and add the following functions:
# database.py
import sqlite3
import datetime
import os
DB_NAME = "bot_database.db"
def init_db():
"""Initializes the database and creates the users table if it doesn't exist."""
if not os.path.exists(DB_NAME):
print(f"Creating database file: {DB_NAME}")
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
# Create a table for storing user data
cursor.execute("""
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
telegram_id INTEGER UNIQUE NOT NULL, -- Ensure telegram IDs are unique
username TEXT,
joined_date TEXT NOT NULL
)
""")
print("Database initialized and 'users' table ensured.")
conn.commit()
conn.close()
def add_user(telegram_id: int, username: str):
"""Adds a new user to the database or ignores if the user already exists."""
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
joined_date = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
try:
cursor.execute("""
INSERT OR IGNORE INTO users (telegram_id, username, joined_date)
VALUES (?, ?, ?)
""", (telegram_id, username, joined_date))
conn.commit()
if cursor.rowcount > 0:
print(f"User {username} (ID: {telegram_id}) added to the database.")
# else:
# print(f"User {username} (ID: {telegram_id}) already exists.")
except sqlite3.Error as e:
print(f"Database error: {e}")
finally:
conn.close()
# Optional: Add functions to retrieve or update user data later
# def get_user(telegram_id): ...
# def update_user_data(telegram_id, ...): ...
This script defines:
init_db()
: Creates the database file (bot_database.db
) if it doesn't exist and ensures theusers
table is set up with columns for an internal ID, the unique Telegram user ID, their username, and the date they first started the bot.add_user()
: Inserts a new user record into the table.INSERT OR IGNORE
prevents errors if we try to add a user who's already in the database (based on theUNIQUE
constraint ontelegram_id
).
Step 4: Writing the Bot's Core Logic
Now, let's write the main part of our bot in main.py
. This script will use the python-telegram-bot
library to listen for commands and messages.
# main.py
import logging
from telegram import Update
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, CallbackContext
# Import our database functions and API token
from database import init_db, add_user
from config import API_TOKEN
import datetime
# Enable logging (optional but recommended)
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
)
logger = logging.getLogger(__name__)
# --- Command Handlers ---
def start(update: Update, context: CallbackContext) -> None:
"""Handles the /start command."""
user = update.effective_user
telegram_id = user.id
# Use first_name if username is not available
username = user.username or user.first_name
logger.info(f"User {username} (ID: {telegram_id}) started the bot.")
# Add user to the database
add_user(telegram_id, username)
update.message.reply_text(f"Hello, {user.first_name}! Welcome to the bot. I've noted your visit.")
# --- Message Handlers ---
def echo(update: Update, context: CallbackContext) -> None:
"""Echoes the user's message."""
user = update.effective_user
text = update.message.text
logger.info(f"User {user.first_name} (ID: {user.id}) said: {text}")
update.message.reply_text(f"You said: {text}")
# --- Error Handler ---
def error_handler(update: Update, context: CallbackContext) -> None:
"""Log Errors caused by Updates."""
logger.error(msg="Exception while handling an update:", exc_info=context.error)
# Optionally, inform the user that something went wrong
# if update and update.effective_message:
# update.effective_message.reply_text("An error occurred. Please try again later.")
# --- Main Function to Run the Bot ---
def main() -> None:
"""Start the bot."""
# Initialize the database first
print("Initializing database...")
init_db()
print("Database ready.")
# Create the Updater and pass it your bot's token.
updater = Updater(API_TOKEN)
# Get the dispatcher to register handlers
dispatcher = updater.dispatcher
# --- Register Handlers ---
# On different commands - answer in Telegram
dispatcher.add_handler(CommandHandler("start", start))
# On non-command textual messages - echo the message on Telegram
dispatcher.add_handler(MessageHandler(Filters.text & ~Filters.command, echo))
# Register the error handler
dispatcher.add_handler(error_handler)
# Start the Bot
print("Starting bot polling...")
updater.start_polling()
print("Bot is running. Press Ctrl+C to stop.")
# Run the bot until you press Ctrl-C
updater.idle()
if __name__ == "__main__":
main()
Explanation:
- Imports: We import necessary classes from
telegram.ext
, our database functions, the API token, and standard libraries likelogging
anddatetime
. - Logging: Basic logging is set up to see bot activity and potential errors in the console.
start()
function: This function is triggered when a user sends the/start
command. It extracts user information (id
,username
,first_name
), callsadd_user
to save/update the user in the database, and sends a welcome message back.echo()
function: This handles any regular text message (that isn't a command). It simply sends the same message back to the user.error_handler()
function: Catches and logs errors from thepython-telegram-bot
library.main()
function:- Calls
init_db()
to ensure the database is ready. - Creates an
Updater
instance, which continuously fetches updates from Telegram. - Gets the
Dispatcher
, which routes updates to the correct handlers. - Registers handlers:
CommandHandler
for/start
andMessageHandler
for text messages. The error handler is also registered. - Starts the bot using
updater.start_polling()
. updater.idle()
keeps the script running until manually stopped (e.g., with Ctrl+C).
- Calls
if __name__ == "__main__":
: Ensuresmain()
runs only when the script is executed directly.
Step 5: Understanding Key Libraries Used
python-telegram-bot
: The core library enabling interaction with the Telegram Bot API. It handles receiving updates (messages, commands) and sending responses. Key components used here areUpdater
,Dispatcher
,CommandHandler
, andMessageHandler
.sqlite3
: Python's built-in library for working with SQLite databases. We use it to connect to the database file, execute SQL commands (likeCREATE TABLE
,INSERT OR IGNORE
), commit changes, and close the connection.datetime
: Used here to get the current timestamp when a user starts the bot, which is then stored in the database.logging
: Python's standard logging module, helpful for monitoring the bot's operation and diagnosing issues.os
: Used briefly indatabase.py
to check if the database file exists before potentially creating it (thoughsqlite3.connect
handles file creation itself).
Step 6: Running and Testing Your Bot
- Navigate: Open your terminal or command prompt and navigate to your
telegram_bot
directory. - Run: Execute the main script: Bash
python main.py
You should see output indicating the database initialization and that the bot is polling. - Test: Open Telegram, find the bot you created (using its username), and send the
/start
command. You should receive the welcome message. Try sending other text messages – the bot should echo them back. Check your console output to see the logging messages, including user additions to the database.
Visualizing the Process: Diagrams
Understanding the flow can be easier with diagrams. Here are conceptual representations using Mermaid syntax (which can be rendered by many Markdown tools) or descriptions:
1. High-Level Workflow (Process Map / Workflow Diagram)
This shows the overall journey of a user interaction:
sequenceDiagram
participant User
participant Telegram API
participant Python Bot (Updater/Dispatcher)
participant Start Handler (`start`)
participant Database (`database.py`)
participant Echo Handler (`echo`)
User->>Telegram API: Sends /start command
Telegram API->>Python Bot (Updater/Dispatcher): Delivers Update
Python Bot (Updater/Dispatcher)->>Start Handler (`start`): Routes update
Start Handler (`start`)->>Database (`database.py`): Calls add_user(id, name)
Database (`database.py`)-->>Start Handler (`start`): User added/ignored
Start Handler (`start`)->>Telegram API: Sends "Hello..." reply
Telegram API->>User: Displays reply
User->>Telegram API: Sends "some text"
Telegram API->>Python Bot (Updater/Dispatcher): Delivers Update
Python Bot (Updater/Dispatcher)->>Echo Handler (`echo`): Routes update
Echo Handler (`echo`)->>Telegram API: Sends "You said: some text" reply
Telegram API->>User: Displays reply
2. Bot Initialization and Running (Flowchart)
This details the steps in main.py
to get the bot running:
graph TD
A[Start main.py] --> B(Call init_db());
B --> C{Database Initialized?};
C -- Yes --> D[Create Updater with API_TOKEN];
C -- No --> E[Error/Exit];
D --> F[Get Dispatcher];
F --> G[Add CommandHandler for /start];
G --> H[Add MessageHandler for text];
H --> I[Add Error Handler];
I --> J(Start Polling updater.start_polling());
J --> K(Wait for Updates / Idle updater.idle());
K --> L{Ctrl+C Pressed?};
L -- Yes --> M[Stop];
L -- No --> K;
3. /start
Command Handling (Process Diagram / Detailed Flowchart)
This zooms in on the start
function's logic:
graph TD
A[Update with /start received] --> B(Dispatcher calls `start` function);
B --> C[Get user info: id, username from `update.effective_user`];
C --> D[Log user interaction];
D --> E(Call `add_user(telegram_id, username)`);
subgraph Database Interaction
E --> F[Connect to DB];
F --> G[Get Cursor];
G --> H[Execute INSERT OR IGNORE];
H --> I[Commit Changes];
I --> J[Close Connection];
end
J --> K[Database returns control];
K --> L[Prepare reply message: "Hello..."];
L --> M(Send reply via `update.message.reply_text()`);
M --> N[End /start processing];
4. add_user
Database Function (Process Diagram / Flowchart Fragment)
This focuses solely on the database insertion logic:
graph TD
A[Function `add_user` called with telegram_id, username] --> B(Get current timestamp);
B --> C(Connect to bot_database.db);
C --> D[Get cursor object];
D --> E(Execute SQL: INSERT OR IGNORE INTO users ... VALUES (?, ?, ?));
E --> F{User already exists?};
F -- Yes (IGNORE) --> G[Commit transaction];
F -- No (INSERT) --> G;
G --> H(Close database connection);
H --> I[Return control];
Conclusion
Congratulations! You've built a basic Telegram bot using Python and SQLite3. This foundation allows you to:
- Register users who interact with your bot.
- Respond to specific commands (
/start
). - Handle general text messages.
- Persist basic user data.
From here, you can expand your bot's capabilities significantly:
- Add more commands and functionalities.
- Query the database to retrieve user information.
- Implement more complex conversation flows.
- Integrate with external APIs.
- Improve error handling and user feedback.
Happy bot building! Feel free to ask if you want to explore specific features further.