110 lines
3.7 KiB
Python
110 lines
3.7 KiB
Python
# adapter/telegram/bot.py
|
|
from __future__ import annotations
|
|
|
|
import asyncio
|
|
import os
|
|
|
|
import structlog
|
|
from aiogram import Bot, Dispatcher
|
|
from aiogram.fsm.storage.memory import MemoryStorage
|
|
from aiogram.types import BotCommand
|
|
|
|
from adapter.telegram import db
|
|
from adapter.telegram.handlers import auth, chat, confirm, forum, settings
|
|
from core.auth import AuthManager
|
|
from core.chat import ChatManager
|
|
from core.handler import EventDispatcher
|
|
from core.handlers.callback import handle_confirm as core_handle_confirm
|
|
from core.handlers.chat import handle_archive, handle_list_chats, handle_new_chat, handle_rename
|
|
from core.handlers.message import handle_message
|
|
from core.handlers.settings import (
|
|
handle_settings,
|
|
handle_settings_skills,
|
|
)
|
|
from core.handlers.start import handle_start
|
|
from core.settings import SettingsManager
|
|
from core.store import InMemoryStore
|
|
from sdk.mock import MockPlatformClient
|
|
|
|
logger = structlog.get_logger(__name__)
|
|
|
|
|
|
class DispatcherMiddleware:
|
|
"""Injects EventDispatcher into every handler via data dict."""
|
|
|
|
def __init__(self, dispatcher: EventDispatcher) -> None:
|
|
self._dispatcher = dispatcher
|
|
|
|
async def __call__(self, handler, event, data):
|
|
data["dispatcher"] = self._dispatcher
|
|
return await handler(event, data)
|
|
|
|
|
|
def build_event_dispatcher(platform: MockPlatformClient) -> EventDispatcher:
|
|
store = InMemoryStore()
|
|
chat_mgr = ChatManager(platform, store)
|
|
auth_mgr = AuthManager(platform, store)
|
|
settings_mgr = SettingsManager(platform, store)
|
|
|
|
ed = EventDispatcher(
|
|
platform=platform,
|
|
chat_mgr=chat_mgr,
|
|
auth_mgr=auth_mgr,
|
|
settings_mgr=settings_mgr,
|
|
)
|
|
|
|
# Register core handlers
|
|
from core.protocol import IncomingCallback, IncomingCommand, IncomingMessage
|
|
ed.register(IncomingCommand, "start", handle_start)
|
|
ed.register(IncomingCommand, "settings", handle_settings)
|
|
ed.register(IncomingCommand, "settings_skills", handle_settings_skills)
|
|
ed.register(IncomingCommand, "new", handle_new_chat)
|
|
ed.register(IncomingCommand, "chats", handle_list_chats)
|
|
ed.register(IncomingCommand, "rename", handle_rename)
|
|
ed.register(IncomingCommand, "archive", handle_archive)
|
|
ed.register(IncomingMessage, "*", handle_message)
|
|
ed.register(IncomingCallback, "confirm", core_handle_confirm)
|
|
ed.register(IncomingCallback, "cancel", core_handle_confirm)
|
|
|
|
return ed
|
|
|
|
|
|
async def main() -> None:
|
|
token = os.environ.get("BOT_TOKEN")
|
|
if not token:
|
|
raise RuntimeError("BOT_TOKEN env variable is not set")
|
|
|
|
db.init_db()
|
|
|
|
bot = Bot(token=token)
|
|
storage = MemoryStorage()
|
|
dp = Dispatcher(storage=storage)
|
|
|
|
platform = MockPlatformClient()
|
|
event_dispatcher = build_event_dispatcher(platform)
|
|
|
|
# Register middleware on all update types
|
|
dp.message.middleware(DispatcherMiddleware(event_dispatcher))
|
|
dp.callback_query.middleware(DispatcherMiddleware(event_dispatcher))
|
|
|
|
# Include routers
|
|
dp.include_router(auth.router)
|
|
dp.include_router(forum.router)
|
|
dp.include_router(chat.router)
|
|
dp.include_router(settings.router)
|
|
dp.include_router(confirm.router)
|
|
|
|
await bot.set_my_commands([
|
|
BotCommand(command="start", description="Начать / восстановить сессию"),
|
|
BotCommand(command="new", description="Создать новый чат"),
|
|
BotCommand(command="chats", description="Список чатов"),
|
|
BotCommand(command="settings", description="Настройки"),
|
|
BotCommand(command="forum", description="Подключить Forum-группу"),
|
|
])
|
|
|
|
logger.info("Bot starting")
|
|
await dp.start_polling(bot)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main())
|