From f05e33301db1edc479432d26997bf9423471da32 Mon Sep 17 00:00:00 2001 From: KurimuzonAkuma Date: Wed, 4 Sep 2024 17:04:45 +0300 Subject: [PATCH] test --- compiler/docs/compiler.py | 12 ++ pyrogram/dispatcher.py | 46 ++++++- pyrogram/handlers/__init__.py | 4 + pyrogram/handlers/chat_boost_handler.py | 49 +++++++ .../message_reaction_count_handler.py | 49 +++++++ pyrogram/handlers/message_reaction_handler.py | 49 +++++++ pyrogram/handlers/shipping_query_handler.py | 49 +++++++ pyrogram/methods/bots/__init__.py | 6 +- .../methods/bots/answer_shipping_query.py | 81 ++++++++++++ pyrogram/methods/payments/__init__.py | 4 +- pyrogram/methods/payments/apply_gift_code.py | 64 +++++++++ .../{check_giftcode.py => check_gift_code.py} | 2 +- pyrogram/types/bots_and_keyboards/__init__.py | 10 ++ .../bots_and_keyboards/callback_query.py | 47 +++++-- .../bots_and_keyboards/chat_boost_updated.py | 62 +++++++++ .../message_reaction_count_updated.py | 89 +++++++++++++ .../message_reaction_updated.py | 125 ++++++++++++++++++ .../bots_and_keyboards/shipping_address.py | 18 +++ .../bots_and_keyboards/shipping_option.py | 73 ++++++++++ .../bots_and_keyboards/shipping_query.py | 121 +++++++++++++++++ pyrogram/types/messages_and_media/__init__.py | 2 + .../types/messages_and_media/chat_boost.py | 102 ++++++++++++++ 22 files changed, 1044 insertions(+), 20 deletions(-) create mode 100644 pyrogram/handlers/chat_boost_handler.py create mode 100644 pyrogram/handlers/message_reaction_count_handler.py create mode 100644 pyrogram/handlers/message_reaction_handler.py create mode 100644 pyrogram/handlers/shipping_query_handler.py create mode 100644 pyrogram/methods/bots/answer_shipping_query.py create mode 100644 pyrogram/methods/payments/apply_gift_code.py rename pyrogram/methods/payments/{check_giftcode.py => check_gift_code.py} (96%) create mode 100644 pyrogram/types/bots_and_keyboards/chat_boost_updated.py create mode 100644 pyrogram/types/bots_and_keyboards/message_reaction_count_updated.py create mode 100644 pyrogram/types/bots_and_keyboards/message_reaction_updated.py create mode 100644 pyrogram/types/bots_and_keyboards/shipping_option.py create mode 100644 pyrogram/types/bots_and_keyboards/shipping_query.py create mode 100644 pyrogram/types/messages_and_media/chat_boost.py diff --git a/compiler/docs/compiler.py b/compiler/docs/compiler.py index ea98bae091..841b8f5217 100644 --- a/compiler/docs/compiler.py +++ b/compiler/docs/compiler.py @@ -321,6 +321,7 @@ def get_title_list(s: str) -> list: """, payments=""" Payments + apply_gift_code check_gift_code get_payment_form send_payment_form @@ -355,6 +356,7 @@ def get_title_list(s: str) -> list: get_chat_menu_button answer_web_app_query answer_pre_checkout_query + answer_shipping_query create_invoice_link refund_star_payment """, @@ -535,6 +537,7 @@ def get_title_list(s: str) -> list: PaidMediaInfo PaidMediaPreview PaymentForm + ChatBoost """, bot_keyboards=""" Bot keyboards @@ -562,6 +565,11 @@ def get_title_list(s: str) -> list: OrderInfo PreCheckoutQuery ShippingAddress + ShippingQuery + MessageReactionUpdated + MessageReactionCountUpdated + ChatBoostUpdated + ShippingOption """, bot_commands=""" Bot commands @@ -751,6 +759,10 @@ def get_title_list(s: str) -> list: PreCheckoutQuery PreCheckoutQuery.answer """, + shipping_query=""" + ShippingQuery + ShippingQuery.answer + """, chat_join_request=""" ChatJoinRequest ChatJoinRequest.approve diff --git a/pyrogram/dispatcher.py b/pyrogram/dispatcher.py index ddcd90193d..0d2aead5ba 100644 --- a/pyrogram/dispatcher.py +++ b/pyrogram/dispatcher.py @@ -28,7 +28,8 @@ from pyrogram.handlers import ( CallbackQueryHandler, MessageHandler, EditedMessageHandler, DeletedMessagesHandler, UserStatusHandler, RawUpdateHandler, InlineQueryHandler, PollHandler, PreCheckoutQueryHandler, - ChosenInlineResultHandler, ChatMemberUpdatedHandler, ChatJoinRequestHandler, StoryHandler + ChosenInlineResultHandler, ChatMemberUpdatedHandler, ChatJoinRequestHandler, StoryHandler, + ShippingQueryHandler, MessageReactionHandler, MessageReactionCountHandler, ChatBoostHandler ) from pyrogram.raw.types import ( UpdateNewMessage, UpdateNewChannelMessage, UpdateNewScheduledMessage, @@ -38,7 +39,8 @@ UpdateBotCallbackQuery, UpdateInlineBotCallbackQuery, UpdateBotPrecheckoutQuery, UpdateUserStatus, UpdateBotInlineQuery, UpdateMessagePoll, UpdateBotInlineSend, UpdateChatParticipant, UpdateChannelParticipant, - UpdateBotChatInviteRequester, UpdateStory + UpdateBotChatInviteRequester, UpdateStory, UpdateBotShippingQuery, UpdateBotMessageReaction, + UpdateBotMessageReactions, UpdateBotChatBoost, UpdateBusinessBotCallbackQuery ) log = logging.getLogger(__name__) @@ -48,7 +50,7 @@ class Dispatcher: NEW_MESSAGE_UPDATES = (UpdateNewMessage, UpdateNewChannelMessage, UpdateNewScheduledMessage, UpdateBotNewBusinessMessage) EDIT_MESSAGE_UPDATES = (UpdateEditMessage, UpdateEditChannelMessage, UpdateBotEditBusinessMessage) DELETE_MESSAGES_UPDATES = (UpdateDeleteMessages, UpdateDeleteChannelMessages, UpdateBotDeleteBusinessMessage) - CALLBACK_QUERY_UPDATES = (UpdateBotCallbackQuery, UpdateInlineBotCallbackQuery) + CALLBACK_QUERY_UPDATES = (UpdateBotCallbackQuery, UpdateInlineBotCallbackQuery, UpdateBusinessBotCallbackQuery) CHAT_MEMBER_UPDATES = (UpdateChatParticipant, UpdateChannelParticipant) USER_STATUS_UPDATES = (UpdateUserStatus,) BOT_INLINE_QUERY_UPDATES = (UpdateBotInlineQuery,) @@ -57,6 +59,10 @@ class Dispatcher: CHAT_JOIN_REQUEST_UPDATES = (UpdateBotChatInviteRequester,) NEW_STORY_UPDATES = (UpdateStory,) PRE_CHECKOUT_QUERY_UPDATES = (UpdateBotPrecheckoutQuery,) + SHIPPING_QUERY_UPDATES = (UpdateBotShippingQuery,) + MESSAGE_REACTION_UPDATES = (UpdateBotMessageReaction,) + MESSAGE_REACTION_COUNT_UPDATES = (UpdateBotMessageReactions,) + CHAT_BOOST_UPDATES = (UpdateBotChatBoost,) def __init__(self, client: "pyrogram.Client"): self.client = client @@ -70,7 +76,7 @@ def __init__(self, client: "pyrogram.Client"): async def message_parser(update, users, chats): connection_id = getattr(update, "connection_id", None) - + return ( await pyrogram.types.Message._parse( self.client, @@ -102,7 +108,7 @@ async def deleted_messages_parser(update, users, chats): async def callback_query_parser(update, users, chats): return ( - await pyrogram.types.CallbackQuery._parse(self.client, update, users), + await pyrogram.types.CallbackQuery._parse(self.client, update, users, chats), CallbackQueryHandler ) @@ -154,6 +160,30 @@ async def pre_checkout_query_parser(update, users, chats): PreCheckoutQueryHandler ) + async def shipping_query_parser(update, users, chats): + return ( + await pyrogram.types.ShippingQuery._parse(self.client, update, users), + ShippingQueryHandler + ) + + async def message_reaction_parser(update, users, chats): + return ( + pyrogram.types.MessageReactionUpdated._parse(self.client, update, users, chats), + MessageReactionHandler + ) + + async def message_reaction_count_parser(update, users, chats): + return ( + pyrogram.types.MessageReactionCountUpdated._parse(self.client, update, users, chats), + MessageReactionCountHandler + ) + + async def chat_boost_parser(update, users, chats): + return ( + pyrogram.types.ChatBoostUpdated._parse(self.client, update, users, chats), + ChatBoostHandler + ) + self.update_parsers = { Dispatcher.NEW_MESSAGE_UPDATES: message_parser, Dispatcher.EDIT_MESSAGE_UPDATES: edited_message_parser, @@ -166,7 +196,11 @@ async def pre_checkout_query_parser(update, users, chats): Dispatcher.CHAT_MEMBER_UPDATES: chat_member_updated_parser, Dispatcher.CHAT_JOIN_REQUEST_UPDATES: chat_join_request_parser, Dispatcher.NEW_STORY_UPDATES: story_parser, - Dispatcher.PRE_CHECKOUT_QUERY_UPDATES: pre_checkout_query_parser + Dispatcher.PRE_CHECKOUT_QUERY_UPDATES: pre_checkout_query_parser, + Dispatcher.SHIPPING_QUERY_UPDATES: shipping_query_parser, + Dispatcher.MESSAGE_REACTION_UPDATES: message_reaction_parser, + Dispatcher.MESSAGE_REACTION_COUNT_UPDATES: message_reaction_count_parser, + Dispatcher.CHAT_BOOST_UPDATES: chat_boost_parser } self.update_parsers = {key: value for key_tuple, value in self.update_parsers.items() for key in key_tuple} diff --git a/pyrogram/handlers/__init__.py b/pyrogram/handlers/__init__.py index b6f3aacf0e..e10f3a6cad 100644 --- a/pyrogram/handlers/__init__.py +++ b/pyrogram/handlers/__init__.py @@ -17,6 +17,7 @@ # along with Pyrogram. If not, see . from .callback_query_handler import CallbackQueryHandler +from .chat_boost_handler import ChatBoostHandler from .chat_join_request_handler import ChatJoinRequestHandler from .chat_member_updated_handler import ChatMemberUpdatedHandler from .chosen_inline_result_handler import ChosenInlineResultHandler @@ -25,8 +26,11 @@ from .edited_message_handler import EditedMessageHandler from .inline_query_handler import InlineQueryHandler from .message_handler import MessageHandler +from .message_reaction_count_handler import MessageReactionCountHandler +from .message_reaction_handler import MessageReactionHandler from .poll_handler import PollHandler from .pre_checkout_query_handler import PreCheckoutQueryHandler from .raw_update_handler import RawUpdateHandler +from .shipping_query_handler import ShippingQueryHandler from .story_handler import StoryHandler from .user_status_handler import UserStatusHandler diff --git a/pyrogram/handlers/chat_boost_handler.py b/pyrogram/handlers/chat_boost_handler.py new file mode 100644 index 0000000000..764737964e --- /dev/null +++ b/pyrogram/handlers/chat_boost_handler.py @@ -0,0 +1,49 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present 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 + +from .handler import Handler + + +class ChatBoostHandler(Handler): + """The Story handler class. Used to handle new stories. + It is intended to be used with :meth:`~pyrogram.Client.add_handler` + + For a nicer way to register this handler, have a look at the + :meth:`~pyrogram.Client.on_story` decorator. + + Parameters: + callback (``Callable``): + Pass a function that will be called when a new Stories arrives. It takes *(client, story)* + 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 stories to be passed + in your callback function. + + Other parameters: + client (:obj:`~pyrogram.Client`): + The Client itself, useful when you want to call other API methods inside the story handler. + + story (:obj:`~pyrogram.types.Story`): + The received story. + """ + + def __init__(self, callback: Callable, filters=None): + super().__init__(callback, filters) diff --git a/pyrogram/handlers/message_reaction_count_handler.py b/pyrogram/handlers/message_reaction_count_handler.py new file mode 100644 index 0000000000..e1757d0e1a --- /dev/null +++ b/pyrogram/handlers/message_reaction_count_handler.py @@ -0,0 +1,49 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present 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 + +from .handler import Handler + + +class MessageReactionCountHandler(Handler): + """The Story handler class. Used to handle new stories. + It is intended to be used with :meth:`~pyrogram.Client.add_handler` + + For a nicer way to register this handler, have a look at the + :meth:`~pyrogram.Client.on_story` decorator. + + Parameters: + callback (``Callable``): + Pass a function that will be called when a new Stories arrives. It takes *(client, story)* + 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 stories to be passed + in your callback function. + + Other parameters: + client (:obj:`~pyrogram.Client`): + The Client itself, useful when you want to call other API methods inside the story handler. + + story (:obj:`~pyrogram.types.Story`): + The received story. + """ + + def __init__(self, callback: Callable, filters=None): + super().__init__(callback, filters) diff --git a/pyrogram/handlers/message_reaction_handler.py b/pyrogram/handlers/message_reaction_handler.py new file mode 100644 index 0000000000..4942638185 --- /dev/null +++ b/pyrogram/handlers/message_reaction_handler.py @@ -0,0 +1,49 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present 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 + +from .handler import Handler + + +class MessageReactionHandler(Handler): + """The Story handler class. Used to handle new stories. + It is intended to be used with :meth:`~pyrogram.Client.add_handler` + + For a nicer way to register this handler, have a look at the + :meth:`~pyrogram.Client.on_story` decorator. + + Parameters: + callback (``Callable``): + Pass a function that will be called when a new Stories arrives. It takes *(client, story)* + 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 stories to be passed + in your callback function. + + Other parameters: + client (:obj:`~pyrogram.Client`): + The Client itself, useful when you want to call other API methods inside the story handler. + + story (:obj:`~pyrogram.types.Story`): + The received story. + """ + + def __init__(self, callback: Callable, filters=None): + super().__init__(callback, filters) diff --git a/pyrogram/handlers/shipping_query_handler.py b/pyrogram/handlers/shipping_query_handler.py new file mode 100644 index 0000000000..c182bdab9c --- /dev/null +++ b/pyrogram/handlers/shipping_query_handler.py @@ -0,0 +1,49 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present 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 + +from .handler import Handler + + +class ShippingQueryHandler(Handler): + """The Story handler class. Used to handle new stories. + It is intended to be used with :meth:`~pyrogram.Client.add_handler` + + For a nicer way to register this handler, have a look at the + :meth:`~pyrogram.Client.on_story` decorator. + + Parameters: + callback (``Callable``): + Pass a function that will be called when a new Stories arrives. It takes *(client, story)* + 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 stories to be passed + in your callback function. + + Other parameters: + client (:obj:`~pyrogram.Client`): + The Client itself, useful when you want to call other API methods inside the story handler. + + story (:obj:`~pyrogram.types.Story`): + The received story. + """ + + def __init__(self, callback: Callable, filters=None): + super().__init__(callback, filters) diff --git a/pyrogram/methods/bots/__init__.py b/pyrogram/methods/bots/__init__.py index 250df0dfea..cbeb375e3d 100644 --- a/pyrogram/methods/bots/__init__.py +++ b/pyrogram/methods/bots/__init__.py @@ -19,6 +19,7 @@ from .answer_callback_query import AnswerCallbackQuery from .answer_inline_query import AnswerInlineQuery from .answer_pre_checkout_query import AnswerPreCheckoutQuery +from .answer_shipping_query import AnswerShippingQuery from .answer_web_app_query import AnswerWebAppQuery from .create_invoice_link import CreateInvoiceLink from .delete_bot_commands import DeleteBotCommands @@ -41,6 +42,8 @@ class Bots( AnswerCallbackQuery, AnswerInlineQuery, + AnswerPreCheckoutQuery, + AnswerShippingQuery, CreateInvoiceLink, GetInlineBotResults, RefundStarPayment, @@ -57,7 +60,6 @@ class Bots( GetBotDefaultPrivileges, SetChatMenuButton, GetChatMenuButton, - AnswerWebAppQuery, - AnswerPreCheckoutQuery + AnswerWebAppQuery ): pass diff --git a/pyrogram/methods/bots/answer_shipping_query.py b/pyrogram/methods/bots/answer_shipping_query.py new file mode 100644 index 0000000000..1b887e049c --- /dev/null +++ b/pyrogram/methods/bots/answer_shipping_query.py @@ -0,0 +1,81 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present 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 Optional, List + +import pyrogram +from pyrogram import raw +from pyrogram import types + + +class AnswerShippingQuery: + async def answer_shipping_query( + self: "pyrogram.Client", + shipping_query_id: str, + ok: bool, + shipping_options: Optional[List["types.ShippingOption"]] = None, + error_message: Optional[str] = None + ): + """If you sent an invoice requesting a shipping address and the parameter ``is_flexible`` was specified, the API sends the confirmation in the form of an :obj:`~pyrogram.handlers.ShippingQueryHandler`. + + Use this method to reply to shipping queries. + + .. include:: /_includes/usable-by/bots.rst + + Parameters: + shipping_query_id (``str``): + Unique identifier for the query to be answered. + + ok (``bool``): + Specify True if everything is alright (goods are available, etc.) and the bot is ready to proceed with the order. Use False if there are any problems. + + shipping_options (List of :obj:`~pyrogram.types.ShippingOptions`, *optional*): + Required if ok is True. A array of available shipping options. + + error_message (``str``, *optional*): + Required if ok is False. + Error message in human readable form that explains why it is impossible to complete the order (e.g. "Sorry, delivery to your desired address is unavailable"). Telegram will display this message to the user. + + Returns: + ``bool``: True, on success. + + Example: + .. code-block:: python + + # Proceed with the order + await app.answer_shipping_query(query_id, ok=True, shipping_options=shipping_options) + + # Answer with error message + await app.answer_shipping_query(query_id, ok=False, error_message="Error Message displayed to the user") + + """ + if ok and not shipping_options: + raise ValueError("Shipping options required.") + + r = await self.invoke( + raw.functions.messages.SetBotShippingResults( + query_id=int(shipping_query_id), + shipping_options=[ + so.write() + for so in shipping_options + ] if shipping_options else None, + error=error_message + ) + ) + + return r diff --git a/pyrogram/methods/payments/__init__.py b/pyrogram/methods/payments/__init__.py index 93ee99991f..d1b600c025 100644 --- a/pyrogram/methods/payments/__init__.py +++ b/pyrogram/methods/payments/__init__.py @@ -16,11 +16,13 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from .check_giftcode import CheckGiftCode +from .apply_gift_code import ApplyGiftCode +from .check_gift_code import CheckGiftCode from .get_payment_form import GetPaymentForm from .send_payment_form import SendPaymentForm class Payments( + ApplyGiftCode, CheckGiftCode, GetPaymentForm, SendPaymentForm diff --git a/pyrogram/methods/payments/apply_gift_code.py b/pyrogram/methods/payments/apply_gift_code.py new file mode 100644 index 0000000000..130c88bc57 --- /dev/null +++ b/pyrogram/methods/payments/apply_gift_code.py @@ -0,0 +1,64 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present 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 . +import re + +import pyrogram +from pyrogram import raw, types + + +class ApplyGiftCode: + async def apply_gift_code( + self: "pyrogram.Client", + link: str, + ) -> bool: + """Apply a gift code. + + .. include:: /_includes/usable-by/users.rst + + Parameters: + link (``str``): + The gift code link. + + Returns: + ``bool``: On success, True is returned. + + Raises: + ValueError: In case the gift code link is invalid. + + Example: + .. code-block:: python + + # apply a gift code + app.apply_gift_code("t.me/giftcode/abc1234567def") + """ + match = re.match(r"^(?:https?://)?(?:www\.)?(?:t(?:elegram)?\.(?:org|me|dog)/(?:giftcode/|\+))([\w-]+)$", link) + + if match: + slug = match.group(1) + elif isinstance(link, str): + slug = link + else: + raise ValueError("Invalid gift code link") + + await self.invoke( + raw.functions.payments.ApplyGiftCode( + slug=slug + ) + ) + + return True diff --git a/pyrogram/methods/payments/check_giftcode.py b/pyrogram/methods/payments/check_gift_code.py similarity index 96% rename from pyrogram/methods/payments/check_giftcode.py rename to pyrogram/methods/payments/check_gift_code.py index 613595918c..b72724f0de 100644 --- a/pyrogram/methods/payments/check_giftcode.py +++ b/pyrogram/methods/payments/check_gift_code.py @@ -38,7 +38,7 @@ async def check_gift_code( :obj:`~pyrogram.types.CheckedGiftCode`: On success, a checked gift code is returned. Raises: - ValueError: In case the folder invite link is invalid. + ValueError: In case the gift code link is invalid. Example: .. code-block:: python diff --git a/pyrogram/types/bots_and_keyboards/__init__.py b/pyrogram/types/bots_and_keyboards/__init__.py index 21af449cf6..6534151c06 100644 --- a/pyrogram/types/bots_and_keyboards/__init__.py +++ b/pyrogram/types/bots_and_keyboards/__init__.py @@ -27,6 +27,7 @@ from .bot_command_scope_default import BotCommandScopeDefault from .callback_game import CallbackGame from .callback_query import CallbackQuery +from .chat_boost_updated import ChatBoostUpdated from .force_reply import ForceReply from .game_high_score import GameHighScore from .inline_keyboard_button import InlineKeyboardButton @@ -38,6 +39,8 @@ from .menu_button_commands import MenuButtonCommands from .menu_button_default import MenuButtonDefault from .menu_button_web_app import MenuButtonWebApp +from .message_reaction_count_updated import MessageReactionCountUpdated +from .message_reaction_updated import MessageReactionUpdated from .order_info import OrderInfo from .pre_checkout_query import PreCheckoutQuery from .reply_keyboard_markup import ReplyKeyboardMarkup @@ -48,12 +51,15 @@ from .request_user_info import RequestUserInfo from .requested_chats import RequestedChats from .sent_web_app_message import SentWebAppMessage +from .shipping_option import ShippingOption +from .shipping_query import ShippingQuery from .shipping_address import ShippingAddress from .web_app_info import WebAppInfo __all__ = [ "CallbackGame", "CallbackQuery", + "ChatBoostUpdated", "ForceReply", "GameHighScore", "InlineKeyboardButton", @@ -81,9 +87,13 @@ "MenuButton", "MenuButtonCommands", "MenuButtonWebApp", + "MessageReactionCountUpdated", + "MessageReactionUpdated", "OrderInfo", "PreCheckoutQuery", "MenuButtonDefault", "SentWebAppMessage", + "ShippingOption", + "ShippingQuery", "ShippingAddress" ] diff --git a/pyrogram/types/bots_and_keyboards/callback_query.py b/pyrogram/types/bots_and_keyboards/callback_query.py index efdd14ca4d..d4ad787f57 100644 --- a/pyrogram/types/bots_and_keyboards/callback_query.py +++ b/pyrogram/types/bots_and_keyboards/callback_query.py @@ -19,8 +19,8 @@ from typing import Union, List, Match, Optional import pyrogram -from pyrogram import raw, enums -from pyrogram import types +from pyrogram import raw, enums, types +from pyrogram.errors import ChannelPrivate from ..object import Object from ..update import Update from ... import utils @@ -87,7 +87,7 @@ def __init__( self.matches = matches @staticmethod - async def _parse(client: "pyrogram.Client", callback_query, users) -> "CallbackQuery": + async def _parse(client: "pyrogram.Client", callback_query, users, chats) -> "CallbackQuery": message = None inline_message_id = None @@ -98,16 +98,43 @@ async def _parse(client: "pyrogram.Client", callback_query, users) -> "CallbackQ message = client.message_cache[(chat_id, message_id)] if not message: - message = await client.get_messages(chat_id, message_id) + try: + message = await client.get_messages( + chat_id=chat_id, + message_ids=message_id + ) + except ChannelPrivate: + channel = chats.get(utils.get_raw_peer_id(callback_query.peer), None) + if channel: + message = types.Message( + id=message_id, + chat=types.Chat._parse_chat( + client, + channel + ) + ) elif isinstance(callback_query, raw.types.UpdateInlineBotCallbackQuery): inline_message_id = utils.pack_inline_message_id(callback_query.msg_id) - + elif isinstance(callback_query, raw.types.UpdateBusinessBotCallbackQuery): + message = await types.Message._parse( + client, + callback_query.message, + users, + chats, + is_scheduled=False, + replies=0, + business_connection_id=callback_query.connection_id, + raw_reply_to_message=getattr(callback_query, "reply_to_message", None) + ) # Try to decode callback query data into string. If that fails, fallback to bytes instead of decoding by # ignoring/replacing errors, this way, button clicks will still work. - try: - data = callback_query.data.decode() - except (UnicodeDecodeError, AttributeError): - data = callback_query.data + data = getattr(callback_query, "data", None) + + if data: + try: + data = data.decode() + except (UnicodeDecodeError, AttributeError): + data = data return CallbackQuery( id=str(callback_query.query_id), @@ -116,7 +143,7 @@ async def _parse(client: "pyrogram.Client", callback_query, users) -> "CallbackQ inline_message_id=inline_message_id, chat_instance=str(callback_query.chat_instance), data=data, - game_short_name=callback_query.game_short_name, + game_short_name=getattr(callback_query, "game_short_name", None), client=client ) diff --git a/pyrogram/types/bots_and_keyboards/chat_boost_updated.py b/pyrogram/types/bots_and_keyboards/chat_boost_updated.py new file mode 100644 index 0000000000..66797ee261 --- /dev/null +++ b/pyrogram/types/bots_and_keyboards/chat_boost_updated.py @@ -0,0 +1,62 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present 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 Dict + +import pyrogram +from pyrogram import raw, utils +from pyrogram import types +from ..object import Object +from ..update import Update + + +class ChatBoostUpdated(Object, Update): + """A channel/supergroup boost has changed (bots only). + + Parameters: + chat (:obj:`~pyrogram.types.Chat`): + The chat where boost was changed. + + boost (:obj:`~pyrogram.types.ChatBoost`): + New boost information. + """ + + def __init__( + self, + *, + client: "pyrogram.Client" = None, + chat: "types.Chat", + boost: "types.ChatBoost" + ): + super().__init__(client) + + self.chat = chat + self.boost = boost + + @staticmethod + def _parse( + client: "pyrogram.Client", + update: "raw.types.UpdateBotChatBoost", + users: Dict[int, "raw.types.User"], + chats: Dict[int, "raw.types.Channel"], + ) -> "ChatBoostUpdated": + return ChatBoostUpdated( + chat=types.Chat._parse_channel_chat(client, chats.get(utils.get_raw_peer_id(update.peer))), + boost=types.ChatBoost._parse(client, update.boost, users), + client=client + ) diff --git a/pyrogram/types/bots_and_keyboards/message_reaction_count_updated.py b/pyrogram/types/bots_and_keyboards/message_reaction_count_updated.py new file mode 100644 index 0000000000..5a159ace98 --- /dev/null +++ b/pyrogram/types/bots_and_keyboards/message_reaction_count_updated.py @@ -0,0 +1,89 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present 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 datetime import datetime +from typing import Dict, List + +import pyrogram +from pyrogram import raw, types, utils +from ..object import Object +from ..update import Update + + +class MessageReactionCountUpdated(Object, Update): + """Reactions to a message with anonymous reactions were changed. + + These updates are heavy and their changes may be delayed by a few minutes. + + Parameters: + chat (:obj:`~pyrogram.types.Chat`): + The chat containing the message the user reacted to. + + message_id (``int``): + Unique identifier of the message inside the chat. + + date (:py:obj:`~datetime.datetime`): + Date of change of the reaction. + + reactions (:obj:`~pyrogram.types.ReactionCount`): + List of reactions that are present on the message. + """ + + def __init__( + self, + *, + client: "pyrogram.Client" = None, + chat: "types.Chat", + message_id: int, + date: datetime, + reactions: List["types.ReactionCount"] + ): + super().__init__(client) + + self.chat = chat + self.message_id = message_id + self.date = date + self.reactions = reactions + + @staticmethod + def _parse( + client: "pyrogram.Client", + update: "raw.types.UpdateBotMessageReactions", + users: Dict[int, "raw.types.User"], + chats: Dict[int, "raw.types.Chat"] + ) -> "MessageReactionCountUpdated": + peer_id = utils.get_peer_id(update.peer) + raw_peer_id = utils.get_raw_peer_id(update.peer) + + if peer_id > 0: + chat = types.Chat._parse_user_chat(client, users[raw_peer_id]) + else: + chat = types.Chat._parse_chat(client, chats[raw_peer_id]) + + return MessageReactionCountUpdated( + client=client, + chat=chat, + message_id=update.msg_id, + date=utils.timestamp_to_datetime(update.date), + reactions=[ + types.Reaction._parse_count( + client, + reaction + ) for reaction in update.reactions + ] + ) diff --git a/pyrogram/types/bots_and_keyboards/message_reaction_updated.py b/pyrogram/types/bots_and_keyboards/message_reaction_updated.py new file mode 100644 index 0000000000..376c92e334 --- /dev/null +++ b/pyrogram/types/bots_and_keyboards/message_reaction_updated.py @@ -0,0 +1,125 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present 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 datetime import datetime +from typing import Optional, Dict, List + +import pyrogram +from pyrogram import raw, types, utils +from ..object import Object +from ..update import Update + + +class MessageReactionUpdated(Object, Update): + """This object represents a change of a reaction on a message performed by a user. + A reaction to a message was changed by a user. + The update isn't received for reactions set by bots. + + These updates are heavy and their changes may be delayed by a few minutes. + + Parameters: + chat (:obj:`~pyrogram.types.Chat`): + The chat containing the message the user reacted to. + + message_id (``int``): + Unique identifier of the message inside the chat. + + user (:obj:`~pyrogram.types.User`, *optional*): + The user that changed the reaction, if the user isn't anonymous. + + actor_chat (:obj:`~pyrogram.types.Chat`, *optional*): + The chat on behalf of which the reaction was changed, if the user is anonymous. + + date (:py:obj:`~datetime.datetime`): + Date of change of the reaction. + + old_reaction (List of :obj:`~pyrogram.types.Reaction`): + Previous list of reaction types that were set by the user. + + new_reaction (List of :obj:`~pyrogram.types.Reaction`): + New list of reaction types that have been set by the user. + """ + + def __init__( + self, + *, + client: "pyrogram.Client" = None, + chat: "types.Chat", + message_id: int, + user: "types.User", + actor_chat: "types.Chat", + date: datetime, + old_reaction: List["types.Reaction"], + new_reaction: List["types.Reaction"] + ): + super().__init__(client) + + self.chat = chat + self.message_id = message_id + self.user = user + self.actor_chat = actor_chat + self.date = date + self.old_reaction = old_reaction + self.new_reaction = new_reaction + + @staticmethod + def _parse( + client: "pyrogram.Client", + update: "raw.types.UpdateBotMessageReaction", + users: Dict[int, "raw.types.User"], + chats: Dict[int, "raw.types.Chat"] + ) -> "MessageReactionUpdated": + peer_id = utils.get_peer_id(update.peer) + raw_peer_id = utils.get_raw_peer_id(update.peer) + + if peer_id > 0: + chat = types.Chat._parse_user_chat(client, users[raw_peer_id]) + else: + chat = types.Chat._parse_chat(client, chats[raw_peer_id]) + + user = None + actor_chat = None + + raw_actor_peer_id = utils.get_raw_peer_id(update.actor) + actor_peer_id = utils.get_peer_id(update.actor) + + if actor_peer_id > 0: + user = types.User._parse(client, users[raw_actor_peer_id]) + else: + actor_chat = types.Chat._parse_channel_chat(client, chats[raw_actor_peer_id]) + + return MessageReactionUpdated( + client=client, + chat=chat, + message_id=update.msg_id, + user=user, + actor_chat=actor_chat, + date=utils.timestamp_to_datetime(update.date), + old_reaction=[ + types.Reaction._parse( + client, + reaction + ) for reaction in update.old_reactions + ], + new_reaction=[ + types.Reaction._parse( + client, + reaction + ) for reaction in update.new_reactions + ] + ) diff --git a/pyrogram/types/bots_and_keyboards/shipping_address.py b/pyrogram/types/bots_and_keyboards/shipping_address.py index c7a468e2ab..e05fdb0cf3 100644 --- a/pyrogram/types/bots_and_keyboards/shipping_address.py +++ b/pyrogram/types/bots_and_keyboards/shipping_address.py @@ -16,6 +16,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . +from pyrogram import raw + from ..object import Object @@ -61,3 +63,19 @@ def __init__( self.street_line1 = street_line1 self.street_line2 = street_line2 self.post_code = post_code + + @staticmethod + def _parse( + shipping_address: "raw.types.PostAddress", + ) -> "ShippingAddress": + if not shipping_address: + return None + + return ShippingAddress( + country_code=shipping_address.country_iso2, + state=shipping_address.state, + city=shipping_address.city, + street_line1=shipping_address.street_line1, + street_line2=shipping_address.street_line2, + post_code=shipping_address.post_code + ) diff --git a/pyrogram/types/bots_and_keyboards/shipping_option.py b/pyrogram/types/bots_and_keyboards/shipping_option.py new file mode 100644 index 0000000000..a6f380495c --- /dev/null +++ b/pyrogram/types/bots_and_keyboards/shipping_option.py @@ -0,0 +1,73 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present 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 List + +from pyrogram import raw, types + +from ..object import Object + + +class ShippingOption(Object): + """This object represents one shipping option. + + Parameters: + id (``str``): + Shipping option identifier. + + title (``str``): + Option title. + + prices (List of :obj:`~pyrogram.types.LabeledPrice`): + List of price portions. + + """ + + def __init__( + self, + id: str, + title: str, + prices: List["types.LabeledPrice"] + ): + super().__init__() + + self.id = id + self.title = title + self.prices = prices + + @staticmethod + def _parse(shipping_option: "raw.types.ShippingOption") -> "ShippingOption": + if isinstance(shipping_option, raw.types.ShippingOption): + return ShippingOption( + id=shipping_option.id, + title=shipping_option.title, + prices=[ + types.LabeledPrice._parse(price) + for price in shipping_option.prices + ] + ) + + def write(self): + return raw.types.ShippingOption( + id=self.id, + title=self.title, + prices=[ + price.write() + for price in self.prices + ] + ) diff --git a/pyrogram/types/bots_and_keyboards/shipping_query.py b/pyrogram/types/bots_and_keyboards/shipping_query.py new file mode 100644 index 0000000000..1f8236b859 --- /dev/null +++ b/pyrogram/types/bots_and_keyboards/shipping_query.py @@ -0,0 +1,121 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present 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 Optional + +import pyrogram +from pyrogram import types, raw +from ..object import Object +from ..update import Update + + +class ShippingQuery(Object, Update): + """This object contains information about an incoming shipping query. + + Parameters: + id (``str``): + Unique query identifier. + + from_user (:obj:`~pyrogram.types.User`): + User who sent the query. + + invoice_payload (``str``): + Bot specified invoice payload. Only available to the bot that received the payment. + + shipping_address (:obj:`~pyrogram.types.ShippingAddress`): + User specified shipping address. Only available to the bot that received the payment. + """ + + def __init__( + self, + *, + client: "pyrogram.Client" = None, + id: str, + from_user: "types.User", + invoice_payload: str, + shipping_address: Optional["types.ShippingAddress"] = None + ): + super().__init__(client) + + self.id = id + self.from_user = from_user + self.invoice_payload = invoice_payload + self.shipping_address = shipping_address + + @staticmethod + async def _parse( + client: "pyrogram.Client", + shipping_query: "raw.types.UpdateBotShippingQuery", + users: dict + ) -> "ShippingQuery": + # Try to decode shipping query payload into string. If that fails, fallback to bytes instead of decoding by + # ignoring/replacing errors, this way, button clicks will still work. + try: + payload = shipping_query.payload.decode() + except (UnicodeDecodeError, AttributeError): + payload = shipping_query.payload + + return ShippingQuery( + id=str(shipping_query.query_id), + from_user=types.User._parse(client, users[shipping_query.user_id]), + invoice_payload=payload, + shipping_address=types.ShippingAddress._parse(shipping_query.shipping_address), + client=client + ) + + async def answer( + self, + ok: bool, + shipping_options: "types.ShippingOptions" = None, + error_message: str = None + ): + """Bound method *answer* of :obj:`~pyrogram.types.ShippingQuery`. + + Use this method as a shortcut for: + + .. code-block:: python + + await client.answer_shipping_query( + shipping_query.id, + ok=True + ) + + Example: + .. code-block:: python + + await shipping_query.answer(ok=True) + + Parameters: + ok (``bool``): + Pass True if delivery to the specified address is possible and False if there are any problems (for example, if delivery to the specified address is not possible). + + shipping_options (:obj:`~pyrogram.types.ShippingOptions`, *optional*): + Required if ok is True. A JSON-serialized array of available shipping options. + + error_message (``str``, *optional*): + Required if ok is False. Error message in human readable form that explains why it is impossible to complete the order (e.g. "Sorry, delivery to your desired address is unavailable'). Telegram will display this message to the user. + + Returns: + ``bool``: True, on success. + """ + return await self._client.answer_shipping_query( + shipping_query_id=self.id, + ok=ok, + shipping_options=shipping_options, + error_message=error_message + ) diff --git a/pyrogram/types/messages_and_media/__init__.py b/pyrogram/types/messages_and_media/__init__.py index fc47844ef3..ed9307d7a8 100644 --- a/pyrogram/types/messages_and_media/__init__.py +++ b/pyrogram/types/messages_and_media/__init__.py @@ -21,6 +21,7 @@ from .available_effect import AvailableEffect from .boosts_status import BoostsStatus from .business_message import BusinessMessage +from .chat_boost import ChatBoost from .checked_gift_code import CheckedGiftCode from .contact import Contact from .dice import Dice @@ -67,6 +68,7 @@ "AvailableEffect", "BoostsStatus", "BusinessMessage", + "ChatBoost", "CheckedGiftCode", "Contact", "Dice", diff --git a/pyrogram/types/messages_and_media/chat_boost.py b/pyrogram/types/messages_and_media/chat_boost.py new file mode 100644 index 0000000000..b5af01d427 --- /dev/null +++ b/pyrogram/types/messages_and_media/chat_boost.py @@ -0,0 +1,102 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present 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 datetime import datetime +from typing import Optional + +import pyrogram +from pyrogram import raw, types, utils +from ..object import Object + + +class ChatBoost(Object): + """Contains information about one or more boosts applied by a specific user. + + Parameters: + id (``str``): + Unique identifier for this set of boosts. + + date (:py:obj:`~datetime.datetime`): + Date the boost was applied. + + expire_date (:py:obj:`~datetime.datetime`): + Point in time when the boost will expire. + + multiplier (``int``): + If set, this boost counts as multiplier boosts, otherwise it counts as a single boost. + + from_user (:obj:`~pyrogram.types.User`, *optional*): + The user that that applied the boost. + + is_gift (``bool``, *optional*): + Whether this boost was applied because the channel/supergroup directly gifted a subscription to the user. + + is_giveaway (``bool``, *optional*): + Whether this boost was applied because the user was chosen in a giveaway started by the channel/supergroup. + + is_unclaimed (``bool``, *optional*): + If set, the user hasn't yet invoked :meth:`~pyrogram.Client.apply_gift_code` to claim a subscription gifted directly or in a giveaway by the channel. + + giveaway_message_id (``int``, *optional*): + The message identifier of the giveaway. + + used_gift_slug (``str``, *optional*): + The created Telegram Premium gift code, only set if either gift or giveaway are set AND it is either a gift code for the currently logged in user or if it was already claimed. + """ + + def __init__( + self, + *, + id: str, + date: datetime, + expire_date: datetime, + multiplier: int, + from_user: Optional["types.User"] = None, + is_gift: Optional[bool] = None, + is_giveaway: Optional[bool] = None, + is_unclaimed: Optional[bool] = None, + giveaway_message_id: Optional[int] = None, + used_gift_slug: Optional[str] = None + ): + super().__init__() + + self.id = id + self.date = date + self.expire_date = expire_date + self.multiplier = multiplier + self.from_user = from_user + self.is_gift = is_gift + self.is_giveaway = is_giveaway + self.is_unclaimed = is_unclaimed + self.giveaway_message_id = giveaway_message_id + self.used_gift_slug = used_gift_slug + + @staticmethod + def _parse(client: "pyrogram.Client", boost: "raw.types.Boost", users) -> "ChatBoost": + return ChatBoost( + id=boost.id, + date=utils.timestamp_to_datetime(boost.date), + expire_date=utils.timestamp_to_datetime(boost.expires), + multiplier=getattr(boost, "multiplier", 1), + from_user=types.User._parse(client, users.get(boost.user_id)), + is_gift=getattr(boost, "", None), + is_giveaway=getattr(boost, "", None), + is_unclaimed=getattr(boost, "", None), + giveaway_message_id=getattr(boost, "", None), + used_gift_slug=getattr(boost, "", None), + )