diff --git a/compiler/docs/compiler.py b/compiler/docs/compiler.py index bd1ef7c4e..e778ab4e4 100644 --- a/compiler/docs/compiler.py +++ b/compiler/docs/compiler.py @@ -402,7 +402,7 @@ def get_title_list(s: str) -> list: get_payment_form send_payment_form get_available_gifts - get_user_gifts + get_received_gifts sell_gift send_gift toggle_gift_is_saved @@ -522,7 +522,7 @@ def get_title_list(s: str) -> list: Location Venue Gift - UserGift + ReceivedGift UpgradedGift WebAppData MessageAutoDeleteTimerChanged @@ -759,7 +759,7 @@ def get_title_list(s: str) -> list: Message.translate Message.pay Message.star - UserGift.toggle + ReceivedGift.toggle ExternalReplyInfo.download """, chat=""" diff --git a/docs/source/releases/changes-in-this-fork.rst b/docs/source/releases/changes-in-this-fork.rst index fe5922d9d..b0a080c10 100644 --- a/docs/source/releases/changes-in-this-fork.rst +++ b/docs/source/releases/changes-in-this-fork.rst @@ -33,6 +33,7 @@ Changes in this Fork | Scheme layer used: 200 | +------------------------+ +- Rename ``UserGift`` to :obj:`~pyrogram.types.ReceivedGift`, ``get_user_gifts`` to :meth:`~pyrogram.Client.get_received_gifts` and the corresponding fields appropriately. - Added the field ``paid_message_star_count`` to the classes :obj:`~pyrogram.types.Chat`, :obj:`~pyrogram.types.Message` and :obj:`~pyrogram.types.User`. - Added the parameter ``paid_message_star_count`` to the methods :meth:`~pyrogram.Client.copy_media_group`, :meth:`~pyrogram.Client.send_game`, :meth:`~pyrogram.Client.send_invoice`, :meth:`~pyrogram.Client.forward_messages`, :meth:`~pyrogram.Client.send_animation`, :meth:`~pyrogram.Client.send_audio`, :meth:`~pyrogram.Client.send_cached_media`, :meth:`~pyrogram.Client.send_contact`, :meth:`~pyrogram.Client.send_dice`, :meth:`~pyrogram.Client.send_document`, :meth:`~pyrogram.Client.send_location`, :meth:`~pyrogram.Client.send_media_group`, :meth:`~pyrogram.Client.send_message`, :meth:`~pyrogram.Client.send_paid_media`, :meth:`~pyrogram.Client.send_photo`, :meth:`~pyrogram.Client.send_poll`, :meth:`~pyrogram.Client.send_sticker`, :meth:`~pyrogram.Client.send_venue`, :meth:`~pyrogram.Client.send_video_note`, :meth:`~pyrogram.Client.send_video`, :meth:`~pyrogram.Client.send_voice` and the bound methods :meth:`~pyrogram.types.Message.forward` and :meth:`~pyrogram.types.Message.copy`. - View `new and changed `__ `raw API methods `__. diff --git a/pyrogram/enums/message_service_type.py b/pyrogram/enums/message_service_type.py index f435dde43..e3bd22d58 100644 --- a/pyrogram/enums/message_service_type.py +++ b/pyrogram/enums/message_service_type.py @@ -141,8 +141,8 @@ class MessageServiceType(AutoName): WRITE_ACCESS_ALLOWED = auto() "The user accepted webapp bot's request to send messages" - USER_GIFT = auto() - "Star gift" + RECEIVED_GIFT = auto() + "Owner Received gift" UNKNOWN = auto() "This service message is unsupported by the current version of Pyrogram" diff --git a/pyrogram/filters.py b/pyrogram/filters.py index 60a79cdfd..3ec474ad4 100644 --- a/pyrogram/filters.py +++ b/pyrogram/filters.py @@ -367,13 +367,13 @@ async def gift_code_filter(_, __, m: Message): # endregion -# region user_gift -async def user_gift_filter(_, __, m: Message): - return bool(m.user_gift) +# region received_gift +async def received_gift_filter(_, __, m: Message): + return bool(m.received_gift) -user_gift = create(user_gift_filter) -"""Filter messages that contain :obj:`~pyrogram.types.UserGift` objects.""" +received_gift = create(received_gift_filter) +"""Filter messages that contain :obj:`~pyrogram.types.ReceivedGift` objects.""" # endregion diff --git a/pyrogram/methods/business/__init__.py b/pyrogram/methods/business/__init__.py index 18eb4cd2d..ec3205cea 100644 --- a/pyrogram/methods/business/__init__.py +++ b/pyrogram/methods/business/__init__.py @@ -27,7 +27,7 @@ from .send_payment_form import SendPaymentForm from .get_available_gifts import GetAvailableGifts from .get_owned_star_count import GetOwnedStarCount -from .get_user_gifts import GetUserGifts +from .get_received_gifts import GetReceivedGifts from .sell_gift import SellGift from .send_gift import SendGift from .toggle_gift_is_saved import ToggleGiftIsSaved @@ -45,7 +45,7 @@ class TelegramBusiness( SendPaymentForm, GetAvailableGifts, GetOwnedStarCount, - GetUserGifts, + GetReceivedGifts, SellGift, SendGift, ToggleGiftIsSaved, diff --git a/pyrogram/methods/business/get_user_gifts.py b/pyrogram/methods/business/get_received_gifts.py similarity index 53% rename from pyrogram/methods/business/get_user_gifts.py rename to pyrogram/methods/business/get_received_gifts.py index e07f577c6..de176b5fc 100644 --- a/pyrogram/methods/business/get_user_gifts.py +++ b/pyrogram/methods/business/get_received_gifts.py @@ -23,19 +23,25 @@ from pyrogram import raw, types -class GetUserGifts: - async def get_user_gifts( +class GetReceivedGifts: + async def get_received_gifts( self: "pyrogram.Client", - chat_id: Union[int, str], + owner_id: Union[int, str], offset: str = "", limit: int = 0, - ) -> Optional[AsyncGenerator["types.UserGift", None]]: - """Get gifts saved to profile by the given user. + exclude_unsaved: bool = None, + exclude_saved: bool = None, + exclude_unlimited: bool = None, + exclude_limited: bool = None, + exclude_upgraded: bool = None, + sort_by_price: bool = None + ) -> Optional[AsyncGenerator["types.ReceivedGift", None]]: + """Returns gifts received by the given user or chat. .. include:: /_includes/usable-by/users.rst Parameters: - chat_id (``int`` | ``str``): + owner_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". For a contact that exists in your Telegram address book you can use his phone number (str). @@ -46,16 +52,34 @@ async def get_user_gifts( limit (``int``, *optional*): The maximum number of gifts to be returned; must be positive and can't be greater than 100. For optimal performance, the number of returned objects is chosen by Telegram Server and can be smaller than the specified limit. + exclude_unsaved (``bool``, *optional*): + Pass True to exclude gifts that aren't saved to the chat's profile page. Always True for gifts received by other users and channel chats without ``can_post_messages`` administrator right. + + exclude_saved (``bool``, *optional*): + Pass True to exclude gifts that are saved to the chat's profile page. Always False for gifts received by other users and channel chats without ``can_post_messages`` administrator right. + + exclude_unlimited (``bool``, *optional*): + Pass True to exclude gifts that can be purchased unlimited number of times. + + exclude_limited (``bool``, *optional*): + Pass True to exclude gifts that can be purchased limited number of times. + + exclude_upgraded (``bool``, *optional*): + Pass True to exclude upgraded gifts. + + sort_by_price (``bool``, *optional*): + Pass True to sort results by gift price instead of send date. + Returns: - ``Generator``: A generator yielding :obj:`~pyrogram.types.UserGift` objects. + ``Generator``: A generator yielding :obj:`~pyrogram.types.ReceivedGift` objects. Example: .. code-block:: python - async for user_gift in app.get_user_gifts(user_id): - print(user_gift) + async for received_gift in app.get_received_gifts(owner_id): + print(received_gift) """ - peer = await self.resolve_peer(chat_id) + peer = await self.resolve_peer(owner_id) current = 0 total = abs(limit) or (1 << 31) - 1 @@ -64,10 +88,15 @@ async def get_user_gifts( while True: r = await self.invoke( raw.functions.payments.GetSavedStarGifts( - # TODO peer=peer, offset=offset, - limit=limit + limit=limit, + exclude_unsaved=exclude_unsaved, + exclude_saved=exclude_saved, + exclude_unlimited=exclude_unlimited, + exclude_limited=exclude_limited, + exclude_unique=exclude_upgraded, + sort_by_value=sort_by_price ), sleep_threshold=60 ) @@ -75,17 +104,17 @@ async def get_user_gifts( users = {u.id: u for u in r.users} chats = {c.id: c for c in r.chats} - user_gifts = [ - await types.UserGift._parse(self, gift, users, chats) + received_gifts = [ + await types.ReceivedGift._parse(self, gift, users, chats) for gift in r.gifts ] - if not user_gifts: + if not received_gifts: return - for user_gift in user_gifts: + for received_gift in received_gifts: await sleep(0) - yield user_gift + yield received_gift current += 1 diff --git a/pyrogram/types/messages_and_media/__init__.py b/pyrogram/types/messages_and_media/__init__.py index 35f71b533..54aaada67 100644 --- a/pyrogram/types/messages_and_media/__init__.py +++ b/pyrogram/types/messages_and_media/__init__.py @@ -41,7 +41,7 @@ ) from .sponsored_message import SponsoredMessage from .gift import Gift -from .user_gift import UserGift +from .received_gift import ReceivedGift from .upgraded_gift import UpgradedGift from .sticker import Sticker from .stripped_thumbnail import StrippedThumbnail @@ -111,7 +111,7 @@ "PollOption", "SponsoredMessage", "Gift", - "UserGift", + "ReceivedGift", "UpgradedGift", "Sticker", "Story", diff --git a/pyrogram/types/messages_and_media/message.py b/pyrogram/types/messages_and_media/message.py index c26b73e51..fbb70a32f 100644 --- a/pyrogram/types/messages_and_media/message.py +++ b/pyrogram/types/messages_and_media/message.py @@ -403,7 +403,7 @@ class Message(Object, Update): gifted_stars (:obj:`~pyrogram.types.GiftedStars`, *optional*): Info about gifted Telegram Stars - user_gift (:obj:`~pyrogram.types.UserGift`, *optional*): + received_gift (:obj:`~pyrogram.types.ReceivedGift`, *optional*): Service message: Represents a gift received by a user. contact_registered (:obj:`~pyrogram.types.ContactRegistered`, *optional*): @@ -531,7 +531,7 @@ def __init__( gift_code: "types.GiftCode" = None, gifted_premium: "types.GiftedPremium" = None, gifted_stars: "types.GiftedStars" = None, - user_gift: "types.UserGift" = None, + received_gift: "types.ReceivedGift" = None, empty: bool = None, mentioned: bool = None, service: "enums.MessageServiceType" = None, @@ -654,7 +654,7 @@ def __init__( self.custom_action = custom_action self.sender_business_bot = sender_business_bot self.business_connection_id = business_connection_id - self.user_gift = user_gift + self.received_gift = received_gift self.successful_payment = successful_payment self.paid_media = paid_media self.refunded_payment = refunded_payment @@ -765,7 +765,7 @@ async def _parse( chat_join_type = None screenshot_taken = None - user_gift = None + received_gift = None service_type = enums.MessageServiceType.UNKNOWN @@ -1024,8 +1024,8 @@ async def _parse( isinstance(action, raw.types.MessageActionStarGift) or isinstance(action, raw.types.MessageActionStarGiftUnique) ): - user_gift = await types.UserGift._parse_action(client, message, users, chats) - service_type = enums.MessageServiceType.USER_GIFT + received_gift = await types.ReceivedGift._parse_action(client, message, users, chats) + service_type = enums.MessageServiceType.RECEIVED_GIFT parsed_message = Message( id=message.id, @@ -1058,7 +1058,7 @@ async def _parse( chat_shared=chat_shared, connected_website=connected_website, write_access_allowed=write_access_allowed, - user_gift=user_gift, + received_gift=received_gift, successful_payment=successful_payment, message_auto_delete_timer_changed=message_auto_delete_timer_changed, boost_added=boost_added, diff --git a/pyrogram/types/messages_and_media/user_gift.py b/pyrogram/types/messages_and_media/received_gift.py similarity index 87% rename from pyrogram/types/messages_and_media/user_gift.py rename to pyrogram/types/messages_and_media/received_gift.py index 604773256..0d7ff19c1 100644 --- a/pyrogram/types/messages_and_media/user_gift.py +++ b/pyrogram/types/messages_and_media/received_gift.py @@ -1,5 +1,5 @@ # Pyrogram - Telegram MTProto API Client Library for Python -# Copyright (C) 2017-present Dan +# Copyright (C) 2017-present # # This file is part of Pyrogram. # @@ -25,8 +25,8 @@ from ..object import Object -class UserGift(Object): - """Represents a gift received by a user. +class ReceivedGift(Object): + """Represents a gift received by a user or a chat. Parameters: sender_user (:obj:`~pyrogram.types.User`, *optional*): @@ -38,6 +38,9 @@ class UserGift(Object): entities (List of :obj:`~pyrogram.types.MessageEntity`, *optional*): For text messages, special entities like usernames, URLs, bot commands, etc. that appear in the text. + date (:py:obj:`~datetime.datetime`, *optional*): + Date when the gift was sent. + is_private (``bool``, *optional*): True, if the sender and gift text are shown only to the gift receiver; otherwise, everyone are able to see them. @@ -47,9 +50,6 @@ class UserGift(Object): is_pinned (``bool``, *optional*): True, if the gift is pinned to the top of the chat's profile page. - date (:py:obj:`~datetime.datetime`, *optional*): - Date when the gift was sent. - gift (:obj:`~pyrogram.types.Gift` | :obj:`~pyrogram.types.UpgradedGift`, *optional*): Information about the gift. @@ -57,7 +57,7 @@ class UserGift(Object): Identifier of the message with the gift in the chat with the sender of the gift; can be None or an identifier of a deleted message; only for the gift receiver. sell_star_count (``int``, *optional*): - Number of Telegram Stars that can be claimed by the receiver instead of the gift; only for the gift receiver. + Number of Telegram Stars that can be claimed by the receiver instead of the regular gift; 0 if the gift can't be sold by the current user. was_converted (``bool``, *optional*): True, if the gift was converted to Telegram Stars; only for the receiver of the gift. @@ -106,14 +106,14 @@ def __init__( ): super().__init__(client) + self.sender_user = sender_user + self.text = text + self.entities = entities self.date = date - self.gift = gift self.is_private = is_private self.is_saved = is_saved self.is_pinned = is_pinned - self.sender_user = sender_user - self.text = text - self.entities = entities + self.gift = gift self.message_id = message_id self.sell_star_count = sell_star_count self.was_converted = was_converted @@ -131,32 +131,38 @@ async def _parse( saved_star_gift: "raw.types.SavedStarGift", users: dict, chats: dict - ) -> "UserGift": + ) -> "ReceivedGift": text, entities = None, None if getattr(saved_star_gift, "message", None): text = saved_star_gift.message.text or None entities = [types.MessageEntity._parse(client, entity, users) for entity in saved_star_gift.message.entities] entities = types.List(filter(lambda x: x is not None, entities)) - # TODO refunded:flags.9?true can_upgrade:flags.10?true msg_id:flags.3?int saved_id:flags.11?long upgrade_stars:flags.6?long can_export_at:flags.7?int transfer_stars:flags.8?long sender_user = utils.get_raw_peer_id(saved_star_gift.from_id) - return UserGift( + return ReceivedGift( + sender_user=types.User._parse( + client, + users.get(sender_user) + ) if sender_user else None, + text=Str(text).init(entities) if text else None, + entities=entities, date=utils.timestamp_to_datetime(saved_star_gift.date), + is_private=getattr(saved_star_gift, "name_hidden", None), + is_saved=not saved_star_gift.unsaved if getattr(saved_star_gift, "unsaved", False) else None, + is_pinned=saved_star_gift.pinned_to_top, gift=await types.Gift._parse( client, saved_star_gift.gift, users ), - is_private=getattr(saved_star_gift, "name_hidden", None), - is_saved=not saved_star_gift.unsaved if getattr(saved_star_gift, "unsaved", None) else None, - is_pinned=saved_star_gift.pinned_to_top, - sender_user=types.User._parse( - client, - users.get(sender_user) - ) if sender_user else None, message_id=getattr(saved_star_gift, "msg_id", None), - sell_star_count=getattr(saved_star_gift, "convert_stars", None), - text=Str(text).init(entities) if text else None, - entities=entities, + sell_star_count=getattr(saved_star_gift, "convert_stars", 0), + was_converted=bool(getattr(saved_star_gift, "saved_id", None)), + can_be_upgraded=getattr(saved_star_gift, "can_upgrade", None), + was_refunded=getattr(saved_star_gift, "refunded", None), + prepaid_upgrade_star_count=getattr(saved_star_gift, "upgrade_stars", None), + can_be_transferred=bool(getattr(saved_star_gift, "transfer_stars", None)), + transfer_star_count=getattr(saved_star_gift, "transfer_stars", None), + export_date=utils.timestamp_to_datetime(saved_star_gift.can_export_at), client=client ) @@ -166,7 +172,7 @@ async def _parse_action( message: "raw.base.Message", users: dict, chats: dict - ) -> "UserGift": + ) -> "ReceivedGift": action = message.action text, entities = None, None @@ -176,7 +182,7 @@ async def _parse_action( entities = types.List(filter(lambda x: x is not None, entities)) # TODO if isinstance(action, raw.types.MessageActionStarGift): - return UserGift( + return ReceivedGift( gift=await types.Gift._parse( client, action.gift, @@ -198,7 +204,7 @@ async def _parse_action( ) if isinstance(action, raw.types.MessageActionStarGiftUnique): - return UserGift( + return ReceivedGift( gift=await types.Gift._parse( client, action.gift, @@ -218,7 +224,7 @@ async def _parse_action( ) async def toggle(self, is_saved: bool) -> bool: - """Bound method *toggle* of :obj:`~pyrogram.types.UserGift`. + """Bound method *toggle* of :obj:`~pyrogram.types.ReceivedGift`. Use as a shortcut for: @@ -235,7 +241,7 @@ async def toggle(self, is_saved: bool) -> bool: Example: .. code-block:: python - await user_gift.toggle(is_saved=False) + await received_gift.toggle(is_saved=False) Returns: ``bool``: On success, True is returned.