diff --git a/pybotx/__init__.py b/pybotx/__init__.py
index b3952366..e6e83bb2 100644
--- a/pybotx/__init__.py
+++ b/pybotx/__init__.py
@@ -71,7 +71,7 @@
UserSender,
)
from pybotx.models.message.markup import BubbleMarkup, Button, KeyboardMarkup
-from pybotx.models.message.mentions import Mention, MentionList
+from pybotx.models.message.mentions import Mention, MentionBuilder, MentionList
from pybotx.models.message.message_status import MessageStatus
from pybotx.models.message.outgoing_message import OutgoingMessage
from pybotx.models.message.reply import Reply
@@ -147,6 +147,7 @@
"KeyboardMarkup",
"LeftFromChatEvent",
"Mention",
+ "MentionBuilder",
"MentionList",
"MentionTypes",
"Middleware",
diff --git a/pybotx/models/enums.py b/pybotx/models/enums.py
index 89f8026b..3d67002e 100644
--- a/pybotx/models/enums.py
+++ b/pybotx/models/enums.py
@@ -134,22 +134,6 @@ def convert_client_platform_to_domain(
return converted_type
-def convert_mention_type_to_domain(mention_type: BotAPIMentionTypes) -> MentionTypes:
- mention_types_mapping = {
- BotAPIMentionTypes.CONTACT: MentionTypes.CONTACT,
- BotAPIMentionTypes.CHAT: MentionTypes.CHAT,
- BotAPIMentionTypes.CHANNEL: MentionTypes.CHANNEL,
- BotAPIMentionTypes.USER: MentionTypes.USER,
- BotAPIMentionTypes.ALL: MentionTypes.ALL,
- }
-
- converted_type = mention_types_mapping.get(mention_type)
- if converted_type is None:
- raise NotImplementedError(f"Unsupported mention type: {mention_type}")
-
- return converted_type
-
-
def convert_mention_type_from_domain(
mention_type: MentionTypes,
) -> BotAPIMentionTypes:
diff --git a/pybotx/models/message/incoming_message.py b/pybotx/models/message/incoming_message.py
index ac65518d..2687a689 100644
--- a/pybotx/models/message/incoming_message.py
+++ b/pybotx/models/message/incoming_message.py
@@ -33,7 +33,6 @@
ClientPlatforms,
convert_chat_type_to_domain,
convert_client_platform_to_domain,
- convert_mention_type_to_domain,
)
from pybotx.models.message.forward import BotAPIForward, Forward
from pybotx.models.message.mentions import (
@@ -41,6 +40,7 @@
BotAPIMentionData,
BotAPINestedMentionData,
Mention,
+ MentionBuilder,
MentionList,
)
from pybotx.models.message.reply import BotAPIReply, Reply
@@ -117,18 +117,37 @@ def arguments(self) -> Tuple[str, ...]:
def _convert_bot_api_mention_to_domain(api_mention_data: BotAPIMentionData) -> Mention:
- entity_id: Optional[UUID] = None
- name: Optional[str] = None
-
- if api_mention_data.mention_type != BotAPIMentionTypes.ALL:
- mention_data = cast(BotAPINestedMentionData, api_mention_data.mention_data)
- entity_id = mention_data.entity_id
- name = mention_data.name
-
- return Mention(
- type=convert_mention_type_to_domain(api_mention_data.mention_type),
- entity_id=entity_id,
- name=name,
+ mention_data = cast(BotAPINestedMentionData, api_mention_data.mention_data)
+
+ if api_mention_data.mention_type == BotAPIMentionTypes.USER:
+ return MentionBuilder.user(
+ entity_id=mention_data.entity_id,
+ name=mention_data.name,
+ )
+
+ if api_mention_data.mention_type == BotAPIMentionTypes.CHAT:
+ return MentionBuilder.chat(
+ entity_id=mention_data.entity_id,
+ name=mention_data.name,
+ )
+
+ if api_mention_data.mention_type == BotAPIMentionTypes.CONTACT:
+ return MentionBuilder.contact(
+ entity_id=mention_data.entity_id,
+ name=mention_data.name,
+ )
+
+ if api_mention_data.mention_type == BotAPIMentionTypes.CHANNEL:
+ return MentionBuilder.channel(
+ entity_id=mention_data.entity_id,
+ name=mention_data.name,
+ )
+
+ if api_mention_data.mention_type == BotAPIMentionTypes.ALL:
+ return MentionBuilder.all()
+
+ raise NotImplementedError(
+ f"Unsupported mention type: {api_mention_data.mention_type}",
)
@@ -255,7 +274,10 @@ def to_domain(self, raw_command: Dict[str, Any]) -> IncomingMessage: # noqa: WP
logger.warning("Received unknown entity type")
else:
entity_domain = convert_bot_api_entity_to_domain(entity)
- if isinstance(entity_domain, Mention):
+ if isinstance(
+ entity_domain,
+ Mention.__args__, # type: ignore [attr-defined] # noqa: WPS609
+ ):
mentions.append(entity_domain)
elif isinstance(entity_domain, Forward):
# Max one forward per message
diff --git a/pybotx/models/message/mentions.py b/pybotx/models/message/mentions.py
index 91c0dccd..ec6a3850 100644
--- a/pybotx/models/message/mentions.py
+++ b/pybotx/models/message/mentions.py
@@ -15,53 +15,117 @@
)
+def build_embed_mention(
+ mention_type: MentionTypes,
+ entity_id: Optional[UUID] = None,
+ name: Optional[str] = None,
+) -> str:
+ name = name or ""
+ entity_id_str = "" if entity_id is None else str(entity_id)
+ return f"{mention_type.value}:{entity_id_str}:{name}"
+
+
+@dataclass
+class BaseTargetMention:
+ entity_id: Optional[UUID]
+ name: Optional[str]
+
+
+@dataclass
+class MentionUser(BaseTargetMention):
+ type: Literal[MentionTypes.USER]
+
+ def __str__(self) -> str:
+ return build_embed_mention(self.type, self.entity_id, self.name)
+
+
+@dataclass
+class MentionContact(BaseTargetMention):
+ type: Literal[MentionTypes.CONTACT]
+
+ def __str__(self) -> str:
+ return build_embed_mention(self.type, self.entity_id, self.name)
+
+
+@dataclass
+class MentionChat(BaseTargetMention):
+ type: Literal[MentionTypes.CHAT]
+
+ def __str__(self) -> str:
+ return build_embed_mention(self.type, self.entity_id, self.name)
+
+
+@dataclass
+class MentionChannel(BaseTargetMention):
+ type: Literal[MentionTypes.CHANNEL]
+
+ def __str__(self) -> str:
+ return build_embed_mention(self.type, self.entity_id, self.name)
+
+
@dataclass
-class Mention:
- type: MentionTypes
- entity_id: Optional[UUID] = None
- name: Optional[str] = None
+class MentionAll:
+ type: Literal[MentionTypes.ALL]
def __str__(self) -> str:
- name = self.name or ""
- entity_id = self.entity_id or ""
- mention_type = self.type.value
- return f"{mention_type}:{entity_id}:{name}"
+ return build_embed_mention(self.type)
+
+
+Mention = Union[
+ MentionUser,
+ MentionContact,
+ MentionChat,
+ MentionChannel,
+ MentionAll,
+]
+
+class MentionBuilder:
@classmethod
- def user(cls, huid: UUID, name: Optional[str] = None) -> "Mention":
- return cls(
+ def user(cls, entity_id: Optional[UUID], name: Optional[str] = None) -> MentionUser:
+ return MentionUser(
type=MentionTypes.USER,
- entity_id=huid,
+ entity_id=entity_id,
name=name,
)
@classmethod
- def contact(cls, huid: UUID, name: Optional[str] = None) -> "Mention":
- return cls(
+ def contact(
+ cls,
+ entity_id: Optional[UUID],
+ name: Optional[str] = None,
+ ) -> MentionContact:
+ return MentionContact(
type=MentionTypes.CONTACT,
- entity_id=huid,
+ entity_id=entity_id,
name=name,
)
@classmethod
- def chat(cls, chat_id: UUID, name: Optional[str] = None) -> "Mention":
- return cls(
+ def chat(cls, entity_id: Optional[UUID], name: Optional[str] = None) -> MentionChat:
+ return MentionChat(
type=MentionTypes.CHAT,
- entity_id=chat_id,
+ entity_id=entity_id,
name=name,
)
@classmethod
- def channel(cls, chat_id: UUID, name: Optional[str] = None) -> "Mention":
- return cls(
+ def channel(
+ cls,
+ entity_id: Optional[UUID],
+ name: Optional[str] = None,
+ ) -> MentionChannel:
+ return MentionChannel(
type=MentionTypes.CHANNEL,
- entity_id=chat_id,
+ entity_id=entity_id,
name=name,
)
@classmethod
- def all(cls) -> "Mention":
- return cls(type=MentionTypes.ALL)
+ def all(cls) -> MentionAll:
+ return MentionAll(
+ type=MentionTypes.ALL,
+ )
class MentionList(List[Mention]):
diff --git a/pyproject.toml b/pyproject.toml
index 1553d553..5a689d36 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[tool.poetry]
name = "pybotx"
-version = "0.33.0"
+version = "0.34.0"
description = "A python library for interacting with eXpress BotX API"
authors = [
"Sidnev Nikolay ",
diff --git a/tests/client/events_api/test_edit_event.py b/tests/client/events_api/test_edit_event.py
index b536a603..07fcc223 100644
--- a/tests/client/events_api/test_edit_event.py
+++ b/tests/client/events_api/test_edit_event.py
@@ -13,7 +13,7 @@
EditMessage,
HandlerCollector,
KeyboardMarkup,
- Mention,
+ MentionBuilder,
OutgoingAttachment,
lifespan_wrapper,
)
@@ -146,7 +146,7 @@ async def test__edit_message__maximum_edit_succeed(
await bot.edit_message(
bot_id=bot_id,
sync_id=UUID("8ba66c5b-40bf-5c77-911d-519cb4e382e9"),
- body=f"{Mention.user(UUID('8f3abcc8-ba00-4c89-88e0-b786beb8ec24'))}!",
+ body=f"{MentionBuilder.user(UUID('8f3abcc8-ba00-4c89-88e0-b786beb8ec24'))}!",
metadata={"message": "metadata"},
bubbles=bubbles,
keyboard=keyboard,
@@ -289,7 +289,7 @@ async def test__edit__succeed(
message = EditMessage(
bot_id=bot_id,
sync_id=UUID("8ba66c5b-40bf-5c77-911d-519cb4e382e9"),
- body=f"{Mention.user(UUID('8f3abcc8-ba00-4c89-88e0-b786beb8ec24'))}!",
+ body=f"{MentionBuilder.user(UUID('8f3abcc8-ba00-4c89-88e0-b786beb8ec24'))}!",
metadata={"message": "metadata"},
bubbles=bubbles,
keyboard=keyboard,
diff --git a/tests/client/events_api/test_reply_event.py b/tests/client/events_api/test_reply_event.py
index da80ab76..b60e0f18 100644
--- a/tests/client/events_api/test_reply_event.py
+++ b/tests/client/events_api/test_reply_event.py
@@ -12,7 +12,7 @@
BubbleMarkup,
HandlerCollector,
KeyboardMarkup,
- Mention,
+ MentionBuilder,
OutgoingAttachment,
ReplyMessage,
lifespan_wrapper,
@@ -162,7 +162,7 @@ async def test__reply_message__maximum_filled_reply_succeed(
await bot.reply_message(
bot_id=bot_id,
sync_id=UUID("8ba66c5b-40bf-5c77-911d-519cb4e382e9"),
- body=f"{Mention.user(UUID('8f3abcc8-ba00-4c89-88e0-b786beb8ec24'))}!",
+ body=f"{MentionBuilder.user(UUID('8f3abcc8-ba00-4c89-88e0-b786beb8ec24'))}!",
metadata={"message": "metadata"},
bubbles=bubbles,
keyboard=keyboard,
@@ -270,7 +270,7 @@ async def test__reply__succeed(
message = ReplyMessage(
bot_id=bot_id,
sync_id=UUID("8ba66c5b-40bf-5c77-911d-519cb4e382e9"),
- body=f"{Mention.user(UUID('8f3abcc8-ba00-4c89-88e0-b786beb8ec24'))}!",
+ body=f"{MentionBuilder.user(UUID('8f3abcc8-ba00-4c89-88e0-b786beb8ec24'))}!",
metadata={"message": "metadata"},
bubbles=bubbles,
keyboard=keyboard,
diff --git a/tests/client/notifications_api/test_direct_notification.py b/tests/client/notifications_api/test_direct_notification.py
index ed51ed12..3cba3401 100644
--- a/tests/client/notifications_api/test_direct_notification.py
+++ b/tests/client/notifications_api/test_direct_notification.py
@@ -19,7 +19,7 @@
HandlerCollector,
IncomingMessage,
KeyboardMarkup,
- Mention,
+ MentionBuilder,
OutgoingAttachment,
OutgoingMessage,
StealthModeDisabledError,
@@ -622,7 +622,7 @@ async def test__send_message__maximum_filled_succeed(
lambda: UUID("f3e176d5-ff46-4b18-b260-25008338c06e"),
)
- body = f"Hi, {Mention.user(UUID('8f3abcc8-ba00-4c89-88e0-b786beb8ec24'))}!"
+ body = f"Hi, {MentionBuilder.user(UUID('8f3abcc8-ba00-4c89-88e0-b786beb8ec24'))}!"
formatted_body = "Hi, @{mention:f3e176d5-ff46-4b18-b260-25008338c06e}!"
endpoint = respx_mock.post(
@@ -781,14 +781,14 @@ async def test__send_message__all_mentions_types_succeed(
)
mentioned_user_huid = UUID("8f3abcc8-ba00-4c89-88e0-b786beb8ec24")
- user_mention = Mention.user(mentioned_user_huid)
+ user_mention = MentionBuilder.user(mentioned_user_huid)
mentioned_contact_huid = UUID("1e0529fd-f091-4be9-93cc-6704a8957432")
- contact_mention = Mention.contact(mentioned_contact_huid)
+ contact_mention = MentionBuilder.contact(mentioned_contact_huid)
mentioned_chat_huid = UUID("454d73ad-1d32-4939-a708-e14b77414e86")
- chat_mention = Mention.chat(mentioned_chat_huid, "Our chat")
+ chat_mention = MentionBuilder.chat(mentioned_chat_huid, "Our chat")
mentioned_channel_huid = UUID("78198bec-3285-48d0-9fe2-c0eb3afaffd7")
- channel_mention = Mention.channel(mentioned_channel_huid)
- all_mention = Mention.all()
+ channel_mention = MentionBuilder.channel(mentioned_channel_huid)
+ all_mention = MentionBuilder.all()
body = (
f"Hi, {user_mention}, want you to know, "
diff --git a/tests/models/test_mentions_list.py b/tests/models/test_mentions_list.py
index c071069b..c6782207 100644
--- a/tests/models/test_mentions_list.py
+++ b/tests/models/test_mentions_list.py
@@ -1,59 +1,34 @@
-from typing import Callable, Optional
-from uuid import UUID, uuid4
+from uuid import uuid4
-import pytest
+from pybotx import MentionBuilder, MentionList
-from pybotx import Mention, MentionList, MentionTypes
-
-@pytest.fixture
-def mention_factory() -> Callable[..., Mention]:
- def factory(
- mention_type: MentionTypes,
- huid: UUID,
- name: Optional[str] = None,
- ) -> Mention:
- return Mention(
- type=mention_type,
- entity_id=huid,
- name=name,
- )
-
- return factory
-
-
-def test__mentions_list_properties__filled(
- mention_factory: Callable[..., Mention],
-) -> None:
+def test__mentions_list_properties__filled() -> None:
# - Arrange -
contacts = [
- mention_factory(
- mention_type=MentionTypes.CONTACT,
- huid=uuid4(),
+ MentionBuilder.contact(
+ entity_id=uuid4(),
name=str(name),
)
for name in range(2)
]
chats = [
- mention_factory(
- mention_type=MentionTypes.CHAT,
- huid=uuid4(),
+ MentionBuilder.chat(
+ entity_id=uuid4(),
name=str(name),
)
for name in range(2)
]
channels = [
- mention_factory(
- mention_type=MentionTypes.CHANNEL,
- huid=uuid4(),
+ MentionBuilder.channel(
+ entity_id=uuid4(),
name=str(name),
)
for name in range(2)
]
users = [
- mention_factory(
- mention_type=MentionTypes.USER,
- huid=uuid4(),
+ MentionBuilder.user(
+ entity_id=uuid4(),
name=str(name),
)
for name in range(2)
@@ -68,15 +43,12 @@ def test__mentions_list_properties__filled(
assert mentions.users == users
-def test__mentions_list_all_users_mentioned__filled(
- mention_factory: Callable[..., Mention],
-) -> None:
+def test__mentions_list_all_users_mentioned__filled() -> None:
# - Arrange -
- user_mention = mention_factory(
- mention_type=MentionTypes.CONTACT,
- huid=uuid4(),
+ user_mention = MentionBuilder.contact(
+ entity_id=uuid4(),
)
- all_mention = Mention(type=MentionTypes.ALL)
+ all_mention = MentionBuilder.all()
one_all_mention = MentionList([user_mention, all_mention])
two_all_mentions = MentionList([all_mention, all_mention])
diff --git a/tests/test_incoming_message.py b/tests/test_incoming_message.py
index 60682a02..95c9ceba 100644
--- a/tests/test_incoming_message.py
+++ b/tests/test_incoming_message.py
@@ -16,9 +16,8 @@
HandlerCollector,
Image,
IncomingMessage,
- Mention,
+ MentionBuilder,
MentionList,
- MentionTypes,
Reply,
UserDevice,
UserSender,
@@ -299,8 +298,7 @@ async def default_handler(message: IncomingMessage, bot: Bot) -> None:
),
mentions=MentionList(
[
- Mention(
- type=MentionTypes.CONTACT,
+ MentionBuilder.contact(
entity_id=UUID("ab103983-6001-44e9-889e-d55feb295494"),
name="Вася Иванов",
),
@@ -317,8 +315,7 @@ async def default_handler(message: IncomingMessage, bot: Bot) -> None:
body="все равно документацию никто не читает...",
mentions=MentionList(
[
- Mention(
- type=MentionTypes.CONTACT,
+ MentionBuilder.contact(
entity_id=UUID("ab103983-6001-44e9-889e-d55feb295494"),
name="Вася Иванов",
),
@@ -446,31 +443,23 @@ async def default_handler(message: IncomingMessage, bot: Bot) -> None:
assert incoming_message
assert incoming_message.mentions == MentionList(
[
- Mention(
- type=MentionTypes.CONTACT,
+ MentionBuilder.contact(
entity_id=UUID("ab103983-6001-44e9-889e-d55feb295494"),
name="Вася Иванов",
),
- Mention(
- type=MentionTypes.USER,
+ MentionBuilder.user(
entity_id=UUID("ab103983-6001-44e9-889e-d55feb295494"),
name="Вася Иванов",
),
- Mention(
- type=MentionTypes.CHANNEL,
+ MentionBuilder.channel(
entity_id=UUID("ab103983-6001-44e9-889e-d55feb295494"),
name="Вася Иванов",
),
- Mention(
- type=MentionTypes.CHAT,
+ MentionBuilder.chat(
entity_id=UUID("ab103983-6001-44e9-889e-d55feb295494"),
name="Вася Иванов",
),
- Mention(
- type=MentionTypes.ALL,
- entity_id=None,
- name=None,
- ),
+ MentionBuilder.all(),
],
)