diff --git a/aiogram/api/types/chat.py b/aiogram/api/types/chat.py index 2e3163b2..d9eb9f99 100644 --- a/aiogram/api/types/chat.py +++ b/aiogram/api/types/chat.py @@ -3,6 +3,7 @@ from __future__ import annotations from typing import TYPE_CHECKING, Optional from .base import TelegramObject +from ...utils import helper if TYPE_CHECKING: # pragma: no cover from .chat_permissions import ChatPermissions @@ -51,3 +52,52 @@ class Chat(TelegramObject): """For supergroups, name of group sticker set. Returned only in getChat.""" can_set_sticker_set: Optional[bool] = None """True, if the bot can change the group sticker set. Returned only in getChat.""" + + @property + def full_name(self) -> str: + """ + Get user's full name for private chats and chat title for groups/channels. + """ + if self.type == ChatType.PRIVATE: + return f'{self.first_name} {self.last_name}' if self.last_name else self.first_name + + return self.title + + @property + def mention(self) -> Optional[str]: + """ + Get mention if a Chat has a username, or get full name if this is a Private Chat, otherwise None is returned. + """ + if self.username: + return f'@{self.username}' + elif self.type == ChatType.PRIVATE: + return self.full_name + + return None + + @property + def user_url(self) -> str: + """ + Get user's url (only for private chats!). URL works only if user doesn't have forward privacy enabled. + """ + if self.type != ChatType.PRIVATE: + raise TypeError('\"user_url\" property is only available in private chats!') + + return f"tg://user?id={self.id}" + + +class ChatType(helper.Helper): + """ + List of chat types + :key: PRIVATE + :key: GROUP + :key: SUPER_GROUP + :key: CHANNEL + """ + + mode = helper.HelperMode.lowercase + + PRIVATE = helper.Item() # private + GROUP = helper.Item() # group + SUPER_GROUP = helper.Item() # supergroup + CHANNEL = helper.Item() # channel diff --git a/docs/api/types/chat.md b/docs/api/types/chat.md index c269927c..1275234f 100644 --- a/docs/api/types/chat.md +++ b/docs/api/types/chat.md @@ -25,6 +25,23 @@ This object represents a chat. | `can_set_sticker_set` | `#!python Optional[bool]` | Optional. True, if the bot can change the group sticker set. Returned only in getChat. | +## Extensions + +| Name | Type | Description | +| - | - | - | +| `full_name` | `#!python str` | User's full name for private chats and chat title for groups/channels. | +| `mention` | `#!python Optional[str]` | Mention if a Chat has a username, or get full name if this is a Private Chat, otherwise None is returned. | +| `user_url` | `#!python str` | User's url (only for private chats!). URL works only if user doesn't have forward privacy enabled. | + +## ChatMemberStatus helper + +This object helps to describe chat type. + +#### Attributes: +- PRIVATE +- GROUP +- SUPER_GROUP +- CHANNEL ## Location diff --git a/tests/test_api/test_types/test_chat.py b/tests/test_api/test_types/test_chat.py new file mode 100644 index 00000000..03285fc3 --- /dev/null +++ b/tests/test_api/test_types/test_chat.py @@ -0,0 +1,43 @@ +import pytest + +from aiogram.api.types import Chat +from typing import Optional + + +class TestChat: + @pytest.mark.parametrize( + "chat_type,title,first_name,last_name,result", + [ + ["private", None, 'name', None, 'name'], + ["private", None, 'name', 'surname', 'name surname'], + ["supergroup", 'Chat title', None, None, 'Chat title'] + ] + ) + def test_full_name(self, chat_type: Optional[str], title: Optional[str], first_name: Optional[str], + last_name: Optional[str], result): + chat = Chat(id=0, type=chat_type, title=title, first_name=first_name, last_name=last_name) + assert chat.full_name == result + + @pytest.mark.parametrize( + "chat_type,title,first_name,last_name,username,result", + [ + ["private", None, 'name', None, None, 'name'], + ["supergroup", None, 'name', None, None, None], + ["private", None, 'name', None, 'user', '@user'], + ["supergroup", None, 'name', None, 'user', '@user'] + ] + ) + def test_mention(self, chat_type: Optional[str], title: Optional[str], first_name: Optional[str], + last_name: Optional[str], username: Optional[str], result): + chat = Chat(id=0, type=chat_type, title=title, first_name=first_name, last_name=last_name, username=username) + assert chat.mention == result + + @pytest.mark.parametrize( + "chat_type,chat_id,result", + [ + ["private", 123124123, 'tg://user?id=123124123'] + ] + ) + def test_user_url(self, chat_type: Optional[str], chat_id: int, result): + chat = Chat(type=chat_type, id=chat_id) + assert chat.user_url == result