Replace single report type with composable analysis: depth levels (basic/standard/full) + focus area multi-select (psychology, business, marketing, content, audience, sentiment). Multi-step inline keyboard flow guides users through selection. - i18n: English + Russian, auto-detect from Telegram, /lang override - AI providers: Anthropic + OpenRouter via AIClient abstraction - Telegram Stars payments with per-depth pricing and free trial - SQLite (aiosqlite) for users, analyses, payments tracking - User middleware for auto-registration and language detection - Report persistence: save .md locally, offer file download - New commands: /features, /prices, /lang - Composable prompt system: depth modifiers + focus area fragments
41 lines
1.4 KiB
Python
41 lines
1.4 KiB
Python
from typing import Any, Awaitable, Callable
|
|
|
|
from aiogram import BaseMiddleware
|
|
from aiogram.types import TelegramObject, Update
|
|
|
|
from bot.db import user_repo
|
|
from bot.i18n import Lang, detect_lang
|
|
|
|
|
|
class UserMiddleware(BaseMiddleware):
|
|
async def __call__(
|
|
self,
|
|
handler: Callable[[TelegramObject, dict[str, Any]], Awaitable[Any]],
|
|
event: TelegramObject,
|
|
data: dict[str, Any],
|
|
) -> Any:
|
|
user = None
|
|
if isinstance(event, Update):
|
|
if event.message and event.message.from_user:
|
|
user = event.message.from_user
|
|
elif event.callback_query and event.callback_query.from_user:
|
|
user = event.callback_query.from_user
|
|
elif event.pre_checkout_query and event.pre_checkout_query.from_user:
|
|
user = event.pre_checkout_query.from_user
|
|
elif hasattr(event, "from_user") and event.from_user:
|
|
user = event.from_user
|
|
|
|
if user:
|
|
db_user = await user_repo.get_or_create(
|
|
telegram_id=user.id,
|
|
username=user.username,
|
|
first_name=user.first_name,
|
|
lang=detect_lang(user.language_code).value,
|
|
)
|
|
data["lang"] = Lang(db_user["lang"])
|
|
data["db_user"] = db_user
|
|
else:
|
|
data["lang"] = Lang.EN
|
|
data["db_user"] = None
|
|
|
|
return await handler(event, data)
|