import asyncio from vkbottle.bot import Bot, Message, MessageEvent from vkbottle import Keyboard, Text from vkbottle_types.events import GroupEventType from config import Token, SYNC_ADMINS from database.init_db import init_db from menus.engine import show_menu from handlers.menu import handle_menu from handlers.fallback import handle_fallback, handle_tech_feedback_event from services.sync_google import sync_all from services.log_export import log_message, export_chatlog_and_freq from services.instructions import handle_pause_response, handle_pause_event # ─── INIT ──────────────────────────────────────────────── bot = Bot(token=Token) # ─── START / MAIN MENU ─────────────────────────────────── @bot.on.message(text=["Начать", "начать", "Старт", "Главное меню"]) async def start_handler(message: Message): await message.answer( "👋 Привет! Кратко опишите проблему в одном сообщении — я попробую найти инструкцию.\n" "🔗 Полезные ссылки доступны в меню «Важные ссылки»." ) await show_menu(message, "main") # ─── SYNC COMMAND (ADMIN) ──────────────────────────────── @bot.on.message(text=["синхра", "sync", "/sync"]) async def sync_handler(message: Message): if message.from_id not in SYNC_ADMINS: await message.answer("⛔ Нет доступа к синхронизации.") return await message.answer("🔄 Запускаю синхронизацию...") try: await asyncio.to_thread(sync_all) await message.answer("✅ Данные успешно обновлены") except Exception as e: await message.answer(f"❌ Ошибка синхронизации:\n{e}") @bot.on.message(text=["/export_logs", "export_logs"]) async def export_logs_handler(message: Message): if message.from_id not in SYNC_ADMINS: await message.answer("⛔ Нет доступа к экпорту логов.") return await message.answer("🔄 Запускаю экпорт логов...") try: await asyncio.to_thread(export_chatlog_and_freq) await message.answer("✅ Экспорт логов успешен") except Exception as e: await message.answer(f"❌ Ошибка экспорта:\n{e}") # ─── MENU HANDLER ──────────────────────────────────────── @bot.on.message() async def menu_handler(message: Message): print("➡ handler got:", message.text) cmd_text = (message.text or "").strip().lower() if cmd_text in ['/export_logs', '/sync', 'export_logs', 'sync']: return if not message.text and getattr(message, "attachments", None): await message.answer( "⚠️ Я пока не умею работать с голосовыми, " "изображениями, кружками и видео. " "Опишите проблему текстом." ) return if message.text: log_message(message.from_id, message.text) if await handle_pause_response(message): return handled = await handle_menu(message) print("➡ handled:", handled) if handled: return await handle_fallback(message) @bot.on.raw_event(GroupEventType.MESSAGE_EVENT, MessageEvent) async def pause_event_handler(event: MessageEvent): payload = event.get_payload_json() if payload and payload.get("pause") in ("yes", "no"): if event.conversation_message_id is not None: await event.ctx_api.messages.delete( peer_id=event.peer_id, conversation_message_ids=[event.conversation_message_id], delete_for_all=1 ) await handle_pause_event(event) await event.send_empty_answer() return if payload and payload.get("tech_feedback") in ("yes", "no"): if event.conversation_message_id is not None: await event.ctx_api.messages.delete( peer_id=event.peer_id, conversation_message_ids=[event.conversation_message_id], delete_for_all=1 ) await handle_tech_feedback_event(event) await event.send_empty_answer() # ─── RUN ───────────────────────────────────────────────── if __name__ == "__main__": init_db() print("🤖 Bot started") bot.run_forever()