В современном мире технологии искусственного интеллекта становятся все более доступными для разработчиков, открывая новые возможности для создания умных и интерактивных приложений. Одним из самых популярных инструментов в этой области является 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: "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, который будет отсылать предупреждение "Отправляйте голосовые сообщения!" 3... Как удалить сообщение от Telegram бота (aiorgam) через какое-то определённое время? Например удалить вот такое сообщение через 24 часа:
await bot.send_message(message.from_user.id, "Это сообщение будет удалено через 24 часа",...
|