from aiogram import Router, types
from aiogram.types import Message
from tg_bot.config.settings import settings
from tg_bot.domain.user_service import UserService, User
from tg_bot.application.services.rag_service import RAGService
import re
router = Router()
rag_service = RAGService()
user_service = UserService()
@router.message()
async def handle_question(message: Message):
user_id = message.from_user.id
question_text = message.text.strip()
if question_text.startswith('/'):
return
try:
user = await user_service.get_user_by_telegram_id(user_id)
if not user:
user = await user_service.get_or_create_user(
user_id,
message.from_user.username or "",
message.from_user.first_name or "",
message.from_user.last_name or ""
)
if user.is_premium:
await process_premium_question(message, user, question_text)
elif user.questions_used < settings.FREE_QUESTIONS_LIMIT:
await process_free_question(message, user, question_text)
else:
await handle_limit_exceeded(message, user)
except Exception as e:
print(f"Error processing question: {e}")
await message.answer(
"Произошла ошибка. Попробуйте позже.",
parse_mode="HTML"
)
async def process_premium_question(message: Message, user: User, question_text: str):
await user_service.update_user_questions(int(user.telegram_id))
user = await user_service.get_user_by_telegram_id(int(user.telegram_id))
await message.bot.send_chat_action(message.chat.id, "typing")
try:
rag_result = await rag_service.generate_answer_with_rag(
question_text,
str(message.from_user.id)
)
answer = rag_result.get("answer", "Извините, не удалось сгенерировать ответ.")
sources = rag_result.get("sources", [])
# Беседа уже сохранена в бэкенде через API /rag/question
import re
formatted_answer = answer
formatted_answer = re.sub(r'\*\*(.+?)\*\*', r'\1', formatted_answer)
formatted_answer = re.sub(r'^(\d+)\.\s+', r'\1. ', formatted_answer, flags=re.MULTILINE)
formatted_answer = formatted_answer.replace("- ", "• ")
response = (
f"Ваш вопрос:\n"
f"{question_text[:200]}\n\n"
f"━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n"
f"💬 Ответ:\n\n"
f"{formatted_answer}\n\n"
)
if sources:
response += f"━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n"
response += f"📚 Источники:\n"
for idx, source in enumerate(sources[:5], 1):
title = source.get('title', 'Без названия')
try:
from urllib.parse import unquote
decoded = unquote(title)
if decoded != title or '%' in title:
title = decoded
except:
pass
response += f" {idx}. {title}\n"
response += "\n💡 Используйте /mycollections для просмотра всех коллекций\n\n"
response += (
f"━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n"
f"✨ Статус: Premium (вопросов безлимитно)\n"
f"📊 Всего вопросов: {user.questions_used}"
)
except Exception as e:
print(f"Error generating answer: {e}")
response = (
f"Ваш вопрос:\n"
f"{question_text[:200]}\n\n"
f"━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n"
f"❌ Ошибка при генерации ответа.\n"
f"Попробуйте позже.\n\n"
f"━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n"
f"✨ Статус: Premium\n"
f"📊 Всего вопросов: {user.questions_used}"
)
await message.answer(response, parse_mode="HTML")
async def process_free_question(message: Message, user: User, question_text: str):
await user_service.update_user_questions(int(user.telegram_id))
user = await user_service.get_user_by_telegram_id(int(user.telegram_id))
remaining = settings.FREE_QUESTIONS_LIMIT - user.questions_used
await message.bot.send_chat_action(message.chat.id, "typing")
try:
rag_result = await rag_service.generate_answer_with_rag(
question_text,
str(message.from_user.id)
)
answer = rag_result.get("answer", "Извините, не удалось сгенерировать ответ.")
sources = rag_result.get("sources", [])
# Уже все сохранили через /rag/question
formatted_answer = answer
formatted_answer = re.sub(r'\*\*(.+?)\*\*', r'\1', formatted_answer)
formatted_answer = re.sub(r'^(\d+)\.\s+', r'\1. ', formatted_answer, flags=re.MULTILINE)
formatted_answer = formatted_answer.replace("- ", "• ")
response = (
f"Ваш вопрос:\n"
f"{question_text[:200]}\n\n"
f"━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n"
f"💬 Ответ:\n\n"
f"{formatted_answer}\n\n"
)
if sources:
response += f"━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n"
response += f"📚 Источники:\n"
for idx, source in enumerate(sources[:5], 1):
title = source.get('title', 'Без названия')
try:
from urllib.parse import unquote
decoded = unquote(title)
if decoded != title or '%' in title:
title = decoded
except:
pass
response += f" {idx}. {title}\n"
response += "\n💡 Используйте /mycollections для просмотра всех коллекций\n\n"
response += (
f"━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n"
f"📊 Статус: Бесплатный доступ\n"
f"📈 Использовано вопросов: {user.questions_used}/{settings.FREE_QUESTIONS_LIMIT}\n"
f"🎯 Осталось бесплатных: {remaining}\n\n"
)
if remaining <= 3 and remaining > 0:
response += f"⚠️ Осталось мало вопросов! Для продолжения используйте /buy\n\n"
response += f"💎 Для безлимитного доступа: /buy"
except Exception as e:
print(f"Error generating answer: {e}")
response = (
f"Ваш вопрос:\n"
f"{question_text[:200]}\n\n"
f"━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n"
f"❌ Ошибка при генерации ответа.\n"
f"Попробуйте позже.\n\n"
f"━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n"
f"📊 Статус: Бесплатный доступ\n"
f"📈 Использовано вопросов: {user.questions_used}/{settings.FREE_QUESTIONS_LIMIT}\n"
f"🎯 Осталось бесплатных: {remaining}\n\n"
f"💎 Для безлимитного доступа: /buy"
)
await message.answer(response, parse_mode="HTML")
#Сново сохраняется в /rag/question
async def handle_limit_exceeded(message: Message, user: User):
response = (
f"Лимит бесплатных вопросов исчерпан!\n\n"
f"Ваша статистика:\n"
f"• Использовано вопросов: {user.questions_used}\n"
f"• Бесплатный лимит: {settings.FREE_QUESTIONS_LIMIT}\n\n"
f"Что делать дальше?\n"
f"1. Купите подписку командой /buy\n"
f"2. Получите неограниченный доступ к вопросам\n"
f"3. Продолжайте использовать бот без ограничений\n\n"
f"Подписка включает:\n"
f"• Неограниченное количество вопросов\n"
f"• Приоритетную обработку\n"
f"• Доступ ко всем функциям\n\n"
f"Нажмите /buy чтобы продолжить"
)
await message.answer(response, parse_mode="HTML")