diff --git a/telegram/bot.py b/telegram/bot.py index bb9b3ecf5b2..c4c1abff0e3 100644 --- a/telegram/bot.py +++ b/telegram/bot.py @@ -2835,6 +2835,39 @@ def set_chat_permissions(self, chat_id, permissions, timeout=None, **kwargs): return result + @log + def set_chat_administrator_custom_title(self, chat_id, user_id, custom_title, timeout=None, **kwargs): + """ + Use this method to set custom title for owner or administrators. The bot must be an + administrator in the supergroup for this to work. Returns True on success. + + Args: + chat_id (:obj:`int` | :obj:`str`): Unique identifier for the target chat or username of + the target supergroup (in the format `@supergroupusername`). + user_id (:obj:`int`): Unique identifier of the target administrator. + custom_title (:obj:`str`) New custom title for the administrator. It must be a string + with len 0-16 characters, emoji are not allowed. + timeout (:obj:`int` | :obj:`float`, optional): If this value is specified, use it as + the read timeout from the server (instead of the one specified during creation of + the connection pool). + **kwargs (:obj:`dict`): Arbitrary keyword arguments + + Returns: + :obj:`bool`: Returns True on success. + + Raises: + :class:`telegram.TelegramError` + + """ + url = '{0}/setChatAdministratorCustomTitle'.format(self.base_url) + + data = {'chat_id': chat_id, 'user_id': user_id, 'custom_title': custom_title} + data.update(kwargs) + + result = self._request.post(url, data, timeout=timeout) + + return result + @log def export_chat_invite_link(self, chat_id, timeout=None, **kwargs): """ diff --git a/telegram/chat.py b/telegram/chat.py index 2afc03ee64c..5e32c397241 100644 --- a/telegram/chat.py +++ b/telegram/chat.py @@ -40,6 +40,8 @@ class Chat(TelegramObject): Returned only in get_chat. permissions (:class:`telegram.ChatPermission`): Optional. Default chat member permissions, for groups and supergroups. Returned only in getChat. + slow_mode_delay (:obj:`int`): Optional. For supergroups, the minimum allowed delay between + consecutive messages sent by each unpriviledged user. Returned only in getChat. sticker_set_name (:obj:`str`): Optional. For supergroups, name of Group sticker set. can_set_sticker_set (:obj:`bool`): Optional. ``True``, if the bot can change group the sticker set. @@ -65,6 +67,8 @@ class Chat(TelegramObject): Returned only in get_chat. permissions (:class:`telegram.ChatPermission`): Optional. Default chat member permissions, for groups and supergroups. Returned only in getChat. + slow_mode_delay (:obj:`int`, optional): For supergroups, the minimum allowed delay between + consecutive messages sent by each unpriviledged user. Returned only in getChat. bot (:class:`telegram.Bot`, optional): The Bot to use for instance methods. sticker_set_name (:obj:`str`, optional): For supergroups, name of Group sticker set. Returned only in get_chat. @@ -96,6 +100,7 @@ def __init__(self, invite_link=None, pinned_message=None, permissions=None, + slow_mode_delay=None, sticker_set_name=None, can_set_sticker_set=None, **kwargs): @@ -114,6 +119,7 @@ def __init__(self, self.invite_link = invite_link self.pinned_message = pinned_message self.permissions = permissions + self.slow_mode_delay = slow_mode_delay self.sticker_set_name = sticker_set_name self.can_set_sticker_set = can_set_sticker_set @@ -237,6 +243,17 @@ def set_permissions(self, *args, **kwargs): """ return self.bot.set_chat_permissions(self.id, *args, **kwargs) + def set_administrator_custom_title(self, *args, **kwargs): + """Shortcut for:: + + bot.set_chat_administrator_custom_title(update.message.chat.id, *args, **kwargs) + + Returns: + :obj:`bool`: If the action was sent successfully. + + """ + return self.bot.set_chat_administrator_custom_title(self.id, *args, **kwargs) + def send_message(self, *args, **kwargs): """Shortcut for:: diff --git a/telegram/chatmember.py b/telegram/chatmember.py index 9cb5526389e..3423733814d 100644 --- a/telegram/chatmember.py +++ b/telegram/chatmember.py @@ -28,6 +28,7 @@ class ChatMember(TelegramObject): Attributes: user (:class:`telegram.User`): Information about the user. status (:obj:`str`): The member's status in the chat. + custom_title (:obj:`str`): Optional. Custom title for owner and administrators. until_date (:class:`datetime.datetime`): Optional. Date when restrictions will be lifted for this user. can_be_edited (:obj:`bool`): Optional. If the bot is allowed to edit administrator @@ -62,6 +63,8 @@ class ChatMember(TelegramObject): user (:class:`telegram.User`): Information about the user. status (:obj:`str`): The member's status in the chat. Can be 'creator', 'administrator', 'member', 'restricted', 'left' or 'kicked'. + custom_title (:obj:`str`, optional): Owner and administrators only. + Custom title for this user. until_date (:class:`datetime.datetime`, optional): Restricted and kicked only. Date when restrictions will be lifted for this user. can_be_edited (:obj:`bool`, optional): Administrators only. True, if the bot is allowed to @@ -112,7 +115,7 @@ class ChatMember(TelegramObject): RESTRICTED = 'restricted' """:obj:`str`: 'restricted'""" - def __init__(self, user, status, until_date=None, can_be_edited=None, + def __init__(self, user, status, custom_title=None, until_date=None, can_be_edited=None, can_change_info=None, can_post_messages=None, can_edit_messages=None, can_delete_messages=None, can_invite_users=None, can_restrict_members=None, can_pin_messages=None, @@ -122,6 +125,7 @@ def __init__(self, user, status, until_date=None, can_be_edited=None, # Required self.user = user self.status = status + self.custom_title = custom_title self.until_date = until_date self.can_be_edited = can_be_edited self.can_change_info = can_change_info diff --git a/tests/test_bot.py b/tests/test_bot.py index 586d13ccdd1..918f59b96b6 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -288,6 +288,16 @@ def test(_, url, data, *args, **kwargs): assert bot.set_chat_permissions(2, chat_permissions) + def test_set_chat_administrator_custom_title(self, monkeypatch, bot): + def test(_, url, data, *args, **kwargs): + chat_id = data['chat_id'] == 2 + user_id = data['user_id'] == 32 + custom_title = data['custom_title'] == 'custom_title' + return chat_id and user_id and custom_title + + monkeypatch.setattr('telegram.utils.request.Request.post', test) + assert bot.set_chat_administrator_custom_title(2, 32, 'custom_title') + # TODO: Needs improvement. Need an incoming callbackquery to test def test_answer_callback_query(self, monkeypatch, bot): # For now just test that our internals pass the correct data diff --git a/tests/test_chat.py b/tests/test_chat.py index 23e95806a15..8bb1653e6b0 100644 --- a/tests/test_chat.py +++ b/tests/test_chat.py @@ -29,7 +29,8 @@ def chat(bot): all_members_are_administrators=TestChat.all_members_are_administrators, bot=bot, sticker_set_name=TestChat.sticker_set_name, can_set_sticker_set=TestChat.can_set_sticker_set, - permissions=TestChat.permissions) + permissions=TestChat.permissions, + slow_mode_delay=TestChat.slow_mode_delay) class TestChat(object): @@ -45,6 +46,7 @@ class TestChat(object): can_change_info=False, can_invite_users=True, ) + slow_mode_delay = 30 def test_de_json(self, bot): json_dict = { @@ -55,7 +57,8 @@ def test_de_json(self, bot): 'all_members_are_administrators': self.all_members_are_administrators, 'sticker_set_name': self.sticker_set_name, 'can_set_sticker_set': self.can_set_sticker_set, - 'permissions': self.permissions.to_dict() + 'permissions': self.permissions.to_dict(), + 'slow_mode_delay': self.slow_mode_delay } chat = Chat.de_json(json_dict, bot) @@ -67,6 +70,7 @@ def test_de_json(self, bot): assert chat.sticker_set_name == self.sticker_set_name assert chat.can_set_sticker_set == self.can_set_sticker_set assert chat.permissions == self.permissions + assert chat.slow_mode_delay == self.slow_mode_delay def test_to_dict(self, chat): chat_dict = chat.to_dict() @@ -78,6 +82,7 @@ def test_to_dict(self, chat): assert chat_dict['username'] == chat.username assert chat_dict['all_members_are_administrators'] == chat.all_members_are_administrators assert chat_dict['permissions'] == chat.permissions.to_dict() + assert chat_dict['slow_mode_delay'] == chat.slow_mode_delay def test_link(self, chat): assert chat.link == 'https://t.me/{}'.format(chat.username) @@ -151,6 +156,16 @@ def test(*args, **kwargs): monkeypatch.setattr('telegram.Bot.set_chat_permissions', test) assert chat.set_permissions(self.permissions) + def test_set_administrator_custom_title(self, monkeypatch, chat): + def test(*args, **kwargs): + chat_id = args[1] == chat.id + user_id = args[2] == 42 + custom_title = args[3] == 'custom_title' + return chat_id and user_id and custom_title + + monkeypatch.setattr('telegram.Bot.set_chat_administrator_custom_title', test) + assert chat.set_administrator_custom_title(42, 'custom_title') + def test_instance_method_send_message(self, monkeypatch, chat): def test(*args, **kwargs): return args[1] == chat.id and args[2] == 'test' diff --git a/tests/test_chatmember.py b/tests/test_chatmember.py index edd66034b5c..0f3aebf4b35 100644 --- a/tests/test_chatmember.py +++ b/tests/test_chatmember.py @@ -47,8 +47,11 @@ def test_de_json_required_args(self, bot, user): def test_de_json_all_args(self, bot, user): time = datetime.datetime.utcnow() + custom_title = 'custom_title' + json_dict = {'user': user.to_dict(), 'status': self.status, + 'custom_title': custom_title, 'until_date': to_timestamp(time), 'can_be_edited': False, 'can_change_info': True, @@ -69,6 +72,7 @@ def test_de_json_all_args(self, bot, user): assert chat_member.user == user assert chat_member.status == self.status + assert chat_member.custom_title == custom_title assert chat_member.can_be_edited is False assert chat_member.can_change_info is True assert chat_member.can_post_messages is False