Skip to content

Commit

Permalink
Bot API 8.2 full support
Browse files Browse the repository at this point in the history
  • Loading branch information
coder2020official committed Jan 2, 2025
1 parent c56f9de commit b0afe2d
Show file tree
Hide file tree
Showing 7 changed files with 209 additions and 21 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<p align="center">A simple, but extensible Python implementation for the <a href="https://core.telegram.org/bots/api">Telegram Bot API</a>.</p>
<p align="center">Both synchronous and asynchronous.</p>

## <p align="center">Supported Bot API version: <a href="https://core.telegram.org/bots/api#november-17-2024"><img src="https://img.shields.io/badge/Bot%20API-8.1-blue?logo=telegram" alt="Supported Bot API version"></a>
## <p align="center">Supported Bot API version: <a href="https://core.telegram.org/bots/api#january-1-2025"><img src="https://img.shields.io/badge/Bot%20API-8.2-blue?logo=telegram" alt="Supported Bot API version"></a>

<h2><a href='https://pytba.readthedocs.io/en/latest/index.html'>Official documentation</a></h2>
<h2><a href='https://pytba.readthedocs.io/ru/latest/index.html'>Official ru documentation</a></h2>
Expand Down
72 changes: 70 additions & 2 deletions telebot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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`
Expand All @@ -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:
"""
Expand Down
38 changes: 31 additions & 7 deletions telebot/apihelper.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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):
Expand Down Expand Up @@ -2271,12 +2301,6 @@ def convert_input_media_array(array):
if media_dict['media'].startswith('attach://'):
key = media_dict['media'].replace('attach://', '')
files[key] = input_media.media
if 'thumbnail' in media_dict:
thumbnail = media_dict['thumbnail']
if isinstance(thumbnail, types.InputFile):
thumbnail_key = 'thumbnail_' + key
files[thumbnail_key] = thumbnail
media_dict['thumbnail'] = 'attach://' + thumbnail_key
media.append(media_dict)
return json.dumps(media), files

Expand Down
72 changes: 70 additions & 2 deletions telebot/async_telebot.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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`
Expand All @@ -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)

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)

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:
"""
Expand Down
34 changes: 27 additions & 7 deletions telebot/asyncio_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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):
Expand Down Expand Up @@ -2243,12 +2269,6 @@ async def convert_input_media_array(array):
if media_dict['media'].startswith('attach://'):
key = media_dict['media'].replace('attach://', '')
files[key] = input_media.media
if 'thumbnail' in media_dict:
thumbnail = media_dict['thumbnail']
if isinstance(thumbnail, types.InputFile):
thumbnail_key = 'thumbnail_' + key
files[thumbnail_key] = thumbnail
media_dict['thumbnail'] = 'attach://' + thumbnail_key
media.append(media_dict)
return json.dumps(media), files

Expand Down
10 changes: 9 additions & 1 deletion telebot/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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`
Expand All @@ -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):
Expand Down
2 changes: 1 addition & 1 deletion telebot/version.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Versions should comply with PEP440.
# This line is parsed in setup.py:
__version__ = '4.25.0'
__version__ = '4.24.0'

0 comments on commit b0afe2d

Please sign in to comment.