Skip to content
19 changes: 13 additions & 6 deletions telebot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6250,19 +6250,23 @@ 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,
def send_gift(self, gift_id: str, user_id: Optional[Union[str, int]] = None, chat_id: Optional[Union[str, int]] = None, text: Optional[str]=None, text_parse_mode: Optional[str]=None,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot change order of fixed parameters or ones who had been fixed. :(((

In this case I propose to make all parameters optional and check inside gift_id to be not None. Or even not check: Telegram will return error himself.

Mark in manual, that gift_id IS NOT optional in fact.

def send_gift(self, user_id: Optional[Union[str, int]] = None, gift_id: Optional[Union[str, int]] = None, chat_id: Optional[Union[str, int]] = None, text: Optional[str]=None, text_parse_mode: Optional[str]=None,...

if not gift_id:
    ValueError("gift_id must be specified.")

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get annoyed to see how we are still 'outdated' from the API. Will fix it :(

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.

Telegram documentation: https://core.telegram.org/bots/api#sendgift

:param user_id: Unique identifier of the target user that will receive the gift
:type user_id: :obj:`int`

:param gift_id: Identifier of the gift
:type gift_id: :obj:`str`

:param user_id: Required if chat_id is not specified. Unique identifier of the target user who will receive the gift.
:type user_id::obj:`int` | :obj:`str`

:param chat_id: Required if user_id is not specified. Unique identifier for the chat or username of the channel
(in the format @channelusername) that will receive the gift.
:type chat_id: :obj:`int` | :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`

Expand All @@ -6278,8 +6282,11 @@ 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,
pay_for_upgrade=pay_for_upgrade)
if user_id is None and chat_id is None:
raise ValueError("Either user_id or chat_id must be specified.")

return apihelper.send_gift(self.token, gift_id, text=text, text_parse_mode=text_parse_mode, text_entities=text_entities,
pay_for_upgrade=pay_for_upgrade, chat_id=chat_id, user_id=user_id)

def verify_user(self, user_id: int, custom_description: Optional[str]=None) -> bool:
"""
Expand Down
7 changes: 6 additions & 1 deletion telebot/apihelper.py
Original file line number Diff line number Diff line change
Expand Up @@ -1929,7 +1929,8 @@ 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, pay_for_upgrade=None):
def send_gift(token, gift_id, text=None, text_parse_mode=None, text_entities=None, pay_for_upgrade=None,
chat_id=None, user_id=None):
method_url = 'sendGift'
payload = {'user_id': user_id, 'gift_id': gift_id}
if text:
Expand All @@ -1940,6 +1941,10 @@ def send_gift(token, user_id, gift_id, text=None, text_parse_mode=None, text_ent
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
if chat_id:
payload['chat_id'] = chat_id
if user_id:
payload['user_id'] = user_id
return _make_request(token, method_url, params=payload, method='post')


Expand Down
21 changes: 15 additions & 6 deletions telebot/async_telebot.py
Original file line number Diff line number Diff line change
Expand Up @@ -7707,19 +7707,24 @@ 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, pay_for_upgrade: Optional[bool]=None) -> bool:
async def send_gift(self, gift_id: str, user_id: Optional[Union[str, int]] = None, chat_id: Optional[Union[str, int]] = None,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same here: not possible to change fixed parameters order. :(

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.

Telegram documentation: https://core.telegram.org/bots/api#sendgift

:param user_id: Unique identifier of the target user that will receive the gift
:type user_id: :obj:`int`

:param gift_id: Identifier of the gift
:type gift_id: :obj:`str`

:param user_id: Required if chat_id is not specified. Unique identifier of the target user who will receive the gift.
:type user_id::obj:`int` | :obj:`str`

:param chat_id: Required if user_id is not specified. Unique identifier for the chat or username of the channel
(in the format @channelusername) that will receive the gift.
:type chat_id: :obj:`int` | :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`

Expand All @@ -7735,7 +7740,11 @@ 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, pay_for_upgrade=pay_for_upgrade)
if user_id is None and chat_id is None:
raise ValueError("Either user_id or chat_id must be specified.")

return await asyncio_helper.send_gift(self.token, gift_id, text, text_parse_mode, text_entities, pay_for_upgrade=pay_for_upgrade,
chat_id=chat_id, user_id=user_id)

async def verify_user(self, user_id: int, custom_description: Optional[str]=None) -> bool:
"""
Expand Down
7 changes: 6 additions & 1 deletion telebot/asyncio_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -1916,7 +1916,8 @@ 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, pay_for_upgrade=None):
async def send_gift(token, gift_id, text=None, text_parse_mode=None, text_entities=None, pay_for_upgrade=None,
user_id=None, chat_id=None):
method_url = 'sendGift'
payload = {'user_id': user_id, 'gift_id': gift_id}
if text:
Expand All @@ -1927,6 +1928,10 @@ async def send_gift(token, user_id, gift_id, text=None, text_parse_mode=None, te
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
if chat_id:
payload['chat_id'] = chat_id
if user_id:
payload['user_id'] = user_id
return await _process_request(token, method_url, params=payload, method='post')

async def verify_user(token, user_id, custom_description=None):
Expand Down