diff --git a/README.md b/README.md
index bbc6f1698..ff1b5159f 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@
A simple, but extensible Python implementation for the Telegram Bot API.
Both synchronous and asynchronous.
-## Supported Bot API version:
+##
Supported Bot API version:
diff --git a/telebot/__init__.py b/telebot/__init__.py
index 51eb63d4a..ae210f130 100644
--- a/telebot/__init__.py
+++ b/telebot/__init__.py
@@ -6250,7 +6250,8 @@ def delete_sticker_set(self, name:str) -> bool:
"""
return apihelper.delete_sticker_set(self.token, name)
- def send_gift(self, user_id: int, gift_id: str, text: Optional[str]=None, text_parse_mode: Optional[str]=None, text_entities: Optional[List[types.MessageEntity]]=None) -> bool:
+ def send_gift(self, user_id: int, gift_id: str, text: Optional[str]=None, text_parse_mode: Optional[str]=None,
+ text_entities: Optional[List[types.MessageEntity]]=None, pay_for_upgrade: Optional[bool]=None) -> bool:
"""
Sends a gift to the given user. The gift can't be converted to Telegram Stars by the user. Returns True on success.
@@ -6262,6 +6263,9 @@ def send_gift(self, user_id: int, gift_id: str, text: Optional[str]=None, text_p
:param gift_id: Identifier of the gift
:type gift_id: :obj:`str`
+ :param pay_for_upgrade: Pass True to pay for the gift upgrade from the bot's balance, thereby making the upgrade free for the receiver
+ :type pay_for_upgrade: :obj:`bool`
+
:param text: Text that will be shown along with the gift; 0-255 characters
:type text: :obj:`str`
@@ -6274,7 +6278,71 @@ def send_gift(self, user_id: int, gift_id: str, text: Optional[str]=None, text_p
:return: Returns True on success.
:rtype: :obj:`bool`
"""
- return apihelper.send_gift(self.token, user_id, gift_id, text=text, text_parse_mode=text_parse_mode, text_entities=text_entities)
+ return apihelper.send_gift(self.token, user_id, gift_id, text=text, text_parse_mode=text_parse_mode, text_entities=text_entities,
+ pay_for_upgrade=pay_for_upgrade)
+
+ def verify_user(self, user_id: int, custom_description: Optional[str]=None) -> bool:
+ """
+ Verifies a user on behalf of the organization which is represented by the bot. Returns True on success.
+
+ Telegram documentation: https://core.telegram.org/bots/api#verifyuser
+
+ :param user_id: Unique identifier of the target user
+ :type user_id: :obj:`int`
+
+ :param custom_description: Custom description for the verification; 0-70 characters. Must be empty if the organization isn't allowed to provide a custom verification description.
+ :type custom_description: :obj:`str`
+
+ :return: Returns True on success.
+ :rtype: :obj:`bool`
+ """
+ return apihelper.verify_user(self.token, user_id, custom_description=custom_description)
+
+ def verify_chat(self, chat_id: Union[int, str], custom_description: Optional[str]=None) -> bool:
+ """
+ Verifies a chat on behalf of the organization which is represented by the bot. Returns True on success.
+
+ Telegram documentation: https://core.telegram.org/bots/api#verifychat
+
+ :param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
+ :type chat_id: :obj:`int` | :obj:`str`
+
+ :param custom_description: Custom description for the verification; 0-70 characters. Must be empty if the organization isn't allowed to provide a custom verification description.
+ :type custom_description: :obj:`str`
+
+ :return: Returns True on success.
+ :rtype: :obj:`bool`
+ """
+ return apihelper.verify_chat(self.token, chat_id, custom_description=custom_description)
+
+ def remove_user_verification(self, user_id: int) -> bool:
+ """
+ Removes verification from a user who is currently verified on behalf of the organization represented by the bot. Returns True on success.
+
+ Telegram documentation: https://core.telegram.org/bots/api#removeuserverification
+
+ :param user_id: Unique identifier of the target user
+ :type user_id: :obj:`int`
+
+ :return: Returns True on success.
+ :rtype: :obj:`bool`
+ """
+
+ return apihelper.remove_user_verification(self.token, user_id)
+
+ def remove_chat_verification(self, chat_id: Union[int, str]) -> bool:
+ """
+ Removes verification from a chat that is currently verified on behalf of the organization represented by the bot. Returns True on success.
+
+ Telegram documentation: https://core.telegram.org/bots/api#removechatverification
+
+ :param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
+ :type chat_id: :obj:`int` | :obj:`str`
+
+ :return: Returns True on success.
+ :rtype: :obj:`bool`
+ """
+ return apihelper.remove_chat_verification(self.token, chat_id)
def get_available_gifts(self) -> types.Gifts:
"""
diff --git a/telebot/apihelper.py b/telebot/apihelper.py
index 3044b226d..69f3f8e4f 100644
--- a/telebot/apihelper.py
+++ b/telebot/apihelper.py
@@ -1929,7 +1929,7 @@ def get_available_gifts(token):
return _make_request(token, method_url)
-def send_gift(token, user_id, gift_id, text=None, text_parse_mode=None, text_entities=None):
+def send_gift(token, user_id, gift_id, text=None, text_parse_mode=None, text_entities=None, pay_for_upgrade=None):
method_url = 'sendGift'
payload = {'user_id': user_id, 'gift_id': gift_id}
if text:
@@ -1938,6 +1938,36 @@ def send_gift(token, user_id, gift_id, text=None, text_parse_mode=None, text_ent
payload['text_parse_mode'] = text_parse_mode
if text_entities:
payload['text_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(text_entities))
+ if pay_for_upgrade is not None:
+ payload['pay_for_upgrade'] = pay_for_upgrade
+ return _make_request(token, method_url, params=payload, method='post')
+
+
+def verify_user(token, user_id, custom_description=None):
+ method_url = 'verifyUser'
+ payload = {'user_id': user_id}
+ if custom_description:
+ payload['custom_description'] = custom_description
+ return _make_request(token, method_url, params=payload, method='post')
+
+
+def verify_chat(token, chat_id, custom_description=None):
+ method_url = 'verifyChat'
+ payload = {'chat_id': chat_id}
+ if custom_description:
+ payload['custom_description'] = custom_description
+ return _make_request(token, method_url, params=payload, method='post')
+
+
+def remove_user_verification(token, user_id):
+ method_url = 'removeUserVerification'
+ payload = {'user_id': user_id}
+ return _make_request(token, method_url, params=payload, method='post')
+
+
+def remove_chat_verification(token, chat_id):
+ method_url = 'removeChatVerification'
+ payload = {'chat_id': chat_id}
return _make_request(token, method_url, params=payload, method='post')
def set_sticker_emoji_list(token, sticker, emoji_list):
@@ -2276,7 +2306,7 @@ def convert_input_media_array(array):
if isinstance(thumbnail, types.InputFile):
thumbnail_key = 'thumbnail_' + key
files[thumbnail_key] = thumbnail
- media_dict['thumbnail'] = 'attach://' + thumbnail_key
+ media_dict['thumbnail'] = 'attach://' + thumbnail_key
media.append(media_dict)
return json.dumps(media), files
diff --git a/telebot/async_telebot.py b/telebot/async_telebot.py
index 0e298ace7..a3f717dff 100644
--- a/telebot/async_telebot.py
+++ b/telebot/async_telebot.py
@@ -7707,7 +7707,8 @@ async def delete_sticker_set(self, name:str) -> bool:
return await asyncio_helper.delete_sticker_set(self.token, name)
- async def send_gift(self, user_id: int, gift_id: str, text: Optional[str]=None, text_parse_mode: Optional[str]=None, text_entities: Optional[List[types.MessageEntity]]=None) -> bool:
+ async def send_gift(self, user_id: int, gift_id: str, text: Optional[str]=None, text_parse_mode: Optional[str]=None,
+ text_entities: Optional[List[types.MessageEntity]]=None, pay_for_upgrade: Optional[bool]=None) -> bool:
"""
Sends a gift to the given user. The gift can't be converted to Telegram Stars by the user. Returns True on success.
@@ -7719,6 +7720,9 @@ async def send_gift(self, user_id: int, gift_id: str, text: Optional[str]=None,
:param gift_id: Identifier of the gift
:type gift_id: :obj:`str`
+ :param pay_for_upgrade: Pass True to pay for the gift upgrade from the bot's balance, thereby making the upgrade free for the receiver
+ :type pay_for_upgrade: :obj:`bool`
+
:param text: Text that will be shown along with the gift; 0-255 characters
:type text: :obj:`str`
@@ -7731,7 +7735,71 @@ async def send_gift(self, user_id: int, gift_id: str, text: Optional[str]=None,
:return: Returns True on success.
:rtype: :obj:`bool`
"""
- return await asyncio_helper.send_gift(self.token, user_id, gift_id, text, text_parse_mode, text_entities)
+ return await asyncio_helper.send_gift(self.token, user_id, gift_id, text, text_parse_mode, text_entities, pay_for_upgrade=pay_for_upgrade)
+
+ async def verify_user(self, user_id: int, custom_description: Optional[str]=None) -> bool:
+ """
+ Verifies a user on behalf of the organization which is represented by the bot. Returns True on success.
+
+ Telegram documentation: https://core.telegram.org/bots/api#verifyuser
+
+ :param user_id: Unique identifier of the target user
+ :type user_id: :obj:`int`
+
+ :param custom_description: Custom description for the verification; 0-70 characters. Must be empty if the organization isn't allowed to provide a custom verification description.
+ :type custom_description: :obj:`str`
+
+ :return: Returns True on success.
+ :rtype: :obj:`bool`
+ """
+ return await asyncio_helper.verify_user(self.token, user_id, custom_description=custom_description)
+
+ async def verify_chat(self, chat_id: Union[int, str], custom_description: Optional[str]=None) -> bool:
+ """
+ Verifies a chat on behalf of the organization which is represented by the bot. Returns True on success.
+
+ Telegram documentation: https://core.telegram.org/bots/api#verifychat
+
+ :param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
+ :type chat_id: :obj:`int` | :obj:`str`
+
+ :param custom_description: Custom description for the verification; 0-70 characters. Must be empty if the organization isn't allowed to provide a custom verification description.
+ :type custom_description: :obj:`str`
+
+ :return: Returns True on success.
+ :rtype: :obj:`bool`
+ """
+
+ return await asyncio_helper.verify_chat(self.token, chat_id, custom_description=custom_description)
+
+ async def remove_user_verification(self, user_id: int) -> bool:
+ """
+ Removes verification from a user who is currently verified on behalf of the organization represented by the bot. Returns True on success.
+
+ Telegram documentation: https://core.telegram.org/bots/api#removeuserverification
+
+ :param user_id: Unique identifier of the target user
+ :type user_id: :obj:`int`
+
+ :return: Returns True on success.
+ :rtype: :obj:`bool`
+
+ """
+ return await asyncio_helper.remove_user_verification(self.token, user_id)
+
+ async def remove_chat_verification(self, chat_id: Union[int, str]) -> bool:
+ """
+ Removes verification from a chat that is currently verified on behalf of the organization represented by the bot. Returns True on success.
+
+ Telegram documentation: https://core.telegram.org/bots/api#removechatverification
+
+ :param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
+ :type chat_id: :obj:`int` | :obj:`str`
+
+ :return: Returns True on success.
+ :rtype: :obj:`bool`
+ """
+ return await asyncio_helper.remove_chat_verification(self.token, chat_id)
async def get_available_gifts(self) -> types.Gifts:
"""
diff --git a/telebot/asyncio_helper.py b/telebot/asyncio_helper.py
index d11245d56..ba51a7daa 100644
--- a/telebot/asyncio_helper.py
+++ b/telebot/asyncio_helper.py
@@ -1916,7 +1916,7 @@ async def delete_sticker_set(token, name):
payload = {'name': name}
return await _process_request(token, method_url, params=payload, method='post')
-async def send_gift(token, user_id, gift_id, text=None, text_parse_mode=None, text_entities=None):
+async def send_gift(token, user_id, gift_id, text=None, text_parse_mode=None, text_entities=None, pay_for_upgrade=None):
method_url = 'sendGift'
payload = {'user_id': user_id, 'gift_id': gift_id}
if text:
@@ -1925,6 +1925,32 @@ async def send_gift(token, user_id, gift_id, text=None, text_parse_mode=None, te
payload['text_parse_mode'] = text_parse_mode
if text_entities:
payload['text_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(text_entities))
+ if pay_for_upgrade is not None:
+ payload['pay_for_upgrade'] = pay_for_upgrade
+ return await _process_request(token, method_url, params=payload, method='post')
+
+async def verify_user(token, user_id, custom_description=None):
+ method_url = 'verifyUser'
+ payload = {'user_id': user_id}
+ if custom_description:
+ payload['custom_description'] = custom_description
+ return await _process_request(token, method_url, params=payload, method='post')
+
+async def verify_chat(token, chat_id, custom_description=None):
+ method_url = 'verifyChat'
+ payload = {'chat_id': chat_id}
+ if custom_description:
+ payload['custom_description'] = custom_description
+ return await _process_request(token, method_url, params=payload, method='post')
+
+async def remove_user_verification(token, user_id):
+ method_url = 'removeUserVerification'
+ payload = {'user_id': user_id}
+ return await _process_request(token, method_url, params=payload, method='post')
+
+async def remove_chat_verification(token, chat_id):
+ method_url = 'removeChatVerification'
+ payload = {'chat_id': chat_id}
return await _process_request(token, method_url, params=payload, method='post')
async def get_available_gifts(token):
@@ -2248,7 +2274,7 @@ async def convert_input_media_array(array):
if isinstance(thumbnail, types.InputFile):
thumbnail_key = 'thumbnail_' + key
files[thumbnail_key] = thumbnail
- media_dict['thumbnail'] = 'attach://' + thumbnail_key
+ media_dict['thumbnail'] = 'attach://' + thumbnail_key
media.append(media_dict)
return json.dumps(media), files
diff --git a/telebot/types.py b/telebot/types.py
index e4dafaa7d..301ae61a1 100644
--- a/telebot/types.py
+++ b/telebot/types.py
@@ -4449,6 +4449,10 @@ def __init__(self, id: str, title: str, input_message_content: InputMessageConte
self.thumbnail_width: Optional[int] = thumbnail_width
self.thumbnail_height: Optional[int] = thumbnail_height
+ if hide_url:
+ log_deprecation_warning('The parameter "hide_url" is deprecated. Pass an empty string as url instead.')
+ self.url = ''
+
@property
def thumb_url(self) -> str:
@@ -11059,6 +11063,9 @@ class Gift(JsonDeserializable):
:param star_count: The number of Telegram Stars that must be paid to send the sticker
:type star_count: :obj:`int`
+ :param upgrade_star_count: Optional. The number of Telegram Stars that must be paid to upgrade the gift to a unique one
+ :type upgrade_star_count: :obj:`int`
+
:param total_count: Optional. The total number of the gifts of this type that can be sent; for limited gifts only
:type total_count: :obj:`int`
@@ -11069,12 +11076,13 @@ class Gift(JsonDeserializable):
:rtype: :class:`Gift`
"""
- def __init__(self, id, sticker, star_count, total_count=None, remaining_count=None, **kwargs):
+ def __init__(self, id, sticker, star_count, total_count=None, remaining_count=None, upgrade_star_count=None, **kwargs):
self.id: str = id
self.sticker: Sticker = sticker
self.star_count: int = star_count
self.total_count: Optional[int] = total_count
self.remaining_count: Optional[int] = remaining_count
+ self.upgrade_star_count: Optional[int] = upgrade_star_count
@classmethod
def de_json(cls, json_string):