Форум программистов, компьютерный форум, киберфорум
bytestream
Войти
Регистрация
Восстановить пароль
Оценить эту запись

Как создать ChatGPT бота в Telegram на Python

Запись от bytestream размещена 16.01.2025 в 21:28. Обновил(-а) bytestream 16.01.2025 в 21:34
Показов 1738 Комментарии 0
Метки ai, bot, chatgpt, openai, python, telegram, ии

Нажмите на изображение для увеличения
Название: b78895f3-2645-4039-8568-ce6834dcfcc8.png
Просмотров: 55
Размер:	1.76 Мб
ID:	9217
В современном мире технологии искусственного интеллекта становятся все более доступными для разработчиков, открывая новые возможности для создания умных и интерактивных приложений. Одним из самых популярных инструментов в этой области является ChatGPT - языковая модель, способная вести осмысленный диалог и генерировать человекоподобные ответы. Интеграция ChatGPT с популярными мессенджерами, такими как Telegram, позволяет создавать полезные чат-боты, которые могут помогать пользователям в различных задачах.

В этой статье мы подробно рассмотрим процесс создания Telegram-бота, который будет использовать возможности ChatGPT для общения с пользователями. Мы будем использовать Python как основной язык программирования, так как он предоставляет широкие возможности для работы с API различных сервисов и имеет богатую экосистему библиотек. Особое внимание будет уделено пошаговому объяснению каждого этапа разработки, чтобы даже начинающие программисты могли успешно создать своего бота.

Для успешной работы над проектом потребуется базовое понимание Python и его синтаксиса, а также общее представление о работе с API и веб-сервисами. Мы будем использовать несколько ключевых технологий и инструментов: библиотеку python-telegram-bot для взаимодействия с Telegram API, OpenAI API для работы с ChatGPT, а также стандартные инструменты Python для обработки данных и управления зависимостями.

В результате работы над проектом мы получим полноценного Telegram-бота, способного вести диалог с пользователями используя возможности ChatGPT. Бот сможет обрабатывать текстовые сообщения, поддерживать контекст беседы и предоставлять информативные ответы на вопросы пользователей. Важной особенностью нашей реализации станет возможность легко настраивать параметры взаимодействия с ChatGPT, что позволит адаптировать бота под различные задачи и сценарии использования.

Процесс разработки будет разделен на несколько логических этапов: настройку рабочего окружения, создание базовой структуры бота, интеграцию с ChatGPT API и добавление расширенной функциональности. На каждом этапе мы будем рассматривать практические примеры кода, подробно объясняя каждую строку и принцип работы различных компонентов. Особое внимание будет уделено обработке ошибок и созданию надежного, отказоустойчивого решения.

Подготовка рабочего окружения



Прежде чем приступить к разработке Telegram-бота с интеграцией ChatGPT, необходимо правильно настроить рабочее окружение и установить все необходимые инструменты. Начнем с установки Python, если он еще не установлен на вашей системе. Рекомендуется использовать версию Python 3.8 или выше, так как она обеспечивает наилучшую совместимость с современными библиотеками. После установки Python убедитесь, что вместе с ним установлен менеджер пакетов pip, который потребуется для установки дополнительных библиотек.

Для изоляции зависимостей проекта рекомендуется использовать виртуальное окружение. Создание виртуального окружения позволяет избежать конфликтов между различными проектами и их зависимостями. Для создания виртуального окружения используйте следующие команды в терминале:

Python
1
2
3
4
python -m venv chatgpt_bot_env
source chatgpt_bot_env/bin/activate  # для Linux/MacOS
# или
chatgpt_bot_env\Scripts\activate  # для Windows
После активации виртуального окружения установим необходимые библиотеки. Основными зависимостями для нашего проекта будут python-telegram-bot для работы с Telegram API и openai для взаимодействия с ChatGPT. Установку можно выполнить с помощью следующих команд:

Python
1
2
3
pip install python-telegram-bot==13.15
pip install openai
pip install python-dotenv
Библиотека python-dotenv понадобится для безопасного хранения конфиденциальных данных, таких как API-ключи, в отдельном файле конфигурации. Создадим файл `.env` в корневой директории проекта и добавим в него необходимые переменные окружения:

Python
1
2
3
# .env
TELEGRAM_BOT_TOKEN=your_telegram_bot_token
OPENAI_API_KEY=your_openai_api_key
Следующим важным шагом является получение необходимых API-ключей. Для создания Telegram-бота необходимо обратиться к BotFather - официальному боту Telegram для управления ботами. Процесс получения токена включает несколько простых шагов: найдите @BotFather в Telegram, отправьте команду /newbot и следуйте инструкциям. BotFather попросит указать имя для вашего бота и его username, после чего предоставит токен для доступа к API.

Для работы с ChatGPT необходимо получить API-ключ от OpenAI. Для этого требуется создать аккаунт на официальном сайте OpenAI, перейти в раздел управления API-ключами и создать новый ключ. Важно помнить, что использование API ChatGPT является платным сервисом, поэтому рекомендуется внимательно ознакомиться с условиями использования и тарификацией.

Также создадим базовую структуру проекта, которая будет включать несколько основных файлов:

Python
1
2
3
4
5
6
chatgpt_bot/
    ├── .env                # Файл с переменными окружения
    ├── config.py          # Конфигурационные параметры
    ├── bot.py            # Основной файл с логикой бота
    ├── requirements.txt   # Список зависимостей
    └── README.md         # Документация проекта
В файле `config.py` будем хранить основные настройки и конфигурационные параметры бота:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
from dotenv import load_dotenv
import os
 
load_dotenv()
 
# Загрузка конфигурационных параметров из переменных окружения
TELEGRAM_BOT_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN')
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
 
# Дополнительные параметры конфигурации
MODEL_NAME = "gpt-3.5-turbo"  # Модель ChatGPT
MAX_TOKENS = 1000  # Максимальное количество токенов в ответе
TEMPERATURE = 0.7  # Параметр, влияющий на креативность ответов
После настройки базовой структуры проекта важно убедиться, что все установленные компоненты работают корректно. Создадим простой скрипт для проверки подключения к API сервисов. В файле `test_connection.py` напишем код для тестирования соединения:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import telegram
import openai
from config import TELEGRAM_BOT_TOKEN, OPENAI_API_KEY
 
def test_telegram_connection():
    try:
        bot = telegram.Bot(token=TELEGRAM_BOT_TOKEN)
        bot_info = bot.get_me()
        print(f"Успешное подключение к Telegram API. Имя бота: {bot_info.first_name}")
        return True
    except Exception as e:
        print(f"Ошибка подключения к Telegram API: {str(e)}")
        return False
 
def test_openai_connection():
    try:
        openai.api_key = OPENAI_API_KEY
        response = openai.ChatCompletion.create(
            model="gpt-3.5-turbo",
            messages=[{"role": "user", "content": "Test connection"}],
            max_tokens=10
        )
        print("Успешное подключение к OpenAI API")
        return True
    except Exception as e:
        print(f"Ошибка подключения к OpenAI API: {str(e)}")
        return False
Для управления зависимостями проекта создадим файл `requirements.txt`, в котором укажем все необходимые библиотеки и их версии. Это упростит развертывание проекта на других системах:

Python
1
2
3
4
python-telegram-bot==13.15
openai==0.28.0
python-dotenv==0.19.0
requests==2.26.0
Важным аспектом подготовки рабочего окружения является настройка логирования для отслеживания работы бота и отладки возможных ошибок. Создадим отдельный модуль `logger.py` для централизованной настройки логирования:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import logging
import os
from datetime import datetime
 
def setup_logger():
    # Создаем директорию для логов, если она не существует
    if not os.path.exists('logs'):
        os.makedirs('logs')
    
    # Настраиваем формат логирования
    log_format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    logging.basicConfig(
        level=logging.INFO,
        format=log_format,
        handlers=[
            logging.FileHandler(
                f'logs/bot_{datetime.now().strftime("%Y%m%d")}.log'
            ),
            logging.StreamHandler()
        ]
    )
    
    return logging.getLogger(__name__)
Для обеспечения безопасности и защиты конфиденциальных данных следует создать файл `.gitignore`, чтобы исключить чувствительные файлы из системы контроля версий:

Код
# .gitignore
.env
__pycache__/
*.pyc
logs/
.vscode/
.idea/
venv/
chatgpt_bot_env/
Также рекомендуется настроить параметры форматирования кода для поддержания единого стиля в проекте. Создадим файл `setup.cfg` с настройками для популярных инструментов форматирования:

Код
[flake8]
max-line-length = 88
extend-ignore = E203
exclude = .git,__pycache__,build,dist

[isort]
profile = black
multi_line_output = 3
include_trailing_comma = True
force_grid_wrap = 0
use_parentheses = True
line_length = 88
Для удобства разработки и автоматизации часто выполняемых задач создадим файл `Makefile` (для Unix-систем) или `make.bat` (для Windows):

Код
.PHONY: install test run lint clean

install:
    pip install -r requirements.txt

test:
    python -m pytest tests/

run:
    python bot.py

lint:
    flake8 .
    black .
    isort .

clean:
    find . -type d -name "__pycache__" -exec rm -r {} +
    find . -type f -name "*.pyc" -delete
После завершения настройки рабочего окружения важно провести тестовый запуск всех компонентов и убедиться, что система работает корректно. Это можно сделать, запустив созданный ранее скрипт тестирования подключений:

Python
1
2
3
if __name__ == "__main__":
    test_telegram_connection()
    test_openai_connection()

Как ограничить бота? Telegram Python
Итак, доброго времени суток. У меня вопрос: как сделать так, чтобы бот реагировал на сообщения пользователей только в моей группе? То есть, если...

Как посмотреть текст сообщения бота (Telegram bot, Python)?
Использую библиотеку Telebot. Ситуация: пользователь написал боту сообщения. Мне нужно узнать текст сообщения бота, которое находится перед...

Как создать бота, который реагирует на определенный текст в сообщении Telegram?
Всем привет, хотел бы реализовать программу, которая реагирует на определенный текст входящего сообщения в Telegram. Например, пришло входящее...

Проблема с настройкой бота в telegram на python
Всем привет, я новичок в создании ботов на python. Сегодня начал создавать gdz бота который должен выводить ответы на вопросы путем поиска: предмет...


Создание базовой структуры бота



Теперь, когда рабочее окружение настроено, приступим к созданию базовой структуры Telegram-бота. Начнем с реализации основного файла `bot.py`, где будет размещена вся логика взаимодействия с пользователем. В первую очередь необходимо импортировать все требуемые библиотеки и настроить базовые параметры бота.

Создадим основной класс бота, который будет отвечать за всю функциональность. Этот подход позволит организовать код более структурированно и облегчит дальнейшее расширение функциональности:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters
from telegram import Update, ParseMode
from telegram.ext import CallbackContext
import logging
from config import TELEGRAM_BOT_TOKEN
 
class ChatGPTBot:
    def __init__(self):
        self.updater = Updater(TELEGRAM_BOT_TOKEN, use_context=True)
        self.dispatcher = self.updater.dispatcher
        self.setup_handlers()
        self.logger = logging.getLogger(__name__)
        
    def setup_handlers(self):
        self.dispatcher.add_handler(CommandHandler("start", self.start_command))
        self.dispatcher.add_handler(CommandHandler("help", self.help_command))
        self.dispatcher.add_handler(MessageHandler(Filters.text & ~Filters.command, self.handle_message))
        self.dispatcher.add_error_handler(self.error_handler)
Реализуем базовые обработчики команд, которые будут отвечать за взаимодействие с пользователем. Начнем с команды `/start`, которая будет приветствовать пользователя и объяснять основные возможности бота:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def start_command(self, update: Update, context: CallbackContext):
    user = update.effective_user
    welcome_message = f"""
    Здравствуйте, {user.first_name}!
 
    Я бот, работающий на базе ChatGPT. Я готов помочь вам с различными задачами:
    • Ответить на ваши вопросы
    • Помочь с написанием текстов
    • Объяснить сложные концепции
    • Предложить идеи и решения
 
    Просто напишите мне сообщение, и я постараюсь помочь!
    
    Используйте /help для получения дополнительной информации.
    """
    update.message.reply_text(welcome_message, parse_mode=ParseMode.MARKDOWN)
Команда `/help` будет предоставлять пользователю информацию о доступных командах и возможностях бота:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def help_command(self, update: Update, context: CallbackContext):
    help_message = """
    *Доступные команды:*
    
    /start - Начать диалог с ботом
    /help - Показать это сообщение помощи
    /clear - Очистить историю диалога
    /settings - Настройки бота
    
    *Как использовать бота:*
    • Просто отправьте текстовое сообщение
    • Бот поддерживает контекст беседы
    • Для начала новой темы используйте /clear
    
    *Совет:* Чем точнее ваш запрос, тем полезнее будет ответ.
    """
    update.message.reply_text(help_message, parse_mode=ParseMode.MARKDOWN)
Основной функционал бота будет реализован в методе `handle_message`, который обрабатывает все текстовые сообщения от пользователя:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def handle_message(self, update: Update, context: CallbackContext):
    try:
        user_message = update.message.text
        chat_id = update.effective_chat.id
        
        # Отправляем уведомление о печати
        context.bot.send_chat_action(chat_id=chat_id, action='typing')
        
        # Здесь позже добавим обработку сообщения через ChatGPT
        
        # Временный ответ для проверки работоспособности
        response = f"Получено сообщение: {user_message}"
        update.message.reply_text(response)
        
    except Exception as e:
        self.logger.error(f"Ошибка при обработке сообщения: {str(e)}")
        update.message.reply_text("Произошла ошибка при обработке вашего сообщения. Пожалуйста, попробуйте позже.")
Добавим обработчик ошибок, который будет логировать возникающие проблемы и информировать пользователя о них:

Python
1
2
3
4
5
6
def error_handler(self, update: Update, context: CallbackContext):
    self.logger.error(f"Update {update} caused error {context.error}")
    
    error_message = "Произошла ошибка при обработке запроса. Пожалуйста, попробуйте позже."
    if update and update.effective_message:
        update.effective_message.reply_text(error_message)
Для запуска бота реализуем метод `run`, который будет запускать основной цикл обработки сообщений:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def run(self):
    self.logger.info("Бот запущен и готов к работе")
    self.updater.start_polling()
    self.updater.idle()
 
if __name__ == '__main__':
    # Настройка логирования
    logging.basicConfig(
        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
        level=logging.INFO
    )
    
    # Создание и запуск бота
    bot = ChatGPTBot()
    bot.run()
Важной частью базовой структуры является обработка пользовательской сессии. Добавим класс для управления сессиями пользователей:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class UserSession:
    def __init__(self):
        self.conversation_history = []
        self.last_interaction = None
        self.settings = {
            'max_tokens': 1000,
            'temperature': 0.7,
            'language': 'ru'
        }
    
    def add_message(self, role: str, content: str):
        self.conversation_history.append({
            'role': role,
            'content': content,
            'timestamp': datetime.now()
        })
    
    def clear_history(self):
        self.conversation_history = []
Также добавим словарь для хранения пользовательских сессий в классе бота:

Python
1
2
3
4
5
6
7
8
9
class ChatGPTBot:
    def __init__(self):
        # ... предыдущий код ...
        self.user_sessions = {}
    
    def get_user_session(self, user_id: int) -> UserSession:
        if user_id not in self.user_sessions:
            self.user_sessions[user_id] = UserSession()
        return self.user_sessions[user_id]
Реализуем метод для очистки истории диалога:

Python
1
2
3
4
5
def clear_command(self, update: Update, context: CallbackContext):
    user_id = update.effective_user.id
    session = self.get_user_session(user_id)
    session.clear_history()
    update.message.reply_text("История диалога очищена. Можете начать новую беседу.")
Для удобства работы с настройками пользователей добавим команду `/settings`, которая позволит пользователям просматривать и изменять параметры взаимодействия с ботом:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def settings_command(self, update: Update, context: CallbackContext):
    user_id = update.effective_user.id
    session = self.get_user_session(user_id)
    
    settings_message = f"""
    *Текущие настройки:*
    • Максимальное количество токенов: {session.settings['max_tokens']}
    • Температура генерации: {session.settings['temperature']}
    • Язык ответов: {session.settings['language']}
    
    Для изменения настроек используйте команды:
    /set_tokens <число> - установить максимальное количество токенов
    /set_temp <число> - установить температуру (0.1-1.0)
    /set_lang <код языка> - установить язык ответов
    """
    update.message.reply_text(settings_message, parse_mode=ParseMode.MARKDOWN)
Для обеспечения более надежной работы бота добавим систему мониторинга состояния и использования ресурсов. Создадим класс `BotMonitor`, который будет отслеживать различные метрики:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class BotMonitor:
    def __init__(self):
        self.start_time = datetime.now()
        self.request_count = 0
        self.error_count = 0
        self.active_users = set()
    
    def log_request(self, user_id: int):
        self.request_count += 1
        self.active_users.add(user_id)
    
    def log_error(self):
        self.error_count += 1
    
    def get_stats(self):
        uptime = datetime.now() - self.start_time
        return {
            'uptime': str(uptime),
            'requests': self.request_count,
            'errors': self.error_count,
            'active_users': len(self.active_users)
        }
Для оптимизации работы с памятью реализуем механизм очистки неактивных сессий:

Python
1
2
3
4
5
6
7
8
9
10
11
def cleanup_sessions(self):
    current_time = datetime.now()
    inactive_timeout = timedelta(hours=24)
    
    inactive_users = []
    for user_id, session in self.user_sessions.items():
        if current_time - session.last_interaction > inactive_timeout:
            inactive_users.append(user_id)
    
    for user_id in inactive_users:
        del self.user_sessions[user_id]
Добавим функционал для сохранения состояния бота на случай перезапуска или сбоя:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import json
import pickle
 
class StateManager:
    def __init__(self, filename='bot_state.pickle'):
        self.filename = filename
    
    def save_state(self, bot_instance):
        state = {
            'user_sessions': bot_instance.user_sessions,
            'monitor_data': bot_instance.monitor.get_stats()
        }
        with open(self.filename, 'wb') as f:
            pickle.dump(state, f)
    
    def load_state(self, bot_instance):
        try:
            with open(self.filename, 'rb') as f:
                state = pickle.load(f)
                bot_instance.user_sessions = state['user_sessions']
                return True
        except FileNotFoundError:
            return False
Для улучшения пользовательского опыта добавим систему подсказок, которая будет предлагать возможные команды и действия на основе контекста беседы:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class SuggestionSystem:
    def __init__(self):
        self.command_patterns = {
            'вопрос': '/help',
            'очистить': '/clear',
            'настройки': '/settings',
            'начать': '/start'
        }
    
    def get_suggestions(self, message: str) -> list:
        suggestions = []
        message = message.lower()
        
        for trigger, command in self.command_patterns.items():
            if trigger in message:
                suggestions.append(command)
        
        return suggestions[:3]  # Возвращаем не более трех подсказок
Для обеспечения безопасности и контроля доступа добавим систему ограничений и квот:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class RateLimiter:
    def __init__(self):
        self.requests = {}
        self.max_requests = 50  # максимальное количество запросов в час
        self.window_size = 3600  # размер окна в секундах (1 час)
    
    def can_process(self, user_id: int) -> bool:
        current_time = time.time()
        user_requests = self.requests.get(user_id, [])
        
        # Удаляем старые запросы
        user_requests = [req for req in user_requests 
                        if current_time - req < self.window_size]
        
        if len(user_requests) >= self.max_requests:
            return False
        
        user_requests.append(current_time)
        self.requests[user_id] = user_requests
        return True
Интегрируем все созданные компоненты в основной класс бота:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class ChatGPTBot:
    def __init__(self):
        # ... предыдущий код ...
        self.monitor = BotMonitor()
        self.state_manager = StateManager()
        self.suggestion_system = SuggestionSystem()
        self.rate_limiter = RateLimiter()
        
        # Загружаем сохраненное состояние
        self.state_manager.load_state(self)
        
        # Добавляем периодическую очистку сессий
        self.updater.job_queue.run_repeating(
            self.cleanup_job,
            interval=timedelta(hours=1)
        )
    
    def cleanup_job(self, context: CallbackContext):
        self.cleanup_sessions()
        self.state_manager.save_state(self)

Интеграция с ChatGPT API



Теперь, когда базовая структура бота готова, приступим к интеграции с ChatGPT API. Начнем с создания отдельного класса для работы с OpenAI API, который будет отвечать за взаимодействие с языковой моделью. Этот подход позволит изолировать логику работы с API и сделать код более организованным и поддерживаемым.

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import openai
from typing import List, Dict
from config import OPENAI_API_KEY, MODEL_NAME
 
class ChatGPTHandler:
    def __init__(self):
        openai.api_key = OPENAI_API_KEY
        self.model = MODEL_NAME
        self.default_params = {
            'temperature': 0.7,
            'max_tokens': 1000,
            'top_p': 1.0,
            'frequency_penalty': 0.0,
            'presence_penalty': 0.0
        }
    
    async def generate_response(self, messages: List[Dict], custom_params: Dict = None) -> str:
        try:
            params = self.default_params.copy()
            if custom_params:
                params.update(custom_params)
                
            response = await openai.ChatCompletion.acreate(
                model=self.model,
                messages=messages,
                **params
            )
            return response.choices[0].message.content
        except openai.error.OpenAIError as e:
            raise ChatGPTException(f"Ошибка при обращении к ChatGPT: {str(e)}")
Для более эффективной работы с API реализуем систему кэширования ответов, которая поможет снизить количество запросов к API и ускорить работу бота:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from functools import lru_cache
import hashlib
import json
 
class ResponseCache:
    def __init__(self, cache_size: int = 1000):
        self.cache = lru_cache(maxsize=cache_size)(self._generate_response_cached)
        
    def _generate_cache_key(self, messages: List[Dict], params: Dict) -> str:
        cache_data = {
            'messages': messages,
            'params': params
        }
        return hashlib.md5(json.dumps(cache_data, sort_keys=True).encode()).hexdigest()
    
    async def _generate_response_cached(self, cache_key: str):
        chatgpt = ChatGPTHandler()
        return await chatgpt.generate_response(messages, params)
    
    async def get_response(self, messages: List[Dict], params: Dict = None) -> str:
        cache_key = self._generate_cache_key(messages, params)
        return await self.cache(cache_key)
Для обработки различных форматов сообщений и подготовки их для отправки в ChatGPT API создадим класс для форматирования сообщений:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class MessageFormatter:
    @staticmethod
    def format_conversation_history(history: List[Dict]) -> List[Dict]:
        formatted_messages = []
        for message in history:
            formatted_messages.append({
                'role': message['role'],
                'content': message['content']
            })
        return formatted_messages
    
    @staticmethod
    def create_system_message(instructions: str) -> Dict:
        return {
            'role': 'system',
            'content': instructions
        }
    
    @staticmethod
    def create_user_message(content: str) -> Dict:
        return {
            'role': 'user',
            'content': content
        }
Добавим систему управления контекстом беседы, которая будет следить за историей сообщений и поддерживать связность диалога:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class ConversationManager:
    def __init__(self, max_history: int = 10):
        self.max_history = max_history
        
    def prepare_messages(self, session: UserSession, new_message: str) -> List[Dict]:
        messages = [MessageFormatter.create_system_message(
            "Вы - полезный ассистент, который отвечает на вопросы пользователя."
        )]
        
        # Добавляем историю сообщений
        history = session.conversation_history[-self.max_history:]
        messages.extend(MessageFormatter.format_conversation_history(history))
        
        # Добавляем новое сообщение
        messages.append(MessageFormatter.create_user_message(new_message))
        return messages
Для обработки ошибок API и управления повторными попытками создадим специализированный класс:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class APIRetryHandler:
    def __init__(self, max_retries: int = 3, delay: float = 1.0):
        self.max_retries = max_retries
        self.delay = delay
    
    async def execute_with_retry(self, func, *args, **kwargs):
        for attempt in range(self.max_retries):
            try:
                return await func(*args, **kwargs)
            except openai.error.RateLimitError:
                if attempt == self.max_retries - 1:
                    raise
                await asyncio.sleep(self.delay * (2 ** attempt))
            except openai.error.APIError as e:
                if attempt == self.max_retries - 1:
                    raise
                await asyncio.sleep(self.delay)
Теперь интегрируем все созданные компоненты в основной класс бота, добавив методы для обработки сообщений через ChatGPT:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class ChatGPTBot:
    def __init__(self):
        # ... предыдущий код ...
        self.chatgpt = ChatGPTHandler()
        self.cache = ResponseCache()
        self.conversation_manager = ConversationManager()
        self.retry_handler = APIRetryHandler()
    
    async def process_message(self, update: Update, context: CallbackContext):
        user_id = update.effective_user.id
        message_text = update.message.text
        session = self.get_user_session(user_id)
        
        try:
            # Подготовка сообщений для отправки в API
            messages = self.conversation_manager.prepare_messages(
                session,
                message_text
            )
            
            # Получение ответа от ChatGPT с использованием системы повторных попыток
            response = await self.retry_handler.execute_with_retry(
                self.chatgpt.generate_response,
                messages,
                session.settings
            )
            
            # Сохранение истории диалога
            session.add_message('user', message_text)
            session.add_message('assistant', response)
            
            # Отправка ответа пользователю
            await update.message.reply_text(response)
            
        except Exception as e:
            self.logger.error(f"Ошибка при обработке сообщения: {str(e)}")
            await update.message.reply_text(
                "Произошла ошибка при обработке вашего сообщения. "
                "Пожалуйста, попробуйте позже."
            )
Для оптимизации использования API добавим систему управления токенами:

Python
1
2
3
4
5
6
7
8
9
10
11
12
class TokenManager:
    def __init__(self):
        self.encoder = tiktoken.get_encoding("cl100k_base")
    
    def count_tokens(self, text: str) -> int:
        return len(self.encoder.encode(text))
    
    def truncate_text(self, text: str, max_tokens: int) -> str:
        tokens = self.encoder.encode(text)
        if len(tokens) <= max_tokens:
            return text
        return self.encoder.decode(tokens[:max_tokens])
Реализуем систему мониторинга производительности API, которая поможет отслеживать качество работы сервиса и оптимизировать использование ресурсов:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class APIPerformanceMonitor:
    def __init__(self):
        self.response_times = []
        self.error_counts = defaultdict(int)
        self.token_usage = []
    
    def log_request(self, start_time: float, end_time: float, tokens_used: int, error: Exception = None):
        response_time = end_time - start_time
        self.response_times.append(response_time)
        self.token_usage.append(tokens_used)
        
        if error:
            error_type = type(error).__name__
            self.error_counts[error_type] += 1
    
    def get_statistics(self) -> Dict:
        return {
            'avg_response_time': statistics.mean(self.response_times),
            'max_response_time': max(self.response_times),
            'total_tokens': sum(self.token_usage),
            'error_distribution': dict(self.error_counts)
        }
Добавим систему управления контекстом модели, которая позволит настраивать поведение ChatGPT под конкретные задачи:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class ModelContextManager:
    def __init__(self):
        self.context_templates = {
            'general': "Вы - полезный ассистент, готовый помочь с любыми вопросами.",
            'technical': "Вы - технический эксперт, специализирующийся на программировании и технологиях.",
            'creative': "Вы - креативный помощник, способный генерировать идеи и творческие решения.",
            'academic': "Вы - академический ассистент, помогающий с научными и образовательными вопросами."
        }
    
    def get_context(self, context_type: str, custom_instructions: str = None) -> str:
        base_context = self.context_templates.get(context_type, self.context_templates['general'])
        if custom_instructions:
            return f"{base_context}\n{custom_instructions}"
        return base_context
Для обеспечения безопасности и фильтрации контента реализуем систему модерации:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class ContentModerator:
    def __init__(self):
        self.blocked_patterns = [
            r'(?i)нецензурная_лексика',
            r'(?i)оскорбления',
            r'(?i)спам'
        ]
        self.sensitive_topics = set(['политика', 'религия', 'конфликты'])
    
    def check_content(self, text: str) -> Tuple[bool, str]:
        # Проверка на запрещенные паттерны
        for pattern in self.blocked_patterns:
            if re.search(pattern, text):
                return False, "Сообщение содержит недопустимый контент"
        
        # Проверка на чувствительные темы
        words = set(text.lower().split())
        if words.intersection(self.sensitive_topics):
            return True, "Внимание: сообщение содержит чувствительные темы"
        
        return True, ""
Для улучшения качества ответов добавим систему постобработки:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class ResponsePostProcessor:
    def __init__(self):
        self.markdown_formatter = markdown2.Markdown()
        
    def format_response(self, response: str) -> str:
        # Форматирование кода
        response = self.format_code_blocks(response)
        
        # Проверка и исправление пунктуации
        response = self.fix_punctuation(response)
        
        # Форматирование списков
        response = self.format_lists(response)
        
        return response
    
    def format_code_blocks(self, text: str) -> str:
        code_pattern = r'```(\w+)?\n(.*?)\n```'
        return re.sub(code_pattern, self.process_code_block, text, flags=re.DOTALL)
    
    def process_code_block(self, match) -> str:
        language = match.group(1) or ''
        code = match.group(2)
        return f"```{language}\n{textwrap.dedent(code).strip()}\n```"
Реализуем систему управления контекстом диалога для поддержания связности беседы:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class DialogueContextManager:
    def __init__(self, max_context_length: int = 2000):
        self.max_context_length = max_context_length
        self.token_manager = TokenManager()
    
    def prepare_context(self, history: List[Dict], new_message: str) -> List[Dict]:
        context = []
        current_length = 0
        
        # Добавляем системное сообщение
        system_message = MessageFormatter.create_system_message(
            ModelContextManager().get_context('general')
        )
        context.append(system_message)
        
        # Обрабатываем историю сообщений
        for message in reversed(history):
            message_tokens = self.token_manager.count_tokens(message['content'])
            if current_length + message_tokens > self.max_context_length:
                break
                
            context.insert(1, message)
            current_length += message_tokens
        
        # Добавляем новое сообщение
        context.append(MessageFormatter.create_user_message(new_message))
        
        return context
Для оптимизации работы с большими диалогами добавим систему сжатия истории:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class HistoryCompressor:
    def __init__(self):
        self.token_manager = TokenManager()
        
    def compress_history(self, history: List[Dict], max_tokens: int) -> List[Dict]:
        if not history:
            return []
            
        # Вычисляем общее количество токенов
        total_tokens = sum(self.token_manager.count_tokens(msg['content']) 
                          for msg in history)
        
        if total_tokens <= max_tokens:
            return history
            
        # Создаем сжатое представление истории
        compressed = []
        current_tokens = 0
        
        for message in reversed(history):
            tokens = self.token_manager.count_tokens(message['content'])
            if current_tokens + tokens > max_tokens:
                break
                
            compressed.insert(0, message)
            current_tokens += tokens
        
        return compressed
Интегрируем все новые компоненты в основной класс бота:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
class ChatGPTBot:
    def __init__(self):
        # ... предыдущий код ...
        self.performance_monitor = APIPerformanceMonitor()
        self.content_moderator = ContentModerator()
        self.post_processor = ResponsePostProcessor()
        self.dialogue_context = DialogueContextManager()
        self.history_compressor = HistoryCompressor()
    
    async def handle_message(self, update: Update, context: CallbackContext):
        user_id = update.effective_user.id
        message_text = update.message.text
        session = self.get_user_session(user_id)
        
        # Проверка содержимого
        is_safe, moderation_message = self.content_moderator.check_content(message_text)
        if not is_safe:
            await update.message.reply_text(moderation_message)
            return
        
        start_time = time.time()
        try:
            # Подготовка контекста
            messages = self.dialogue_context.prepare_context(
                session.conversation_history,
                message_text
            )
            
            # Получение ответа
            response = await self.chatgpt.generate_response(messages)
            
            # Постобработка ответа
            formatted_response = self.post_processor.format_response(response)
            
            # Сжатие и сохранение истории
            session.conversation_history = self.history_compressor.compress_history(
                session.conversation_history + [
                    {'role': 'user', 'content': message_text},
                    {'role': 'assistant', 'content': response}
                ],
                self.dialogue_context.max_context_length
            )
            
            await update.message.reply_text(formatted_response)
            
        except Exception as e:
            self.logger.error(f"Ошибка при обработке сообщения: {str(e)}")
            await update.message.reply_text(
                "Произошла ошибка при обработке вашего сообщения."
            )
        finally:
            # Логирование производительности
            end_time = time.time()
            self.performance_monitor.log_request(
                start_time,
                end_time,
                self.token_manager.count_tokens(message_text)
            )

Расширенная функциональность



Для создания более функционального и удобного бота важно реализовать дополнительные возможности, которые улучшат пользовательский опыт и расширят возможности взаимодействия. Начнем с реализации системы управления пользовательскими настройками, которая позволит каждому пользователю настраивать бота под свои потребности. Создадим класс для хранения и управления пользовательскими предпочтениями:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class UserPreferences:
    def __init__(self):
        self.settings = {
            'language': 'ru',
            'response_length': 'medium',
            'creativity_level': 0.7,
            'notifications': True,
            'auto_clear': False
        }
        
    def update_settings(self, **kwargs):
        for key, value in kwargs.items():
            if key in self.settings:
                self.settings[key] = value
                
    def get_setting(self, key):
        return self.settings.get(key)
Следующим важным компонентом является система управления медиаконтентом, которая позволит боту обрабатывать различные типы сообщений, включая изображения, документы и голосовые сообщения. Реализуем соответствующий обработчик:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class MediaHandler:
    def __init__(self):
        self.supported_formats = {
            'image': ['jpeg', 'png', 'gif'],
            'document': ['pdf', 'txt', 'doc', 'docx'],
            'voice': ['ogg', 'mp3']
        }
        
    async def process_media(self, message: Message, media_type: str):
        if media_type == 'image':
            return await self.process_image(message)
        elif media_type == 'document':
            return await self.process_document(message)
        elif media_type == 'voice':
            return await self.process_voice(message)
            
    async def process_image(self, message: Message):
        photo = message.photo[-1]  # Берем версию с наивысшим качеством
        file = await photo.get_file()
        return f"Изображение получено и обработано: {file.file_size} байт"
Добавим систему аналитики пользовательских взаимодействий, которая поможет отслеживать популярные запросы и улучшать качество ответов бота:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class UserAnalytics:
    def __init__(self):
        self.interaction_history = defaultdict(list)
        self.popular_queries = Counter()
        
    def log_interaction(self, user_id: int, query: str, response: str):
        self.interaction_history[user_id].append({
            'timestamp': datetime.now(),
            'query': query,
            'response': response
        })
        self.popular_queries[query] += 1
        
    def get_user_statistics(self, user_id: int):
        user_interactions = self.interaction_history[user_id]
        return {
            'total_queries': len(user_interactions),
            'average_length': statistics.mean(
                len(i['query']) for i in user_interactions
            ),
            'most_frequent': self.popular_queries.most_common(5)
        }
Реализуем систему планировщика задач, которая позволит пользователям настраивать отложенные запросы и регулярные уведомления:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class TaskScheduler:
    def __init__(self):
        self.scheduled_tasks = {}
        self.periodic_tasks = {}
        
    async def schedule_task(self, user_id: int, task: str, execute_time: datetime):
        task_id = str(uuid.uuid4())
        self.scheduled_tasks[task_id] = {
            'user_id': user_id,
            'task': task,
            'execute_time': execute_time
        }
        return task_id
        
    async def add_periodic_task(self, user_id: int, task: str, interval: timedelta):
        task_id = str(uuid.uuid4())
        self.periodic_tasks[task_id] = {
            'user_id': user_id,
            'task': task,
            'interval': interval,
            'last_executed': None
        }
        return task_id
Для повышения качества ответов бота добавим систему обучения на основе пользовательской обратной связи:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class FeedbackLearning:
    def __init__(self):
        self.feedback_history = []
        self.response_quality = defaultdict(float)
        
    def add_feedback(self, query: str, response: str, rating: float):
        self.feedback_history.append({
            'query': query,
            'response': response,
            'rating': rating,
            'timestamp': datetime.now()
        })
        self.update_quality_metrics(query, rating)
        
    def update_quality_metrics(self, query: str, rating: float):
        current_rating = self.response_quality[query]
        self.response_quality[query] = (current_rating + rating) / 2
Создадим систему тегирования и категоризации запросов для более эффективной обработки сообщений:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class QueryCategorizer:
    def __init__(self):
        self.categories = {
            'technical': ['программирование', 'код', 'ошибка'],
            'creative': ['идея', 'дизайн', 'творчество'],
            'educational': ['учеба', 'образование', 'наука'],
            'general': ['помощь', 'совет', 'информация']
        }
        
    def categorize_query(self, query: str) -> str:
        query_words = set(query.lower().split())
        for category, keywords in self.categories.items():
            if query_words.intersection(keywords):
                return category
        return 'general'
Интегрируем все новые компоненты в основной класс бота и добавим соответствующие обработчики команд:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class ChatGPTBot:
    def __init__(self):
        # ... предыдущий код ...
        self.preferences = UserPreferences()
        self.media_handler = MediaHandler()
        self.analytics = UserAnalytics()
        self.scheduler = TaskScheduler()
        self.feedback = FeedbackLearning()
        self.categorizer = QueryCategorizer()
        
    async def handle_message(self, update: Update, context: CallbackContext):
        user_id = update.effective_user.id
        message = update.message
        
        # Обработка медиаконтента
        if message.photo:
            response = await self.media_handler.process_media(message, 'image')
        elif message.document:
            response = await self.media_handler.process_media(message, 'document')
        elif message.voice:
            response = await self.media_handler.process_media(message, 'voice')
        else:
            # Категоризация и обработка текстового запроса
            category = self.categorizer.categorize_query(message.text)
            response = await self.process_text_message(message.text, category)
            
        # Логирование взаимодействия
        self.analytics.log_interaction(user_id, message.text, response)
        await update.message.reply_text(response)
Добавим систему уведомлений, которая будет информировать пользователей о важных событиях и обновлениях. Реализуем соответствующий класс для управления различными типами уведомлений:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class NotificationSystem:
    def __init__(self):
        self.subscribers = defaultdict(set)
        self.notification_types = {
            'updates': 'Обновления системы',
            'scheduled': 'Запланированные задачи',
            'alerts': 'Важные уведомления'
        }
    
    async def subscribe(self, user_id: int, notification_type: str):
        if notification_type in self.notification_types:
            self.subscribers[notification_type].add(user_id)
            return True
        return False
    
    async def send_notification(self, notification_type: str, message: str, bot):
        if notification_type in self.subscribers:
            for user_id in self.subscribers[notification_type]:
                await bot.send_message(user_id, message)
Для улучшения качества диалога реализуем систему контекстных подсказок, которая будет предлагать пользователям релевантные команды и действия на основе текущего состояния беседы:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class ContextualSuggestions:
    def __init__(self):
        self.suggestion_patterns = {
            'question': ['Возможно, вам также будет интересно...', 'Похожие вопросы:'],
            'error': ['Попробуйте следующие решения:', 'Распространенные способы исправления:'],
            'request': ['Дополнительные возможности:', 'Вы также можете:']
        }
        
    def get_suggestions(self, message: str, context: dict) -> List[str]:
        message_type = self.determine_message_type(message)
        base_suggestions = self.suggestion_patterns.get(message_type, [])
        
        context_based = self.generate_context_suggestions(context)
        return base_suggestions + context_based[:3]
Для обеспечения отказоустойчивости и восстановления после сбоев добавим систему резервного копирования и восстановления данных:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class BackupSystem:
    def __init__(self, backup_dir: str = 'backups'):
        self.backup_dir = backup_dir
        os.makedirs(backup_dir, exist_ok=True)
        
    def create_backup(self, data: dict, backup_type: str):
        timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
        filename = f"{backup_type}_{timestamp}.json"
        
        with open(os.path.join(self.backup_dir, filename), 'w') as f:
            json.dump(data, f, indent=4, default=str)
        
    def restore_from_backup(self, backup_type: str, timestamp: str = None):
        if timestamp:
            filename = f"{backup_type}_{timestamp}.json"
        else:
            # Получаем последний backup
            files = glob.glob(os.path.join(self.backup_dir, f"{backup_type}_*.json"))
            if not files:
                return None
            filename = max(files, key=os.path.getctime)
            
        with open(filename, 'r') as f:
            return json.load(f)
Реализуем систему мониторинга производительности, которая будет отслеживать различные метрики работы бота и предоставлять статистику:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class PerformanceMonitor:
    def __init__(self):
        self.metrics = {
            'response_times': [],
            'error_rates': defaultdict(int),
            'memory_usage': [],
            'api_calls': defaultdict(int)
        }
        
    def record_metric(self, metric_type: str, value: Any):
        if metric_type in self.metrics:
            if isinstance(self.metrics[metric_type], list):
                self.metrics[metric_type].append(value)
            else:
                self.metrics[metric_type][value] += 1
                
    def get_statistics(self) -> Dict:
        return {
            'avg_response_time': statistics.mean(self.metrics['response_times']),
            'error_distribution': dict(self.metrics['error_rates']),
            'memory_usage_trend': self.calculate_memory_trend(),
            'api_usage': dict(self.metrics['api_calls'])
        }
Для оптимизации работы с большими объемами данных добавим систему кэширования и управления памятью:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class CacheManager:
    def __init__(self, max_size: int = 1000):
        self.cache = TTLCache(maxsize=max_size, ttl=3600)
        self.stats = {
            'hits': 0,
            'misses': 0,
            'evictions': 0
        }
        
    def get(self, key: str) -> Any:
        try:
            value = self.cache[key]
            self.stats['hits'] += 1
            return value
        except KeyError:
            self.stats['misses'] += 1
            return None
            
    def set(self, key: str, value: Any):
        if len(self.cache) >= self.cache.maxsize:
            self.stats['evictions'] += 1
        self.cache[key] = value
Интегрируем все новые компоненты в основной класс бота и добавим соответствующие обработчики:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class ChatGPTBot:
    def __init__(self):
        # ... предыдущий код ...
        self.notifications = NotificationSystem()
        self.suggestions = ContextualSuggestions()
        self.backup = BackupSystem()
        self.performance = PerformanceMonitor()
        self.cache = CacheManager()
        
    async def process_message(self, update: Update, context: CallbackContext):
        start_time = time.time()
        user_id = update.effective_user.id
        message_text = update.message.text
        
        try:
            # Проверяем кэш
            cached_response = self.cache.get(message_text)
            if cached_response:
                await update.message.reply_text(cached_response)
                return
                
            # Получаем контекстные подсказки
            suggestions = self.suggestions.get_suggestions(
                message_text,
                context.user_data
            )
            
            # Обрабатываем сообщение
            response = await self.generate_response(message_text)
            
            # Кэшируем ответ
            self.cache.set(message_text, response)
            
            # Отправляем ответ с подсказками
            await update.message.reply_text(
                response,
                reply_markup=self.create_suggestion_keyboard(suggestions)
            )
            
        finally:
            # Записываем метрики производительности
            self.performance.record_metric(
                'response_times',
                time.time() - start_time
            )

Финальная реализация



После создания всех необходимых компонентов бота приступим к финальной реализации, где соберем все части воедино и создадим полноценное работающее приложение. Начнем с создания основного файла `main.py`, который будет содержать точку входа в программу и инициализацию всех компонентов системы.

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters
from telegram import Update, ParseMode
import logging
import os
from dotenv import load_dotenv
from pathlib import Path
 
# Загрузка переменных окружения
load_dotenv()
TELEGRAM_TOKEN = os.getenv('TELEGRAM_TOKEN')
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
 
class TelegramGPTBot:
    def __init__(self):
        self.updater = Updater(TELEGRAM_TOKEN, use_context=True)
        self.dispatcher = self.updater.dispatcher
        self.setup_logging()
        self.setup_handlers()
        
    def setup_logging(self):
        logging.basicConfig(
            format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
            level=logging.INFO,
            handlers=[
                logging.FileHandler('bot.log'),
                logging.StreamHandler()
            ]
        )
        self.logger = logging.getLogger(__name__)
        
    def setup_handlers(self):
        self.dispatcher.add_handler(CommandHandler("start", self.start_command))
        self.dispatcher.add_handler(CommandHandler("help", self.help_command))
        self.dispatcher.add_handler(MessageHandler(
            Filters.text & ~Filters.command, 
            self.handle_message
        ))
        self.dispatcher.add_error_handler(self.error_handler)
Создадим основной класс для работы с ChatGPT API, который будет отвечать за генерацию ответов:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import openai
from typing import List, Dict
 
class ChatGPTHandler:
    def __init__(self, api_key: str):
        openai.api_key = api_key
        self.model = "gpt-3.5-turbo"
        
    async def generate_response(self, messages: List[Dict]) -> str:
        try:
            response = await openai.ChatCompletion.acreate(
                model=self.model,
                messages=messages,
                max_tokens=1000,
                temperature=0.7
            )
            return response.choices[0].message.content
        except Exception as e:
            logging.error(f"Ошибка при генерации ответа: {str(e)}")
            raise
Реализуем класс для управления сессиями пользователей, который будет хранить контекст беседы и настройки:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class UserSession:
    def __init__(self):
        self.conversation_history = []
        self.settings = {
            'max_tokens': 1000,
            'temperature': 0.7,
            'language': 'ru'
        }
        
    def add_message(self, role: str, content: str):
        self.conversation_history.append({
            'role': role,
            'content': content
        })
        
    def get_context(self, max_messages: int = 5) -> List[Dict]:
        return self.conversation_history[-max_messages:]
Добавим основные обработчики команд и сообщений в класс бота:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
from telegram.ext import CallbackContext
 
class TelegramGPTBot:
    async def start_command(self, update: Update, context: CallbackContext):
        welcome_message = """
        Привет! Я бот на базе ChatGPT.
        
        Я могу помочь вам с различными задачами:
        • Ответить на вопросы
        • Помочь с программированием
        • Объяснить сложные концепции
        • Генерировать идеи
        
        Просто напишите мне сообщение, и я постараюсь помочь!
        """
        await update.message.reply_text(welcome_message, parse_mode=ParseMode.MARKDOWN)
        
    async def help_command(self, update: Update, context: CallbackContext):
        help_message = """
        *Доступные команды:*
        /start - Начать диалог
        /help - Показать это сообщение
        /clear - Очистить историю диалога
        /settings - Настройки бота
        """
        await update.message.reply_text(help_message, parse_mode=ParseMode.MARKDOWN)
        
    async def handle_message(self, update: Update, context: CallbackContext):
        user_id = update.effective_user.id
        message_text = update.message.text
        
        # Получаем или создаем сессию пользователя
        if not hasattr(context.user_data, 'session'):
            context.user_data.session = UserSession()
            
        session = context.user_data.session
        
        try:
            # Добавляем сообщение пользователя в историю
            session.add_message('user', message_text)
            
            # Генерируем ответ
            messages = session.get_context()
            response = await self.chatgpt.generate_response(messages)
            
            # Сохраняем ответ в истории
            session.add_message('assistant', response)
            
            # Отправляем ответ пользователю
            await update.message.reply_text(response)
            
        except Exception as e:
            self.logger.error(f"Ошибка при обработке сообщения: {str(e)}")
            await update.message.reply_text(
                "Произошла ошибка при обработке вашего сообщения. "
                "Пожалуйста, попробуйте позже."
            )
Добавим обработку ошибок и систему восстановления после сбоев:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class TelegramGPTBot:
    async def error_handler(self, update: Update, context: CallbackContext):
        self.logger.error(f"Update {update} caused error {context.error}")
        
        error_message = """
        Произошла ошибка при обработке запроса.
        
        Пожалуйста, попробуйте:
        1. Отправить сообщение позже
        2. Использовать команду /clear для очистки истории
        3. Перезапустить диалог командой /start
        """
        
        if update and update.effective_message:
            await update.effective_message.reply_text(
                error_message,
                parse_mode=ParseMode.MARKDOWN
            )
Создадим функцию для запуска бота и обработки завершения работы:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import signal
import sys
 
def signal_handler(signum, frame):
    print("\nПолучен сигнал завершения. Останавливаем бота...")
    bot.updater.stop()
    sys.exit(0)
 
if __name__ == '__main__':
    # Регистрируем обработчик сигналов
    signal.signal(signal.SIGINT, signal_handler)
    signal.signal(signal.SIGTERM, signal_handler)
    
    # Создаем и запускаем бота
    bot = TelegramGPTBot()
    
    print("Бот запущен и готов к работе!")
    bot.updater.start_polling()
    bot.updater.idle()
В результате мы получили полностью функционального Telegram-бота, интегрированного с ChatGPT API. Бот способен поддерживать диалог с пользователями, сохранять контекст беседы и обрабатывать различные команды. При этом реализована система обработки ошибок и восстановления после сбоев, что делает бота надежным и устойчивым к различным проблемам.

Для обеспечения удобства развертывания и обновления бота создадим скрипт `deploy.py`, который будет автоматизировать процесс установки и настройки:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import subprocess
import sys
import os
 
def setup_environment():
    print("Настройка виртуального окружения...")
    subprocess.run([sys.executable, "-m", "venv", "venv"])
    
    if os.name == 'nt':  # Windows
        activate_script = "venv\\Scripts\\activate"
    else:  # Unix
        activate_script = "source venv/bin/activate"
    
    subprocess.run(activate_script, shell=True)
    subprocess.run(["pip", "install", "-r", "requirements.txt"])
 
def check_dependencies():
    print("Проверка зависимостей...")
    try:
        import telegram
        import openai
        print("Все необходимые зависимости установлены")
        return True
    except ImportError as e:
        print(f"Ошибка: {str(e)}")
        return False
 
if __name__ == "__main__":
    setup_environment()
    if check_dependencies():
        print("Установка завершена успешно")
Для упрощения процесса обновления бота создадим файл `update.sh` (для Unix-систем) и `update.bat` (для Windows):

Bash
1
2
3
4
5
6
#!/bin/bash
# update.sh
git pull
source venv/bin/activate
pip install -r requirements.txt
systemctl restart telegram_gpt_bot
Windows Batch file
1
2
3
4
5
6
7
@echo off
REM update.bat
git pull
call venv\Scripts\activate
pip install -r requirements.txt
net stop TelegramGPTBot
net start TelegramGPTBot
Также обязательно создадим файл `README.md` с подробной документацией по установке и использованию бота:

Код
# ChatGPT Telegram Bot

## Установка

1. Клонируйте репозиторий
2. Создайте файл .env с необходимыми переменными окружения
3. Запустите скрипт установки: python deploy.py
4. Запустите бота: python main.py

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

- TELEGRAM_TOKEN - токен вашего Telegram бота
- OPENAI_API_KEY - ключ API OpenAI
- DEBUG - режим отладки (true/false)

## Использование

Бот поддерживает следующие команды:
- /start - начать диалог
- /help - показать справку
- /clear - очистить историю
- /settings - настройки бота
Финальная структура проекта будет выглядеть следующим образом:

Код
chatgpt_bot/
├── main.py           # Основной файл бота
├── config.py         # Конфигурация
├── handlers/         # Обработчики команд
├── services/         # Сервисные классы
├── utils/           # Вспомогательные функции
├── tests/           # Модульные тесты
├── deploy.py        # Скрипт установки
├── update.sh        # Скрипт обновления (Unix)
├── update.bat       # Скрипт обновления (Windows)
├── requirements.txt # Зависимости
├── .env            # Переменные окружения
└── README.md       # Документация
Для мониторинга работы бота в продакшене рекомендуется настроить систему логирования с использованием специализированных сервисов или локального хранения логов. Создадим конфигурацию для логирования в файл `logging_config.py`:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import logging
from logging.handlers import RotatingFileHandler
 
def setup_logging():
    logger = logging.getLogger('telegram_gpt_bot')
    logger.setLevel(logging.INFO)
    
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    )
    
    file_handler = RotatingFileHandler(
        'logs/bot.log',
        maxBytes=1024*1024,  # 1MB
        backupCount=5
    )
    file_handler.setFormatter(formatter)
    logger.addHandler(file_handler)
    
    return logger

Проблема с запуском Telegram бота на Python
Пытаюсь написать примитивного бота с использованием pyTelegramBotAPI, но при компиляции вылезает куча ошибок, и все сводятся к тому, что: ...

С чего начать при написании бота в telegram На python?
Здравствуйте! Я хочу понять, с чего стоит начинать изучать написание телеграм-ботов на питон? Я выучил основы питона + некоторые фреймворки, хотелось...

Написал простенького бота (telegram) на python`e . Не работает на ubuntu server
своя OC - ubuntu 18.10 OC на сервере - Ubuntu 18.04 (LTS) x64 (DigitalOcean) Написал простенького бота на python`e который отправляет им...

Как создать inline клавиатуру для бота в ВК на python?
Помогите, пожалуйста. Если кто знает, как сделать inline keyboard через vk_api longpoll на Python, напишите код.

Ошибка "несуществующей клавиши" для бота Telegram на python
Проблема следующая, я в python не селён, но пару раз писал ботов для Telegram. А тут у меня вдруг ошибка - ERROR - TeleBot: &quot;A request to the...

Как удалить секунды из видео (chatgpt, python)
chatgpt. Изначально был .bat/ffmpeg, но варианты не работают, тогда я спросил на каком языке программирования ты можешь написать такой код, он выбрал...

Как развернуть Telegram бота на сервере?
Я написал start.sh и добавил его в автозапуск #!/bin/bash source /root/TeleBot/bin/activate cd /root/TeleBot/Bot/ python TeleBot.py...

Как добавить гиперссылку в кнопку Telegram бота?
Здравствуйте! Имеется небольшой код на Python, используется TelegramBotAPI (telebot) import telebot from telebot import types bot =...

Как сделать Telegram бота, пересылающего сообщения?
Добрый день. Сориентируйте, пожалуйста, как можно реализовать telegram-бота, получающего сообщения по API и пересылающего их в те каналы, где он...

Как интегрировать telegram бота благодаря коду из GitHub
Здравствуйте, уважаемые знатоки) По работе столкнулся с потребностью вести общий бюджет с несколькими людьми, и решил поискать решение в интернете....

Как написать бота для Telegram, который будет отсылать предупреждение
Здравствуйте, у меня вопрос: как написать бота для Telegram, который будет отсылать предупреждение &quot;Отправляйте голосовые сообщения!&quot; 3...

Как удалить сообщение от Telegram бота (aiorgam) через какое-то определённое время?
Например удалить вот такое сообщение через 24 часа: await bot.send_message(message.from_user.id, &quot;Это сообщение будет удалено через 24 часа&quot;,...

Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 0
Комментарии
 
Новые блоги и статьи
Ошибка "Cleartext HTTP traffic not permitted" в Android
hw_wired 13.02.2025
При разработке Android-приложений можно столнуться с неприятной ошибкой "Cleartext HTTP traffic not permitted", которая может серьезно затруднить отладку и тестирование. Эта проблема особенно. . .
Изменение версии по умолчанию в NVM
hw_wired 13.02.2025
Node Version Manager, или коротко NVM - незаменимый инструмент для разработчиков, использующих Node. js. Многие сталкивались с ситуацией, когда разные проекты требуют различных версий Node. js,. . .
Переименование коммита в Git (локального и удаленного)
hw_wired 13.02.2025
Git как система контроля версий предоставляет разработчикам множество средств для управления этой историей, и одним из таких важных средств является возможность изменения сообщений коммитов. Но зачем. . .
Отличия Promise и Observable в Angular
hw_wired 13.02.2025
В веб-разработки асинхронные операции стали неотъемлимой частью почти каждого приложения. Ведь согласитесь, было бы странно, если бы при каждом запросе к серверу или при обработке больших объемов. . .
Сравнение NPM, Gulp, Webpack, Bower, Grunt и Browserify
hw_wired 13.02.2025
В современной веб-разработке существует множество средств сборки и управления зависимостями проектов, каждое из которых решает определенные задачи и имеет свои особенности. Когда я начинаю новый. . .
Отличия AddTransient, AddScoped и AddSingleton в ASP.Net Core DI
hw_wired 13.02.2025
В современной разработке веб-приложений на платформе ASP. NET Core правильное управление зависимостями играет ключевую роль в создании надежного и производительного кода. Фреймворк предоставляет три. . .
Отличия между venv, pyenv, pyvenv, virtualenv, pipenv, conda, virtualenvwrapp­­er, poetry и другими в Python
hw_wired 13.02.2025
В Python существует множество средств для управления зависимостями и виртуальными окружениями, что порой вызывает замешательство даже у опытных разработчиков. Каждый инструмент создавался для решения. . .
Навигация с помощью React Router
hw_wired 13.02.2025
React Router - это наиболее распространенное средство для создания навигации в React-приложениях, без которого сложно представить современную веб-разработку. Когда мы разрабатываем сложное. . .
Ошибка "error:0308010C­­:dig­ital envelope routines::unsup­­ported"
hw_wired 13.02.2025
Если вы сталкиваетесь с ошибкой "error:0308010C:digital envelope routines::unsupported" при разработке Node. js приложений, то наверняка уже успели поломать голову над её решением. Эта коварная ошибка. . .
Подключение к контейнеру Docker и работа с его содержимым
hw_wired 13.02.2025
В мире современной разработки контейнеры Docker изменили подход к созданию, развертыванию и масштабированию приложений. Эта технология позволяет упаковать приложение со всеми его зависимостями в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru