diff --git a/aiogram/types/chat.py b/aiogram/types/chat.py index 936b2126..08d935e5 100644 --- a/aiogram/types/chat.py +++ b/aiogram/types/chat.py @@ -64,6 +64,18 @@ class Chat(base.TelegramObject): return f"tg://user?id={self.id}" + @property + def shifted_id(self) -> int: + """ + Get shifted id of chat, e.g. for private links + + For example: -1001122334455 -> 1122334455 + """ + if self.type == ChatType.PRIVATE: + raise TypeError('`shifted_id` property is not available for private chats') + shift = -1_000_000_000_000 + return shift - self.id + def get_mention(self, name=None, as_html=True) -> base.String: if name is None: name = self.mention diff --git a/aiogram/types/message.py b/aiogram/types/message.py index b776e74e..badf1d51 100644 --- a/aiogram/types/message.py +++ b/aiogram/types/message.py @@ -230,12 +230,19 @@ class Message(base.TelegramObject): :return: str """ - if self.chat.type not in [ChatType.SUPER_GROUP, ChatType.CHANNEL]: + if ChatType.is_private(self.chat): raise TypeError('Invalid chat type!') - elif not self.chat.username: - raise TypeError('This chat does not have @username') - return f"https://t.me/{self.chat.username}/{self.message_id}" + url = 'https://t.me/' + if self.chat.username: + # Generates public link + url += f'{self.chat.username}/' + else: + # Generates private link available for chat members + url += f'c/{self.chat.shifted_id}/' + url += f'{self.message_id}' + + return url def link(self, text, as_html=True) -> str: """