Files
ai-char-bot/main.py
2026-02-03 14:20:22 +03:00

108 lines
4.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import asyncio
import logging
import os
from aiogram import Bot, Dispatcher, Router, F
from aiogram.client.default import DefaultBotProperties
from aiogram.enums import ParseMode
from aiogram.filters import CommandStart, Command, CommandObject
from aiogram.types import Message, BufferedInputFile
from aiogram.fsm.storage.mongo import MongoStorage
from dotenv import load_dotenv
from motor.motor_asyncio import AsyncIOMotorClient
# Импорты
from adapters.google_adapter import GoogleAdapter
from middlewares.album import AlbumMiddleware
from middlewares.auth import AuthMiddleware
from middlewares.dao import DaoMiddleware
from repos.char_repo import CharacterRepo
from repos.dao import DAO
from repos.user_repo import UsersRepo
from routers import char_router
# ВАЖНО: Импортируем роутер с логикой кнопок, а не создаем пустой
from routers.auth_router import router as auth_router
from routers.gen_router import router as gen_router
from routers.char_router import router as char_router
from routers.assets_router import router as assets_router
load_dotenv()
# Настройки
BOT_TOKEN = os.getenv("BOT_TOKEN")
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
MONGO_HOST = os.getenv("MONGO_HOST")
ADMIN_ID = int(os.getenv("ADMIN_ID")) # Сразу преобразуем в int
# Инициализация
bot = Bot(token=BOT_TOKEN, default=DefaultBotProperties(parse_mode=ParseMode.HTML))
# БД
mongo_client = AsyncIOMotorClient(MONGO_HOST)
users_repo = UsersRepo(mongo_client)
char_repo = CharacterRepo(mongo_client)
# Dispatcher
# Если MongoStorage пока не настроен на authSource=admin, можно временно убрать storage=...
dp = Dispatcher(storage=MongoStorage(mongo_client))
# ВНЕДРЕНИЕ ЗАВИСИМОСТЕЙ (чтобы они были доступны в хендлерах)
dp["repo"] = users_repo
dp["admin_id"] = ADMIN_ID
dp["gemini"] = GoogleAdapter(api_key=GEMINI_API_KEY) # Инициализируем тут
# РОУТИНГ
# 1. Роутер авторизации (кнопки) - ПОДКЛЮЧАЕМ ПЕРВЫМ И БЕЗ МИДЛВАРИ
dp.include_router(auth_router)
main_router = Router()
dp.include_router(main_router)
dp.include_router(assets_router)
dp.include_router(char_router)
dp.include_router(gen_router)
# 2. Основной роутер (чат с ботом)
# Вешаем защиту ТОЛЬКО на основной роутер
main_router.message.middleware(AuthMiddleware(repo=users_repo, admin_id=ADMIN_ID))
gen_router.message.middleware(AuthMiddleware(repo=users_repo, admin_id=ADMIN_ID))
gen_router.message.middleware(AlbumMiddleware(latency=0.8))
assets_router.message.middleware(AuthMiddleware(repo=users_repo, admin_id=ADMIN_ID))
dp.update.middleware(DaoMiddleware(dao=DAO(client=mongo_client)))
def setup_logging() -> None:
logging.basicConfig(level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s")
# --- ХЕНДЛЕРЫ ОСНОВНОГО РОУТЕРА ---
# Переносим их прямо сюда или в отдельный файл routers/chat_router.py
@main_router.message(Command("help"))
async def show_help(message: Message) -> None:
await message.answer("Для того, чтобы обратиться для текстовой генерации - просто отправь промпт.\n\n"
"Для генерации фото - /image {prompt}\n\n"
"Можно отправить фото и команду /image {prompt}\n\n"
"Диалоги не поддерживаются!!!! <b>Каждое новое сообщение - новый диалог</b>")
@main_router.message(CommandStart())
async def cmd_start(message: Message):
await message.answer("👋 Привет! Я готов к работе.\n\n"
"Для того, чтобы обратиться для текстовой генерации - просто отправь промпт.\n\n"
"Для генерации фото - /image {prompt}\n\n"
"Можно отправить фото и команду /image {prompt}\n\n"
"Диалоги не поддерживаются!!!! <b>Каждое новое сообщение - новый диалог</b>"
)
# --- ЗАПУСК ---
if __name__ == "__main__":
setup_logging()
try:
asyncio.run(dp.start_polling(bot))
except KeyboardInterrupt:
print("Bot stopped")