How to Build a Telegram Bot That Captures Leads 24/7

Here's a comprehensive guide to building a lead-capturing Telegram bot with Python, covering everything from code to deployment.

Building a Lead-Capturing Telegram Bot

This guide will walk you through creating a Python Telegram bot using aiogram (or Telethon if you prefer, though aiogram is generally more straightforward for bot development). We'll cover essential features like commands, inline buttons, lead storage, anti-spam, and deployment.

1. Project Setup and Dependencies

First, ensure you have Python installed. We'll use pip for package management.

Create a project directory:

mkdir telegram_lead_bot
cd telegram_lead_bot

Create a virtual environment:

python -m venv venv

Activate the virtual environment:

  • Windows: venv\Scripts\activate
  • macOS/Linux: source venv/bin/activate

Install necessary libraries:

pip install aiogram python-dotenv google-api-python-client google-auth-httplib2 google-auth-oauthlib
  • aiogram: The asynchronous Telegram Bot API framework.
  • python-dotenv: To manage environment variables (like your bot token).
  • google-api-python-client, google-auth-httplib2, google-auth-oauthlib: For interacting with Google Sheets.

2. Telegram Bot Token

You need a bot token from BotFather.

  1. Open Telegram and search for @BotFather.
  2. Start a chat with it.
  3. Send /newbot.
  4. Follow the prompts to name your bot and choose a username (must end with "bot").
  5. BotFather will give you an API token. Keep this token secret!

3. Google Sheets Setup (for Lead Storage)

We'll use Google Sheets as a simple CRM.

  1. Go to Google Sheets.
  2. Create a new spreadsheet. Name it something like "Telegram Leads".
  3. Create columns for the data you want to capture (e.g., "Name", "Email", "Phone", "Message", "Timestamp").
  4. Enable Google Sheets API:
    • Go to the Google Cloud Console.
    • Create a new project or select an existing one.
    • Navigate to "APIs & Services" -> "Library".
    • Search for "Google Sheets API" and enable it.
    • Navigate to "APIs & Services" -> "Credentials".
    • Click "Create Credentials" -> "OAuth client ID".
    • Select "Desktop app" as the application type.
    • Give it a name (e.g., "Telegram Bot Credentials").
    • Click "Create".
    • Download the JSON file containing your client secrets. Rename it to client_secrets.json and place it in your project directory.
  5. Share your Sheet:
    • In your Google Sheet, click "Share".
    • Under "General access", change "Restricted" to "Anyone with the link".
    • Copy the link. This will be your Sheet ID. The Sheet ID is the long string of characters in the URL between /d/ and /edit.

4. Bot Code Skeleton (main.py)

Create a file named main.py in your project directory.

import logging
import os
from dotenv import load_dotenv
from aiogram import Bot, Dispatcher, types, executor
from aiogram.contrib.middlewares.logging import LoggingMiddleware
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from google.oauth2 import service_account
from googleapiclient.discovery import build
from datetime import datetime

# Load environment variables
load_dotenv()
BOT_TOKEN = os.getenv("BOT_TOKEN")
SHEET_ID = os.getenv("SHEET_ID") # Your Google Sheet ID
SERVICE_ACCOUNT_FILE = 'client_secrets.json' # Path to your downloaded JSON

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Initialize bot and dispatcher
bot = Bot(token=BOT_TOKEN)
dp = Dispatcher(bot)

# Google Sheets API setup
SCOPES = ['https://www.googleapis.com/auth/spreadsheets']
creds = service_account.Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES)
service = build('sheets', 'v4', credentials=creds)
sheet = service.spreadsheets()

# --- Anti-Spam ---
# Basic rate limiting: store user message timestamps
user_timestamps = {}
MESSAGE_COOLDOWN = 5 # seconds

def is_spam(user_id):
    current_time = datetime.now().timestamp()
    if user_id in user_timestamps:
        if current_time - user_timestamps[user_id] < MESSAGE_COOLDOWN:
            return True
    user_timestamps[user_id] = current_time
    return False

# --- Command Handlers ---

@dp.message_handler(commands=['start'])
async def send_welcome(message: types.Message):
    """
    Handles the /start command.
    """
    markup = InlineKeyboardMarkup(row_width=1)
    btn_lead = InlineKeyboardButton("Submit Lead Info", callback_data="submit_lead")
    markup.add(btn_lead)
    await message.reply(
        "Welcome! I can help you capture leads. Click the button below to submit your information.",
        reply_markup=markup
    )

@dp.message_handler(commands=['help'])
async def send_help(message: types.Message):
    """
    Handles the /help command.
    """
    await message.reply("Use /start to begin. I'll guide you through submitting your lead details.")

# --- Callback Query Handlers ---

@dp.callback_query_handler(lambda c: c.data == 'submit_lead')
async def process_submit_lead_callback(callback_query: types.CallbackQuery):
    """
    Handles the 'submit_lead' inline button click.
    """
    await bot.send_message(callback_query.from_user.id, "Please provide your name:")
    # Store state to know what information is expected next
    await dp.current_state(user=callback_query.from_user.id).set_state('awaiting_name')
    await bot.answer_callback_query(callback_query.id)

# --- Message Handlers for Lead Capture ---

@dp.message_handler(state='awaiting_name')
async def process_name(message: types.Message):
    """
    Processes the name provided by the user.
    """
    user_data = {
        'name': message.text,
        'user_id': message.from_user.id,
        'username': message.from_user.username
    }
    await dp.current_state(user=message.from_user.id).set_state('awaiting_email')
    await dp.current_state(user=message.from_user.id).update_data(**user_data)
    await message.reply("Thanks, {}! Now, please provide your email:".format(message.text))

@dp.message_handler(state='awaiting_email')
async def process_email(message: types.Message):
    """
    Processes the email provided by the user.
    """
    if is_spam(message.from_user.id):
        await message.reply("Please wait a moment before sending another message.")
        return

    user_data = await dp.current_state(user=message.from_user.id).get_data()
    user_data['email'] = message.text
    await dp.current_state(user=message.from_user.id).set_state('awaiting_phone')
    await dp.current_state(user=message.from_user.id).update_data(**user_data)
    await message.reply("Got it. What's your phone number?")

@dp.message_handler(state='awaiting_phone')
async def process_phone(message: types.Message):
    """
    Processes the phone number provided by the user.
    """
    if is_spam(message.from_user.id):
        await message.reply("Please wait a moment before sending another message.")
        return

    user_data = await dp.current_state(user=message.from_user.id).get_data()
    user_data['phone'] = message.text
    await dp.current_state(user=message.from_user.id).set_state('awaiting_message')
    await dp.current_state(user=message.from_user.id).update_data(**user_data)
    await message.reply("And finally, any additional message you'd like to add?")

@dp.message_handler(state='awaiting_message')
async def process_final_message(message: types.Message):
    """
    Processes the final message and saves the lead.
    """
    if is_spam(message.from_user.id):
        await message.reply("Please wait a moment before sending another message.")
        return

    user_data = await dp.current_state(user=message.from_user.id).get_data()
    user_data['message'] = message.text
    user_data['timestamp'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    # Save lead to Google Sheets
    try:
        values = [
            [
                user_data.get('name', ''),
                user_data.get('email', ''),
                user_data.get('phone', ''),
                user_data.get('message', ''),
                user_data.get('timestamp', ''),
                user_data.get('user_id', ''),
                user_data.get('username', '')
            ]
        ]
        body = {'values': values}
        # Assuming your sheet has columns: Name, Email, Phone, Message, Timestamp, TelegramUserID, TelegramUsername
        # Adjust 'Sheet1!A2' if your sheet name or starting row is different
        result = sheet.values().append(
            spreadsheetId=SHEET_ID,
            range='Sheet1!A2', # Append to the first empty row in Sheet1, starting from column A
            valueInputOption='USER_ENTERED',
            body=body
        ).execute()
        logger.info(f"Lead saved to sheet: {result}")
        await message.reply("Thank you! Your lead information has been successfully submitted.")
    except Exception as e:
        logger.error(f"Error saving lead to Google Sheets: {e}")
        await message.reply("Sorry, there was an error saving your lead. Please try again later.")

    # Clear state for the user
    await dp.current_state(user=message.from_user.id).finish()

# --- Main Execution ---

if __name__ == '__main__':
    # Add LoggingMiddleware for debugging
    dp.middleware.setup(LoggingMiddleware())

    # Start polling
    executor.start_polling(dp, skip_updates=True)

5. Environment Variables (.env file)

Create a file named .env in your project directory and add your bot token and sheet ID:

BOT_TOKEN=YOUR_TELEGRAM_BOT_TOKEN
SHEET_ID=YOUR_GOOGLE_SHEET_ID

Replace YOUR_TELEGRAM_BOT_TOKEN with your actual bot token and YOUR_GOOGLE_SHEET_ID with the ID of your Google Sheet.

6. Running the Bot Locally

Make sure your virtual environment is activated.

python main.py

You should see log messages indicating the bot has started polling. Test it in Telegram by sending /start to your bot.

7. Deploying on a VPS with Systemd

Deploying on a VPS ensures your bot runs 24/7.

7.1. VPS Setup

  1. Choose a VPS Provider: DigitalOcean, Linode, AWS EC2, etc.
  2. Launch a Linux Instance: Ubuntu 20.04/22.04 LTS is a good choice.
  3. Connect via SSH: bash ssh your_user@your_vps_ip_address
  4. Update System: bash sudo apt update && sudo apt upgrade -y
  5. Install Python and Pip: bash sudo apt install python3 python3-pip python3-venv -y
  6. Create a dedicated user for the bot (recommended for security): bash sudo adduser telegram_bot_user sudo su - telegram_bot_user (You'll be logged in as telegram_bot_user)

7.2. Transfer Project Files

  1. On your local machine: bash # Install scp if you don't have it # sudo apt install openssh-client (Linux/macOS) # scp -r /path/to/your/telegram_lead_bot your_user@your_vps_ip_address:/home/your_user/ Then, on the VPS, move the project directory to the telegram_bot_user's home directory: bash sudo mv /home/your_user/telegram_lead_bot /home/telegram_bot_user/

7.3. Set up Project on VPS

  1. Log in as telegram_bot_user: bash sudo su - telegram_bot_user cd telegram_lead_bot
  2. Create and activate virtual environment: bash python3 -m venv venv source venv/bin/activate
  3. Install dependencies: bash pip install -r requirements.txt # Create this file first: pip freeze > requirements.txt # Or directly install from the list if you didn't create requirements.txt pip install aiogram python-dotenv google-api-python-client google-auth-httplib2 google-auth-oauthlib
  4. Upload client_secrets.json and .env:
    • Use scp from your local machine to upload these files to /home/telegram_bot_user/telegram_lead_bot/ on the VPS.
    • Crucially, ensure .env contains your actual secrets.
    • Ensure client_secrets.json is also in the same directory.

7.4. Create Systemd Service File

This file tells systemd how to manage your bot process.

  1. Exit telegram_bot_user shell and log in as root or use sudo: bash exit # if you were in telegram_bot_user shell sudo nano /etc/systemd/system/telegram-lead-bot.service
  2. Paste the following content:

    ```ini [Unit] Description=Telegram Lead Capture Bot After=network.target

    [Service] User=telegram_bot_user Group=telegram_bot_user WorkingDirectory=/home/telegram_bot_user/telegram_lead_bot ExecStart=/home/telegram_bot_user/telegram_lead_bot/venv/bin/python /home/telegram_bot_user/telegram_lead_bot/main.py Restart=always RestartSec=10 StandardOutput=syslog StandardError=syslog SyslogIdentifier=telegram-lead-bot

    [Install] WantedBy=multi-user.target ```

    • User and Group: Should match the user you created for the bot.
    • WorkingDirectory: Path to your bot's project directory.
    • ExecStart: The command to run your bot, ensuring it uses the Python interpreter from your virtual environment.
  3. Save and exit Nano: Ctrl+X, Y, Enter.

7.5. Manage the Service

  1. Reload systemd to recognize the new service: bash sudo systemctl daemon-reload
  2. Start the bot service: bash sudo systemctl start telegram-lead-bot
  3. Check the bot's status: bash sudo systemctl status telegram-lead-bot You should see "active (running)". If not, check the logs.
  4. Enable the bot to start on boot: bash sudo systemctl enable telegram-lead-bot
  5. View logs: bash sudo journalctl -u telegram-lead-bot -f (Press Ctrl+C to exit the log view)
  6. To stop the bot: bash sudo systemctl stop telegram-lead-bot
  7. To restart the bot: bash sudo systemctl restart telegram-lead-bot

Checklist

  • [ ] Telegram Bot Token obtained from BotFather.
  • [ ] Google Sheet created with necessary columns.
  • [ ] Google Sheets API enabled and client_secrets.json downloaded.
  • [ ] .env file created with BOT_TOKEN and SHEET_ID.
  • [ ] client_secrets.json file in the project root.
  • [ ] main.py code written and tested locally.
  • [ ] Virtual environment created and activated.
  • [ ] Dependencies installed (aiogram, python-dotenv, Google API clients).
  • [ ] VPS provisioned and accessible via SSH.
  • [ ] Python 3 and venv installed on VPS.
  • [ ] Project files transferred to VPS.
  • [ ] Project set up on VPS (venv, dependencies).
  • [ ] client_secrets.json and .env uploaded to VPS.
  • [ ] systemd service file (telegram-lead-bot.service) created and configured correctly.
  • [ ] systemd service started, enabled, and status checked.
  • [ ] Bot tested on Telegram after deployment.

Common Mistakes

  • Forgetting to activate the virtual environment: Leads to using system Python and missing dependencies.
  • Hardcoding secrets: Never put your BOT_TOKEN or SHEET_ID directly in the code. Use .env.
  • Incorrect Google Sheets API setup: Wrong scopes, incorrect client_secrets.json path, or sheet not shared properly.
  • SHEET_ID format: Ensure you're using the correct ID from the Sheet URL.
  • Incorrect range in Google Sheets API: Sheet1!A2 is crucial for appending. If you have headers, start from row 2.
  • systemd service file typos: Incorrect paths, wrong user/group, or ExecStart command issues.
  • Firewall issues: Ensure your VPS firewall allows outgoing connections for Telegram API and Google API.
  • Not handling skip_updates=True: Can lead to duplicate messages if the bot restarts.
  • State management errors: Bot not transitioning between states correctly, leading to broken conversation flows.
  • Google API rate limits: For very high-traffic bots, you might hit Google API limits. Consider caching or alternative storage.

Need this done for you? Hire me on Freelancehunt: https://freelancehunt.com/freelancer/sspoisk

Originally posted at https://guardlabs.online/care/

Комментарии

Популярные сообщения из этого блога

Как обновить 40 000 товаров на OkayCMS за секунды и не потерять 120 тысяч рублей на заказах

Архитектура торговых систем: уроки инженера-строителя