diff --git a/compiler/docs/compiler.py b/compiler/docs/compiler.py index 20e0dd25..c78a47ee 100644 --- a/compiler/docs/compiler.py +++ b/compiler/docs/compiler.py @@ -366,6 +366,7 @@ def pyrogram_api(): InlineQueryResultArticle InlineQueryResultPhoto InlineQueryResultAnimation + ChosenInlineResult """, input_message_content=""" InputMessageContent diff --git a/docs/source/api/decorators.rst b/docs/source/api/decorators.rst index 2fc856bc..cacb43b1 100644 --- a/docs/source/api/decorators.rst +++ b/docs/source/api/decorators.rst @@ -41,6 +41,7 @@ Index - :meth:`~Client.on_message` - :meth:`~Client.on_callback_query` - :meth:`~Client.on_inline_query` + - :meth:`~Client.on_chosen_inline_result` - :meth:`~Client.on_deleted_messages` - :meth:`~Client.on_user_status` - :meth:`~Client.on_poll` @@ -56,6 +57,7 @@ Details .. autodecorator:: pyrogram.Client.on_message() .. autodecorator:: pyrogram.Client.on_callback_query() .. autodecorator:: pyrogram.Client.on_inline_query() +.. autodecorator:: pyrogram.Client.on_chosen_inline_result() .. autodecorator:: pyrogram.Client.on_deleted_messages() .. autodecorator:: pyrogram.Client.on_user_status() .. autodecorator:: pyrogram.Client.on_poll() diff --git a/docs/source/api/handlers.rst b/docs/source/api/handlers.rst index e66b66bd..4fdc511e 100644 --- a/docs/source/api/handlers.rst +++ b/docs/source/api/handlers.rst @@ -38,6 +38,7 @@ Index - :class:`DeletedMessagesHandler` - :class:`CallbackQueryHandler` - :class:`InlineQueryHandler` + - :class:`ChosenInlineResultHandler` - :class:`UserStatusHandler` - :class:`PollHandler` - :class:`DisconnectHandler` @@ -53,6 +54,7 @@ Details .. autoclass:: DeletedMessagesHandler() .. autoclass:: CallbackQueryHandler() .. autoclass:: InlineQueryHandler() +.. autoclass:: ChosenInlineResultHandler() .. autoclass:: UserStatusHandler() .. autoclass:: PollHandler() .. autoclass:: DisconnectHandler() diff --git a/pyrogram/client/ext/dispatcher.py b/pyrogram/client/ext/dispatcher.py index 20be359e..256dd5f2 100644 --- a/pyrogram/client/ext/dispatcher.py +++ b/pyrogram/client/ext/dispatcher.py @@ -28,12 +28,14 @@ from pyrogram.api.types import ( UpdateEditMessage, UpdateEditChannelMessage, UpdateDeleteMessages, UpdateDeleteChannelMessages, UpdateBotCallbackQuery, UpdateInlineBotCallbackQuery, - UpdateUserStatus, UpdateBotInlineQuery, UpdateMessagePoll + UpdateUserStatus, UpdateBotInlineQuery, UpdateMessagePoll, + UpdateBotInlineSend ) from . import utils from ..handlers import ( CallbackQueryHandler, MessageHandler, DeletedMessagesHandler, - UserStatusHandler, RawUpdateHandler, InlineQueryHandler, PollHandler + UserStatusHandler, RawUpdateHandler, InlineQueryHandler, PollHandler, + ChosenInlineResultHandler ) log = logging.getLogger(__name__) @@ -99,7 +101,11 @@ class Dispatcher: lambda upd, usr, cht: (pyrogram.InlineQuery._parse(self.client, upd, usr), InlineQueryHandler), (UpdateMessagePoll,): - lambda upd, usr, cht: (pyrogram.Poll._parse_update(self.client, upd), PollHandler) + lambda upd, usr, cht: (pyrogram.Poll._parse_update(self.client, upd), PollHandler), + + (UpdateBotInlineSend,): + lambda upd, usr, cht: (pyrogram.ChosenInlineResult._parse(self.client, upd, usr), + ChosenInlineResultHandler) } self.update_parsers = {key: value for key_tuple, value in self.update_parsers.items() for key in key_tuple} diff --git a/pyrogram/client/handlers/__init__.py b/pyrogram/client/handlers/__init__.py index 25acbedc..87ef10c5 100644 --- a/pyrogram/client/handlers/__init__.py +++ b/pyrogram/client/handlers/__init__.py @@ -24,8 +24,9 @@ from .message_handler import MessageHandler from .poll_handler import PollHandler from .raw_update_handler import RawUpdateHandler from .user_status_handler import UserStatusHandler +from .chosen_inline_result_handler import ChosenInlineResultHandler __all__ = [ "MessageHandler", "DeletedMessagesHandler", "CallbackQueryHandler", "RawUpdateHandler", "DisconnectHandler", - "UserStatusHandler", "InlineQueryHandler", "PollHandler" + "UserStatusHandler", "InlineQueryHandler", "PollHandler", "ChosenInlineResultHandler" ] diff --git a/pyrogram/client/handlers/chosen_inline_result_handler.py b/pyrogram/client/handlers/chosen_inline_result_handler.py new file mode 100644 index 00000000..f5014ab0 --- /dev/null +++ b/pyrogram/client/handlers/chosen_inline_result_handler.py @@ -0,0 +1,48 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2020 Dan +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . + +from .handler import Handler + + +class ChosenInlineResultHandler(Handler): + """The ChosenInlineResultHandler handler class. Used to handle chosen inline results coming from inline queries. + It is intended to be used with :meth:`~Client.add_handler` + + For a nicer way to register this handler, have a look at the + :meth:`~Client.on_chosen_inline_query` decorator. + + Parameters: + callback (``callable``): + Pass a function that will be called when a new chosen inline result arrives. + It takes *(client, chosen_inline_result)* as positional arguments (look at the section below for a + detailed description). + + filters (:obj:`Filters`): + Pass one or more filters to allow only a subset of chosen inline results to be passed + in your callback function. + + Other parameters: + client (:obj:`Client`): + The Client itself, useful when you want to call other API methods inside the message handler. + + chosen_inline_result (:obj:`ChosenInlineResult`): + The received chosen inline result. + """ + + def __init__(self, callback: callable, filters=None): + super().__init__(callback, filters) diff --git a/pyrogram/client/methods/decorators/__init__.py b/pyrogram/client/methods/decorators/__init__.py index 2c0a749a..5a60ff9b 100644 --- a/pyrogram/client/methods/decorators/__init__.py +++ b/pyrogram/client/methods/decorators/__init__.py @@ -24,6 +24,7 @@ from .on_message import OnMessage from .on_poll import OnPoll from .on_raw_update import OnRawUpdate from .on_user_status import OnUserStatus +from .on_chosen_inline_result import OnChosenInlineResult class Decorators( @@ -34,6 +35,7 @@ class Decorators( OnDisconnect, OnUserStatus, OnInlineQuery, - OnPoll + OnPoll, + OnChosenInlineResult ): pass diff --git a/pyrogram/client/methods/decorators/on_chosen_inline_result.py b/pyrogram/client/methods/decorators/on_chosen_inline_result.py new file mode 100644 index 00000000..40446eb2 --- /dev/null +++ b/pyrogram/client/methods/decorators/on_chosen_inline_result.py @@ -0,0 +1,56 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2020 Dan +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . + +from typing import Callable + +import pyrogram +from pyrogram.client.filters.filter import Filter +from ...ext import BaseClient + + +class OnChosenInlineResult(BaseClient): + def on_chosen_inline_result( + self=None, + filters=None, + group: int = 0 + ) -> callable: + """Decorator for handling chosen inline results. + + This does the same thing as :meth:`~pyrogram.Client.add_handler` using the :obj:`~pyrogram.ChosenInlineResult`. + + Parameters: + filters (:obj:`~pyrogram.Filters`, *optional*): + Pass one or more filters to allow only a subset of chosen inline results to be passed + in your function. + + group (``int``, *optional*): + The group identifier, defaults to 0. + """ + + def decorator(func: Callable) -> Callable: + if isinstance(self, pyrogram.Client): + self.add_handler(pyrogram.ChosenInlineResultHandler(func, filters), group) + elif isinstance(self, Filter) or self is None: + func.handler = ( + pyrogram.ChosenInlineResultHandler(func, self), + group if filters is None else filters + ) + + return func + + return decorator diff --git a/pyrogram/client/types/inline_mode/__init__.py b/pyrogram/client/types/inline_mode/__init__.py index 68da92d7..4980377d 100644 --- a/pyrogram/client/types/inline_mode/__init__.py +++ b/pyrogram/client/types/inline_mode/__init__.py @@ -21,8 +21,9 @@ from .inline_query_result import InlineQueryResult from .inline_query_result_animation import InlineQueryResultAnimation from .inline_query_result_article import InlineQueryResultArticle from .inline_query_result_photo import InlineQueryResultPhoto +from .chosen_inline_result import ChosenInlineResult __all__ = [ "InlineQuery", "InlineQueryResult", "InlineQueryResultArticle", "InlineQueryResultPhoto", - "InlineQueryResultAnimation" + "InlineQueryResultAnimation", "ChosenInlineResult" ] diff --git a/pyrogram/client/types/inline_mode/chosen_inline_result.py b/pyrogram/client/types/inline_mode/chosen_inline_result.py new file mode 100644 index 00000000..cdc5afc9 --- /dev/null +++ b/pyrogram/client/types/inline_mode/chosen_inline_result.py @@ -0,0 +1,117 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2020 Dan +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . + +from base64 import b64encode +from struct import pack +from typing import Union + +import pyrogram +from pyrogram.api import types +from pyrogram.client.types.object import Object +from pyrogram.client.types.update import Update +from pyrogram.client.types.user_and_chats import User +from pyrogram.client.types.messages_and_media import Location +from pyrogram.client.ext import utils + + +class ChosenInlineResult(Object, Update): + """A :doc:`result ` of an inline query chosen by the user and sent to their chat partner. + + Parameters: + result_id (``str``): + The unique identifier for the result that was chosen. + + from_user (:obj:`User`): + The user that chose the result. + + query (``str``): + The query that was used to obtain the result. + + location (:obj:`Location`, *optional*): + Sender location, only for bots that require user location. + + inline_message_id (``str``, *optional*): + Identifier of the sent inline message. + Available only if there is an :doc:`inline keyboard ` attached to the message. + Will be also received in :doc:`callback queries ` and can be used to edit the message. + + .. note:: + + It is necessary to enable inline feedback via `@Botfather `_ in order to receive these + objects in updates. + """ + + def __init__( + self, + *, + client: "pyrogram.BaseClient" = None, + result_id: str, + from_user: User, + query: str, + location: "pyrogram.Location" = None, + inline_message_id: str = None, + ): + super().__init__(client) + + self.result_id = result_id + self.from_user = from_user + self.query = query + self.location = location + self.inline_message_id = inline_message_id + + @staticmethod + def _parse(client, chosen_inline_result: types.UpdateBotInlineSend, users) -> "ChosenInlineResult": + inline_message_id = None + + if isinstance(chosen_inline_result.msg_id, types.InputBotInlineMessageID): + inline_message_id = b64encode( + pack( + "