Building an AI-Powered Telegram Bot with Google Gemini API: A Step-by-Step Guide

Uttam MahataUttam Mahata
7 min read

Below is a step‐by‐step explanation of how to build a Telegram bot that leverages Google's Gemini AI using Python. In this tutorial, we'll walk through the code, discuss the design decisions, and explain how each component works together to provide an AI-powered chat experience.


Introduction

In this blog, we build an AI-powered Telegram bot that integrates Google's Gemini API. The bot listens for user messages, sends the input to the Gemini AI, and returns the AI-generated response to the user. We use the python-telegram-bot library for bot functionality, python-dotenv to load sensitive credentials, and the genai client for interacting with Gemini. Let's dive into the code and break it down step by step.


1. Setting Up the Environment

a. Importing Required Libraries

At the top of our script, we import the necessary libraries:

  • Logging: For debugging and tracking bot operations.
  • Telegram Modules: To handle updates, messages, and commands.
  • Google Gemini Client: To interact with the Gemini API.
  • dotenv and OS: For loading and accessing environment variables.
  • sys: To safely exit when critical issues occur.
import logging
from telegram import Update
from telegram.constants import ParseMode  # Updated import for ParseMode
from telegram.ext import Application, CommandHandler, MessageHandler, filters, ContextTypes
from google import genai
from dotenv import load_dotenv
import os
import sys

b. Loading Environment Variables

We use python-dotenv to load environment variables from a .env file. This allows us to manage sensitive information such as API keys outside of our codebase.

# Load environment variables
load_dotenv()

c. Configuring Logging

A proper logging configuration helps in troubleshooting. We configure logging to display the timestamp, logger name, log level, and message.

# Enable logging
logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    level=logging.INFO
)
logger = logging.getLogger(__name__)

2. Validating Environment Variables

Before proceeding, we check that both the Telegram bot token and the Gemini API key are present in the environment. If either is missing, the program logs an error and exits.

# Check for required environment variables
if not os.getenv("TELEGRAM_BOT_TOKEN"):
    logger.error("TELEGRAM_BOT_TOKEN not found in environment variables")
    sys.exit(1)
if not os.getenv("GEMINI_API_KEY"):
    logger.error("GEMINI_API_KEY not found in environment variables")
    sys.exit(1)

This early check prevents runtime errors due to missing configuration.


3. Initializing the Google Gemini Client

We initialize the Gemini API client using the provided API key. The code attempts to create a chat session with the Gemini model (in this case, "gemini-1.5-flash"). Error handling ensures that if the initialization fails, the program logs the error and terminates.

# Initialize Google Gemini client
try:
    client = genai.Client(api_key=os.getenv("GEMINI_API_KEY"))
    chat = client.chats.create(model="gemini-1.5-flash")
except Exception as e:
    logger.error(f"Failed to initialize Gemini client: {e}")
    sys.exit(1)

4. Creating Command and Message Handlers

a. The /start Command

When a user sends the /start command, the start function sends a welcome message. The message is formatted using MarkdownV2 to add style elements like bold text and emojis.

# Define command handler for /start command
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Send a welcome message when the command /start is issued."""
    welcome_message = (
        "👋 *Welcome to the Gemini AI Bot\!*\n\n"
        "I'm powered by Google's Gemini AI\. Send me any message and I'll respond with AI\-generated content\.\n\n"
        "Just type your message and I'll do my best to help you\!"
    )
    await update.message.reply_text(welcome_message, parse_mode=ParseMode.MARKDOWN_V2)

b. Handling Incoming Messages

The handle_message function is responsible for processing all non-command text messages. When a message is received:

  1. Typing Action: The bot sends a "typing…" action to indicate that it's processing the message.
  2. Extracting User Message: The message text is retrieved from the update.
  3. Generating a Response: The function calls get_gemini_response to obtain an AI-generated response.
  4. Error Checking: If the response is empty, an error message is returned to the user.
  5. Sending the Response: The generated response is sent back to the user.
# Define message handler
async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Handle incoming messages and respond using Gemini API."""
    try:
        # Send typing action
        await update.message.chat.send_action(action="typing")

        user_message = update.message.text
        response = get_gemini_response(user_message)

        if not response.strip():
            await update.message.reply_text("I couldn't generate a response. Please try again.")
            return

        await update.message.reply_text(response)
    except Exception as e:
        logger.error(f"Error handling message: {e}")
        await update.message.reply_text(
            "Sorry, I encountered an error while processing your message. Please try again later."
        )

5. Communicating with the Gemini API

The function get_gemini_response sends the user's message to the Gemini API. Since the API returns a stream of response chunks, the function concatenates these chunks into a single response string. Error handling ensures that any issues during the API call are logged and an error message is returned.

# Function to call Google Gemini API
def get_gemini_response(message: str) -> str:
    try:
        response = chat.send_message_stream(message)
        response_text = ""
        for chunk in response:
            response_text += chunk.text
        return response_text
    except Exception as e:
        logger.error(f"Error getting Gemini response: {e}")
        return "Sorry, I encountered an error while generating a response."

6. Running the Bot

The run_bot function sets up the Telegram bot application:

  1. Creating the Application: Initializes the bot with the provided token.
  2. Registering Handlers: Associates the /start command and text message handler with their respective functions.
  3. Starting the Polling Loop: Begins polling for new updates. This loop keeps the bot active and responsive.
def run_bot():
    """Start and run the bot."""
    try:
        # Create the Application and pass it your bot's token
        application = Application.builder().token(os.getenv("TELEGRAM_BOT_TOKEN")).build()

        # Register command handler
        application.add_handler(CommandHandler("start", start))

        # Register message handler
        application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))

        # Start the Bot using run_polling() method
        logger.info("Starting bot...")
        application.run_polling(allowed_updates=Update.ALL_TYPES)
    except Exception as e:
        logger.error(f"Error running bot: {e}")
        sys.exit(1)

Finally, the script checks if it is being run as the main program and then calls run_bot().

if __name__ == '__main__':
    run_bot()

Conclusion

In this tutorial, we built a Telegram bot that harnesses the power of Google's Gemini AI. We:

  • Loaded environment variables and configured logging.
  • Checked for necessary credentials.
  • Initialized the Gemini client.
  • Set up asynchronous command and message handlers.
  • Integrated with the Gemini API to stream and collect responses.
  • Deployed the bot using polling.

This comprehensive walkthrough should help you understand how to combine Telegram's API with an AI service, enabling you to create interactive and intelligent bots. Happy coding!


Deploying the Bot to a Server

To ensure your bot runs continuously and reliably, you should deploy it to a server. Here are several deployment options:

1. Traditional VPS/Cloud Server (e.g., DigitalOcean, AWS EC2, Google Cloud)

  1. Server Setup:

    # Update system packages
    sudo apt update && sudo apt upgrade -y
    
    # Install Python and pip
    sudo apt install python3 python3-pip -y
    
    # Install virtual environment
    sudo apt install python3-venv -y
    
  2. Project Setup:

    # Clone your repository
    git clone <your-repo-url>
    cd <your-project-directory>
    
    # Create and activate virtual environment
    python3 -m venv venv
    source venv/bin/activate
    
    # Install dependencies
    pip install -r requirements.txt
    
  3. Running as a Service: Create a systemd service file:

    sudo nano /etc/systemd/system/telegram-bot.service
    

    Add the following content:

    [Unit]
    Description=Telegram Bot Service
    After=network.target
    
    [Service]
    User=<your-username>
    WorkingDirectory=/path/to/your/bot
    Environment=PATH=/path/to/your/bot/venv/bin
    ExecStart=/path/to/your/bot/venv/bin/python main.py
    Restart=always
    
    [Install]
    WantedBy=multi-user.target
    

    Enable and start the service:

    sudo systemctl enable telegram-bot
    sudo systemctl start telegram-bot
    

2. Docker Deployment

  1. Create a Dockerfile:

    FROM python:3.9-slim
    
    WORKDIR /app
    
    COPY requirements.txt .
    RUN pip install --no-cache-dir -r requirements.txt
    
    COPY . .
    
    CMD ["python", "main.py"]
    
  2. Build and Run:

    docker build -t telegram-bot .
    docker run -d --name telegram-bot --env-file .env telegram-bot
    

3. Platform as a Service (PaaS)

Heroku Deployment:

  1. Create Procfile:

    worker: python main.py
    
  2. Deploy:

    heroku create your-bot-name
    heroku git:remote -a your-bot-name
    git push heroku main
    
  3. Set Environment Variables:

    heroku config:set TELEGRAM_BOT_TOKEN=your_token
    heroku config:set GEMINI_API_KEY=your_key
    
  4. Start Worker:

    heroku ps:scale worker=1
    

Best Practices for Deployment

  1. Environment Variables:

    • Never commit .env files to version control
    • Use the server's environment variable management system
    • Keep production credentials separate from development
  2. Logging:

    • Implement comprehensive logging
    • Use a logging service (e.g., Papertrail, CloudWatch)
    • Monitor bot's health and performance
  3. Backup and Recovery:

    • Regularly backup any persistent data
    • Document deployment and recovery procedures
    • Keep track of dependencies and versions
  4. Security:

    • Keep system packages updated
    • Use firewalls and security groups
    • Implement rate limiting
    • Regular security audits
  5. Monitoring:

    • Set up uptime monitoring
    • Configure alerts for critical errors
    • Monitor resource usage

By following these deployment guidelines, your bot will run reliably and be easier to maintain in a production environment.


0
Subscribe to my newsletter

Read articles from Uttam Mahata directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Uttam Mahata
Uttam Mahata

As an undergraduate student pursuing a Bachelor's degree in Computer Science and Technology at the Indian Institute of Engineering Science and Technology, Shibpur, I have developed a deep interest in data science, machine learning, and web development. I am actively seeking internship opportunities to gain hands-on experience and apply my skills in a formal, professional setting. Programming Languages: C/C++, Java, Python Web Development: HTML, CSS, Angular, JavaScript, TypeScript, PrimeNG, Bootstrap Technical Skills: Data Structures, Algorithms, Object-Oriented Programming, Data Science, MySQL, SpringBoot Version Control : Git Technical Interests: Data Science, Machine Learning, Web Development