Создание 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 комментариев
Комментарии (0)
Пока нет комментариев. Будьте первым!