mirror of
https://github.com/aiogram/aiogram.git
synced 2025-12-11 18:01:04 +00:00
Added get_url() method for Message object and shifted_id property for Chat object (#585)
* Added get_url() method for Message object and shifted_id property for Chat object * Added missing closing bracket to shifted_id description * Added basic groups to skipped pattern, simplified code * Return None instead of raising TypeError, removed redundant f-string * Change get_url typing to Optional[str] * Better shifted_id method * get_url tests added * Added whitespace (E226) * Code format with black * Parametrized test
This commit is contained in:
parent
53da50045e
commit
32bc05130f
3 changed files with 86 additions and 0 deletions
|
|
@ -54,3 +54,19 @@ class Chat(TelegramObject):
|
||||||
"""*Optional*. Unique identifier for the linked chat, i.e. the discussion group identifier for a channel and vice versa; for supergroups and channel chats. This identifier may be greater than 32 bits and some programming languages may have difficulty/silent defects in interpreting it. But it is smaller than 52 bits, so a signed 64 bit integer or double-precision float type are safe for storing this identifier. Returned only in :class:`aiogram.methods.get_chat.GetChat`."""
|
"""*Optional*. Unique identifier for the linked chat, i.e. the discussion group identifier for a channel and vice versa; for supergroups and channel chats. This identifier may be greater than 32 bits and some programming languages may have difficulty/silent defects in interpreting it. But it is smaller than 52 bits, so a signed 64 bit integer or double-precision float type are safe for storing this identifier. Returned only in :class:`aiogram.methods.get_chat.GetChat`."""
|
||||||
location: Optional[ChatLocation] = None
|
location: Optional[ChatLocation] = None
|
||||||
"""*Optional*. For supergroups, the location to which the supergroup is connected. Returned only in :class:`aiogram.methods.get_chat.GetChat`."""
|
"""*Optional*. For supergroups, the location to which the supergroup is connected. Returned only in :class:`aiogram.methods.get_chat.GetChat`."""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def shifted_id(self) -> int:
|
||||||
|
"""
|
||||||
|
Returns shifted chat ID (positive and without "-100" prefix).
|
||||||
|
Mostly used for private links like t.me/c/chat_id/message_id
|
||||||
|
|
||||||
|
Currently supergroup/channel IDs have 10-digit ID after "-100" prefix removed.
|
||||||
|
However, these IDs might become 11-digit in future. So, first we remove "-100"
|
||||||
|
prefix and count remaining number length. Then we multiple
|
||||||
|
-1 * 10 ^ (number_length + 2)
|
||||||
|
Finally, self.id is substracted from that number
|
||||||
|
"""
|
||||||
|
short_id = str(self.id).replace("-100", "")
|
||||||
|
shift = int(-1 * pow(10, len(short_id) + 2))
|
||||||
|
return shift - self.id
|
||||||
|
|
|
||||||
|
|
@ -1760,6 +1760,25 @@ class Message(TelegramObject):
|
||||||
|
|
||||||
return DeleteMessage(chat_id=self.chat.id, message_id=self.message_id)
|
return DeleteMessage(chat_id=self.chat.id, message_id=self.message_id)
|
||||||
|
|
||||||
|
def get_url(self, force_private: bool = False) -> Optional[str]:
|
||||||
|
"""
|
||||||
|
Returns message URL. Cannot be used in private (one-to-one) chats.
|
||||||
|
If chat has a username, returns URL like https://t.me/username/message_id
|
||||||
|
Otherwise (or if {force_private} flag is set), returns https://t.me/c/shifted_chat_id/message_id
|
||||||
|
|
||||||
|
:param force_private: if set, a private URL is returned even for a public chat
|
||||||
|
:return: string with full message URL
|
||||||
|
"""
|
||||||
|
if self.chat.type in ("private", "group"):
|
||||||
|
return None
|
||||||
|
|
||||||
|
if not self.chat.username or force_private:
|
||||||
|
chat_value = f"c/{self.chat.shifted_id}"
|
||||||
|
else:
|
||||||
|
chat_value = self.chat.username
|
||||||
|
|
||||||
|
return f"https://t.me/{chat_value}/{self.message_id}"
|
||||||
|
|
||||||
|
|
||||||
class ContentType(helper.Helper):
|
class ContentType(helper.Helper):
|
||||||
mode = helper.HelperMode.snake_case
|
mode = helper.HelperMode.snake_case
|
||||||
|
|
|
||||||
51
tests/test_api/test_methods/test_get_url.py
Normal file
51
tests/test_api/test_methods/test_get_url.py
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
import datetime
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from aiogram.types import Chat, Message
|
||||||
|
|
||||||
|
from tests.mocked_bot import MockedBot
|
||||||
|
|
||||||
|
|
||||||
|
class TestGetMessageUrl:
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"chat_type,chat_id,chat_username,force_private,expected_result",
|
||||||
|
[
|
||||||
|
["private", 123456, "username", False, None],
|
||||||
|
["group", -123456, "username", False, None],
|
||||||
|
["supergroup", -1001234567890, None, False, "https://t.me/c/1234567890/10"],
|
||||||
|
["supergroup", -1001234567890, None, True, "https://t.me/c/1234567890/10"],
|
||||||
|
["supergroup", -1001234567890, "username", False, "https://t.me/username/10"],
|
||||||
|
["supergroup", -1001234567890, "username", True, "https://t.me/c/1234567890/10"],
|
||||||
|
["channel", -1001234567890, None, False, "https://t.me/c/1234567890/10"],
|
||||||
|
["channel", -1001234567890, None, True, "https://t.me/c/1234567890/10"],
|
||||||
|
["channel", -1001234567890, "username", False, "https://t.me/username/10"],
|
||||||
|
["channel", -1001234567890, "username", True, "https://t.me/c/1234567890/10"],
|
||||||
|
# 2 extra cases: 9-digit ID and 11-digit ID (without "-100")
|
||||||
|
["supergroup", -100123456789, None, True, "https://t.me/c/123456789/10"],
|
||||||
|
["supergroup", -10012345678901, None, True, "https://t.me/c/12345678901/10"],
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_method(
|
||||||
|
self,
|
||||||
|
bot: MockedBot,
|
||||||
|
chat_type: str,
|
||||||
|
chat_id: int,
|
||||||
|
chat_username: Optional[str],
|
||||||
|
force_private: bool,
|
||||||
|
expected_result: Optional[str],
|
||||||
|
):
|
||||||
|
|
||||||
|
fake_chat = Chat(id=chat_id, username=chat_username, type=chat_type)
|
||||||
|
fake_message_id = 10
|
||||||
|
fake_message = Message(
|
||||||
|
message_id=fake_message_id,
|
||||||
|
date=datetime.datetime.now(),
|
||||||
|
text="test",
|
||||||
|
chat=fake_chat,
|
||||||
|
)
|
||||||
|
|
||||||
|
if expected_result is None:
|
||||||
|
assert fake_message.get_url(force_private=force_private) is None
|
||||||
|
else:
|
||||||
|
assert fake_message.get_url(force_private=force_private) == expected_result
|
||||||
Loading…
Add table
Add a link
Reference in a new issue