Skip to content

Commit

Permalink
Merge pull request #2030 from coder2020official/botapi6.8
Browse files Browse the repository at this point in the history
Bot API 6.8: Stories, voting as a chat, and other minor changes
  • Loading branch information
Badiboy authored Aug 20, 2023
2 parents 396d476 + 9fd6ef3 commit 01b0071
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 9 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<p align="center">A simple, but extensible Python implementation for the <a href="https://core.telegram.org/bots/api">Telegram Bot API</a>.</p>
<p align="center">Both synchronous and asynchronous.</p>

## <p align="center">Supported Bot API version: <a href="https://core.telegram.org/bots/api#april-21-2023">6.7</a>!
## <p align="center">Supported Bot API version: <a href="https://core.telegram.org/bots/api#august-18-2023">6.8</a>!

<h2><a href='https://pytba.readthedocs.io/en/latest/index.html'>Official documentation</a></h2>
<h2><a href='https://pytba.readthedocs.io/ru/latest/index.html'>Official ru documentation</a></h2>
Expand Down
18 changes: 18 additions & 0 deletions telebot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
5 changes: 5 additions & 0 deletions telebot/apihelper.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
18 changes: 18 additions & 0 deletions telebot/async_telebot.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
5 changes: 5 additions & 0 deletions telebot/asyncio_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
63 changes: 55 additions & 8 deletions telebot/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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`
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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):
Expand Down Expand Up @@ -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

0 comments on commit 01b0071

Please sign in to comment.