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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy