54 lines
2.0 KiB
Python
54 lines
2.0 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Any, Awaitable, Callable
|
|
|
|
from aiogram import BaseMiddleware
|
|
from aiogram.types import CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup, Message, TelegramObject
|
|
|
|
from bot.clients.budget_api import YandexLoginRequired
|
|
|
|
YANDEX_REQUIRED_TEXT = """\
|
|
Чтобы пользоваться ботом, войдите через Яндекс.
|
|
|
|
Так Telegram, сайт и приложение — один аккаунт, и бюджеты не потеряются.
|
|
|
|
Откройте ссылку, примите документы и нажмите «Войти через Яндекс». Потом вернитесь в бот и напишите /start.
|
|
"""
|
|
|
|
|
|
def yandex_login_keyboard(login_url: str) -> InlineKeyboardMarkup | None:
|
|
url = (login_url or "").strip()
|
|
if not url.startswith(("https://", "http://")):
|
|
return None
|
|
return InlineKeyboardMarkup(
|
|
inline_keyboard=[[InlineKeyboardButton(text="Войти через Яндекс", url=url)]]
|
|
)
|
|
|
|
|
|
class YandexLoginGateMiddleware(BaseMiddleware):
|
|
async def __call__(
|
|
self,
|
|
handler: Callable[[TelegramObject, dict[str, Any]], Awaitable[Any]],
|
|
event: TelegramObject,
|
|
data: dict[str, Any],
|
|
) -> Any:
|
|
user = getattr(event, "from_user", None)
|
|
service = data.get("budget_service")
|
|
ensure = getattr(service, "ensure_yandex_login", None)
|
|
if user is None or not callable(ensure):
|
|
return await handler(event, data)
|
|
|
|
try:
|
|
await ensure(user.id)
|
|
except YandexLoginRequired as exc:
|
|
markup = yandex_login_keyboard(exc.login_url)
|
|
if isinstance(event, Message):
|
|
await event.answer(YANDEX_REQUIRED_TEXT, reply_markup=markup)
|
|
elif isinstance(event, CallbackQuery):
|
|
await event.answer()
|
|
if event.message:
|
|
await event.message.answer(YANDEX_REQUIRED_TEXT, reply_markup=markup)
|
|
return None
|
|
|
|
return await handler(event, data)
|