Создание Telegram бота с нуля на Python

Telegram боты - это мощный инструмент для автоматизации и взаимодействия с пользователями. В этой статье мы создадим полноценного Telegram бота с нуля, используя Python и библиотеку python-telegram-bot.

Содержание

Регистрация бота

Шаг 1: Создание бота через BotFather

  • Откройте Telegram и найдите @BotFather
  • Отправьте команду /newbot
  • Введите имя вашего бота (например: "Мой Супер Бот")
  • Введите username бота (например: "my_super_bot")
  • Сохраните полученный токен - он понадобится для работы с API
# Пример токена (НЕ используйте этот в продакшене!)
1234567890:ABCdefGHIjklMNOpqrsTUVwxyz

Шаг 2: Настройка бота

# Установка описания
/setdescription

# Установка команды помощи
/setcommands

# Установка аватара
/setuserpic

Настройка окружения

Создание проекта

mkdir telegram-bot
cd telegram-bot
python -m venv venv
source venv/bin/activate  # Linux/Mac
# или
venv\Scripts\activate     # Windows

Установка зависимостей

pip install python-telegram-bot python-dotenv

Структура проекта

telegram-bot/
├── bot.py              # Основной файл бота
├── config.py           # Конфигурация
├── handlers/           # Обработчики команд
│   ├── __init__.py
│   ├── start.py
│   ├── help.py
│   └── echo.py
├── keyboards/          # Клавиатуры
│   ├── __init__.py
│   └── main_menu.py
├── utils/              # Утилиты
│   ├── __init__.py
│   └── database.py
├── .env               # Переменные окружения
├── requirements.txt   # Зависимости
└── README.md         # Документация

Базовый функционал

Создание основного файла бота

# bot.py
import logging
import os
from telegram import Update
from telegram.ext import Application, CommandHandler, MessageHandler, filters, ContextTypes
from dotenv import load_dotenv

# Загрузка переменных окружения
load_dotenv()

# Настройка логирования
logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    level=logging.INFO
)
logger = logging.getLogger(__name__)

# Токен бота из переменных окружения
BOT_TOKEN = os.getenv('BOT_TOKEN')

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Обработчик команды /start"""
    user = update.effective_user
    await update.message.reply_text(
        f'Привет, {user.first_name}! 👋\n\n'
        'Я бот, созданный с помощью Python!\n'
        'Используй /help для получения списка команд.'
    )

async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Обработчик команды /help"""
    help_text = """
🤖 Доступные команды:

/start - Начать работу с ботом
/help - Показать это сообщение
/echo - Эхо-режим (отвечает тем же сообщением)
/info - Информация о пользователе
/time - Текущее время

Просто отправь мне любое сообщение, и я отвечу!
    """
    await update.message.reply_text(help_text, parse_mode='Markdown')

async def echo(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Обработчик обычных сообщений"""
    await update.message.reply_text(f'Вы написали: {update.message.text}')

async def info(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Информация о пользователе"""
    user = update.effective_user
    info_text = f"""
👤 Информация о пользователе:

🆔 ID: {user.id}
👤 Имя: {user.first_name}
📝 Username: @{user.username or 'не указан'}
🌐 Язык: {user.language_code or 'не указан'}
    """
    await update.message.reply_text(info_text, parse_mode='Markdown')

async def time_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Показать текущее время"""
    from datetime import datetime
    current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    await update.message.reply_text(f'🕐 Текущее время: {current_time}')

def main():
    """Основная функция запуска бота"""
    if not BOT_TOKEN:
        logger.error("BOT_TOKEN не найден в переменных окружения!")
        return
    
    # Создание приложения
    application = Application.builder().token(BOT_TOKEN).build()
    
    # Добавление обработчиков команд
    application.add_handler(CommandHandler("start", start))
    application.add_handler(CommandHandler("help", help_command))
    application.add_handler(CommandHandler("info", info))
    application.add_handler(CommandHandler("time", time_command))
    
    # Добавление обработчика обычных сообщений
    application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, echo))
    
    # Запуск бота
    logger.info("Бот запущен!")
    application.run_polling()

if __name__ == '__main__':
    main()

Файл конфигурации

# config.py
import os
from dotenv import load_dotenv

load_dotenv()

class Config:
    BOT_TOKEN = os.getenv('BOT_TOKEN')
    DATABASE_URL = os.getenv('DATABASE_URL', 'sqlite:///bot.db')
    DEBUG = os.getenv('DEBUG', 'False').lower() == 'true'
    ADMIN_IDS = [int(x) for x in os.getenv('ADMIN_IDS', '').split(',') if x]

Переменные окружения

# .env
BOT_TOKEN=your_bot_token_here
DATABASE_URL=sqlite:///bot.db
DEBUG=False
ADMIN_IDS=123456789,987654321

Обработка команд

Расширенная система команд

# handlers/start.py
from telegram import Update
from telegram.ext import ContextTypes

async def start_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Расширенный обработчик команды /start"""
    user = update.effective_user
    
    # Приветственное сообщение с кнопками
    welcome_text = f"""
🎉 Добро пожаловать, {user.first_name}!

Я ваш персональный помощник. Вот что я умею:

🔍 Поиск информации
📊 Аналитика данных  
🎮 Мини-игры
⚙️ Настройки

Выберите действие из меню ниже:
    """
    
    # Создание клавиатуры
    from telegram import ReplyKeyboardMarkup, KeyboardButton
    
    keyboard = [
        [KeyboardButton("🔍 Поиск"), KeyboardButton("📊 Аналитика")],
        [KeyboardButton("🎮 Игры"), KeyboardButton("⚙️ Настройки")],
        [KeyboardButton("❓ Помощь")]
    ]
    reply_markup = ReplyKeyboardMarkup(keyboard, resize_keyboard=True)
    
    await update.message.reply_text(
        welcome_text, 
        parse_mode='Markdown',
        reply_markup=reply_markup
    )

Работа с клавиатурами

Inline клавиатуры

# keyboards/main_menu.py
from telegram import InlineKeyboardButton, InlineKeyboardMarkup

def get_main_menu():
    """Главное меню бота"""
    keyboard = [
        [
            InlineKeyboardButton("🔍 Поиск", callback_data="search"),
            InlineKeyboardButton("📊 Статистика", callback_data="stats")
        ],
        [
            InlineKeyboardButton("🎮 Игры", callback_data="games"),
            InlineKeyboardButton("⚙️ Настройки", callback_data="settings")
        ],
        [
            InlineKeyboardButton("❓ Помощь", callback_data="help"),
            InlineKeyboardButton("📞 Поддержка", callback_data="support")
        ]
    ]
    return InlineKeyboardMarkup(keyboard)

def get_games_menu():
    """Меню игр"""
    keyboard = [
        [
            InlineKeyboardButton("🎲 Угадай число", callback_data="game_number"),
            InlineKeyboardButton("🎯 Викторина", callback_data="game_quiz")
        ],
        [
            InlineKeyboardButton("🔙 Назад", callback_data="back_main")
        ]
    ]
    return InlineKeyboardMarkup(keyboard)

# Обработчик callback-запросов
async def button_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Обработчик нажатий на кнопки"""
    query = update.callback_query
    await query.answer()
    
    if query.data == "search":
        await query.edit_message_text("🔍 Режим поиска активирован!")
    elif query.data == "stats":
        await query.edit_message_text("📊 Статистика:\n\n👥 Пользователей: 1,234\n📝 Сообщений: 5,678")
    elif query.data == "games":
        await query.edit_message_text(
            "🎮 Выберите игру:",
            reply_markup=get_games_menu()
        )
    elif query.data == "back_main":
        await query.edit_message_text(
            "🏠 Главное меню:",
            reply_markup=get_main_menu()
        )

Обработка файлов

Работа с изображениями

async def handle_photo(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Обработка фотографий"""
    photo = update.message.photo[-1]  # Берем фото наивысшего качества
    
    # Получение информации о файле
    file_info = await context.bot.get_file(photo.file_id)
    
    # Скачивание файла
    file_path = f"downloads/{photo.file_id}.jpg"
    await file_info.download_to_drive(file_path)
    
    await update.message.reply_text(
        f"📸 Фото получено!\n"
        f"Размер: {photo.width}x{photo.height}\n"
        f"Файл сохранен: {file_path}"
    )

async def handle_document(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Обработка документов"""
    document = update.message.document
    
    # Проверка типа файла
    allowed_types = ['.pdf', '.doc', '.docx', '.txt', '.py']
    file_extension = os.path.splitext(document.file_name)[1].lower()
    
    if file_extension not in allowed_types:
        await update.message.reply_text("❌ Неподдерживаемый тип файла!")
        return
    
    # Скачивание файла
    file_info = await context.bot.get_file(document.file_id)
    file_path = f"downloads/{document.file_name}"
    await file_info.download_to_drive(file_path)
    
    await update.message.reply_text(
        f"📄 Документ получен!\n"
        f"Название: {document.file_name}\n"
        f"Размер: {document.file_size} байт"
    )

Развертывание

Docker контейнеризация

# Dockerfile
FROM python:3.11-slim

WORKDIR /app

# Установка системных зависимостей
RUN apt-get update && apt-get install -y \
    gcc \
    && rm -rf /var/lib/apt/lists/*

# Копирование файлов зависимостей
COPY requirements.txt .

# Установка Python зависимостей
RUN pip install --no-cache-dir -r requirements.txt

# Копирование исходного кода
COPY . .

# Создание пользователя для безопасности
RUN useradd --create-home --shell /bin/bash bot
RUN chown -R bot:bot /app
USER bot

# Команда запуска
CMD ["python", "bot.py"]

Docker Compose

# docker-compose.yml
version: '3.8'

services:
  telegram-bot:
    build: .
    container_name: telegram-bot
    restart: unless-stopped
    environment:
      - BOT_TOKEN=${BOT_TOKEN}
      - DATABASE_URL=${DATABASE_URL}
    volumes:
      - ./downloads:/app/downloads
      - ./logs:/app/logs
    networks:
      - bot-network

networks:
  bot-network:
    driver: bridge

Запуск в продакшене

# Сборка и запуск
docker-compose up -d --build

# Просмотр логов
docker-compose logs -f telegram-bot

# Остановка
docker-compose down

Заключение

В этой статье мы создали полноценного Telegram бота с нуля, включая:
  • ✅ Регистрацию и настройку бота
  • ✅ Базовый функционал и команды
  • ✅ Работу с клавиатурами
  • ✅ Обработку файлов
  • ✅ Развертывание в Docker
Этот бот может служить основой для более сложных проектов. В следующих статьях мы рассмотрим интеграцию с базами данных, создание админ-панели и монетизацию ботов.

Полезные ссылки

1941 просмотров
2 лайков
0 комментариев