diff --git a/pybotx/__init__.py b/pybotx/__init__.py index cb0539cb..e760ac43 100644 --- a/pybotx/__init__.py +++ b/pybotx/__init__.py @@ -62,6 +62,7 @@ from pybotx.client.smartapps_api.exceptions import SyncSmartAppEventHandlerNotFoundError from pybotx.client.smartapps_api.smartapp_manifest import ( SmartappManifest, + SmartappManifestUnreadCounterParams, SmartappManifestWebParams, ) from pybotx.client.stickers_api.exceptions import ( @@ -235,6 +236,7 @@ "SmartAppEvent", "SmartappManifest", "SmartappManifestWebLayoutChoices", + "SmartappManifestUnreadCounterParams", "SmartappManifestWebParams", "StatusRecipient", "StealthModeDisabledError", diff --git a/pybotx/bot/bot.py b/pybotx/bot/bot.py index b311cf32..013fb3da 100644 --- a/pybotx/bot/bot.py +++ b/pybotx/bot/bot.py @@ -139,6 +139,8 @@ BotXAPISmartAppManifestRequestPayload, SmartappManifest, SmartAppManifestMethod, + SmartappManifestUnreadCounterParams, + SmartappManifestWebParams, ) from pybotx.client.smartapps_api.smartapp_notification import ( BotXAPISmartAppNotificationRequestPayload, @@ -227,7 +229,6 @@ from pybotx.models.chats import ChatInfo, ChatListItem from pybotx.models.commands import BotAPICommand, BotCommand from pybotx.models.enums import ChatTypes -from pybotx.models.enums import SmartappManifestWebLayoutChoices as WebLayoutChoices from pybotx.models.message.edit_message import EditMessage from pybotx.models.message.markup import BubbleMarkup, KeyboardMarkup from pybotx.models.message.message_status import MessageStatus @@ -1547,17 +1548,14 @@ async def send_smartapp_manifest( self, *, bot_id: UUID, - web_default_layout: WebLayoutChoices = WebLayoutChoices.minimal, - web_expanded_layout: WebLayoutChoices = WebLayoutChoices.half, - web_always_pinned: bool = False, + web_layout: Missing[SmartappManifestWebParams] = Undefined, + unread_counter: Missing[SmartappManifestUnreadCounterParams] = Undefined, ) -> SmartappManifest: """Send smartapp manifest with given parameters. :param bot_id: Bot which should perform the request. - :param web_default_layout: default smartapp layout for web clients. - :param web_expanded_layout: expanded smartapp layout for web clients. - :param web_always_pinned: True if smartapp icon should be always pinned - in the web clients sidebar. + :param web_layout: Smartapp layout for web clients. + :param unread_counter: Entities that can be subscribed to in the unread counter. :return: Smartapp manifest with the set parameters received from BotX. """ @@ -1568,9 +1566,8 @@ async def send_smartapp_manifest( self._bot_accounts_storage, ) payload = BotXAPISmartAppManifestRequestPayload.from_domain( - web_default_layout=web_default_layout, - web_expanded_layout=web_expanded_layout, - web_always_pinned=web_always_pinned, + web_layout=web_layout, + unread_counter=unread_counter, ) smartapp_manifest_response = await method.execute(payload) return smartapp_manifest_response.to_domain() diff --git a/pybotx/client/smartapps_api/smartapp_manifest.py b/pybotx/client/smartapps_api/smartapp_manifest.py index cde503d5..b315b7fb 100644 --- a/pybotx/client/smartapps_api/smartapp_manifest.py +++ b/pybotx/client/smartapps_api/smartapp_manifest.py @@ -1,7 +1,11 @@ -from typing import Literal +from typing import List, Literal +from uuid import UUID + +from pydantic import Field from pybotx.client.authorized_botx_method import AuthorizedBotXMethod -from pybotx.models.api_base import VerifiedPayloadBaseModel +from pybotx.missing import Missing, Undefined +from pybotx.models.api_base import UnverifiedPayloadBaseModel, VerifiedPayloadBaseModel from pybotx.models.enums import SmartappManifestWebLayoutChoices as WebLayoutChoices @@ -11,27 +15,38 @@ class SmartappManifestWebParams(VerifiedPayloadBaseModel): always_pinned: bool = False +class SmartappManifestUnreadCounterParams(VerifiedPayloadBaseModel): + user_huid: List[UUID] = Field(default_factory=list) + group_chat_id: List[UUID] = Field(default_factory=list) + app_id: List[str] = Field(default_factory=list) + + class SmartappManifest(VerifiedPayloadBaseModel): web: SmartappManifestWebParams + unread_counter_link: SmartappManifestUnreadCounterParams -class BotXAPISmartAppManifestRequestPayload(VerifiedPayloadBaseModel): - manifest: SmartappManifest +class SmartappManifestPayload(UnverifiedPayloadBaseModel): + web: Missing[SmartappManifestWebParams] = Undefined + unread_counter_link: Missing[SmartappManifestUnreadCounterParams] = Undefined + + +class BotXAPISmartAppManifestRequestPayload(UnverifiedPayloadBaseModel): + manifest: SmartappManifestPayload @classmethod def from_domain( cls, - web_default_layout: WebLayoutChoices = WebLayoutChoices.minimal, - web_expanded_layout: WebLayoutChoices = WebLayoutChoices.half, - web_always_pinned: bool = False, + web_layout: Missing[SmartappManifestWebParams] = Undefined, + unread_counter: Missing[SmartappManifestUnreadCounterParams] = Undefined, ) -> "BotXAPISmartAppManifestRequestPayload": + if web_layout is Undefined and unread_counter is Undefined: + return cls(manifest={}) + return cls( - manifest=SmartappManifest( - web=SmartappManifestWebParams( - default_layout=web_default_layout, - expanded_layout=web_expanded_layout, - always_pinned=web_always_pinned, - ), + manifest=SmartappManifestPayload( + web=web_layout, + unread_counter_link=unread_counter, ), ) diff --git a/tests/client/smartapps_api/test_smartapp_manifest.py b/tests/client/smartapps_api/test_smartapp_manifest.py index 714066ca..d906cfd6 100644 --- a/tests/client/smartapps_api/test_smartapp_manifest.py +++ b/tests/client/smartapps_api/test_smartapp_manifest.py @@ -14,6 +14,9 @@ SmartappManifestWebParams, lifespan_wrapper, ) +from pybotx.client.smartapps_api.smartapp_manifest import ( + SmartappManifestUnreadCounterParams, +) pytestmark = [ pytest.mark.asyncio, @@ -39,6 +42,11 @@ async def test__send_smartapp_manifest__all_params_provided__succeed( "default_layout": "full", "expanded_layout": "full", }, + "unread_counter_link": { + "user_huid": ["e3568b81-0446-4030-9210-1725841bf8f0"], + "group_chat_id": ["adc03af8-9193-4d3b-b913-7a023cdb4029"], + "app_id": ["test_app"], + }, }, }, ).mock( @@ -51,6 +59,11 @@ async def test__send_smartapp_manifest__all_params_provided__succeed( "default_layout": "full", "expanded_layout": "full", }, + "unread_counter_link": { + "user_huid": ["e3568b81-0446-4030-9210-1725841bf8f0"], + "group_chat_id": ["adc03af8-9193-4d3b-b913-7a023cdb4029"], + "app_id": ["test_app"], + }, }, "status": "ok", }, @@ -63,9 +76,16 @@ async def test__send_smartapp_manifest__all_params_provided__succeed( async with lifespan_wrapper(built_bot) as bot: smartapp_manifest = await bot.send_smartapp_manifest( bot_id=bot_id, - web_default_layout=SmartappManifestWebLayoutChoices.full, - web_expanded_layout=SmartappManifestWebLayoutChoices.full, - web_always_pinned=True, + web_layout=SmartappManifestWebParams( + default_layout=SmartappManifestWebLayoutChoices.full, + expanded_layout=SmartappManifestWebLayoutChoices.full, + always_pinned=True, + ), + unread_counter=SmartappManifestUnreadCounterParams( + user_huid=[UUID("e3568b81-0446-4030-9210-1725841bf8f0")], + group_chat_id=[UUID("adc03af8-9193-4d3b-b913-7a023cdb4029")], + app_id=["test_app"], + ), ) # - Assert - @@ -76,6 +96,11 @@ async def test__send_smartapp_manifest__all_params_provided__succeed( expanded_layout=SmartappManifestWebLayoutChoices.full, always_pinned=True, ), + unread_counter_link=SmartappManifestUnreadCounterParams( + user_huid=[UUID("e3568b81-0446-4030-9210-1725841bf8f0")], + group_chat_id=[UUID("adc03af8-9193-4d3b-b913-7a023cdb4029")], + app_id=["test_app"], + ), ) @@ -90,13 +115,7 @@ async def test__send_smartapp_manifest__only_default_params_provided__succeed( f"https://{host}/api/v1/botx/smartapps/manifest", headers={"Authorization": "Bearer token", "Content-Type": "application/json"}, json={ - "manifest": { - "web": { - "always_pinned": False, - "default_layout": "minimal", - "expanded_layout": "half", - }, - }, + "manifest": {}, }, ).mock( return_value=httpx.Response( @@ -108,6 +127,11 @@ async def test__send_smartapp_manifest__only_default_params_provided__succeed( "default_layout": "minimal", "expanded_layout": "half", }, + "unread_counter_link": { + "app_id": [], + "group_chat_id": [], + "user_huid": [], + }, }, "status": "ok", }, @@ -128,4 +152,9 @@ async def test__send_smartapp_manifest__only_default_params_provided__succeed( expanded_layout=SmartappManifestWebLayoutChoices.half, always_pinned=False, ), + unread_counter_link=SmartappManifestUnreadCounterParams( + user_huid=[], + group_chat_id=[], + app_id=[], + ), )