From c0e1ccfb06265f56feb6f71a34730dbd6203dfe2 Mon Sep 17 00:00:00 2001 From: ITQ Date: Wed, 19 Feb 2025 14:37:11 +0300 Subject: [PATCH] feat(telegram_bot): added dialogs folder --- .../services/telegram_bot/dialogs/__init__.py | 0 .../telegram_bot/dialogs/campaigns.py | 54 ++++++++++++++++ .../services/telegram_bot/dialogs/start.py | 63 +++++++++++++++++++ 3 files changed, 117 insertions(+) create mode 100644 solution/services/telegram_bot/dialogs/__init__.py create mode 100644 solution/services/telegram_bot/dialogs/campaigns.py create mode 100644 solution/services/telegram_bot/dialogs/start.py diff --git a/solution/services/telegram_bot/dialogs/__init__.py b/solution/services/telegram_bot/dialogs/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/solution/services/telegram_bot/dialogs/campaigns.py b/solution/services/telegram_bot/dialogs/campaigns.py new file mode 100644 index 0000000..012b4b5 --- /dev/null +++ b/solution/services/telegram_bot/dialogs/campaigns.py @@ -0,0 +1,54 @@ +from typing import Any + +from aiogram.fsm.context import FSMContext +from aiogram.types import CallbackQuery +from aiogram_dialog import Dialog, DialogManager, Window +from aiogram_dialog.widgets.kbd import Button, ListGroup, ScrollingGroup +from aiogram_dialog.widgets.text import Const, Format + +from api.client import AdNovaClient +from states.campaigns import CampaignsDailogState + + +async def campaigns(**kwargs: dict[Any]) -> dict[str, Any]: + state: FSMContext = kwargs["state"] + state_data = await state.get_data() + + async with AdNovaClient() as client: + campaigns = await client.list_campaigns(state_data["advertiser_id"]) + + campaigns = [campaign.model_dump(mode="json") for campaign in campaigns] + + return { + "campaigns": campaigns, + } + + +async def campaign_detail_on_click( + callback: CallbackQuery, button: Button, manager: DialogManager +) -> None: + await callback.answer() + + +campaigns_dialog = Dialog( + Window( + Const("Campaigns:"), + ScrollingGroup( + ListGroup( + Button( + Format("{item[ad_title]}"), + id="detail", + on_click=campaign_detail_on_click, + ), + id="campaigns", + item_id_getter=lambda item: item["campaign_id"], + items="campaigns", + ), + id="pagination", + width=1, + height=4, + ), + state=CampaignsDailogState.campaigns, + getter=campaigns, + ), +) diff --git a/solution/services/telegram_bot/dialogs/start.py b/solution/services/telegram_bot/dialogs/start.py new file mode 100644 index 0000000..c85cd60 --- /dev/null +++ b/solution/services/telegram_bot/dialogs/start.py @@ -0,0 +1,63 @@ +from aiogram.types import Message +from aiogram_dialog import Dialog, DialogManager, Window +from aiogram_dialog.widgets.input import ManagedTextInput, TextInput +from aiogram_dialog.widgets.text import Const +from pydantic import ValidationError + +from api.client import AdNovaClient +from api.errors import NotFoundError +from api.schemas import Advertiser +from states.start import StartDialogState + + +def check_advertiser_id(advertiser_id: str) -> None: + Advertiser.__pydantic_validator__.validate_assignment( + Advertiser.model_construct(), "advertiser_id", advertiser_id + ) + + try: + client = AdNovaClient() + client.sync_get_advertiser(advertiser_id) + except NotFoundError: + raise ValueError from None + + +async def advertiser_id_on_error( + message: Message, + widget: ManagedTextInput, + dialog_manager: DialogManager, + error: object, +) -> None: + if isinstance(error, ValidationError): + await message.answer("Invalid advertiser UUID.") + elif isinstance(error, ValueError): + await message.answer("Advertiser with this UUID not found.") + + +async def advertiser_id_on_success( + message: Message, + widget: ManagedTextInput, + dialog_manager: DialogManager, + advertiser_id: str, +) -> None: + state = dialog_manager.middleware_data["state"] + state_data = await state.get_data() + state_data["advertiser_id"] = message.text + await state.set_data(state_data) + + await message.answer(f"Successfully authenticated as {message.text}") + await dialog_manager.mark_closed() + + +start_dialog = Dialog( + Window( + Const("Enter adveritser UUID:"), + TextInput( + id="advertiser_id", + type_factory=check_advertiser_id, + on_success=advertiser_id_on_success, + on_error=advertiser_id_on_error, + ), + state=StartDialogState.start, + ), +)