diff --git a/README.md b/README.md
index 82a4beb..3c6b2d5 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@
A simple, but extensible Python implementation for the Telegram Bot API.
Supports both sync and async ways.
-## Supporting Bot API version: 5.5!
+##
Supporting Bot API version: 5.6!
## Contents
@@ -686,6 +686,7 @@ Result will be:
## API conformance
+* ✔ [Bot API 5.6](https://core.telegram.org/bots/api#december-30-2021)
* ✔ [Bot API 5.5](https://core.telegram.org/bots/api#december-7-2021)
* ✔ [Bot API 5.4](https://core.telegram.org/bots/api#november-5-2021)
* ➕ [Bot API 5.3](https://core.telegram.org/bots/api#june-25-2021) - ChatMember* classes are full copies of ChatMember
diff --git a/telebot/__init__.py b/telebot/__init__.py
index 840b047..ca93487 100644
--- a/telebot/__init__.py
+++ b/telebot/__init__.py
@@ -936,32 +936,35 @@ class TeleBot:
def send_message(
self, chat_id: Union[int, str], text: str,
- disable_web_page_preview: Optional[bool]=None,
- reply_to_message_id: Optional[int]=None,
- reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
parse_mode: Optional[str]=None,
- disable_notification: Optional[bool]=None,
- timeout: Optional[int]=None,
entities: Optional[List[types.MessageEntity]]=None,
- allow_sending_without_reply: Optional[bool]=None) -> types.Message:
+ disable_web_page_preview: Optional[bool]=None,
+ disable_notification: Optional[bool]=None,
+ protect_content: Optional[bool]=None,
+ reply_to_message_id: Optional[int]=None,
+ allow_sending_without_reply: Optional[bool]=None,
+ reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
+ timeout: Optional[int]=None) -> types.Message:
"""
Use this method to send text messages.
+
Warning: Do not send more than about 4000 characters each message, otherwise you'll risk an HTTP 414 error.
If you must send more than 4000 characters,
use the `split_string` or `smart_split` function in util.py.
- :param chat_id:
- :param text:
- :param disable_web_page_preview:
- :param reply_to_message_id:
- :param reply_markup:
- :param parse_mode:
- :param disable_notification: Boolean, Optional. Sends the message silently.
+ :param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
+ :param text: Text of the message to be sent
+ :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message.
+ :param entities: List of special entities that appear in message text, which can be specified instead of parse_mode
+ :param disable_web_page_preview: Disables link previews for links in this message
+ :param disable_notification: Sends the message silently. Users will receive a notification with no sound.
+ :param protect_content: If True, the message content will be hidden for all users except for the target user
+ :param reply_to_message_id: If the message is a reply, ID of the original message
+ :param allow_sending_without_reply: Pass True, if the message should be sent even if the specified replied-to message is not found
+ :param reply_markup: Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user.
:param timeout:
- :param entities:
- :param allow_sending_without_reply:
- :return: API reply.
+ :return:
"""
parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
@@ -969,11 +972,12 @@ class TeleBot:
apihelper.send_message(
self.token, chat_id, text, disable_web_page_preview, reply_to_message_id,
reply_markup, parse_mode, disable_notification, timeout,
- entities, allow_sending_without_reply))
+ entities, allow_sending_without_reply, protect_content=protect_content))
def forward_message(
self, chat_id: Union[int, str], from_chat_id: Union[int, str],
- message_id: int, disable_notification: Optional[bool]=None,
+ message_id: int, disable_notification: Optional[bool]=None,
+ protect_content: Optional[bool]=None,
timeout: Optional[int]=None) -> types.Message:
"""
Use this method to forward messages of any kind.
@@ -981,11 +985,12 @@ class TeleBot:
:param chat_id: which chat to forward
:param from_chat_id: which chat message from
:param message_id: message id
+ :param protect_content: Protects the contents of the forwarded message from forwarding and saving
:param timeout:
:return: API reply.
"""
return types.Message.de_json(
- apihelper.forward_message(self.token, chat_id, from_chat_id, message_id, disable_notification, timeout))
+ apihelper.forward_message(self.token, chat_id, from_chat_id, message_id, disable_notification, timeout, protect_content))
def copy_message(
self, chat_id: Union[int, str],
@@ -995,6 +1000,7 @@ class TeleBot:
parse_mode: Optional[str]=None,
caption_entities: Optional[List[types.MessageEntity]]=None,
disable_notification: Optional[bool]=None,
+ protect_content: Optional[bool]=None,
reply_to_message_id: Optional[int]=None,
allow_sending_without_reply: Optional[bool]=None,
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
@@ -1008,6 +1014,7 @@ class TeleBot:
:param parse_mode:
:param caption_entities:
:param disable_notification:
+ :param protect_content:
:param reply_to_message_id:
:param allow_sending_without_reply:
:param reply_markup:
@@ -1017,7 +1024,7 @@ class TeleBot:
return types.MessageID.de_json(
apihelper.copy_message(self.token, chat_id, from_chat_id, message_id, caption, parse_mode, caption_entities,
disable_notification, reply_to_message_id, allow_sending_without_reply, reply_markup,
- timeout))
+ timeout, protect_content))
def delete_message(self, chat_id: Union[int, str], message_id: int,
timeout: Optional[int]=None) -> bool:
@@ -1036,7 +1043,8 @@ class TeleBot:
reply_to_message_id: Optional[int]=None,
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
timeout: Optional[int]=None,
- allow_sending_without_reply: Optional[bool]=None) -> types.Message:
+ allow_sending_without_reply: Optional[bool]=None,
+ protect_content: Optional[bool]=None) -> types.Message:
"""
Use this method to send dices.
:param chat_id:
@@ -1046,35 +1054,39 @@ class TeleBot:
:param reply_markup:
:param timeout:
:param allow_sending_without_reply:
+ :param protect_content:
:return: Message
"""
return types.Message.de_json(
apihelper.send_dice(
self.token, chat_id, emoji, disable_notification, reply_to_message_id,
- reply_markup, timeout, allow_sending_without_reply)
+ reply_markup, timeout, allow_sending_without_reply, protect_content)
)
def send_photo(
self, chat_id: Union[int, str], photo: Union[Any, str],
- caption: Optional[str]=None, reply_to_message_id: Optional[int]=None,
- reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
- parse_mode: Optional[str]=None, disable_notification: Optional[bool]=None,
- timeout: Optional[int]=None,
+ caption: Optional[str]=None, parse_mode: Optional[str]=None,
caption_entities: Optional[List[types.MessageEntity]]=None,
- allow_sending_without_reply: Optional[bool]=None) -> types.Message:
+ disable_notification: Optional[bool]=None,
+ protect_content: Optional[bool]=None,
+ reply_to_message_id: Optional[int]=None,
+ allow_sending_without_reply: Optional[bool]=None,
+ reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
+ timeout: Optional[int]=None,) -> types.Message:
"""
- Use this method to send photos.
+ Use this method to send photos. On success, the sent Message is returned.
:param chat_id:
:param photo:
:param caption:
:param parse_mode:
+ :param caption_entities:
:param disable_notification:
+ :param protect_content:
:param reply_to_message_id:
+ :param allow_sending_without_reply:
:param reply_markup:
:param timeout:
- :param caption_entities:
- :param allow_sending_without_reply:
- :return: API reply.
+ :return: Message
"""
parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
@@ -1082,8 +1094,9 @@ 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))
+ allow_sending_without_reply, protect_content))
+ # TODO: Rewrite this method like in API.
def send_audio(
self, chat_id: Union[int, str], audio: Union[Any, str],
caption: Optional[str]=None, duration: Optional[int]=None,
@@ -1095,7 +1108,8 @@ class TeleBot:
timeout: Optional[int]=None,
thumb: Optional[Union[Any, str]]=None,
caption_entities: Optional[List[types.MessageEntity]]=None,
- allow_sending_without_reply: Optional[bool]=None) -> types.Message:
+ allow_sending_without_reply: Optional[bool]=None,
+ protect_content: Optional[bool]=None) -> types.Message:
"""
Use this method to send audio files, if you want Telegram clients to display them in the music player.
Your audio must be in the .mp3 format.
@@ -1113,6 +1127,7 @@ class TeleBot:
:param thumb:
:param caption_entities:
:param allow_sending_without_reply:
+ :param protect_content:
:return: Message
"""
parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
@@ -1121,8 +1136,9 @@ class TeleBot:
apihelper.send_audio(
self.token, chat_id, audio, caption, duration, performer, title, reply_to_message_id,
reply_markup, parse_mode, disable_notification, timeout, thumb,
- caption_entities, allow_sending_without_reply))
+ caption_entities, allow_sending_without_reply, protect_content))
+ # TODO: Rewrite this method like in API.
def send_voice(
self, chat_id: Union[int, str], voice: Union[Any, str],
caption: Optional[str]=None, duration: Optional[int]=None,
@@ -1132,7 +1148,8 @@ class TeleBot:
disable_notification: Optional[bool]=None,
timeout: Optional[int]=None,
caption_entities: Optional[List[types.MessageEntity]]=None,
- allow_sending_without_reply: Optional[bool]=None) -> types.Message:
+ allow_sending_without_reply: Optional[bool]=None,
+ protect_content: Optional[bool]=None) -> types.Message:
"""
Use this method to send audio files, if you want Telegram clients to display the file
as a playable voice message.
@@ -1147,6 +1164,7 @@ class TeleBot:
:param timeout:
:param caption_entities:
:param allow_sending_without_reply:
+ :param protect_content:
:return: Message
"""
parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
@@ -1155,8 +1173,9 @@ class TeleBot:
apihelper.send_voice(
self.token, chat_id, voice, caption, duration, reply_to_message_id, reply_markup,
parse_mode, disable_notification, timeout, caption_entities,
- allow_sending_without_reply))
+ allow_sending_without_reply, protect_content))
+ # TODO: Rewrite this method like in API.
def send_document(
self, chat_id: Union[int, str], document: Union[Any, str],
reply_to_message_id: Optional[int]=None,
@@ -1170,7 +1189,8 @@ class TeleBot:
allow_sending_without_reply: Optional[bool]=None,
visible_file_name: Optional[str]=None,
disable_content_type_detection: Optional[bool]=None,
- data: Optional[Union[Any, str]]=None) -> types.Message:
+ data: Optional[Union[Any, str]]=None,
+ protect_content: Optional[bool]=None) -> types.Message:
"""
Use this method to send general files.
:param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
@@ -1187,6 +1207,7 @@ class TeleBot:
:param visible_file_name: allows to define file name that will be visible in the Telegram instead of original file name
:param disable_content_type_detection: Disables automatic server-side content type detection for files uploaded using multipart/form-data
:param data: function typo miss compatibility: do not use it
+ :param protect_content:
:return: API reply.
"""
parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
@@ -1200,15 +1221,18 @@ class TeleBot:
reply_to_message_id = reply_to_message_id, reply_markup = reply_markup, parse_mode = parse_mode,
disable_notification = disable_notification, timeout = timeout, caption = caption, thumb = thumb,
caption_entities = caption_entities, allow_sending_without_reply = allow_sending_without_reply,
- disable_content_type_detection = disable_content_type_detection, visible_file_name = visible_file_name))
+ disable_content_type_detection = disable_content_type_detection, visible_file_name = visible_file_name, protect_content = protect_content))
+ # TODO: Rewrite this method like in API.
def send_sticker(
- self, chat_id: Union[int, str], data: Union[Any, str],
+ self, chat_id: Union[int, str], sticker: Union[Any, str],
reply_to_message_id: Optional[int]=None,
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
disable_notification: Optional[bool]=None,
timeout: Optional[int]=None,
- allow_sending_without_reply: Optional[bool]=None) -> types.Message:
+ allow_sending_without_reply: Optional[bool]=None,
+ protect_content:Optional[bool]=None,
+ data: Union[Any, str]=None) -> types.Message:
"""
Use this method to send .webp stickers.
:param chat_id:
@@ -1218,83 +1242,98 @@ class TeleBot:
:param disable_notification: to disable the notification
:param timeout: timeout
:param allow_sending_without_reply:
+ :param protect_content:
+ :param data: function typo miss compatibility: do not use it
:return: API reply.
"""
+ if data and not(sticker):
+ # function typo miss compatibility
+ sticker = data
return types.Message.de_json(
apihelper.send_data(
- self.token, chat_id, data, 'sticker',
+ self.token, chat_id, sticker, 'sticker',
reply_to_message_id=reply_to_message_id, reply_markup=reply_markup,
disable_notification=disable_notification, timeout=timeout,
- allow_sending_without_reply=allow_sending_without_reply))
+ allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content))
def send_video(
- self, chat_id: Union[int, str], data: Union[Any, str],
- duration: Optional[int]=None,
- caption: Optional[str]=None,
- reply_to_message_id: Optional[int]=None,
- reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
- parse_mode: Optional[str]=None,
- supports_streaming: Optional[bool]=None,
- disable_notification: Optional[bool]=None,
- timeout: Optional[int]=None,
- thumb: Optional[Union[Any, str]]=None,
- width: Optional[int]=None,
+ self, chat_id: Union[int, str], video: Union[Any, str],
+ duration: Optional[int]=None,
+ width: Optional[int]=None,
height: Optional[int]=None,
+ thumb: Optional[Union[Any, str]]=None,
+ caption: Optional[str]=None,
+ parse_mode: Optional[str]=None,
caption_entities: Optional[List[types.MessageEntity]]=None,
- allow_sending_without_reply: Optional[bool]=None) -> types.Message:
+ supports_streaming: Optional[bool]=None,
+ disable_notification: Optional[bool]=None,
+ protect_content: Optional[bool]=None,
+ reply_to_message_id: Optional[int]=None,
+ allow_sending_without_reply: Optional[bool]=None,
+ reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
+ timeout: Optional[int]=None,
+ data: Optional[Union[Any, str]]=None) -> types.Message:
"""
- Use this method to send video files, Telegram clients support mp4 videos.
- :param chat_id: Integer : Unique identifier for the message recipient — User or GroupChat id
- :param data: InputFile or String : Video to send. You can either pass a file_id as String to resend
- a video that is already on the Telegram server
- :param duration: Integer : Duration of sent video in seconds
- :param caption: String : Video caption (may also be used when resending videos by file_id).
- :param parse_mode:
- :param supports_streaming:
- :param reply_to_message_id:
- :param reply_markup:
- :param disable_notification:
- :param timeout:
- :param thumb: InputFile or String : Thumbnail of the file sent
- :param width:
- :param height:
+ Use this method to send video files, Telegram clients support mp4 videos (other formats may be sent as Document).
+ :param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
+ :param video: Video to send. You can either pass a file_id as String to resend a video that is already on the Telegram servers, or upload a new video file using multipart/form-data.
+ :param duration: Duration of sent video in seconds
+ :param width: Video width
+ :param height: Video height
+ :param thumb: Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new file, so you can pass “attach://” if the thumbnail was uploaded using multipart/form-data under .
+ :param caption: Video caption (may also be used when resending videos by file_id), 0-1024 characters after entities parsing
+ :param parse_mode: Mode for parsing entities in the video caption
:param caption_entities:
+ :param supports_streaming: Pass True, if the uploaded video is suitable for streaming
+ :param disable_notification: Sends the message silently. Users will receive a notification with no sound.
+ :param protect_content:
+ :param reply_to_message_id: If the message is a reply, ID of the original message
:param allow_sending_without_reply:
- :return:
+ :param reply_markup:
+ :param timeout:
+ :param data: function typo miss compatibility: do not use it
"""
parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
+ if data and not(video):
+ # function typo miss compatibility
+ video = data
return types.Message.de_json(
apihelper.send_video(
- self.token, chat_id, data, duration, caption, reply_to_message_id, reply_markup,
+ 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))
+ caption_entities, allow_sending_without_reply, protect_content))
def send_animation(
self, chat_id: Union[int, str], animation: Union[Any, str],
duration: Optional[int]=None,
- caption: Optional[str]=None,
- reply_to_message_id: Optional[int]=None,
- reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
- parse_mode: Optional[str]=None,
- disable_notification: Optional[bool]=None,
- timeout: Optional[int]=None,
+ width: Optional[int]=None,
+ height: Optional[int]=None,
thumb: Optional[Union[Any, str]]=None,
+ caption: Optional[str]=None,
+ parse_mode: Optional[str]=None,
caption_entities: Optional[List[types.MessageEntity]]=None,
- allow_sending_without_reply: Optional[bool]=None) -> types.Message:
+ disable_notification: Optional[bool]=None,
+ protect_content: Optional[bool]=None,
+ reply_to_message_id: Optional[int]=None,
+ allow_sending_without_reply: Optional[bool]=None,
+ reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
+ timeout: Optional[int]=None, ) -> types.Message:
"""
Use this method to send animation files (GIF or H.264/MPEG-4 AVC video without sound).
:param chat_id: Integer : Unique identifier for the message recipient — User or GroupChat id
:param animation: InputFile or String : Animation to send. You can either pass a file_id as String to resend an
animation that is already on the Telegram server
:param duration: Integer : Duration of sent video in seconds
+ :param width: Integer : Video width
+ :param height: Integer : Video height
+ :param thumb: InputFile or String : Thumbnail of the file sent
:param caption: String : Animation caption (may also be used when resending animation by file_id).
:param parse_mode:
:param reply_to_message_id:
:param reply_markup:
:param disable_notification:
:param timeout:
- :param thumb: InputFile or String : Thumbnail of the file sent
:param caption_entities:
:param allow_sending_without_reply:
:return:
@@ -1305,8 +1344,9 @@ 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))
+ caption_entities, allow_sending_without_reply, protect_content, width, height))
+ # TODO: Rewrite this method like in API.
def send_video_note(
self, chat_id: Union[int, str], data: Union[Any, str],
duration: Optional[int]=None,
@@ -1316,7 +1356,8 @@ class TeleBot:
disable_notification: Optional[bool]=None,
timeout: Optional[int]=None,
thumb: Optional[Union[Any, str]]=None,
- allow_sending_without_reply: Optional[bool]=None) -> types.Message:
+ allow_sending_without_reply: Optional[bool]=None,
+ protect_content: Optional[bool]=None) -> types.Message:
"""
As of v.4.0, Telegram clients support rounded square mp4 videos of up to 1 minute long. Use this method to send
video messages.
@@ -1331,12 +1372,13 @@ class TeleBot:
:param timeout:
:param thumb: InputFile or String : Thumbnail of the file sent
:param allow_sending_without_reply:
+ :param protect_content:
:return:
"""
return types.Message.de_json(
apihelper.send_video_note(
self.token, chat_id, data, duration, length, reply_to_message_id, reply_markup,
- disable_notification, timeout, thumb, allow_sending_without_reply))
+ disable_notification, timeout, thumb, allow_sending_without_reply, protect_content))
def send_media_group(
self, chat_id: Union[int, str],
@@ -1344,6 +1386,7 @@ class TeleBot:
types.InputMediaAudio, types.InputMediaDocument,
types.InputMediaPhoto, types.InputMediaVideo]],
disable_notification: Optional[bool]=None,
+ protect_content: Optional[bool]=None,
reply_to_message_id: Optional[int]=None,
timeout: Optional[int]=None,
allow_sending_without_reply: Optional[bool]=None) -> List[types.Message]:
@@ -1352,6 +1395,7 @@ class TeleBot:
:param chat_id:
:param media:
:param disable_notification:
+ :param protect_content:
:param reply_to_message_id:
:param timeout:
:param allow_sending_without_reply:
@@ -1359,9 +1403,11 @@ class TeleBot:
"""
result = apihelper.send_media_group(
self.token, chat_id, media, disable_notification, reply_to_message_id, timeout,
- allow_sending_without_reply)
+ allow_sending_without_reply, protect_content)
return [types.Message.de_json(msg) for msg in result]
+
+ # TODO: Rewrite this method like in API.
def send_location(
self, chat_id: Union[int, str],
latitude: float, longitude: float,
@@ -1373,7 +1419,8 @@ class TeleBot:
horizontal_accuracy: Optional[float]=None,
heading: Optional[int]=None,
proximity_alert_radius: Optional[int]=None,
- allow_sending_without_reply: Optional[bool]=None) -> types.Message:
+ allow_sending_without_reply: Optional[bool]=None,
+ protect_content: Optional[bool]=None) -> types.Message:
"""
@@ -1390,6 +1437,7 @@ class TeleBot:
:param heading:
:param proximity_alert_radius:
:param allow_sending_without_reply:
+ :param protect_content:
:return: API reply.
"""
return types.Message.de_json(
@@ -1397,7 +1445,7 @@ class TeleBot:
self.token, chat_id, latitude, longitude, live_period,
reply_to_message_id, reply_markup, disable_notification, timeout,
horizontal_accuracy, heading, proximity_alert_radius,
- allow_sending_without_reply))
+ allow_sending_without_reply, protect_content))
def edit_message_live_location(
self, latitude: float, longitude: float,
@@ -1449,6 +1497,7 @@ class TeleBot:
apihelper.stop_message_live_location(
self.token, chat_id, message_id, inline_message_id, reply_markup, timeout))
+ # TODO: Rewrite this method like in API.
def send_venue(
self, chat_id: Union[int, str],
latitude: float, longitude: float,
@@ -1461,7 +1510,8 @@ class TeleBot:
timeout: Optional[int]=None,
allow_sending_without_reply: Optional[bool]=None,
google_place_id: Optional[str]=None,
- google_place_type: Optional[str]=None) -> types.Message:
+ google_place_type: Optional[str]=None,
+ protect_content: Optional[bool]=None) -> types.Message:
"""
Use this method to send information about a venue.
:param chat_id: Integer or String : Unique identifier for the target chat or username of the target channel
@@ -1479,15 +1529,16 @@ class TeleBot:
:param allow_sending_without_reply:
:param google_place_id:
:param google_place_type:
+ :param protect_content:
:return:
"""
return types.Message.de_json(
apihelper.send_venue(
self.token, chat_id, latitude, longitude, title, address, foursquare_id, foursquare_type,
disable_notification, reply_to_message_id, reply_markup, timeout,
- allow_sending_without_reply, google_place_id, google_place_type)
- )
+ allow_sending_without_reply, google_place_id, google_place_type, protect_content))
+ # TODO: Rewrite this method like in API.
def send_contact(
self, chat_id: Union[int, str], phone_number: str,
first_name: str, last_name: Optional[str]=None,
@@ -1496,13 +1547,13 @@ class TeleBot:
reply_to_message_id: Optional[int]=None,
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
timeout: Optional[int]=None,
- allow_sending_without_reply: Optional[bool]=None) -> types.Message:
+ allow_sending_without_reply: Optional[bool]=None,
+ protect_content: Optional[bool]=None) -> types.Message:
return types.Message.de_json(
apihelper.send_contact(
self.token, chat_id, phone_number, first_name, last_name, vcard,
disable_notification, reply_to_message_id, reply_markup, timeout,
- allow_sending_without_reply)
- )
+ allow_sending_without_reply, protect_content))
def send_chat_action(
self, chat_id: Union[int, str], action: str, timeout: Optional[int]=None) -> bool:
@@ -2026,7 +2077,8 @@ class TeleBot:
reply_to_message_id: Optional[int]=None,
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
timeout: Optional[int]=None,
- allow_sending_without_reply: Optional[bool]=None) -> types.Message:
+ allow_sending_without_reply: Optional[bool]=None,
+ protect_content: Optional[bool]=None) -> types.Message:
"""
Used to send the game
:param chat_id:
@@ -2036,12 +2088,13 @@ class TeleBot:
:param reply_markup:
:param timeout:
:param allow_sending_without_reply:
+ :param protect_content:
:return:
"""
result = apihelper.send_game(
self.token, chat_id, game_short_name, disable_notification,
reply_to_message_id, reply_markup, timeout,
- allow_sending_without_reply)
+ allow_sending_without_reply, protect_content)
return types.Message.de_json(result)
def set_game_score(
@@ -2083,6 +2136,7 @@ class TeleBot:
result = apihelper.get_game_high_scores(self.token, user_id, chat_id, message_id, inline_message_id)
return [types.GameHighScore.de_json(r) for r in result]
+ # TODO: rewrite this method like in API
def send_invoice(
self, chat_id: Union[int, str], title: str, description: str,
invoice_payload: str, provider_token: str, currency: str,
@@ -2101,7 +2155,8 @@ class TeleBot:
timeout: Optional[int]=None,
allow_sending_without_reply: Optional[bool]=None,
max_tip_amount: Optional[int] = None,
- suggested_tip_amounts: Optional[List[int]]=None) -> types.Message:
+ suggested_tip_amounts: Optional[List[int]]=None,
+ protect_content: Optional[bool]=None) -> types.Message:
"""
Sends invoice
:param chat_id: Unique identifier for the target private chat
@@ -2140,6 +2195,7 @@ class TeleBot:
:param suggested_tip_amounts: A JSON-serialized array of suggested amounts of tips in the smallest
units of the currency. At most 4 suggested tip amounts can be specified. The suggested tip
amounts must be positive, passed in a strictly increased order and must not exceed max_tip_amount.
+ :param protect_content:
:return:
"""
result = apihelper.send_invoice(
@@ -2148,10 +2204,11 @@ class TeleBot:
photo_height, need_name, need_phone_number, need_email, need_shipping_address,
send_phone_number_to_provider, send_email_to_provider, is_flexible, disable_notification,
reply_to_message_id, reply_markup, provider_data, timeout, allow_sending_without_reply,
- max_tip_amount, suggested_tip_amounts)
+ max_tip_amount, suggested_tip_amounts, protect_content)
return types.Message.de_json(result)
# noinspection PyShadowingBuiltins
+ # TODO: rewrite this method like in API
def send_poll(
self, chat_id: Union[int, str], question: str, options: List[str],
is_anonymous: Optional[bool]=None, type: Optional[str]=None,
@@ -2167,7 +2224,8 @@ class TeleBot:
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
allow_sending_without_reply: Optional[bool]=None,
timeout: Optional[int]=None,
- explanation_entities: Optional[List[types.MessageEntity]]=None) -> types.Message:
+ explanation_entities: Optional[List[types.MessageEntity]]=None,
+ protect_content: Optional[bool]=None) -> types.Message:
"""
Send polls
:param chat_id:
@@ -2188,6 +2246,7 @@ class TeleBot:
:param reply_markup:
:param timeout:
:param explanation_entities:
+ :param protect_content:
:return:
"""
@@ -2201,7 +2260,7 @@ class TeleBot:
is_anonymous, type, allows_multiple_answers, correct_option_id,
explanation, explanation_parse_mode, open_period, close_date, is_closed,
disable_notification, reply_to_message_id, allow_sending_without_reply,
- reply_markup, timeout, explanation_entities))
+ reply_markup, timeout, explanation_entities, protect_content))
def stop_poll(
self, chat_id: Union[int, str], message_id: int,
diff --git a/telebot/apihelper.py b/telebot/apihelper.py
index 229fa78..3f9562d 100644
--- a/telebot/apihelper.py
+++ b/telebot/apihelper.py
@@ -232,7 +232,7 @@ def send_message(
token, chat_id, text,
disable_web_page_preview=None, reply_to_message_id=None, reply_markup=None,
parse_mode=None, disable_notification=None, timeout=None,
- entities=None, allow_sending_without_reply=None):
+ entities=None, allow_sending_without_reply=None, protect_content=None):
"""
Use this method to send text messages. On success, the sent Message is returned.
:param token:
@@ -266,6 +266,8 @@ def send_message(
payload['entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(entities))
if allow_sending_without_reply is not None:
payload['allow_sending_without_reply'] = allow_sending_without_reply
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
return _make_request(token, method_url, params=payload, method='post')
@@ -390,19 +392,21 @@ def get_chat_member(token, chat_id, user_id):
def forward_message(
token, chat_id, from_chat_id, message_id,
- disable_notification=None, timeout=None):
+ disable_notification=None, timeout=None, protect_content=None):
method_url = r'forwardMessage'
payload = {'chat_id': chat_id, 'from_chat_id': from_chat_id, 'message_id': message_id}
if disable_notification is not None:
payload['disable_notification'] = disable_notification
if timeout:
payload['timeout'] = timeout
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
return _make_request(token, method_url, params=payload)
def copy_message(token, chat_id, from_chat_id, message_id, caption=None, parse_mode=None, caption_entities=None,
disable_notification=None, reply_to_message_id=None, allow_sending_without_reply=None,
- reply_markup=None, timeout=None):
+ reply_markup=None, timeout=None, protect_content=None):
method_url = r'copyMessage'
payload = {'chat_id': chat_id, 'from_chat_id': from_chat_id, 'message_id': message_id}
if caption is not None:
@@ -421,13 +425,15 @@ def copy_message(token, chat_id, from_chat_id, message_id, caption=None, parse_m
payload['allow_sending_without_reply'] = allow_sending_without_reply
if timeout:
payload['timeout'] = timeout
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
return _make_request(token, method_url, params=payload)
def send_dice(
token, chat_id,
emoji=None, disable_notification=None, reply_to_message_id=None,
- reply_markup=None, timeout=None, allow_sending_without_reply=None):
+ reply_markup=None, timeout=None, allow_sending_without_reply=None, protect_content=None):
method_url = r'sendDice'
payload = {'chat_id': chat_id}
if emoji:
@@ -442,6 +448,8 @@ def send_dice(
payload['timeout'] = timeout
if allow_sending_without_reply is not None:
payload['allow_sending_without_reply'] = allow_sending_without_reply
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
return _make_request(token, method_url, params=payload)
@@ -449,7 +457,7 @@ def send_photo(
token, chat_id, 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):
+ caption_entities=None, allow_sending_without_reply=None, protect_content=None):
method_url = r'sendPhoto'
payload = {'chat_id': chat_id}
files = None
@@ -475,13 +483,15 @@ def send_photo(
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
if allow_sending_without_reply is not None:
payload['allow_sending_without_reply'] = allow_sending_without_reply
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
return _make_request(token, method_url, params=payload, files=files, method='post')
def send_media_group(
token, chat_id, media,
disable_notification=None, reply_to_message_id=None,
- timeout=None, allow_sending_without_reply=None):
+ timeout=None, allow_sending_without_reply=None, protect_content=None):
method_url = r'sendMediaGroup'
media_json, files = convert_input_media_array(media)
payload = {'chat_id': chat_id, 'media': media_json}
@@ -493,6 +503,8 @@ def send_media_group(
payload['timeout'] = timeout
if allow_sending_without_reply is not None:
payload['allow_sending_without_reply'] = allow_sending_without_reply
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
return _make_request(
token, method_url, params=payload,
method='post' if files else 'get',
@@ -504,7 +516,7 @@ def send_location(
live_period=None, reply_to_message_id=None,
reply_markup=None, disable_notification=None,
timeout=None, horizontal_accuracy=None, heading=None,
- proximity_alert_radius=None, allow_sending_without_reply=None):
+ proximity_alert_radius=None, allow_sending_without_reply=None, protect_content=None):
method_url = r'sendLocation'
payload = {'chat_id': chat_id, 'latitude': latitude, 'longitude': longitude}
if live_period:
@@ -525,6 +537,8 @@ def send_location(
payload['disable_notification'] = disable_notification
if timeout:
payload['timeout'] = timeout
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
return _make_request(token, method_url, params=payload)
@@ -576,7 +590,7 @@ def send_venue(
foursquare_id=None, foursquare_type=None, disable_notification=None,
reply_to_message_id=None, reply_markup=None, timeout=None,
allow_sending_without_reply=None, google_place_id=None,
- google_place_type=None):
+ google_place_type=None, protect_content=None):
method_url = r'sendVenue'
payload = {'chat_id': chat_id, 'latitude': latitude, 'longitude': longitude, 'title': title, 'address': address}
if foursquare_id:
@@ -597,13 +611,15 @@ def send_venue(
payload['google_place_id'] = google_place_id
if google_place_type:
payload['google_place_type'] = google_place_type
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
return _make_request(token, method_url, params=payload)
def send_contact(
token, chat_id, phone_number, first_name, last_name=None, vcard=None,
disable_notification=None, reply_to_message_id=None, reply_markup=None, timeout=None,
- allow_sending_without_reply=None):
+ allow_sending_without_reply=None, protect_content=None):
method_url = r'sendContact'
payload = {'chat_id': chat_id, 'phone_number': phone_number, 'first_name': first_name}
if last_name:
@@ -620,6 +636,9 @@ def send_contact(
payload['timeout'] = timeout
if allow_sending_without_reply is not None:
payload['allow_sending_without_reply'] = allow_sending_without_reply
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
+
return _make_request(token, method_url, params=payload)
@@ -633,7 +652,7 @@ def send_chat_action(token, chat_id, action, timeout=None):
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):
+ thumb=None, width=None, height=None, caption_entities=None, allow_sending_without_reply=None, protect_content=None):
method_url = r'sendVideo'
payload = {'chat_id': chat_id}
files = None
@@ -673,13 +692,15 @@ def send_video(token, chat_id, data, duration=None, caption=None, reply_to_messa
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
if allow_sending_without_reply is not None:
payload['allow_sending_without_reply'] = allow_sending_without_reply
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
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):
+ allow_sending_without_reply=None, protect_content=None, width=None, height=None):
method_url = r'sendAnimation'
payload = {'chat_id': chat_id}
files = None
@@ -713,12 +734,18 @@ def send_animation(
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
if allow_sending_without_reply is not None:
payload['allow_sending_without_reply'] = allow_sending_without_reply
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
+ if width:
+ payload['width'] = width
+ if height:
+ payload['height'] = height
return _make_request(token, method_url, params=payload, files=files, method='post')
def send_voice(token, chat_id, voice, caption=None, duration=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):
+ allow_sending_without_reply=None, protect_content=None):
method_url = r'sendVoice'
payload = {'chat_id': chat_id}
files = None
@@ -744,11 +771,13 @@ def send_voice(token, chat_id, voice, caption=None, duration=None, reply_to_mess
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
if allow_sending_without_reply is not None:
payload['allow_sending_without_reply'] = allow_sending_without_reply
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
return _make_request(token, method_url, params=payload, files=files, method='post')
def send_video_note(token, chat_id, data, duration=None, length=None, reply_to_message_id=None, reply_markup=None,
- disable_notification=None, timeout=None, thumb=None, allow_sending_without_reply=None):
+ disable_notification=None, timeout=None, thumb=None, allow_sending_without_reply=None, protect_content=None):
method_url = r'sendVideoNote'
payload = {'chat_id': chat_id}
files = None
@@ -780,12 +809,14 @@ def send_video_note(token, chat_id, data, duration=None, length=None, reply_to_m
payload['thumb'] = thumb
if allow_sending_without_reply is not None:
payload['allow_sending_without_reply'] = allow_sending_without_reply
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
return _make_request(token, method_url, params=payload, files=files, method='post')
def send_audio(token, chat_id, audio, caption=None, duration=None, performer=None, title=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):
+ caption_entities=None, allow_sending_without_reply=None, protect_content=None):
method_url = r'sendAudio'
payload = {'chat_id': chat_id}
files = None
@@ -823,6 +854,8 @@ def send_audio(token, chat_id, audio, caption=None, duration=None, performer=Non
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
if allow_sending_without_reply is not None:
payload['allow_sending_without_reply'] = allow_sending_without_reply
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
return _make_request(token, method_url, params=payload, files=files, method='post')
@@ -1236,7 +1269,7 @@ def delete_message(token, chat_id, message_id, timeout=None):
def send_game(
token, chat_id, game_short_name,
disable_notification=None, reply_to_message_id=None, reply_markup=None, timeout=None,
- allow_sending_without_reply=None):
+ allow_sending_without_reply=None, protect_content=None):
method_url = r'sendGame'
payload = {'chat_id': chat_id, 'game_short_name': game_short_name}
if disable_notification is not None:
@@ -1249,6 +1282,9 @@ def send_game(
payload['timeout'] = timeout
if allow_sending_without_reply is not None:
payload['allow_sending_without_reply'] = allow_sending_without_reply
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
+
return _make_request(token, method_url, params=payload)
@@ -1313,7 +1349,8 @@ def send_invoice(
need_name=None, need_phone_number=None, need_email=None, need_shipping_address=None,
send_phone_number_to_provider = None, send_email_to_provider = None, is_flexible=None,
disable_notification=None, reply_to_message_id=None, reply_markup=None, provider_data=None,
- timeout=None, allow_sending_without_reply=None, max_tip_amount=None, suggested_tip_amounts=None):
+ timeout=None, allow_sending_without_reply=None, max_tip_amount=None, suggested_tip_amounts=None,
+ protect_content=None):
"""
Use this method to send invoices. On success, the sent Message is returned.
:param token: Bot's token (you don't need to fill this)
@@ -1391,6 +1428,8 @@ def send_invoice(
payload['max_tip_amount'] = max_tip_amount
if suggested_tip_amounts is not None:
payload['suggested_tip_amounts'] = json.dumps(suggested_tip_amounts)
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
return _make_request(token, method_url, params=payload)
@@ -1539,7 +1578,7 @@ def send_poll(
is_anonymous = None, type = None, allows_multiple_answers = None, correct_option_id = None,
explanation = None, explanation_parse_mode=None, open_period = None, close_date = None, is_closed = None,
disable_notification=False, reply_to_message_id=None, allow_sending_without_reply=None,
- reply_markup=None, timeout=None, explanation_entities=None):
+ reply_markup=None, timeout=None, explanation_entities=None, protect_content=None):
method_url = r'sendPoll'
payload = {
'chat_id': str(chat_id),
@@ -1581,6 +1620,8 @@ def send_poll(
if explanation_entities:
payload['explanation_entities'] = json.dumps(
types.MessageEntity.to_list_of_dicts(explanation_entities))
+ if protect_content:
+ payload['protect_content'] = protect_content
return _make_request(token, method_url, params=payload)
diff --git a/telebot/async_telebot.py b/telebot/async_telebot.py
index 6f1fca5..011ff46 100644
--- a/telebot/async_telebot.py
+++ b/telebot/async_telebot.py
@@ -1484,16 +1484,19 @@ class AsyncTeleBot:
result = await asyncio_helper.get_chat_member(self.token, chat_id, user_id)
return types.ChatMember.de_json(result)
+
+
async def send_message(
self, chat_id: Union[int, str], text: str,
- disable_web_page_preview: Optional[bool]=None,
- reply_to_message_id: Optional[int]=None,
- reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
parse_mode: Optional[str]=None,
- disable_notification: Optional[bool]=None,
- timeout: Optional[int]=None,
entities: Optional[List[types.MessageEntity]]=None,
- allow_sending_without_reply: Optional[bool]=None) -> types.Message:
+ disable_web_page_preview: Optional[bool]=None,
+ disable_notification: Optional[bool]=None,
+ protect_content: Optional[bool]=None,
+ reply_to_message_id: Optional[int]=None,
+ allow_sending_without_reply: Optional[bool]=None,
+ reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
+ timeout: Optional[int]=None) -> types.Message:
"""
Use this method to send text messages.
@@ -1511,6 +1514,7 @@ class AsyncTeleBot:
:param timeout:
:param entities:
:param allow_sending_without_reply:
+ :param protect_content:
:return: API reply.
"""
parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
@@ -1519,11 +1523,12 @@ class AsyncTeleBot:
await asyncio_helper.send_message(
self.token, chat_id, text, disable_web_page_preview, reply_to_message_id,
reply_markup, parse_mode, disable_notification, timeout,
- entities, allow_sending_without_reply))
+ entities, allow_sending_without_reply, protect_content))
async def forward_message(
self, chat_id: Union[int, str], from_chat_id: Union[int, str],
- message_id: int, disable_notification: Optional[bool]=None,
+ message_id: int, disable_notification: Optional[bool]=None,
+ protect_content: Optional[bool]=None,
timeout: Optional[int]=None) -> types.Message:
"""
Use this method to forward messages of any kind.
@@ -1531,11 +1536,12 @@ class AsyncTeleBot:
:param chat_id: which chat to forward
:param from_chat_id: which chat message from
:param message_id: message id
+ :param protect_content:
:param timeout:
:return: API reply.
"""
return types.Message.de_json(
- await asyncio_helper.forward_message(self.token, chat_id, from_chat_id, message_id, disable_notification, timeout))
+ await asyncio_helper.forward_message(self.token, chat_id, from_chat_id, message_id, disable_notification, timeout, protect_content))
async def copy_message(
self, chat_id: Union[int, str],
@@ -1545,6 +1551,7 @@ class AsyncTeleBot:
parse_mode: Optional[str]=None,
caption_entities: Optional[List[types.MessageEntity]]=None,
disable_notification: Optional[bool]=None,
+ protect_content: Optional[bool]=None,
reply_to_message_id: Optional[int]=None,
allow_sending_without_reply: Optional[bool]=None,
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
@@ -1562,12 +1569,13 @@ class AsyncTeleBot:
:param allow_sending_without_reply:
:param reply_markup:
:param timeout:
+ :param protect_content:
:return: API reply.
"""
return types.MessageID.de_json(
await asyncio_helper.copy_message(self.token, chat_id, from_chat_id, message_id, caption, parse_mode, caption_entities,
disable_notification, reply_to_message_id, allow_sending_without_reply, reply_markup,
- timeout))
+ timeout, protect_content))
async def delete_message(self, chat_id: Union[int, str], message_id: int,
timeout: Optional[int]=None) -> bool:
@@ -1586,7 +1594,8 @@ class AsyncTeleBot:
reply_to_message_id: Optional[int]=None,
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
timeout: Optional[int]=None,
- allow_sending_without_reply: Optional[bool]=None) -> types.Message:
+ allow_sending_without_reply: Optional[bool]=None,
+ protect_content: Optional[bool]=None) -> types.Message:
"""
Use this method to send dices.
:param chat_id:
@@ -1596,22 +1605,25 @@ class AsyncTeleBot:
:param reply_markup:
:param timeout:
:param allow_sending_without_reply:
+ :param protect_content:
:return: Message
"""
return types.Message.de_json(
await asyncio_helper.send_dice(
self.token, chat_id, emoji, disable_notification, reply_to_message_id,
- reply_markup, timeout, allow_sending_without_reply)
+ reply_markup, timeout, allow_sending_without_reply, protect_content)
)
async def send_photo(
self, chat_id: Union[int, str], photo: Union[Any, str],
- caption: Optional[str]=None, reply_to_message_id: Optional[int]=None,
- reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
- parse_mode: Optional[str]=None, disable_notification: Optional[bool]=None,
- timeout: Optional[int]=None,
+ caption: Optional[str]=None, parse_mode: Optional[str]=None,
caption_entities: Optional[List[types.MessageEntity]]=None,
- allow_sending_without_reply: Optional[bool]=None) -> types.Message:
+ disable_notification: Optional[bool]=None,
+ protect_content: Optional[bool]=None,
+ reply_to_message_id: Optional[int]=None,
+ allow_sending_without_reply: Optional[bool]=None,
+ reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
+ timeout: Optional[int]=None,) -> types.Message:
"""
Use this method to send photos.
:param chat_id:
@@ -1624,6 +1636,7 @@ class AsyncTeleBot:
:param timeout:
:param caption_entities:
:param allow_sending_without_reply:
+ :param protect_content:
:return: API reply.
"""
parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
@@ -1632,7 +1645,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))
+ allow_sending_without_reply, protect_content))
async def send_audio(
self, chat_id: Union[int, str], audio: Union[Any, str],
@@ -1645,7 +1658,8 @@ class AsyncTeleBot:
timeout: Optional[int]=None,
thumb: Optional[Union[Any, str]]=None,
caption_entities: Optional[List[types.MessageEntity]]=None,
- allow_sending_without_reply: Optional[bool]=None) -> types.Message:
+ allow_sending_without_reply: Optional[bool]=None,
+ protect_content: Optional[bool]=None) -> types.Message:
"""
Use this method to send audio files, if you want Telegram clients to display them in the music player.
Your audio must be in the .mp3 format.
@@ -1663,6 +1677,7 @@ class AsyncTeleBot:
:param thumb:
:param caption_entities:
:param allow_sending_without_reply:
+ :param protect_content:
:return: Message
"""
parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
@@ -1671,7 +1686,7 @@ class AsyncTeleBot:
await asyncio_helper.send_audio(
self.token, chat_id, audio, caption, duration, performer, title, reply_to_message_id,
reply_markup, parse_mode, disable_notification, timeout, thumb,
- caption_entities, allow_sending_without_reply))
+ caption_entities, allow_sending_without_reply, protect_content))
async def send_voice(
self, chat_id: Union[int, str], voice: Union[Any, str],
@@ -1682,7 +1697,8 @@ class AsyncTeleBot:
disable_notification: Optional[bool]=None,
timeout: Optional[int]=None,
caption_entities: Optional[List[types.MessageEntity]]=None,
- allow_sending_without_reply: Optional[bool]=None) -> types.Message:
+ allow_sending_without_reply: Optional[bool]=None,
+ protect_content: Optional[bool]=None) -> types.Message:
"""
Use this method to send audio files, if you want Telegram clients to display the file
as a playable voice message.
@@ -1697,6 +1713,7 @@ class AsyncTeleBot:
:param timeout:
:param caption_entities:
:param allow_sending_without_reply:
+ :param protect_content:
:return: Message
"""
parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
@@ -1705,7 +1722,7 @@ class AsyncTeleBot:
await asyncio_helper.send_voice(
self.token, chat_id, voice, caption, duration, reply_to_message_id, reply_markup,
parse_mode, disable_notification, timeout, caption_entities,
- allow_sending_without_reply))
+ allow_sending_without_reply, protect_content))
async def send_document(
self, chat_id: Union[int, str], document: Union[Any, str],
@@ -1720,7 +1737,8 @@ class AsyncTeleBot:
allow_sending_without_reply: Optional[bool]=None,
visible_file_name: Optional[str]=None,
disable_content_type_detection: Optional[bool]=None,
- data: Optional[Union[Any, str]]=None) -> types.Message:
+ data: Optional[Union[Any, str]]=None,
+ protect_content: Optional[bool]=None) -> types.Message:
"""
Use this method to send general files.
:param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
@@ -1737,6 +1755,7 @@ class AsyncTeleBot:
:param visible_file_name: allows to async define file name that will be visible in the Telegram instead of original file name
:param disable_content_type_detection: Disables automatic server-side content type detection for files uploaded using multipart/form-data
:param data: function typo compatibility: do not use it
+ :param protect_content:
:return: API reply.
"""
parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
@@ -1750,67 +1769,75 @@ class AsyncTeleBot:
reply_to_message_id = reply_to_message_id, reply_markup = reply_markup, parse_mode = parse_mode,
disable_notification = disable_notification, timeout = timeout, caption = caption, thumb = thumb,
caption_entities = caption_entities, allow_sending_without_reply = allow_sending_without_reply,
- disable_content_type_detection = disable_content_type_detection, visible_file_name = visible_file_name))
+ disable_content_type_detection = disable_content_type_detection, visible_file_name = visible_file_name, protect_content = protect_content))
async def send_sticker(
- self, chat_id: Union[int, str], data: Union[Any, str],
+ self, chat_id: Union[int, str], sticker: Union[Any, str],
reply_to_message_id: Optional[int]=None,
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
disable_notification: Optional[bool]=None,
timeout: Optional[int]=None,
- allow_sending_without_reply: Optional[bool]=None) -> types.Message:
+ allow_sending_without_reply: Optional[bool]=None,
+ protect_content: Optional[bool]=None,
+ data: Union[Any, str]=None) -> types.Message:
"""
Use this method to send .webp stickers.
:param chat_id:
- :param data:
+ :param sticker:
:param reply_to_message_id:
:param reply_markup:
:param disable_notification: to disable the notification
:param timeout: timeout
:param allow_sending_without_reply:
+ :param protect_content:
:return: API reply.
"""
+ if data and not(sticker):
+ # function typo miss compatibility
+ sticker = data
return types.Message.de_json(
await asyncio_helper.send_data(
- self.token, chat_id, data, 'sticker',
+ self.token, chat_id, sticker, 'sticker',
reply_to_message_id=reply_to_message_id, reply_markup=reply_markup,
disable_notification=disable_notification, timeout=timeout,
- allow_sending_without_reply=allow_sending_without_reply))
+ allow_sending_without_reply=allow_sending_without_reply, protect_content=protect_content))
async def send_video(
- self, chat_id: Union[int, str], data: Union[Any, str],
- duration: Optional[int]=None,
- caption: Optional[str]=None,
- reply_to_message_id: Optional[int]=None,
- reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
- parse_mode: Optional[str]=None,
- supports_streaming: Optional[bool]=None,
- disable_notification: Optional[bool]=None,
- timeout: Optional[int]=None,
- thumb: Optional[Union[Any, str]]=None,
- width: Optional[int]=None,
+ self, chat_id: Union[int, str], video: Union[Any, str],
+ duration: Optional[int]=None,
+ width: Optional[int]=None,
height: Optional[int]=None,
+ thumb: Optional[Union[Any, str]]=None,
+ caption: Optional[str]=None,
+ parse_mode: Optional[str]=None,
caption_entities: Optional[List[types.MessageEntity]]=None,
- allow_sending_without_reply: Optional[bool]=None) -> types.Message:
+ supports_streaming: Optional[bool]=None,
+ disable_notification: Optional[bool]=None,
+ protect_content: Optional[bool]=None,
+ reply_to_message_id: Optional[int]=None,
+ allow_sending_without_reply: Optional[bool]=None,
+ reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
+ timeout: Optional[int]=None,
+ data: Optional[Union[Any, str]]=None) -> types.Message:
"""
- Use this method to send video files, Telegram clients support mp4 videos.
- :param chat_id: Integer : Unique identifier for the message recipient — User or GroupChat id
- :param data: InputFile or String : Video to send. You can either pass a file_id as String to resend
- a video that is already on the Telegram server
- :param duration: Integer : Duration of sent video in seconds
- :param caption: String : Video caption (may also be used when resending videos by file_id).
- :param parse_mode:
- :param supports_streaming:
- :param reply_to_message_id:
- :param reply_markup:
- :param disable_notification:
- :param timeout:
- :param thumb: InputFile or String : Thumbnail of the file sent
- :param width:
- :param height:
+ Use this method to send video files, Telegram clients support mp4 videos (other formats may be sent as Document).
+ :param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
+ :param video: Video to send. You can either pass a file_id as String to resend a video that is already on the Telegram servers, or upload a new video file using multipart/form-data.
+ :param duration: Duration of sent video in seconds
+ :param width: Video width
+ :param height: Video height
+ :param thumb: Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new file, so you can pass “attach://” if the thumbnail was uploaded using multipart/form-data under .
+ :param caption: Video caption (may also be used when resending videos by file_id), 0-1024 characters after entities parsing
+ :param parse_mode: Mode for parsing entities in the video caption
:param caption_entities:
+ :param supports_streaming: Pass True, if the uploaded video is suitable for streaming
+ :param disable_notification: Sends the message silently. Users will receive a notification with no sound.
+ :param protect_content:
+ :param reply_to_message_id: If the message is a reply, ID of the original message
:param allow_sending_without_reply:
- :return:
+ :param reply_markup:
+ :param timeout:
+ :param data: function typo miss compatibility: do not use it
"""
parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
@@ -1818,33 +1845,38 @@ class AsyncTeleBot:
await asyncio_helper.send_video(
self.token, chat_id, data, duration, caption, reply_to_message_id, reply_markup,
parse_mode, supports_streaming, disable_notification, timeout, thumb, width, height,
- caption_entities, allow_sending_without_reply))
+ caption_entities, allow_sending_without_reply, protect_content))
async def send_animation(
self, chat_id: Union[int, str], animation: Union[Any, str],
duration: Optional[int]=None,
- caption: Optional[str]=None,
- reply_to_message_id: Optional[int]=None,
- reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
- parse_mode: Optional[str]=None,
- disable_notification: Optional[bool]=None,
- timeout: Optional[int]=None,
+ width: Optional[int]=None,
+ height: Optional[int]=None,
thumb: Optional[Union[Any, str]]=None,
+ caption: Optional[str]=None,
+ parse_mode: Optional[str]=None,
caption_entities: Optional[List[types.MessageEntity]]=None,
- allow_sending_without_reply: Optional[bool]=None) -> types.Message:
+ disable_notification: Optional[bool]=None,
+ protect_content: Optional[bool]=None,
+ reply_to_message_id: Optional[int]=None,
+ allow_sending_without_reply: Optional[bool]=None,
+ reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
+ timeout: Optional[int]=None, ) -> types.Message:
"""
Use this method to send animation files (GIF or H.264/MPEG-4 AVC video without sound).
:param chat_id: Integer : Unique identifier for the message recipient — User or GroupChat id
:param animation: InputFile or String : Animation to send. You can either pass a file_id as String to resend an
animation that is already on the Telegram server
:param duration: Integer : Duration of sent video in seconds
+ :param width: Integer : Video width
+ :param height: Integer : Video height
+ :param thumb: InputFile or String : Thumbnail of the file sent
:param caption: String : Animation caption (may also be used when resending animation by file_id).
:param parse_mode:
:param reply_to_message_id:
:param reply_markup:
:param disable_notification:
:param timeout:
- :param thumb: InputFile or String : Thumbnail of the file sent
:param caption_entities:
:param allow_sending_without_reply:
:return:
@@ -1855,7 +1887,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))
+ caption_entities, allow_sending_without_reply, width, height, protect_content))
async def send_video_note(
self, chat_id: Union[int, str], data: Union[Any, str],
@@ -1866,7 +1898,8 @@ class AsyncTeleBot:
disable_notification: Optional[bool]=None,
timeout: Optional[int]=None,
thumb: Optional[Union[Any, str]]=None,
- allow_sending_without_reply: Optional[bool]=None) -> types.Message:
+ allow_sending_without_reply: Optional[bool]=None,
+ protect_content: Optional[bool]=None) -> types.Message:
"""
As of v.4.0, Telegram clients support rounded square mp4 videos of up to 1 minute long. Use this method to send
video messages.
@@ -1881,12 +1914,13 @@ class AsyncTeleBot:
:param timeout:
:param thumb: InputFile or String : Thumbnail of the file sent
:param allow_sending_without_reply:
+ :param protect_content:
:return:
"""
return types.Message.de_json(
await asyncio_helper.send_video_note(
self.token, chat_id, data, duration, length, reply_to_message_id, reply_markup,
- disable_notification, timeout, thumb, allow_sending_without_reply))
+ disable_notification, timeout, thumb, allow_sending_without_reply, protect_content))
async def send_media_group(
self, chat_id: Union[int, str],
@@ -1894,6 +1928,7 @@ class AsyncTeleBot:
types.InputMediaAudio, types.InputMediaDocument,
types.InputMediaPhoto, types.InputMediaVideo]],
disable_notification: Optional[bool]=None,
+ protect_content: Optional[bool]=None,
reply_to_message_id: Optional[int]=None,
timeout: Optional[int]=None,
allow_sending_without_reply: Optional[bool]=None) -> List[types.Message]:
@@ -1905,11 +1940,12 @@ class AsyncTeleBot:
:param reply_to_message_id:
:param timeout:
:param allow_sending_without_reply:
+ :param protect_content:
:return:
"""
result = await asyncio_helper.send_media_group(
self.token, chat_id, media, disable_notification, reply_to_message_id, timeout,
- allow_sending_without_reply)
+ allow_sending_without_reply, protect_content)
return [types.Message.de_json(msg) for msg in result]
async def send_location(
@@ -1923,7 +1959,8 @@ class AsyncTeleBot:
horizontal_accuracy: Optional[float]=None,
heading: Optional[int]=None,
proximity_alert_radius: Optional[int]=None,
- allow_sending_without_reply: Optional[bool]=None) -> types.Message:
+ allow_sending_without_reply: Optional[bool]=None,
+ protect_content: Optional[bool]=None) -> types.Message:
"""
@@ -1940,6 +1977,7 @@ class AsyncTeleBot:
:param heading:
:param proximity_alert_radius:
:param allow_sending_without_reply:
+ :param protect_content:
:return: API reply.
"""
return types.Message.de_json(
@@ -1947,7 +1985,7 @@ class AsyncTeleBot:
self.token, chat_id, latitude, longitude, live_period,
reply_to_message_id, reply_markup, disable_notification, timeout,
horizontal_accuracy, heading, proximity_alert_radius,
- allow_sending_without_reply))
+ allow_sending_without_reply, protect_content))
async def edit_message_live_location(
self, latitude: float, longitude: float,
@@ -2011,7 +2049,8 @@ class AsyncTeleBot:
timeout: Optional[int]=None,
allow_sending_without_reply: Optional[bool]=None,
google_place_id: Optional[str]=None,
- google_place_type: Optional[str]=None) -> types.Message:
+ google_place_type: Optional[str]=None,
+ protect_content: Optional[bool]=None) -> types.Message:
"""
Use this method to send information about a venue.
:param chat_id: Integer or String : Unique identifier for the target chat or username of the target channel
@@ -2029,13 +2068,14 @@ class AsyncTeleBot:
:param allow_sending_without_reply:
:param google_place_id:
:param google_place_type:
+ :param protect_content:
:return:
"""
return types.Message.de_json(
await asyncio_helper.send_venue(
self.token, chat_id, latitude, longitude, title, address, foursquare_id, foursquare_type,
disable_notification, reply_to_message_id, reply_markup, timeout,
- allow_sending_without_reply, google_place_id, google_place_type)
+ allow_sending_without_reply, google_place_id, google_place_type, protect_content)
)
async def send_contact(
@@ -2046,12 +2086,27 @@ class AsyncTeleBot:
reply_to_message_id: Optional[int]=None,
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
timeout: Optional[int]=None,
- allow_sending_without_reply: Optional[bool]=None) -> types.Message:
+ allow_sending_without_reply: Optional[bool]=None,
+ protect_content: Optional[bool]=None) -> types.Message:
+ """
+ Use this method to send phone contacts.
+ :param chat_id: Integer or String : Unique identifier for the target chat or username of the target channel
+ :param phone_number: String : Contact's phone number
+ :param first_name: String : Contact's first name
+ :param last_name: String : Contact's last name
+ :param vcard: String : Additional data about the contact in the form of a vCard, 0-2048 bytes
+ :param disable_notification:
+ :param reply_to_message_id:
+ :param reply_markup:
+ :param timeout:
+ :param allow_sending_without_reply:
+ :param protect_content:
+ """
return types.Message.de_json(
await asyncio_helper.send_contact(
self.token, chat_id, phone_number, first_name, last_name, vcard,
disable_notification, reply_to_message_id, reply_markup, timeout,
- allow_sending_without_reply)
+ allow_sending_without_reply, protect_content)
)
async def send_chat_action(
@@ -2576,7 +2631,8 @@ class AsyncTeleBot:
reply_to_message_id: Optional[int]=None,
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
timeout: Optional[int]=None,
- allow_sending_without_reply: Optional[bool]=None) -> types.Message:
+ allow_sending_without_reply: Optional[bool]=None,
+ protect_content: Optional[bool]=None) -> types.Message:
"""
Used to send the game
:param chat_id:
@@ -2586,12 +2642,13 @@ class AsyncTeleBot:
:param reply_markup:
:param timeout:
:param allow_sending_without_reply:
+ :param protect_content:
:return:
"""
result = await asyncio_helper.send_game(
self.token, chat_id, game_short_name, disable_notification,
reply_to_message_id, reply_markup, timeout,
- allow_sending_without_reply)
+ allow_sending_without_reply, protect_content)
return types.Message.de_json(result)
async def set_game_score(
@@ -2651,7 +2708,8 @@ class AsyncTeleBot:
timeout: Optional[int]=None,
allow_sending_without_reply: Optional[bool]=None,
max_tip_amount: Optional[int] = None,
- suggested_tip_amounts: Optional[List[int]]=None) -> types.Message:
+ suggested_tip_amounts: Optional[List[int]]=None,
+ protect_content: Optional[bool]=None) -> types.Message:
"""
Sends invoice
:param chat_id: Unique identifier for the target private chat
@@ -2690,6 +2748,7 @@ class AsyncTeleBot:
:param suggested_tip_amounts: A JSON-serialized array of suggested amounts of tips in the smallest
units of the currency. At most 4 suggested tip amounts can be specified. The suggested tip
amounts must be positive, passed in a strictly increased order and must not exceed max_tip_amount.
+ :param protect_content:
:return:
"""
result = await asyncio_helper.send_invoice(
@@ -2698,7 +2757,7 @@ class AsyncTeleBot:
photo_height, need_name, need_phone_number, need_email, need_shipping_address,
send_phone_number_to_provider, send_email_to_provider, is_flexible, disable_notification,
reply_to_message_id, reply_markup, provider_data, timeout, allow_sending_without_reply,
- max_tip_amount, suggested_tip_amounts)
+ max_tip_amount, suggested_tip_amounts, protect_content)
return types.Message.de_json(result)
# noinspection PyShadowingBuiltins
@@ -2717,7 +2776,8 @@ class AsyncTeleBot:
reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
allow_sending_without_reply: Optional[bool]=None,
timeout: Optional[int]=None,
- explanation_entities: Optional[List[types.MessageEntity]]=None) -> types.Message:
+ explanation_entities: Optional[List[types.MessageEntity]]=None,
+ protect_content: Optional[bool]=None) -> types.Message:
"""
Send polls
:param chat_id:
@@ -2738,6 +2798,7 @@ class AsyncTeleBot:
:param reply_markup:
:param timeout:
:param explanation_entities:
+ :param protect_content:
:return:
"""
@@ -2751,7 +2812,7 @@ class AsyncTeleBot:
is_anonymous, type, allows_multiple_answers, correct_option_id,
explanation, explanation_parse_mode, open_period, close_date, is_closed,
disable_notification, reply_to_message_id, allow_sending_without_reply,
- reply_markup, timeout, explanation_entities))
+ reply_markup, timeout, explanation_entities, protect_content))
async def stop_poll(
self, chat_id: Union[int, str], message_id: int,
diff --git a/telebot/asyncio_helper.py b/telebot/asyncio_helper.py
index eab1aea..fc02775 100644
--- a/telebot/asyncio_helper.py
+++ b/telebot/asyncio_helper.py
@@ -39,7 +39,7 @@ MAX_RETRIES = 3
logger = telebot.logger
async def _process_request(token, url, method='get', params=None, files=None, request_timeout=None):
- params = compose_data(params, files)
+ params = prepare_data(params, files)
if request_timeout is None:
request_timeout = REQUEST_TIMEOUT
timeout = aiohttp.ClientTimeout(total=request_timeout)
@@ -54,6 +54,8 @@ async def _process_request(token, url, method='get', params=None, files=None, re
json_result = await _check_result(url, response)
if json_result:
return json_result['result']
+ except (ApiTelegramException,ApiInvalidJSONException, ApiHTTPException) as e:
+ raise e
except:
pass
if not got_result:
@@ -62,9 +64,9 @@ async def _process_request(token, url, method='get', params=None, files=None, re
-def guess_filename(obj):
+def prepare_file(obj):
"""
- Get file name from object
+ returns os.path.basename for a given file
:param obj:
:return:
@@ -74,9 +76,9 @@ def guess_filename(obj):
return os.path.basename(name)
-def compose_data(params=None, files=None):
+def prepare_data(params=None, files=None):
"""
- Prepare request data
+ prepare data for request.
:param params:
:param files:
@@ -96,7 +98,7 @@ def compose_data(params=None, files=None):
else:
raise ValueError('Tuple must have exactly 2 elements: filename, fileobj')
else:
- filename, fileobj = guess_filename(f) or key, f
+ filename, fileobj = prepare_file(f) or key, f
data.add_field(key, fileobj, filename=filename)
@@ -239,7 +241,7 @@ async def send_message(
token, chat_id, text,
disable_web_page_preview=None, reply_to_message_id=None, reply_markup=None,
parse_mode=None, disable_notification=None, timeout=None,
- entities=None, allow_sending_without_reply=None):
+ entities=None, allow_sending_without_reply=None, protect_content=None):
"""
Use this method to send text messages. On success, the sent Message is returned.
:param token:
@@ -253,6 +255,7 @@ async def send_message(
:param timeout:
:param entities:
:param allow_sending_without_reply:
+ :param protect_content:
:return:
"""
method_name = 'sendMessage'
@@ -273,6 +276,8 @@ async def send_message(
params['entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(entities))
if allow_sending_without_reply is not None:
params['allow_sending_without_reply'] = allow_sending_without_reply
+ if protect_content is not None:
+ params['protect_content'] = protect_content
return await _process_request(token, method_name, params=params)
@@ -344,19 +349,21 @@ async def get_chat_member(token, chat_id, user_id):
async def forward_message(
token, chat_id, from_chat_id, message_id,
- disable_notification=None, timeout=None):
+ disable_notification=None, timeout=None, protect_content=None):
method_url = r'forwardMessage'
payload = {'chat_id': chat_id, 'from_chat_id': from_chat_id, 'message_id': message_id}
if disable_notification is not None:
payload['disable_notification'] = disable_notification
if timeout:
payload['timeout'] = timeout
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
return await _process_request(token, method_url, params=payload)
async def copy_message(token, chat_id, from_chat_id, message_id, caption=None, parse_mode=None, caption_entities=None,
disable_notification=None, reply_to_message_id=None, allow_sending_without_reply=None,
- reply_markup=None, timeout=None):
+ reply_markup=None, timeout=None, protect_content=None):
method_url = r'copyMessage'
payload = {'chat_id': chat_id, 'from_chat_id': from_chat_id, 'message_id': message_id}
if caption is not None:
@@ -375,13 +382,15 @@ async def copy_message(token, chat_id, from_chat_id, message_id, caption=None, p
payload['allow_sending_without_reply'] = allow_sending_without_reply
if timeout:
payload['timeout'] = timeout
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
return await _process_request(token, method_url, params=payload)
async def send_dice(
token, chat_id,
emoji=None, disable_notification=None, reply_to_message_id=None,
- reply_markup=None, timeout=None, allow_sending_without_reply=None):
+ reply_markup=None, timeout=None, allow_sending_without_reply=None, protect_content=None):
method_url = r'sendDice'
payload = {'chat_id': chat_id}
if emoji:
@@ -396,6 +405,8 @@ async def send_dice(
payload['timeout'] = timeout
if allow_sending_without_reply is not None:
payload['allow_sending_without_reply'] = allow_sending_without_reply
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
return await _process_request(token, method_url, params=payload)
@@ -403,7 +414,7 @@ async def send_photo(
token, chat_id, 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):
+ caption_entities=None, allow_sending_without_reply=None, protect_content=None):
method_url = r'sendPhoto'
payload = {'chat_id': chat_id}
files = None
@@ -429,13 +440,15 @@ async def send_photo(
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
if allow_sending_without_reply is not None:
payload['allow_sending_without_reply'] = allow_sending_without_reply
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
return await _process_request(token, method_url, params=payload, files=files, method='post')
async def send_media_group(
token, chat_id, media,
disable_notification=None, reply_to_message_id=None,
- timeout=None, allow_sending_without_reply=None):
+ timeout=None, allow_sending_without_reply=None, protect_content=None):
method_url = r'sendMediaGroup'
media_json, files = await convert_input_media_array(media)
payload = {'chat_id': chat_id, 'media': media_json}
@@ -447,6 +460,8 @@ async def send_media_group(
payload['timeout'] = timeout
if allow_sending_without_reply is not None:
payload['allow_sending_without_reply'] = allow_sending_without_reply
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
return await _process_request(
token, method_url, params=payload,
method='post' if files else 'get',
@@ -458,7 +473,7 @@ async def send_location(
live_period=None, reply_to_message_id=None,
reply_markup=None, disable_notification=None,
timeout=None, horizontal_accuracy=None, heading=None,
- proximity_alert_radius=None, allow_sending_without_reply=None):
+ proximity_alert_radius=None, allow_sending_without_reply=None, protect_content=None):
method_url = r'sendLocation'
payload = {'chat_id': chat_id, 'latitude': latitude, 'longitude': longitude}
if live_period:
@@ -479,6 +494,8 @@ async def send_location(
payload['disable_notification'] = disable_notification
if timeout:
payload['timeout'] = timeout
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
return await _process_request(token, method_url, params=payload)
@@ -530,7 +547,7 @@ async def send_venue(
foursquare_id=None, foursquare_type=None, disable_notification=None,
reply_to_message_id=None, reply_markup=None, timeout=None,
allow_sending_without_reply=None, google_place_id=None,
- google_place_type=None):
+ google_place_type=None, protect_content=None):
method_url = r'sendVenue'
payload = {'chat_id': chat_id, 'latitude': latitude, 'longitude': longitude, 'title': title, 'address': address}
if foursquare_id:
@@ -551,13 +568,15 @@ async def send_venue(
payload['google_place_id'] = google_place_id
if google_place_type:
payload['google_place_type'] = google_place_type
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
return await _process_request(token, method_url, params=payload)
async def send_contact(
token, chat_id, phone_number, first_name, last_name=None, vcard=None,
disable_notification=None, reply_to_message_id=None, reply_markup=None, timeout=None,
- allow_sending_without_reply=None):
+ allow_sending_without_reply=None, protect_content=None):
method_url = r'sendContact'
payload = {'chat_id': chat_id, 'phone_number': phone_number, 'first_name': first_name}
if last_name:
@@ -574,6 +593,8 @@ async def send_contact(
payload['timeout'] = timeout
if allow_sending_without_reply is not None:
payload['allow_sending_without_reply'] = allow_sending_without_reply
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
return await _process_request(token, method_url, params=payload)
@@ -587,7 +608,8 @@ async def send_chat_action(token, chat_id, action, timeout=None):
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):
+ thumb=None, width=None, height=None, caption_entities=None, allow_sending_without_reply=None,
+ protect_content=None):
method_url = r'sendVideo'
payload = {'chat_id': chat_id}
files = None
@@ -627,13 +649,15 @@ async def send_video(token, chat_id, data, duration=None, caption=None, reply_to
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
if allow_sending_without_reply is not None:
payload['allow_sending_without_reply'] = allow_sending_without_reply
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
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):
+ allow_sending_without_reply=None, width=None, height=None, protect_content=None):
method_url = r'sendAnimation'
payload = {'chat_id': chat_id}
files = None
@@ -667,12 +691,18 @@ async def send_animation(
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
if allow_sending_without_reply is not None:
payload['allow_sending_without_reply'] = allow_sending_without_reply
+ if width:
+ payload['width'] = width
+ if height:
+ payload['height'] = height
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
return await _process_request(token, method_url, params=payload, files=files, method='post')
async def send_voice(token, chat_id, voice, caption=None, duration=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):
+ allow_sending_without_reply=None, protect_content=None):
method_url = r'sendVoice'
payload = {'chat_id': chat_id}
files = None
@@ -698,11 +728,13 @@ async def send_voice(token, chat_id, voice, caption=None, duration=None, reply_t
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
if allow_sending_without_reply is not None:
payload['allow_sending_without_reply'] = allow_sending_without_reply
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
return await _process_request(token, method_url, params=payload, files=files, method='post')
async def send_video_note(token, chat_id, data, duration=None, length=None, reply_to_message_id=None, reply_markup=None,
- disable_notification=None, timeout=None, thumb=None, allow_sending_without_reply=None):
+ disable_notification=None, timeout=None, thumb=None, allow_sending_without_reply=None, protect_content=None):
method_url = r'sendVideoNote'
payload = {'chat_id': chat_id}
files = None
@@ -734,12 +766,14 @@ async def send_video_note(token, chat_id, data, duration=None, length=None, repl
payload['thumb'] = thumb
if allow_sending_without_reply is not None:
payload['allow_sending_without_reply'] = allow_sending_without_reply
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
return await _process_request(token, method_url, params=payload, files=files, method='post')
async def send_audio(token, chat_id, audio, caption=None, duration=None, performer=None, title=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):
+ caption_entities=None, allow_sending_without_reply=None, protect_content=None):
method_url = r'sendAudio'
payload = {'chat_id': chat_id}
files = None
@@ -777,12 +811,14 @@ async def send_audio(token, chat_id, audio, caption=None, duration=None, perform
payload['caption_entities'] = json.dumps(types.MessageEntity.to_list_of_dicts(caption_entities))
if allow_sending_without_reply is not None:
payload['allow_sending_without_reply'] = allow_sending_without_reply
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
return await _process_request(token, method_url, params=payload, files=files, method='post')
async def send_data(token, chat_id, data, data_type, reply_to_message_id=None, reply_markup=None, parse_mode=None,
disable_notification=None, timeout=None, caption=None, thumb=None, caption_entities=None,
- allow_sending_without_reply=None, disable_content_type_detection=None, visible_file_name=None):
+ allow_sending_without_reply=None, disable_content_type_detection=None, visible_file_name=None, protect_content=None):
method_url = await get_method_by_type(data_type)
payload = {'chat_id': chat_id}
files = None
@@ -1187,7 +1223,7 @@ async def delete_message(token, chat_id, message_id, timeout=None):
async def send_game(
token, chat_id, game_short_name,
disable_notification=None, reply_to_message_id=None, reply_markup=None, timeout=None,
- allow_sending_without_reply=None):
+ allow_sending_without_reply=None, protect_content=None):
method_url = r'sendGame'
payload = {'chat_id': chat_id, 'game_short_name': game_short_name}
if disable_notification is not None:
@@ -1200,6 +1236,8 @@ async def send_game(
payload['timeout'] = timeout
if allow_sending_without_reply is not None:
payload['allow_sending_without_reply'] = allow_sending_without_reply
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
return await _process_request(token, method_url, params=payload)
@@ -1264,7 +1302,7 @@ async def send_invoice(
need_name=None, need_phone_number=None, need_email=None, need_shipping_address=None,
send_phone_number_to_provider = None, send_email_to_provider = None, is_flexible=None,
disable_notification=None, reply_to_message_id=None, reply_markup=None, provider_data=None,
- timeout=None, allow_sending_without_reply=None, max_tip_amount=None, suggested_tip_amounts=None):
+ timeout=None, allow_sending_without_reply=None, max_tip_amount=None, suggested_tip_amounts=None, protect_content=None):
"""
Use this method to send invoices. On success, the sent Message is returned.
:param token: Bot's token (you don't need to fill this)
@@ -1296,6 +1334,7 @@ async def send_invoice(
:param max_tip_amount: The maximum accepted amount for tips in the smallest units of the currency
:param suggested_tip_amounts: A JSON-serialized array of suggested amounts of tips in the smallest units of the currency.
At most 4 suggested tip amounts can be specified. The suggested tip amounts must be positive, passed in a strictly increased order and must not exceed max_tip_amount.
+ :param protect_content:
:return:
"""
method_url = r'sendInvoice'
@@ -1342,6 +1381,8 @@ async def send_invoice(
payload['max_tip_amount'] = max_tip_amount
if suggested_tip_amounts is not None:
payload['suggested_tip_amounts'] = json.dumps(suggested_tip_amounts)
+ if protect_content is not None:
+ payload['protect_content'] = protect_content
return await _process_request(token, method_url, params=payload)
@@ -1490,7 +1531,7 @@ async def send_poll(
is_anonymous = None, type = None, allows_multiple_answers = None, correct_option_id = None,
explanation = None, explanation_parse_mode=None, open_period = None, close_date = None, is_closed = None,
disable_notification=False, reply_to_message_id=None, allow_sending_without_reply=None,
- reply_markup=None, timeout=None, explanation_entities=None):
+ reply_markup=None, timeout=None, explanation_entities=None, protect_content=None):
method_url = r'sendPoll'
payload = {
'chat_id': str(chat_id),
@@ -1532,6 +1573,8 @@ async def send_poll(
if explanation_entities:
payload['explanation_entities'] = json.dumps(
types.MessageEntity.to_list_of_dicts(explanation_entities))
+ if protect_content:
+ payload['protect_content'] = protect_content
return await _process_request(token, method_url, params=payload)
async def _convert_list_json_serializable(results):
diff --git a/telebot/types.py b/telebot/types.py
index eb3fabf..a200b73 100644
--- a/telebot/types.py
+++ b/telebot/types.py
@@ -582,7 +582,8 @@ class Message(JsonDeserializable):
# "url": "{text}", # @badiboy plain URLs have no text and do not need tags
"text_link": "{text}",
"strikethrough": "{text}",
- "underline": "{text}"
+ "underline": "{text}",
+ "spoiler": "{text}",
}
if hasattr(self, "custom_subs"):