diff --git a/README.md b/README.md
index cf6e75fa9..c37a19eb4 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@
A simple, but extensible Python implementation for the Telegram Bot API.
Both synchronous and asynchronous.
-## Supported Bot API version: 6.7!
+##
Supported Bot API version: 6.8!
diff --git a/telebot/__init__.py b/telebot/__init__.py
index 77cdd0ded..e4377d2a0 100644
--- a/telebot/__init__.py
+++ b/telebot/__init__.py
@@ -4571,6 +4571,24 @@ def answer_inline_query(
return apihelper.answer_inline_query(self.token, inline_query_id, results, cache_time, is_personal, next_offset,
button)
+ def unpin_all_general_forum_topic_messages(self, chat_id: Union[int, str]) -> bool:
+ """
+ Use this method to clear the list of pinned messages in a General forum topic.
+ The bot must be an administrator in the chat for this to work and must have the
+ can_pin_messages administrator right in the supergroup.
+ Returns True on success.
+
+ Telegram documentation: https://core.telegram.org/bots/api#unpinAllGeneralForumTopicMessages
+
+ :param chat_id: Unique identifier for the target chat or username of chat
+ :type chat_id: :obj:`int` | :obj:`str`
+
+ :return: On success, True is returned.
+ :rtype: :obj:`bool`
+ """
+
+ return apihelper.unpin_all_general_forum_topic_messages(self.token, chat_id)
+
def answer_callback_query(
self, callback_query_id: int,
text: Optional[str]=None, show_alert: Optional[bool]=None,
diff --git a/telebot/apihelper.py b/telebot/apihelper.py
index a07f1ef91..cf8a03faf 100644
--- a/telebot/apihelper.py
+++ b/telebot/apihelper.py
@@ -1585,6 +1585,11 @@ def answer_pre_checkout_query(token, pre_checkout_query_id, ok, error_message=No
return _make_request(token, method_url, params=payload)
+def unpin_all_general_forum_topic_messages(token, chat_id):
+ method_url = 'unpinAllGeneralForumTopicMessages'
+ payload = {'chat_id': chat_id}
+ return _make_request(token, method_url, params=payload, method='post')
+
# InlineQuery
def answer_callback_query(token, callback_query_id, text=None, show_alert=None, url=None, cache_time=None):
diff --git a/telebot/async_telebot.py b/telebot/async_telebot.py
index b3f189e16..91d0709c6 100644
--- a/telebot/async_telebot.py
+++ b/telebot/async_telebot.py
@@ -5432,6 +5432,24 @@ async def answer_inline_query(
return await asyncio_helper.answer_inline_query(self.token, inline_query_id, results, cache_time, is_personal, next_offset,
button)
+ async def unpin_all_general_forum_topic_messages(self, chat_id: Union[int, str]) -> bool:
+ """
+ Use this method to clear the list of pinned messages in a General forum topic.
+ The bot must be an administrator in the chat for this to work and must have the
+ can_pin_messages administrator right in the supergroup.
+ Returns True on success.
+
+ Telegram documentation: https://core.telegram.org/bots/api#unpinAllGeneralForumTopicMessages
+
+ :param chat_id: Unique identifier for the target chat or username of chat
+ :type chat_id: :obj:`int` | :obj:`str`
+
+ :return: On success, True is returned.
+ :rtype: :obj:`bool`
+ """
+
+ return await asyncio_helper.unpin_all_general_forum_topic_messages(self.token, chat_id)
+
async def answer_callback_query(
self, callback_query_id: int,
text: Optional[str]=None, show_alert: Optional[bool]=None,
diff --git a/telebot/asyncio_helper.py b/telebot/asyncio_helper.py
index 5a615b397..894b62be5 100644
--- a/telebot/asyncio_helper.py
+++ b/telebot/asyncio_helper.py
@@ -1575,6 +1575,11 @@ async def answer_pre_checkout_query(token, pre_checkout_query_id, ok, error_mess
return await _process_request(token, method_url, params=payload)
+async def unpin_all_general_forum_topic_messages(token, chat_id):
+ method_url = 'unpinAllGeneralForumTopicMessages'
+ payload = {'chat_id': chat_id}
+ return await _process_request(token, method_url, params=payload, method='post')
+
# InlineQuery
async def answer_callback_query(token, callback_query_id, text=None, show_alert=None, url=None, cache_time=None):
diff --git a/telebot/types.py b/telebot/types.py
index 7f5fc3035..a81fad42e 100644
--- a/telebot/types.py
+++ b/telebot/types.py
@@ -543,6 +543,10 @@ class Chat(JsonDeserializable):
Returned only in getChat.
:type emoji_status_custom_emoji_id: :obj:`str`
+ :param emoji_status_expiration_date: Optional. Expiration date of the emoji status of the other party in a private chat,
+ if any. Returned only in getChat.
+ :type emoji_status_expiration_date: :obj:`int`
+
:param bio: Optional. Bio of the other party in a private chat. Returned only in getChat.
:type bio: :obj:`str`
@@ -638,7 +642,7 @@ def __init__(self, id, type, title=None, username=None, first_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,
- has_hidden_members=None, has_aggressive_anti_spam_enabled=None, **kwargs):
+ has_hidden_members=None, has_aggressive_anti_spam_enabled=None, emoji_status_expiration_date=None, **kwargs):
self.id: int = id
self.type: str = type
self.title: str = title
@@ -667,6 +671,7 @@ def __init__(self, id, type, title=None, username=None, first_name=None,
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
+ self.emoji_status_expiration_date: int = emoji_status_expiration_date
class MessageID(JsonDeserializable):
@@ -821,6 +826,9 @@ class Message(JsonDeserializable):
:param sticker: Optional. Message is a sticker, information about the sticker
:type sticker: :class:`telebot.types.Sticker`
+ :param story: Optional. Message is a forwarded story
+ :type story: :class:`telebot.types.Story`
+
:param video: Optional. Message is a video, information about the video
:type video: :class:`telebot.types.Video`
@@ -1177,6 +1185,9 @@ def de_json(cls, json_string):
if 'chat_shared' in obj:
opts['chat_shared'] = ChatShared.de_json(obj['chat_shared'])
content_type = 'chat_shared'
+ if 'story' in obj:
+ opts['story'] = Story.de_json(obj['story'])
+ content_type = 'story'
return cls(message_id, from_user, date, chat, content_type, opts, json_string)
@classmethod
@@ -1274,10 +1285,12 @@ def __init__(self, message_id, from_user, date, chat, content_type, options, jso
self.write_access_allowed: Optional[WriteAccessAllowed] = None
self.user_shared: Optional[UserShared] = None
self.chat_shared: Optional[ChatShared] = None
+ self.story: Optional[Story] = None
for key in options:
setattr(self, key, options[key])
self.json = json_string
+
def __html_text(self, text, entities):
"""
Author: @sviat9440
@@ -6680,7 +6693,10 @@ class PollAnswer(JsonSerializable, JsonDeserializable, Dictionaryable):
:param poll_id: Unique poll identifier
:type poll_id: :obj:`str`
- :param user: The user, who changed the answer to the poll
+ :param voter_chat: Optional. The chat that changed the answer to the poll, if the voter is anonymous
+ :type voter_chat: :class:`telebot.types.Chat`
+
+ :param user: Optional. The user, who changed the answer to the poll
:type user: :class:`telebot.types.User`
:param option_ids: 0-based identifiers of answer options, chosen by the user. May be empty if the user retracted
@@ -6694,21 +6710,34 @@ class PollAnswer(JsonSerializable, JsonDeserializable, Dictionaryable):
def de_json(cls, json_string):
if (json_string is None): return None
obj = cls.check_json(json_string)
- obj['user'] = User.de_json(obj['user'])
+ if 'user' in obj:
+ obj['user'] = User.de_json(obj['user'])
+ if 'voter_chat' in obj:
+ obj['voter_chat'] = Chat.de_json(obj['voter_chat'])
return cls(**obj)
- def __init__(self, poll_id, user, option_ids, **kwargs):
+ def __init__(self, poll_id, option_ids, user=None, voter_chat=None, **kwargs):
self.poll_id: str = poll_id
- self.user: User = user
+ self.user: Optional[User] = user
self.option_ids: List[int] = option_ids
+ self.voter_chat: Optional[Chat] = voter_chat
+
def to_json(self):
return json.dumps(self.to_dict())
def to_dict(self):
- return {'poll_id': self.poll_id,
- 'user': self.user.to_dict(),
- 'option_ids': self.option_ids}
+ # Left for backward compatibility, but with no support for voter_chat
+ json_dict = {
+ "poll_id": self.poll_id,
+ "option_ids": self.option_ids
+ }
+ if self.user:
+ json_dict["user"] = self.user.to_dict()
+ if self.voter_chat:
+ json_dict["voter_chat"] = self.voter_chat
+ return json_dict
+
class ChatLocation(JsonSerializable, JsonDeserializable, Dictionaryable):
@@ -7743,3 +7772,21 @@ def to_dict(self) -> dict:
def to_json(self) -> str:
return json.dumps(self.to_dict())
+
+
+class Story(JsonDeserializable):
+ """
+ This object represents a message about a forwarded story in the chat.
+ Currently holds no information.
+ """
+
+ @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) -> None:
+ pass
+