Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bot API Huge Update - 7.0, introducing reactions, replies and some other changes #2106

Merged
merged 47 commits into from
Jan 3, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
430e327
Start of bot API Update - 7.0
coder2020official Dec 29, 2023
134f45b
Added the classes ReactionTypeEmoji and ReactionTypeCustomEmoji repre…
coder2020official Dec 29, 2023
974395e
New handler: message_reaction_handler(untested)
coder2020official Dec 29, 2023
8fee136
Fix tests for the new handler
coder2020official Dec 29, 2023
97e0d4e
Fix tests #2
coder2020official Dec 29, 2023
2fb2e30
Fix minor issue for tests #3
coder2020official Dec 29, 2023
854c685
Added updates about reaction changes on a message with anonymous rea…
coder2020official Dec 29, 2023
96b4ced
Fix tests for the new handler
coder2020official Dec 29, 2023
b6a0d6c
Added the method setMessageReaction that allows bots to react to mess…
coder2020official Dec 29, 2023
7576458
Added the field available_reactions to the class Chat.
coder2020official Dec 29, 2023
ad816f2
Added the class ExternalReplyInfo and the field external_reply of typ…
coder2020official Dec 29, 2023
5e01891
Added TextQuote and fixed extrernal_reply (forgot in previous commit)…
coder2020official Dec 29, 2023
2604655
ReplyParameters support for sync, including backward compatibility
coder2020official Dec 29, 2023
6211366
Fix the typo and therefore tests
coder2020official Dec 29, 2023
3b5d2d7
Fix tests attempt 2
coder2020official Dec 29, 2023
c04ae53
Added reply_parameters to sync
coder2020official Dec 29, 2023
545cedb
Fix some issues with the previous commit
coder2020official Dec 29, 2023
b8ef19d
Added support for linkpreviewoptions
coder2020official Dec 29, 2023
0485c31
Replaced the field disable_web_page_preview with link_preview_options…
coder2020official Dec 29, 2023
a261174
Added the field link_preview_options to the class Message with infor…
coder2020official Dec 29, 2023
c406e6c
Added Copy,Delete,Forward Messages to sync and async
coder2020official Dec 29, 2023
254387d
Renamed the class KeyboardButtonRequestUser to KeyboardButtonRequest…
coder2020official Dec 29, 2023
350f7fe
Added the class UsersShared. Replaced the field user_shared in the …
coder2020official Dec 29, 2023
e1c9223
Chat Boosts full support for handlers;
coder2020official Dec 30, 2023
137ea69
get_user_chat_boosts for sync and async; +UserChatBoosts
coder2020official Dec 30, 2023
ab2d1fa
Giveaways full support: start and end of giveaways, and information a…
coder2020official Dec 30, 2023
e290f27
Added the fields has_visible_story, accent_color_id, background_cust…
coder2020official Dec 30, 2023
af6f485
Added the class MessageOrigin and replaced the fields forward_from, …
coder2020official Dec 30, 2023
e94d5ce
Added InaccessibleMessage support, not sure on the implementation for…
coder2020official Dec 30, 2023
456a9ed
Minor utils edit that adds all update types
coder2020official Dec 30, 2023
39abb9d
Fix a typo
coder2020official Dec 30, 2023
87404d3
Set func=None by default for new handlers;
coder2020official Dec 30, 2023
bc8120e
Fix issues related with reactions handlers
coder2020official Dec 30, 2023
f081ec8
Fix de_json for some classes
coder2020official Dec 30, 2023
05a939b
Fix reply_markup issue with reply_parameters conflict
coder2020official Dec 31, 2023
52a0314
Fix naming in Update class
Badiboy Jan 2, 2024
79cc127
reply_to_message_id and allow_sending_without_reply deprecation
Badiboy Jan 2, 2024
56fbcaf
disable_web_page_preview deprecation
Badiboy Jan 2, 2024
778a02c
Fix forward_messages return value
Badiboy Jan 2, 2024
0af7f6f
Fix forward_messages return value in Async
Badiboy Jan 2, 2024
0ace17b
Fix the fix forward_messages return value
Badiboy Jan 2, 2024
578d6a3
Fix message_reaction_x_handler description
Badiboy Jan 2, 2024
4359f4f
Fix message_reaction_x_handler description for Async
Badiboy Jan 2, 2024
9831ae2
Fix and align reply_parameters
Badiboy Jan 3, 2024
71f53d3
Fix minor bugs in types.py
Badiboy Jan 3, 2024
b96084f
reply_parameters => to_json
Badiboy Jan 3, 2024
0c9bdfb
Fix classes loading in types.py
Badiboy Jan 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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-changelog#september-22-2023">6.9</a>!
## <p align="center">Supported Bot API version: <a href="https://core.telegram.org/bots/api#december-29-2023">7.0</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
152 changes: 152 additions & 0 deletions telebot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ def __init__(
self.edited_message_handlers = []
self.channel_post_handlers = []
self.edited_channel_post_handlers = []
self.message_reaction_handlers = []
self.message_reaction_count_handlers = []
self.inline_handlers = []
self.chosen_inline_handlers = []
self.callback_query_handlers = []
Expand Down Expand Up @@ -670,6 +672,8 @@ def process_new_updates(self, updates: List[types.Update]):
new_edited_messages = None
new_channel_posts = None
new_edited_channel_posts = None
new_message_reactions = None
message_reaction_counts = None
new_inline_queries = None
new_chosen_inline_results = None
new_callback_queries = None
Expand Down Expand Up @@ -737,6 +741,12 @@ def process_new_updates(self, updates: List[types.Update]):
if update.chat_join_request:
if new_chat_join_request is None: new_chat_join_request = []
new_chat_join_request.append(update.chat_join_request)
if update.message_reaction:
if new_message_reactions is None: new_message_reactions = []
new_message_reactions.append(update.message_reaction)
if update.message_reaction_count:
if message_reaction_counts is None: message_reaction_counts = []
message_reaction_counts.append(update.message_reaction_count)

if new_messages:
self.process_new_messages(new_messages)
Expand Down Expand Up @@ -766,6 +776,10 @@ def process_new_updates(self, updates: List[types.Update]):
self.process_new_chat_member(new_chat_members)
if new_chat_join_request:
self.process_new_chat_join_request(new_chat_join_request)
if new_message_reactions:
self.process_new_message_reaction(new_message_reactions)
if message_reaction_counts:
self.process_new_message_reaction_count(message_reaction_counts)

def process_new_messages(self, new_messages):
"""
Expand Down Expand Up @@ -794,6 +808,18 @@ def process_new_edited_channel_posts(self, edited_channel_post):
"""
self._notify_command_handlers(self.edited_channel_post_handlers, edited_channel_post, 'edited_channel_post')

def process_new_message_reaction(self, message_reactions):
"""
:meta private:
"""
self._notify_command_handlers(self.message_reaction_handlers, message_reactions, 'message_reaction')

def process_new_message_reaction_count(self, message_reaction_counts):
"""
:meta private:
"""
self._notify_command_handlers(self.message_reaction_count_handlers, message_reaction_counts, 'message_reaction_count')

def process_new_inline_query(self, new_inline_queries):
"""
:meta private:
Expand Down Expand Up @@ -1303,6 +1329,29 @@ def close(self) -> bool:
:return: :obj:`bool`
"""
return apihelper.close(self.token)

def set_message_reaction(self, chat_id: Union[int, str], message_id: int, reaction: Optional[List[types.ReactionType]]=None, is_big: Optional[bool]=None) -> bool:
"""
Use this method to set a reaction to a message in a chat. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns True on success.

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

:param chat_id: Unique identifier for the target chat or username of the target supergroup or channel (in the format @channelusername)
:type chat_id: :obj:`int` or :obj:`str`

:param message_id: Identifier of the message to set reaction to
:type message_id: :obj:`int`

:param reaction: New list of reaction types to set on the message. Currently, as non-premium users, bots can set up to one reaction per message.
A custom emoji reaction can be used if it is either already present on the message or explicitly allowed by chat administrators.
:type reaction: :obj:`list` of :class:`telebot.types.ReactionType`

:param is_big: Pass True to set the reaction with a big animation
:type is_big: :obj:`bool`

:return: :obj:`bool`
"""
return apihelper.set_message_reaction(self.token, chat_id, message_id, reaction, is_big)


def get_user_profile_photos(self, user_id: int, offset: Optional[int]=None,
Expand Down Expand Up @@ -6174,6 +6223,109 @@ def register_edited_channel_post_handler(self, callback: Callable, content_types
**kwargs)
self.add_edited_channel_post_handler(handler_dict)


def message_reaction_handler(self, func, **kwargs):
"""
Handles new incoming message reaction.
As a parameter to the decorator function, it passes :class:`telebot.types.Message` object.

:param func: Function executed as a filter
:type func: :obj:`function`

:param kwargs: Optional keyword arguments(custom filters)

:return:
"""
def decorator(handler):
handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
self.add_message_reaction_handler(handler_dict)
return handler

return decorator

def add_message_reaction_handler(self, handler_dict):
"""
Adds message reaction handler
Note that you should use register_message_reaction_handler to add message_reaction_handler to the bot.

:meta private:

:param handler_dict:
:return:
"""
self.message_reaction_handlers.append(handler_dict)

def register_message_reaction_handler(self, callback: Callable, func: Callable, pass_bot: Optional[bool]=False, **kwargs):
"""
Registers message reaction handler.

:param callback: function to be called
:type callback: :obj:`function`

:param func: Function executed as a filter
:type func: :obj:`function`

:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
:type pass_bot: :obj:`bool`

:param kwargs: Optional keyword arguments(custom filters)

:return: None
"""
handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
self.add_message_reaction_handler(handler_dict)

def message_reaction_count_handler(self, func, **kwargs):
"""
Handles new incoming message reaction count.
As a parameter to the decorator function, it passes :class:`telebot.types.Message` object.

:param func: Function executed as a filter
:type func: :obj:`function`

:param kwargs: Optional keyword arguments(custom filters)

:return:
"""
def decorator(handler):
handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
self.add_message_reaction_count_handler(handler_dict)
return handler

return decorator

def add_message_reaction_count_handler(self, handler_dict):
"""
Adds message reaction count handler
Note that you should use register_message_reaction_count_handler to add message_reaction_count_handler to the bot.

:meta private:

:param handler_dict:
:return:
"""
self.message_reaction_count_handlers.append(handler_dict)

def register_message_reaction_count_handler(self, callback: Callable, func: Callable, pass_bot: Optional[bool]=False, **kwargs):
"""
Registers message reaction count handler.

:param callback: function to be called
:type callback: :obj:`function`

:param func: Function executed as a filter
:type func: :obj:`function`

:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
:type pass_bot: :obj:`bool`

:param kwargs: Optional keyword arguments(custom filters)

:return: None
"""
handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
self.add_message_reaction_count_handler(handler_dict)

def inline_handler(self, func, **kwargs):
"""
Handles new incoming inline query.
Expand Down
10 changes: 10 additions & 0 deletions telebot/apihelper.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,16 @@ def get_user_profile_photos(token, user_id, offset=None, limit=None):
payload['limit'] = limit
return _make_request(token, method_url, params=payload)

def set_message_reaction(token, chat_id, message_id, reaction=None, is_big=None):
method_url = r'setMessageReaction'
payload = {'chat_id': chat_id, 'message_id': message_id}
if reaction:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Proposal.
Check if reaction is not list (single reaction) and convert it to list.
or
Check if reaction is not list and raise error with explanation.

Reasonable.
I suppose lot of mistakes by users because of parameter naming: "reaction".

payload['reaction'] = reaction
if is_big is not None:
payload['is_big'] = is_big
return _make_request(token, method_url, params=payload)



def get_chat(token, chat_id):
method_url = r'getChat'
Expand Down
Loading
Loading