diff --git a/tg_bot/infrastructure/telegram/bot.py b/tg_bot/infrastructure/telegram/bot.py index fee0fde..606c203 100644 --- a/tg_bot/infrastructure/telegram/bot.py +++ b/tg_bot/infrastructure/telegram/bot.py @@ -9,7 +9,8 @@ from tg_bot.infrastructure.telegram.handlers import ( help_handler, stats_handler, question_handler, - buy_handler + buy_handler, + collection_handler ) logger = logging.getLogger(__name__) @@ -26,6 +27,7 @@ async def create_bot() -> tuple[Bot, Dispatcher]: dp.include_router(stats_handler.router) dp.include_router(question_handler.router) dp.include_router(buy_handler.router) + dp.include_router(collection_handler.router) return bot, dp diff --git a/tg_bot/infrastructure/telegram/handlers/collection_handler.py b/tg_bot/infrastructure/telegram/handlers/collection_handler.py new file mode 100644 index 0000000..8f270ae --- /dev/null +++ b/tg_bot/infrastructure/telegram/handlers/collection_handler.py @@ -0,0 +1,183 @@ +from aiogram import Router +from aiogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery +from aiogram.filters import Command +import aiohttp + +router = Router() + +BACKEND_URL = "http://localhost:8001/api/v1" + + +async def get_user_collections(telegram_id: str): + try: + async with aiohttp.ClientSession() as session: + async with session.get( + f"{BACKEND_URL}/collections/", + headers={"X-Telegram-ID": telegram_id} + ) as response: + if response.status == 200: + return await response.json() + return [] + except Exception as e: + print(f"Error getting collections: {e}") + return [] + + +async def get_collection_documents(collection_id: str, telegram_id: str): + try: + async with aiohttp.ClientSession() as session: + async with session.get( + f"{BACKEND_URL}/documents/collection/{collection_id}", + headers={"X-Telegram-ID": telegram_id} + ) as response: + if response.status == 200: + return await response.json() + return [] + except Exception as e: + print(f"Error getting documents: {e}") + return [] + + +async def search_in_collection(collection_id: str, query: str, telegram_id: str): + try: + async with aiohttp.ClientSession() as session: + async with session.get( + f"{BACKEND_URL}/documents/collection/{collection_id}", + params={"search": query}, + headers={"X-Telegram-ID": telegram_id} + ) as response: + if response.status == 200: + return await response.json() + return [] + except Exception as e: + print(f"Error searching: {e}") + return [] + + +@router.message(Command("mycollections")) +async def cmd_mycollections(message: Message): + telegram_id = str(message.from_user.id) + collections = await get_user_collections(telegram_id) + + if not collections: + await message.answer( + "У вас пока нет коллекций\n\n" + "Обратитесь к администратору для создания коллекций и добавления документов.", + parse_mode="HTML" + ) + return + + response = "Ваши коллекции документов:\n\n" + keyboard_buttons = [] + + for i, collection in enumerate(collections[:10], 1): + name = collection.get("name", "Без названия") + description = collection.get("description", "") + collection_id = collection.get("collection_id") + + response += f"{i}. {name}\n" + if description: + response += f" {description[:50]}...\n" + response += f" ID: {collection_id}\n\n" + + keyboard_buttons.append([ + InlineKeyboardButton( + text=f"{name}", + callback_data=f"collection:{collection_id}" + ) + ]) + + keyboard = InlineKeyboardMarkup(inline_keyboard=keyboard_buttons) + + response += "Нажмите на коллекцию, чтобы посмотреть документы" + + await message.answer(response, parse_mode="HTML", reply_markup=keyboard) + + +@router.message(Command("search")) +async def cmd_search(message: Message): + parts = message.text.split(maxsplit=2) + if len(parts) < 3: + telegram_id = str(message.from_user.id) + collections = await get_user_collections(telegram_id) + + if not collections: + await message.answer( + "Использование: /search <collection_id> <запрос>\n\n" + "У вас пока нет коллекций. Обратитесь к администратору.", + parse_mode="HTML" + ) + return + + response = "Выберите коллекцию для поиска:\n\n" + response += "Использование: /search <collection_id> <запрос>\n\n" + response += "Доступные коллекции:\n" + for collection in collections[:5]: + name = collection.get("name", "Без названия") + collection_id = collection.get("collection_id") + response += f"• {name}\n {collection_id}\n\n" + response += "Пример: /search " + collections[0].get("collection_id", "")[:8] + "... Как оформить договор?" + + await message.answer(response, parse_mode="HTML") + return + + collection_id = parts[1] + query = parts[2] + telegram_id = str(message.from_user.id) + + await message.bot.send_chat_action(message.chat.id, "typing") + + results = await search_in_collection(collection_id, query, telegram_id) + + if not results: + await message.answer( + f"Ничего не найдено\n\n" + f"По запросу \"{query}\" в коллекции ничего не найдено.\n\n" + f"Попробуйте другой запрос или используйте /mycollections для просмотра доступных коллекций.", + parse_mode="HTML" + ) + return + + response = f"Результаты поиска: \"{query}\"\n\n" + for i, doc in enumerate(results[:5], 1): + title = doc.get("title", "Без названия") + content = doc.get("content", "")[:200] + response += f"{i}. {title}\n" + response += f" {content}...\n\n" + + await message.answer(response, parse_mode="HTML") + + +@router.callback_query(lambda c: c.data.startswith("collection:")) +async def show_collection_documents(callback: CallbackQuery): + collection_id = callback.data.split(":")[1] + telegram_id = str(callback.from_user.id) + + await callback.answer("Загружаю документы...") + + documents = await get_collection_documents(collection_id, telegram_id) + + if not documents: + await callback.message.answer( + f"Коллекция пуста\n\n" + f"В этой коллекции пока нет документов.\n" + f"Обратитесь к администратору для добавления документов.", + parse_mode="HTML" + ) + return + + response = f"Документы в коллекции:\n\n" + for i, doc in enumerate(documents[:10], 1): + title = doc.get("title", "Без названия") + content_preview = doc.get("content", "")[:100] + response += f"{i}. {title}\n" + if content_preview: + response += f" {content_preview}...\n" + response += "\n" + + if len(documents) > 10: + response += f"\nПоказано 10 из {len(documents)} документов" + + await callback.message.answer(response, parse_mode="HTML") + +