Skip to content

Commit 94abf16

Browse files
jonowoEldinnie
authored andcommitted
Add t.me links for User, Chat and Message if available and update User.mention_* (python-telegram-bot#1092)
* Add User.link and update User.mention_* * Add Chat.link * Add Message.link * Link returns None on default * Add test link
1 parent 3d8abc1 commit 94abf16

File tree

6 files changed

+64
-18
lines changed

6 files changed

+64
-18
lines changed

telegram/chat.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,14 @@ def __init__(self,
116116
self.bot = bot
117117
self._id_attrs = (self.id,)
118118

119+
@property
120+
def link(self):
121+
""":obj:`str`: Convenience property. If the chat has a :attr:`username`, returns a t.me
122+
link of the chat."""
123+
if self.username:
124+
return "https://t.me/{}".format(self.username)
125+
return None
126+
119127
@classmethod
120128
def de_json(cls, data, bot):
121129
if not data:

telegram/message.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,14 @@ def chat_id(self):
303303
""":obj:`int`: Shortcut for :attr:`telegram.Chat.id` for :attr:`chat`."""
304304
return self.chat.id
305305

306+
@property
307+
def link(self):
308+
""":obj:`str`: Convenience property. If the chat of the message is a supergroup or a
309+
channel and has a :attr:`Chat.username`, returns a t.me link of the message."""
310+
if self.chat.type in (Chat.SUPERGROUP, Chat.CHANNEL) and self.chat.username:
311+
return "https://t.me/{}/{}".format(self.chat.username, self.message_id)
312+
return None
313+
306314
@classmethod
307315
def de_json(cls, data, bot):
308316
if not data:

telegram/user.py

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -71,26 +71,30 @@ def __init__(self,
7171

7272
@property
7373
def name(self):
74-
"""
75-
:obj:`str`: Convenience property. If available, returns the user's :attr:`username`
76-
prefixed with "@". If :attr:`username` is not available, returns :attr:`full_name`.
77-
78-
"""
74+
""":obj:`str`: Convenience property. If available, returns the user's :attr:`username`
75+
prefixed with "@". If :attr:`username` is not available, returns :attr:`full_name`."""
7976
if self.username:
8077
return '@{}'.format(self.username)
8178
return self.full_name
8279

8380
@property
8481
def full_name(self):
85-
"""
86-
:obj:`str`: Convenience property. The user's :attr:`first_name`, followed by (if available)
87-
:attr:`last_name`.
82+
""":obj:`str`: Convenience property. The user's :attr:`first_name`, followed by (if
83+
available) :attr:`last_name`."""
8884

89-
"""
9085
if self.last_name:
9186
return u'{} {}'.format(self.first_name, self.last_name)
9287
return self.first_name
9388

89+
@property
90+
def link(self):
91+
""":obj:`str`: Convenience property. If :attr:`username` is available, returns a t.me link
92+
of the user."""
93+
94+
if self.username:
95+
return "https://t.me/{}".format(self.username)
96+
return None
97+
9498
@classmethod
9599
def de_json(cls, data, bot):
96100
if not data:
@@ -124,28 +128,28 @@ def de_list(cls, data, bot):
124128
def mention_markdown(self, name=None):
125129
"""
126130
Args:
127-
name (:obj:`str`): If provided, will overwrite the user's name.
131+
name (:obj:`str`): The name used as a link for the user. Defaults to :attr:`full_name`.
128132
129133
Returns:
130134
:obj:`str`: The inline mention for the user as markdown.
135+
131136
"""
132-
if not name:
133-
return util_mention_markdown(self.id, self.name)
134-
else:
137+
if name:
135138
return util_mention_markdown(self.id, name)
139+
return util_mention_markdown(self.id, self.full_name)
136140

137141
def mention_html(self, name=None):
138142
"""
139143
Args:
140-
name (:obj:`str`): If provided, will overwrite the user's name.
144+
name (:obj:`str`): The name used as a link for the user. Defaults to :attr:`full_name`.
141145
142146
Returns:
143147
:obj:`str`: The inline mention for the user as HTML.
148+
144149
"""
145-
if not name:
146-
return util_mention_html(self.id, self.name)
147-
else:
150+
if name:
148151
return util_mention_html(self.id, name)
152+
return util_mention_html(self.id, self.full_name)
149153

150154
def send_message(self, *args, **kwargs):
151155
"""Shortcut for::

tests/test_chat.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
@pytest.fixture(scope='class')
2727
def chat(bot):
28-
return Chat(TestChat.id, TestChat.title, TestChat.type,
28+
return Chat(TestChat.id, TestChat.title, TestChat.type, username=TestChat.username,
2929
all_members_are_administrators=TestChat.all_members_are_administrators,
3030
bot=bot, sticker_set_name=TestChat.sticker_set_name,
3131
can_set_sticker_set=TestChat.can_set_sticker_set)
@@ -35,6 +35,7 @@ class TestChat(object):
3535
id = -28767330
3636
title = 'ToledosPalaceBot - Group'
3737
type = 'group'
38+
username = 'username'
3839
all_members_are_administrators = False
3940
sticker_set_name = 'stickers'
4041
can_set_sticker_set = False
@@ -44,6 +45,7 @@ def test_de_json(self, bot):
4445
'id': self.id,
4546
'title': self.title,
4647
'type': self.type,
48+
'username': self.username,
4749
'all_members_are_administrators': self.all_members_are_administrators,
4850
'sticker_set_name': self.sticker_set_name,
4951
'can_set_sticker_set': self.can_set_sticker_set
@@ -53,6 +55,7 @@ def test_de_json(self, bot):
5355
assert chat.id == self.id
5456
assert chat.title == self.title
5557
assert chat.type == self.type
58+
assert chat.username == self.username
5659
assert chat.all_members_are_administrators == self.all_members_are_administrators
5760
assert chat.sticker_set_name == self.sticker_set_name
5861
assert chat.can_set_sticker_set == self.can_set_sticker_set
@@ -64,8 +67,14 @@ def test_to_dict(self, chat):
6467
assert chat_dict['id'] == chat.id
6568
assert chat_dict['title'] == chat.title
6669
assert chat_dict['type'] == chat.type
70+
assert chat_dict['username'] == chat.username
6771
assert chat_dict['all_members_are_administrators'] == chat.all_members_are_administrators
6872

73+
def test_link(self, chat):
74+
assert chat.link == 'https://t.me/{}'.format(chat.username)
75+
chat.username = None
76+
assert chat.link is None
77+
6978
def test_send_action(self, monkeypatch, chat):
7079
def test(*args, **kwargs):
7180
id = args[1] == chat.id

tests/test_message.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,18 @@ def test_parse_entities_url_emoji(self):
282282
def test_chat_id(self, message):
283283
assert message.chat_id == message.chat.id
284284

285+
def test_link(self, message):
286+
assert message.link is None
287+
message.chat.username = 'username'
288+
message.chat.type = 'supergroup'
289+
assert message.link == 'https://t.me/{}/{}'.format(message.chat.username,
290+
message.message_id)
291+
message.chat.type = 'channel'
292+
assert message.link == 'https://t.me/{}/{}'.format(message.chat.username,
293+
message.message_id)
294+
message.chat.type = 'private'
295+
assert message.link is None
296+
285297
def test_effective_attachment(self, message_params):
286298
for i in ('audio', 'game', 'document', 'photo', 'sticker', 'video', 'voice', 'video_note',
287299
'contact', 'location', 'venue', 'invoice', 'invoice', 'successful_payment'):

tests/test_user.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,11 @@ def test_full_name(self, user):
9696
user.last_name = None
9797
assert user.full_name == u'first\u2022name'
9898

99+
def test_link(self, user):
100+
assert user.link == 'https://t.me/{}'.format(user.username)
101+
user.username = None
102+
assert user.link is None
103+
99104
def test_get_profile_photos(self, monkeypatch, user):
100105
def test(_, *args, **kwargs):
101106
return args[0] == user.id

0 commit comments

Comments
 (0)