1
0
mirror of https://github.com/eternnoir/pyTelegramBotAPI.git synced 2023-08-10 21:12:57 +03:00

Merge pull request #1855 from coder2020official/botapi6.4

Bot API 6.4
This commit is contained in:
Badiboy 2023-01-02 17:55:32 +03:00 committed by GitHub
commit 3b62ad4765
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 438 additions and 43 deletions

View File

@ -11,7 +11,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-5-2022">6.3</a>!
## <p align="center">Supported Bot API version: <a href="https://core.telegram.org/bots/api#december-30-2022">6.4</a>!
<h2><a href='https://pytba.readthedocs.io/en/latest/index.html'>Official documentation</a></h2>

View File

@ -1763,7 +1763,8 @@ class TeleBot:
allow_sending_without_reply: Optional[bool]=None,
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
timeout: Optional[int]=None,
message_thread_id: Optional[int]=None) -> types.Message:
message_thread_id: Optional[int]=None,
has_spoiler: Optional[bool]=None) -> types.Message:
"""
Use this method to send photos. On success, the sent Message is returned.
@ -1809,6 +1810,9 @@ class TeleBot:
:param message_thread_id: Identifier of a message thread, in which the message will be sent
:type message_thread_id: :obj:`int`
:param has_spoiler: Pass True, if the photo should be sent as a spoiler
:type has_spoiler: :obj:`bool`
:return: On success, the sent Message is returned.
:rtype: :class:`telebot.types.Message`
"""
@ -1821,7 +1825,7 @@ class TeleBot:
apihelper.send_photo(
self.token, chat_id, photo, caption, reply_to_message_id, reply_markup,
parse_mode, disable_notification, timeout, caption_entities,
allow_sending_without_reply, protect_content, message_thread_id))
allow_sending_without_reply, protect_content, message_thread_id, has_spoiler))
# TODO: Rewrite this method like in API.
def send_audio(
@ -2171,7 +2175,8 @@ class TeleBot:
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
timeout: Optional[int]=None,
data: Optional[Union[Any, str]]=None,
message_thread_id: Optional[int]=None) -> types.Message:
message_thread_id: Optional[int]=None,
has_spoiler: Optional[bool]=None) -> types.Message:
"""
Use this method to send video files, Telegram clients support mp4 videos (other formats may be sent as Document).
@ -2233,6 +2238,9 @@ class TeleBot:
:param message_thread_id: Identifier of a message thread, in which the video will be sent
:type message_thread_id: :obj:`int`
:param has_spoiler: Pass True, if the video should be sent as a spoiler
:type has_spoiler: :obj:`bool`
:return: On success, the sent Message is returned.
:rtype: :class:`telebot.types.Message`
"""
@ -2249,7 +2257,7 @@ class TeleBot:
apihelper.send_video(
self.token, chat_id, video, duration, caption, reply_to_message_id, reply_markup,
parse_mode, supports_streaming, disable_notification, timeout, thumb, width, height,
caption_entities, allow_sending_without_reply, protect_content, message_thread_id))
caption_entities, allow_sending_without_reply, protect_content, message_thread_id, has_spoiler))
def send_animation(
self, chat_id: Union[int, str], animation: Union[Any, str],
@ -2266,7 +2274,8 @@ class TeleBot:
allow_sending_without_reply: Optional[bool]=None,
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
timeout: Optional[int]=None,
message_thread_id: Optional[int]=None) -> types.Message:
message_thread_id: Optional[int]=None,
has_spoiler: Optional[bool]=None) -> types.Message:
"""
Use this method to send animation files (GIF or H.264/MPEG-4 AVC video without sound).
On success, the sent Message is returned. Bots can currently send animation files of up to 50 MB in size, this limit may be changed in the future.
@ -2327,6 +2336,9 @@ class TeleBot:
:param message_thread_id: Identifier of a message thread, in which the video will be sent
:type message_thread_id: :obj:`int`
:param has_spoiler: Pass True, if the animation should be sent as a spoiler
:type has_spoiler: :obj:`bool`
:return: On success, the sent Message is returned.
:rtype: :class:`telebot.types.Message`
"""
@ -2339,7 +2351,7 @@ class TeleBot:
apihelper.send_animation(
self.token, chat_id, animation, duration, caption, reply_to_message_id,
reply_markup, parse_mode, disable_notification, timeout, thumb,
caption_entities, allow_sending_without_reply, protect_content, width, height, message_thread_id))
caption_entities, allow_sending_without_reply, protect_content, width, height, message_thread_id, has_spoiler))
# TODO: Rewrite this method like in API.
def send_video_note(
@ -2794,7 +2806,7 @@ class TeleBot:
allow_sending_without_reply, protect_content, message_thread_id))
def send_chat_action(
self, chat_id: Union[int, str], action: str, timeout: Optional[int]=None) -> bool:
self, chat_id: Union[int, str], action: str, timeout: Optional[int]=None, message_thread_id: Optional[int]=None) -> bool:
"""
Use this method when you need to tell the user that something is happening on the bot's side.
The status is set for 5 seconds or less (when a message arrives from your bot, Telegram clients clear its typing status).
@ -2817,10 +2829,13 @@ class TeleBot:
:param timeout: Timeout in seconds for the request.
:type timeout: :obj:`int`
:param message_thread_id: The thread identifier of a message from which the reply will be sent(supergroups only)
:type message_thread_id: :obj:`int`
:return: Returns True on success.
:rtype: :obj:`bool`
"""
return apihelper.send_chat_action(self.token, chat_id, action, timeout)
return apihelper.send_chat_action(self.token, chat_id, action, timeout, message_thread_id)
@util.deprecated(deprecation_text="Use ban_chat_member instead")
def kick_chat_member(
@ -4636,8 +4651,8 @@ class TeleBot:
def edit_forum_topic(
self, chat_id: Union[int, str],
message_thread_id: int, name: str,
icon_custom_emoji_id: str,
message_thread_id: int, name: Optional[str]=None,
icon_custom_emoji_id: Optional[str]=None
) -> bool:
"""
Use this method to edit name and icon of a topic in a forum supergroup chat. The bot must be an
@ -4652,10 +4667,13 @@ class TeleBot:
:param message_thread_id: Identifier of the topic to edit
:type message_thread_id: :obj:`int`
:param name: New name of the topic, 1-128 characters
:param name: Optional, New name of the topic, 1-128 characters. If not specififed or empty,
the current name of the topic will be kept
:type name: :obj:`str`
:param icon_custom_emoji_id: New custom emoji for the topic icon. Must be an emoji of type tgs and must be exactly 1 character long
:param icon_custom_emoji_id: Optional, New unique identifier of the custom emoji shown as the topic icon.
Use getForumTopicIconStickers to get all allowed custom emoji identifiers. Pass an empty string to remove the
icon. If not specified, the current icon will be kept
:type icon_custom_emoji_id: :obj:`str`
:return: On success, True is returned.
@ -4739,6 +4757,75 @@ class TeleBot:
"""
return apihelper.unpin_all_forum_topic_messages(self.token, chat_id, message_thread_id)
def edit_general_forum_topic(self, chat_id: Union[int, str], name: str) -> bool:
"""
Use this method to edit the name of the 'General' topic in a forum supergroup chat.
The bot must be an administrator in the chat for this to work and must have can_manage_topics administrator rights.
Returns True on success.
Telegram documentation: https://core.telegram.org/bots/api#editgeneralforumtopic
:param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
:type chat_id: :obj:`int` or :obj:`str`
:param name: New topic name, 1-128 characters
:type name: :obj:`str`
"""
return apihelper.edit_general_forum_topic(self.token, chat_id, name)
def close_general_forum_topic(self, chat_id: Union[int, str]) -> bool:
"""
Use this method to close the 'General' topic in a forum supergroup chat.
The bot must be an administrator in the chat for this to work and must have can_manage_topics administrator rights.
Returns True on success.
Telegram documentation: https://core.telegram.org/bots/api#closegeneralforumtopic
:param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
:type chat_id: :obj:`int` or :obj:`str`
"""
return apihelper.close_general_forum_topic(self.token, chat_id)
def reopen_general_forum_topic(self, chat_id: Union[int, str]) -> bool:
"""
Use this method to reopen the 'General' topic in a forum supergroup chat.
The bot must be an administrator in the chat for this to work and must have can_manage_topics administrator rights.
Returns True on success.
Telegram documentation: https://core.telegram.org/bots/api#reopengeneralforumtopic
:param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
:type chat_id: :obj:`int` or :obj:`str`
"""
return apihelper.reopen_general_forum_topic(self.token, chat_id)
def hide_general_forum_topic(self, chat_id: Union[int, str]) -> bool:
"""
Use this method to hide the 'General' topic in a forum supergroup chat.
The bot must be an administrator in the chat for this to work and must have can_manage_topics administrator rights.
Returns True on success.
Telegram documentation: https://core.telegram.org/bots/api#hidegeneralforumtopic
:param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
:type chat_id: :obj:`int` or :obj:`str`
"""
return apihelper.hide_general_forum_topic(self.token, chat_id)
def unhide_general_forum_topic(self, chat_id: Union[int, str]) -> bool:
"""
Use this method to unhide the 'General' topic in a forum supergroup chat.
The bot must be an administrator in the chat for this to work and must have can_manage_topics administrator rights.
Returns True on success.
Telegram documentation: https://core.telegram.org/bots/api#unhidegeneralforumtopic
:param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
:type chat_id: :obj:`int` or :obj:`str`
"""
return apihelper.unhide_general_forum_topic(self.token, chat_id)
def get_forum_topic_icon_stickers(self) -> List[types.Sticker]:
"""
Use this method to get custom emoji stickers, which can be used as a forum topic icon by any user.

View File

@ -459,7 +459,7 @@ def send_photo(
caption=None, reply_to_message_id=None, reply_markup=None,
parse_mode=None, disable_notification=None, timeout=None,
caption_entities=None, allow_sending_without_reply=None, protect_content=None,
message_thread_id=None):
message_thread_id=None, has_spoiler=None):
method_url = r'sendPhoto'
payload = {'chat_id': chat_id}
files = None
@ -489,6 +489,8 @@ def send_photo(
payload['protect_content'] = protect_content
if message_thread_id is not None:
payload['message_thread_id'] = message_thread_id
if has_spoiler is not None:
payload['has_spoiler'] = has_spoiler
return _make_request(token, method_url, params=payload, files=files, method='post')
@ -655,18 +657,20 @@ def send_contact(
return _make_request(token, method_url, params=payload)
def send_chat_action(token, chat_id, action, timeout=None):
def send_chat_action(token, chat_id, action, timeout=None, message_thread_id=None):
method_url = r'sendChatAction'
payload = {'chat_id': chat_id, 'action': action}
if timeout:
payload['timeout'] = timeout
if message_thread_id is not None:
payload['message_thread_id'] = message_thread_id
return _make_request(token, method_url, params=payload)
def send_video(token, chat_id, data, duration=None, caption=None, reply_to_message_id=None, reply_markup=None,
parse_mode=None, supports_streaming=None, disable_notification=None, timeout=None,
thumb=None, width=None, height=None, caption_entities=None, allow_sending_without_reply=None, protect_content=None,
message_thread_id=None):
message_thread_id=None, has_spoiler=None):
method_url = r'sendVideo'
payload = {'chat_id': chat_id}
files = None
@ -710,13 +714,16 @@ def send_video(token, chat_id, data, duration=None, caption=None, reply_to_messa
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
if has_spoiler is not None:
payload['has_spoiler'] = has_spoiler
return _make_request(token, method_url, params=payload, files=files, method='post')
def send_animation(
token, chat_id, data, duration=None, caption=None, reply_to_message_id=None, reply_markup=None,
parse_mode=None, disable_notification=None, timeout=None, thumb=None, caption_entities=None,
allow_sending_without_reply=None, protect_content=None, width=None, height=None, message_thread_id=None):
allow_sending_without_reply=None, protect_content=None, width=None, height=None, message_thread_id=None,
has_spoiler=None):
method_url = r'sendAnimation'
payload = {'chat_id': chat_id}
files = None
@ -758,6 +765,8 @@ def send_animation(
payload['height'] = height
if message_thread_id:
payload['message_thread_id'] = message_thread_id
if has_spoiler is not None:
payload['has_spoiler'] = has_spoiler
return _make_request(token, method_url, params=payload, files=files, method='post')
@ -1766,9 +1775,13 @@ def create_forum_topic(token, chat_id, name, icon_color=None, icon_custom_emoji_
payload['icon_custom_emoji_id'] = icon_custom_emoji_id
return _make_request(token, method_url, params=payload)
def edit_forum_topic(token, chat_id, message_thread_id, name, icon_custom_emoji_id):
def edit_forum_topic(token, chat_id, message_thread_id, name=None, icon_custom_emoji_id=None):
method_url = r'editForumTopic'
payload = {'chat_id': chat_id, 'message_thread_id': message_thread_id, 'name': name, 'icon_custom_emoji_id': icon_custom_emoji_id}
payload = {'chat_id': chat_id, 'message_thread_id': message_thread_id}
if name is not None:
payload['name'] = name
if icon_custom_emoji_id is not None:
payload['icon_custom_emoji_id'] = icon_custom_emoji_id
return _make_request(token, method_url, params=payload)
def close_forum_topic(token, chat_id, message_thread_id):
@ -1802,6 +1815,31 @@ def stop_poll(token, chat_id, message_id, reply_markup=None):
payload['reply_markup'] = _convert_markup(reply_markup)
return _make_request(token, method_url, params=payload)
def edit_general_forum_topic(token, chat_id, name):
method_url = r'editGeneralForumTopic'
payload = {'chat_id': chat_id, 'name': name}
return _make_request(token, method_url, params=payload)
def close_general_forum_topic(token, chat_id):
method_url = r'closeGeneralForumTopic'
payload = {'chat_id': chat_id}
return _make_request(token, method_url, params=payload)
def reopen_general_forum_topic(token, chat_id):
method_url = r'reopenGeneralForumTopic'
payload = {'chat_id': chat_id}
return _make_request(token, method_url, params=payload)
def hide_general_forum_topic(token, chat_id):
method_url = r'hideGeneralForumTopic'
payload = {'chat_id': chat_id}
return _make_request(token, method_url, params=payload)
def unhide_general_forum_topic(token, chat_id):
method_url = r'unhideGeneralForumTopic'
payload = {'chat_id': chat_id}
return _make_request(token, method_url, params=payload)
def _convert_list_json_serializable(results):
ret = ''

View File

@ -2627,7 +2627,8 @@ class AsyncTeleBot:
allow_sending_without_reply: Optional[bool]=None,
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
timeout: Optional[int]=None,
message_thread_id: Optional[int]=None) -> types.Message:
message_thread_id: Optional[int]=None,
has_spoiler: Optional[bool]=None) -> types.Message:
"""
Use this method to send photos. On success, the sent Message is returned.
@ -2673,6 +2674,9 @@ class AsyncTeleBot:
:param message_thread_id: Identifier of a message thread, in which the message will be sent
:type message_thread_id: :obj:`int`
:param has_spoiler: Pass True, if the photo should be sent as a spoiler
:type has_spoiler: :obj:`bool`
:return: On success, the sent Message is returned.
:rtype: :class:`telebot.types.Message`
"""
@ -2685,7 +2689,7 @@ class AsyncTeleBot:
await asyncio_helper.send_photo(
self.token, chat_id, photo, caption, reply_to_message_id, reply_markup,
parse_mode, disable_notification, timeout, caption_entities,
allow_sending_without_reply, protect_content, message_thread_id))
allow_sending_without_reply, protect_content, message_thread_id, has_spoiler))
async def send_audio(
self, chat_id: Union[int, str], audio: Union[Any, str],
@ -3031,7 +3035,8 @@ class AsyncTeleBot:
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
timeout: Optional[int]=None,
data: Optional[Union[Any, str]]=None,
message_thread_id: Optional[int]=None) -> types.Message:
message_thread_id: Optional[int]=None,
has_spoiler: Optional[bool]=None) -> types.Message:
"""
Use this method to send video files, Telegram clients support mp4 videos (other formats may be sent as Document).
@ -3093,6 +3098,9 @@ class AsyncTeleBot:
:param message_thread_id: Identifier of a message thread, in which the video will be sent
:type message_thread_id: :obj:`int`
:param has_spoiler: Pass True, if the video should be sent as a spoiler
:type has_spoiler: :obj:`bool`
:return: On success, the sent Message is returned.
:rtype: :class:`telebot.types.Message`
"""
@ -3110,7 +3118,7 @@ class AsyncTeleBot:
await asyncio_helper.send_video(
self.token, chat_id, video, duration, caption, reply_to_message_id, reply_markup,
parse_mode, supports_streaming, disable_notification, timeout, thumb, width, height,
caption_entities, allow_sending_without_reply, protect_content, message_thread_id))
caption_entities, allow_sending_without_reply, protect_content, message_thread_id, has_spoiler))
async def send_animation(
self, chat_id: Union[int, str], animation: Union[Any, str],
@ -3127,7 +3135,8 @@ class AsyncTeleBot:
allow_sending_without_reply: Optional[bool]=None,
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
timeout: Optional[int]=None,
message_thread_id: Optional[int]=None) -> types.Message:
message_thread_id: Optional[int]=None,
has_spoiler: Optional[bool]=None) -> types.Message:
"""
Use this method to send animation files (GIF or H.264/MPEG-4 AVC video without sound).
On success, the sent Message is returned. Bots can currently send animation files of up to 50 MB in size, this limit may be changed in the future.
@ -3188,6 +3197,9 @@ class AsyncTeleBot:
:param message_thread_id: Identifier of a message thread, in which the video will be sent
:type message_thread_id: :obj:`int`
:param has_spoiler: Pass True, if the animation should be sent as a spoiler
:type has_spoiler: :obj:`bool`
:return: On success, the sent Message is returned.
:rtype: :class:`telebot.types.Message`
"""
@ -3200,7 +3212,7 @@ class AsyncTeleBot:
await asyncio_helper.send_animation(
self.token, chat_id, animation, duration, caption, reply_to_message_id,
reply_markup, parse_mode, disable_notification, timeout, thumb,
caption_entities, allow_sending_without_reply, width, height, protect_content, message_thread_id))
caption_entities, allow_sending_without_reply, width, height, protect_content, message_thread_id, has_spoiler))
async def send_video_note(
self, chat_id: Union[int, str], data: Union[Any, str],
@ -3652,7 +3664,7 @@ class AsyncTeleBot:
)
async def send_chat_action(
self, chat_id: Union[int, str], action: str, timeout: Optional[int]=None) -> bool:
self, chat_id: Union[int, str], action: str, timeout: Optional[int]=None, message_thread_id: Optional[int]=None) -> bool:
"""
Use this method when you need to tell the user that something is happening on the bot's side.
The status is set for 5 seconds or less (when a message arrives from your bot, Telegram clients clear its typing status).
@ -3675,10 +3687,13 @@ class AsyncTeleBot:
:param timeout: Timeout in seconds for the request.
:type timeout: :obj:`int`
:param message_thread_id: The thread to which the message will be sent(supergroups only)
:type message_thread_id: :obj:`int`
:return: Returns True on success.
:rtype: :obj:`bool`
"""
return await asyncio_helper.send_chat_action(self.token, chat_id, action, timeout)
return await asyncio_helper.send_chat_action(self.token, chat_id, action, timeout, message_thread_id)
async def kick_chat_member(
self, chat_id: Union[int, str], user_id: int,
@ -5502,8 +5517,8 @@ class AsyncTeleBot:
async def edit_forum_topic(
self, chat_id: Union[int, str],
message_thread_id: int, name: str,
icon_custom_emoji_id: str,
message_thread_id: int, name: Optional[str]=None,
icon_custom_emoji_id: Optional[str]=None
) -> bool:
"""
Use this method to edit name and icon of a topic in a forum supergroup chat. The bot must be an
@ -5518,10 +5533,13 @@ class AsyncTeleBot:
:param message_thread_id: Identifier of the topic to edit
:type message_thread_id: :obj:`int`
:param name: New name of the topic, 1-128 characters
:param name: Optional, New name of the topic, 1-128 characters. If not specififed or empty,
the current name of the topic will be kept
:type name: :obj:`str`
:param icon_custom_emoji_id: New custom emoji for the topic icon. Must be an emoji of type tgs and must be exactly 1 character long
:param icon_custom_emoji_id: Optional, New unique identifier of the custom emoji shown as the topic icon.
Use getForumTopicIconStickers to get all allowed custom emoji identifiers. Pass an empty string to remove the
icon. If not specified, the current icon will be kept
:type icon_custom_emoji_id: :obj:`str`
:return: On success, True is returned.
@ -5605,6 +5623,75 @@ class AsyncTeleBot:
"""
return await asyncio_helper.unpin_all_forum_topic_messages(self.token, chat_id, message_thread_id)
async def edit_general_forum_topic(self, chat_id: Union[int, str], name: str) -> bool:
"""
Use this method to edit the name of the 'General' topic in a forum supergroup chat.
The bot must be an administrator in the chat for this to work and must have can_manage_topics administrator rights.
Returns True on success.
Telegram documentation: https://core.telegram.org/bots/api#editgeneralforumtopic
:param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
:type chat_id: :obj:`int` or :obj:`str`
:param name: New topic name, 1-128 characters
:type name: :obj:`str`
"""
return await asyncio_helper.edit_general_forum_topic(self.token, chat_id, name)
async def close_general_forum_topic(self, chat_id: Union[int, str]) -> bool:
"""
Use this method to close the 'General' topic in a forum supergroup chat.
The bot must be an administrator in the chat for this to work and must have can_manage_topics administrator rights.
Returns True on success.
Telegram documentation: https://core.telegram.org/bots/api#closegeneralforumtopic
:param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
:type chat_id: :obj:`int` or :obj:`str`
"""
return await asyncio_helper.close_general_forum_topic(self.token, chat_id)
async def reopen_general_forum_topic(self, chat_id: Union[int, str]) -> bool:
"""
Use this method to reopen the 'General' topic in a forum supergroup chat.
The bot must be an administrator in the chat for this to work and must have can_manage_topics administrator rights.
Returns True on success.
Telegram documentation: https://core.telegram.org/bots/api#reopengeneralforumtopic
:param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
:type chat_id: :obj:`int` or :obj:`str`
"""
return await asyncio_helper.reopen_general_forum_topic(self.token, chat_id)
async def hide_general_forum_topic(self, chat_id: Union[int, str]) -> bool:
"""
Use this method to hide the 'General' topic in a forum supergroup chat.
The bot must be an administrator in the chat for this to work and must have can_manage_topics administrator rights.
Returns True on success.
Telegram documentation: https://core.telegram.org/bots/api#hidegeneralforumtopic
:param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
:type chat_id: :obj:`int` or :obj:`str`
"""
return await asyncio_helper.hide_general_forum_topic(self.token, chat_id)
async def unhide_general_forum_topic(self, chat_id: Union[int, str]) -> bool:
"""
Use this method to unhide the 'General' topic in a forum supergroup chat.
The bot must be an administrator in the chat for this to work and must have can_manage_topics administrator rights.
Returns True on success.
Telegram documentation: https://core.telegram.org/bots/api#unhidegeneralforumtopic
:param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
:type chat_id: :obj:`int` or :obj:`str`
"""
return await asyncio_helper.unhide_general_forum_topic(self.token, chat_id)
async def get_forum_topic_icon_stickers(self) -> List[types.Sticker]:
"""
Use this method to get custom emoji stickers, which can be used as a forum topic icon by any user.

View File

@ -453,7 +453,7 @@ async def send_photo(
caption=None, reply_to_message_id=None, reply_markup=None,
parse_mode=None, disable_notification=None, timeout=None,
caption_entities=None, allow_sending_without_reply=None, protect_content=None,
message_thread_id=None):
message_thread_id=None, has_spoiler=None):
method_url = r'sendPhoto'
payload = {'chat_id': chat_id}
files = None
@ -483,6 +483,8 @@ async def send_photo(
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
if has_spoiler is not None:
payload['has_spoiler'] = has_spoiler
return await _process_request(token, method_url, params=payload, files=files, method='post')
@ -647,18 +649,20 @@ async def send_contact(
return await _process_request(token, method_url, params=payload)
async def send_chat_action(token, chat_id, action, timeout=None):
async def send_chat_action(token, chat_id, action, timeout=None, message_thread_id=None):
method_url = r'sendChatAction'
payload = {'chat_id': chat_id, 'action': action}
if timeout:
payload['timeout'] = timeout
if message_thread_id:
payload['message_thread_id'] = message_thread_id
return await _process_request(token, method_url, params=payload)
async def send_video(token, chat_id, data, duration=None, caption=None, reply_to_message_id=None, reply_markup=None,
parse_mode=None, supports_streaming=None, disable_notification=None, timeout=None,
thumb=None, width=None, height=None, caption_entities=None, allow_sending_without_reply=None,
protect_content=None, message_thread_id=None):
protect_content=None, message_thread_id=None, has_spoiler=None):
method_url = r'sendVideo'
payload = {'chat_id': chat_id}
files = None
@ -702,13 +706,16 @@ async def send_video(token, chat_id, data, duration=None, caption=None, reply_to
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
if has_spoiler is not None:
payload['has_spoiler'] = has_spoiler
return await _process_request(token, method_url, params=payload, files=files, method='post')
async def send_animation(
token, chat_id, data, duration=None, caption=None, reply_to_message_id=None, reply_markup=None,
parse_mode=None, disable_notification=None, timeout=None, thumb=None, caption_entities=None,
allow_sending_without_reply=None, width=None, height=None, protect_content=None, message_thread_id=None):
allow_sending_without_reply=None, width=None, height=None, protect_content=None, message_thread_id=None,
has_spoiler=None):
method_url = r'sendAnimation'
payload = {'chat_id': chat_id}
files = None
@ -750,6 +757,8 @@ async def send_animation(
payload['protect_content'] = protect_content
if message_thread_id:
payload['message_thread_id'] = message_thread_id
if has_spoiler is not None:
payload['has_spoiler'] = has_spoiler
return await _process_request(token, method_url, params=payload, files=files, method='post')
@ -1757,9 +1766,13 @@ async def create_forum_topic(token, chat_id, name, icon_color=None, icon_custom_
payload['icon_custom_emoji_id'] = icon_custom_emoji_id
return await _process_request(token, method_url, params=payload)
async def edit_forum_topic(token, chat_id, message_thread_id, name, icon_custom_emoji_id):
async def edit_forum_topic(token, chat_id, message_thread_id, name=None, icon_custom_emoji_id=None):
method_url = r'editForumTopic'
payload = {'chat_id': chat_id, 'message_thread_id': message_thread_id, 'name': name, 'icon_custom_emoji_id': icon_custom_emoji_id}
payload = {'chat_id': chat_id, 'message_thread_id': message_thread_id}
if name is not None:
payload['name'] = name
if icon_custom_emoji_id is not None:
payload['icon_custom_emoji_id'] = icon_custom_emoji_id
return await _process_request(token, method_url, params=payload)
async def close_forum_topic(token, chat_id, message_thread_id):
@ -1786,6 +1799,31 @@ async def get_forum_topic_icon_stickers(token):
method_url = r'getForumTopicIconStickers'
return await _process_request(token, method_url)
async def edit_general_forum_topic(token, chat_id, name):
method_url = r'editGeneralForumTopic'
payload = {'chat_id': chat_id, 'name': name}
return await _process_request(token, method_url, params=payload)
async def close_general_forum_topic(token, chat_id):
method_url = r'closeGeneralForumTopic'
payload = {'chat_id': chat_id}
return await _process_request(token, method_url, params=payload)
async def reopen_general_forum_topic(token, chat_id):
method_url = r'reopenGeneralForumTopic'
payload = {'chat_id': chat_id}
return await _process_request(token, method_url, params=payload)
async def hide_general_forum_topic(token, chat_id):
method_url = r'hideGeneralForumTopic'
payload = {'chat_id': chat_id}
return await _process_request(token, method_url, params=payload)
async def unhide_general_forum_topic(token, chat_id):
method_url = r'unhideGeneralForumTopic'
payload = {'chat_id': chat_id}
return await _process_request(token, method_url, params=payload)
async def _convert_list_json_serializable(results):
ret = ''
for r in results:

View File

@ -570,6 +570,14 @@ class Chat(JsonDeserializable):
automatically deleted; in seconds. Returned only in getChat.
:type message_auto_delete_time: :obj:`int`
:param has_aggressive_anti_spam_enabled: Optional. :obj:`bool`, if the chat has enabled aggressive anti-spam
protection. Returned only in getChat.
:type has_aggressive_anti_spam_enabled: :obj:`bool`
:param has_hidden_members: Optional. :obj:`bool`, if the chat has enabled hidden members. Returned only in
getChat.
:type has_hidden_members: :obj:`bool`
:param has_protected_content: Optional. :obj:`bool`, if messages from the chat can't be forwarded to other
chats. Returned only in getChat.
:type has_protected_content: :obj:`bool`
@ -615,7 +623,8 @@ class Chat(JsonDeserializable):
message_auto_delete_time=None, has_protected_content=None, sticker_set_name=None,
can_set_sticker_set=None, linked_chat_id=None, location=None,
join_to_send_messages=None, join_by_request=None, has_restricted_voice_and_video_messages=None,
is_forum=None, active_usernames=None, emoji_status_custom_emoji_id=None, **kwargs):
is_forum=None, active_usernames=None, emoji_status_custom_emoji_id=None,
has_hidden_members=None, has_aggressive_anti_spam_enabled=None, **kwargs):
self.id: int = id
self.type: str = type
self.title: str = title
@ -642,6 +651,8 @@ class Chat(JsonDeserializable):
self.location: ChatLocation = location
self.active_usernames: List[str] = active_usernames
self.emoji_status_custom_emoji_id: str = emoji_status_custom_emoji_id
self.has_hidden_members: bool = has_hidden_members
self.has_aggressive_anti_spam_enabled: bool = has_aggressive_anti_spam_enabled
class MessageID(JsonDeserializable):
@ -812,6 +823,9 @@ class Message(JsonDeserializable):
commands, etc. that appear in the caption
:type caption_entities: :obj:`list` of :class:`telebot.types.MessageEntity`
:param has_media_spoiler: Optional. True, if the message media is covered by a spoiler animation
:type has_media_spoiler: :obj:`bool`
:param contact: Optional. Message is a shared contact, information about the contact
:type contact: :class:`telebot.types.Contact`
@ -892,6 +906,10 @@ class Message(JsonDeserializable):
Telegram Login »
:type connected_website: :obj:`str`
:param write_access_allowed: Optional. Service message: the user allowed the bot added to the attachment
menu to write messages
:type write_access_allowed: :class:`telebot.types.WriteAccessAllowed`
:param passport_data: Optional. Telegram Passport data
:type passport_data: :class:`telebot.types.PassportData`
@ -902,12 +920,21 @@ class Message(JsonDeserializable):
:param forum_topic_created: Optional. Service message: forum topic created
:type forum_topic_created: :class:`telebot.types.ForumTopicCreated`
:param forum_topic_edited: Optional. Service message: forum topic edited
:type forum_topic_edited: :class:`telebot.types.ForumTopicEdited`
:param forum_topic_closed: Optional. Service message: forum topic closed
:type forum_topic_closed: :class:`telebot.types.ForumTopicClosed`
:param forum_topic_reopened: Optional. Service message: forum topic reopened
:type forum_topic_reopened: :class:`telebot.types.ForumTopicReopened`
:param general_forum_topic_hidden: Optional. Service message: the 'General' forum topic hidden
:type general_forum_topic_hidden: :class:`telebot.types.GeneralForumTopicHidden`
:param general_forum_topic_unhidden: Optional. Service message: the 'General' forum topic unhidden
:type general_forum_topic_unhidden: :class:`telebot.types.GeneralForumTopicUnhidden`
:param video_chat_scheduled: Optional. Service message: video chat scheduled
:type video_chat_scheduled: :class:`telebot.types.VideoChatScheduled`
@ -1110,6 +1137,20 @@ class Message(JsonDeserializable):
if 'forum_topic_reopened' in obj:
opts['forum_topic_reopened'] = ForumTopicReopened.de_json(obj['forum_topic_reopened'])
content_type = 'forum_topic_reopened'
if 'has_media_spoiler' in obj:
opts['has_media_spoiler'] = obj['has_media_spoiler']
if 'forum_topic_edited' in obj:
opts['forum_topic_edited'] = ForumTopicEdited.de_json(obj['forum_topic_edited'])
content_type = 'forum_topic_edited'
if 'general_forum_topic_hidden' in obj:
opts['general_forum_topic_hidden'] = GeneralForumTopicHidden.de_json(obj['general_forum_topic_hidden'])
content_type = 'general_forum_topic_hidden'
if 'general_forum_topic_unhidden' in obj:
opts['general_forum_topic_unhidden'] = GeneralForumTopicUnhidden.de_json(obj['general_forum_topic_unhidden'])
content_type = 'general_forum_topic_unhidden'
if 'write_access_allowed' in obj:
opts['write_access_allowed'] = WriteAccessAllowed.de_json(obj['write_access_allowed'])
content_type = 'write_access_allowed'
return cls(message_id, from_user, date, chat, content_type, opts, json_string)
@classmethod
@ -1200,6 +1241,11 @@ class Message(JsonDeserializable):
self.forum_topic_created: Optional[ForumTopicCreated] = None
self.forum_topic_closed: Optional[ForumTopicClosed] = None
self.forum_topic_reopened: Optional[ForumTopicReopened] = None
self.has_media_spoiler: Optional[bool] = None
self.forum_topic_edited: Optional[ForumTopicEdited] = None
self.general_forum_topic_hidden: Optional[GeneralForumTopicHidden] = None
self.general_forum_topic_unhidden: Optional[GeneralForumTopicUnhidden] = None
self.write_access_allowed: Optional[WriteAccessAllowed] = None
for key in options:
setattr(self, key, options[key])
self.json = json_string
@ -2055,13 +2101,21 @@ class ReplyKeyboardMarkup(JsonSerializable):
replies to the request with a keyboard to select the new language. Other users in the group don't see the keyboard.
:type selective: :obj:`bool`
:param is_persistent: Optional. Use this parameter if you want to show the keyboard to specific users only.
Targets: 1) users that are @mentioned in the text of the Message object; 2) if the bot's message is a
reply (has reply_to_message_id), sender of the original message.
Example: A user requests to change the bot's language, bot replies to the request with a keyboard to
select the new language. Other users in the group don't see the keyboard.
:return: Instance of the class
:rtype: :class:`telebot.types.ReplyKeyboardMarkup`
"""
max_row_keys = 12
def __init__(self, resize_keyboard: Optional[bool]=None, one_time_keyboard: Optional[bool]=None,
selective: Optional[bool]=None, row_width: int=3, input_field_placeholder: Optional[str]=None):
selective: Optional[bool]=None, row_width: int=3, input_field_placeholder: Optional[str]=None,
is_persistent: Optional[bool]=None):
if row_width > self.max_row_keys:
# Todo: Will be replaced with Exception in future releases
if not DISABLE_KEYLEN_ERROR:
@ -2074,6 +2128,7 @@ class ReplyKeyboardMarkup(JsonSerializable):
self.row_width: int = row_width
self.input_field_placeholder: str = input_field_placeholder
self.keyboard: List[List[KeyboardButton]] = []
self.is_persistent: bool = is_persistent
def add(self, *args, row_width=None):
"""
@ -2139,6 +2194,8 @@ class ReplyKeyboardMarkup(JsonSerializable):
json_dict['selective'] = self.selective
if self.input_field_placeholder:
json_dict['input_field_placeholder'] = self.input_field_placeholder
if self.is_persistent is not None:
json_dict['is_persistent'] = self.is_persistent
return json.dumps(json_dict)
@ -5781,18 +5838,26 @@ class InputMediaPhoto(InputMedia):
instead of parse_mode
:type caption_entities: :obj:`list` of :class:`telebot.types.MessageEntity`
:param has_spoiler: Optional. True, if the uploaded photo is a spoiler
:type has_spoiler: :obj:`bool`
:return: Instance of the class
:rtype: :class:`telebot.types.InputMediaPhoto`
"""
def __init__(self, media, caption=None, parse_mode=None, caption_entities=None):
def __init__(self, media, caption=None, parse_mode=None, caption_entities=None, has_spoiler=None):
if util.is_pil_image(media):
media = util.pil_image_to_file(media)
super(InputMediaPhoto, self).__init__(
type="photo", media=media, caption=caption, parse_mode=parse_mode, caption_entities=caption_entities)
self.has_spoiler: Optional[bool] = has_spoiler
def to_dict(self):
return super(InputMediaPhoto, self).to_dict()
ret = super(InputMediaPhoto, self).to_dict()
if self.has_spoiler is not None:
ret['has_spoiler'] = self.has_spoiler
return ret
class InputMediaVideo(InputMedia):
@ -5836,11 +5901,14 @@ class InputMediaVideo(InputMedia):
:param supports_streaming: Optional. Pass True, if the uploaded video is suitable for streaming
:type supports_streaming: :obj:`bool`
:param has_spoiler: Optional. True, if the uploaded video is a spoiler
:type has_spoiler: :obj:`bool`
:return: Instance of the class
:rtype: :class:`telebot.types.InputMediaVideo`
"""
def __init__(self, media, thumb=None, caption=None, parse_mode=None, caption_entities=None,
width=None, height=None, duration=None, supports_streaming=None):
width=None, height=None, duration=None, supports_streaming=None, has_spoiler=None):
super(InputMediaVideo, self).__init__(
type="video", media=media, caption=caption, parse_mode=parse_mode, caption_entities=caption_entities)
self.thumb = thumb
@ -5848,6 +5916,7 @@ class InputMediaVideo(InputMedia):
self.height = height
self.duration = duration
self.supports_streaming = supports_streaming
self.has_spoiler: Optional[bool] = has_spoiler
def to_dict(self):
ret = super(InputMediaVideo, self).to_dict()
@ -5861,6 +5930,8 @@ class InputMediaVideo(InputMedia):
ret['duration'] = self.duration
if self.supports_streaming:
ret['supports_streaming'] = self.supports_streaming
if self.has_spoiler is not None:
ret['has_spoiler'] = self.has_spoiler
return ret
@ -5902,17 +5973,21 @@ class InputMediaAnimation(InputMedia):
:param duration: Optional. Animation duration in seconds
:type duration: :obj:`int`
:param has_spoiler: Optional. True, if the uploaded animation is a spoiler
:type has_spoiler: :obj:`bool`
:return: Instance of the class
:rtype: :class:`telebot.types.InputMediaAnimation`
"""
def __init__(self, media, thumb=None, caption=None, parse_mode=None, caption_entities=None,
width=None, height=None, duration=None):
width=None, height=None, duration=None, has_spoiler=None):
super(InputMediaAnimation, self).__init__(
type="animation", media=media, caption=caption, parse_mode=parse_mode, caption_entities=caption_entities)
self.thumb = thumb
self.width = width
self.height = height
self.duration = duration
self.has_spoiler: Optional[bool] = has_spoiler
def to_dict(self):
ret = super(InputMediaAnimation, self).to_dict()
@ -5924,6 +5999,8 @@ class InputMediaAnimation(InputMedia):
ret['height'] = self.height
if self.duration:
ret['duration'] = self.duration
if self.has_spoiler is not None:
ret['has_spoiler'] = self.has_spoiler
return ret
@ -6829,6 +6906,61 @@ class ForumTopicReopened(JsonDeserializable):
def __init__(self) -> None:
pass
class ForumTopicEdited(JsonDeserializable):
"""
This object represents a service message about an edited forum topic.
Telegram documentation: https://core.telegram.org/bots/api#forumtopicedited
:param name: Optional, Name of the topic(if updated)
:type name: :obj:`str`
:param icon_custom_emoji_id: Optional. New identifier of the custom emoji shown as the topic icon, if it was edited;
an empty string if the icon was removed
:type icon_custom_emoji_id: :obj:`str`
"""
@classmethod
def de_json(cls, json_string):
if json_string is None: return None
obj = cls.check_json(json_string)
return cls(**obj)
def __init__(self, name: Optional[str]=None, icon_custom_emoji_id: Optional[str]=None) -> None:
self.name: Optional[str] = name
self.icon_custom_emoji_id: Optional[str] = icon_custom_emoji_id
class GeneralForumTopicHidden(JsonDeserializable):
"""
This object represents a service message about General forum topic hidden in the chat.
Currently holds no information.
Telegram documentation: https://core.telegram.org/bots/api#generalforumtopichidden
"""
@classmethod
def de_json(cls, json_string):
return cls()
def __init__(self) -> None:
pass
class GeneralForumTopicUnhidden(JsonDeserializable):
"""
This object represents a service message about General forum topic unhidden in the chat.
Currently holds no information.
Telegram documentation: https://core.telegram.org/bots/api#generalforumtopicunhidden
"""
@classmethod
def de_json(cls, json_string):
return cls()
def __init__(self) -> None:
pass
class ForumTopic(JsonDeserializable):
"""
@ -6865,6 +6997,19 @@ class ForumTopic(JsonDeserializable):
self.icon_custom_emoji_id: Optional[str] = icon_custom_emoji_id
class WriteAccessAllowed(JsonDeserializable):
"""
This object represents a service message about a user allowed to post messages in the chat.
Currently holds no information.
Telegram documentation: https://core.telegram.org/bots/api#writeaccessallowed
"""
@classmethod
def de_json(cls, json_string):
return cls()
def __init__(self) -> None:
pass