pyrofork: Refactor Star Gift Based On New Layer

Signed-off-by: Yasir <git@yasir.id>
This commit is contained in:
KurimuzonAkuma 2025-01-07 17:17:44 +07:00 committed by Yasir
parent 9e101ef4d9
commit 14fb99cf77
28 changed files with 677 additions and 1072 deletions

View file

@ -498,4 +498,5 @@ TTL_PERIOD_INVALID The provided TTL period is invalid
BOOSTS_REQUIRED The specified channel must first be boosted by its users in order to perform this action
BOOSTS_EMPTY You can't modify the icon of the General topic.
BOOST_NOT_MODIFIED You're already boosting the specified channel.
PAYMENT_REQUIRED The payment is required
BOOST_PEER_INVALID The specified `boost_peer` is invalid.

1 id message
498 BOOSTS_REQUIRED The specified channel must first be boosted by its users in order to perform this action
499 BOOSTS_EMPTY You can't modify the icon of the General topic.
500 BOOST_NOT_MODIFIED You're already boosting the specified channel.
501 PAYMENT_REQUIRED The payment is required
502 BOOST_PEER_INVALID The specified `boost_peer` is invalid.

View file

@ -26,6 +26,7 @@ from .chat_members_filter import ChatMembersFilter
from .chat_type import ChatType
from .client_platform import ClientPlatform
from .folder_color import FolderColor
from .gift_attribute_type import GiftAttributeType
from .listerner_types import ListenerTypes
from .message_entity_type import MessageEntityType
from .message_media_type import MessageMediaType
@ -38,7 +39,6 @@ from .profile_color import ProfileColor
from .reaction_type import ReactionType
from .reply_color import ReplyColor
from .sent_code_type import SentCodeType
from .star_gift_attribute_type import StarGiftAttributeType
from .stories_privacy_rules import StoriesPrivacyRules
from .story_privacy import StoryPrivacy
from .user_status import UserStatus
@ -53,6 +53,7 @@ __all__ = [
'ChatType',
'ClientPlatform',
'FolderColor',
'GiftAttributeType',
'ListenerTypes',
'MessageEntityType',
'MessageMediaType',
@ -65,7 +66,6 @@ __all__ = [
'ReactionType',
'ReplyColor',
'SentCodeType',
'StarGiftAttributeType',
"StoriesPrivacyRules",
"StoryPrivacy",
'UserStatus'

View file

@ -20,8 +20,8 @@ from pyrogram import raw
from .auto_name import AutoName
class StarGiftAttributeType(AutoName):
"""Star gift attribute type enumeration used in :obj:`~pyrogram.types.StarGiftAttribute`."""
class GiftAttributeType(AutoName):
"""Star gift attribute type enumeration used in :obj:`~pyrogram.types.GiftAttribute`."""
MODEL = raw.types.StarGiftAttributeModel
"Model attribute"
@ -31,3 +31,6 @@ class StarGiftAttributeType(AutoName):
BACKDROP = raw.types.StarGiftAttributeBackdrop
"Backdrop attribute"
ORIGINAL_DETAILS = raw.types.StarGiftAttributeOriginalDetails
"Original details attribute"

View file

@ -58,7 +58,7 @@ class MessageServiceType(AutoName):
GAME_HIGH_SCORE = auto()
"Game high score"
ChatShared = auto()
CHAT_SHARED = auto()
"a shared chat/channel/user"
FORUM_TOPIC_CREATED = auto()
@ -127,7 +127,7 @@ class MessageServiceType(AutoName):
GIFT_CODE = auto()
"Gift code"
STAR_GIFT = auto()
GIFT = auto()
"Star gift"
SCREENSHOT_TAKEN = auto()

View file

@ -360,9 +360,9 @@ gift_code = create(gift_code_filter)
# region star_gift_filter
async def star_gift_filter(_, __, m: Message):
return bool(m.star_gift)
return bool(m.gift)
star_gift = create(star_gift_filter)
"""Filter messages that contain :obj:`~pyrogram.types.StarGift` objects."""
"""Filter messages that contain :obj:`~pyrogram.types.Gift` objects."""
# endregion
# region video_filter

View file

@ -17,21 +17,13 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from .answer_pre_checkout_query import AnswerPreCheckoutQuery
from .answer_shipping_query import AnswerShippingQuery
from .get_business_connection import GetBusinessConnection
from .get_available_gifts import GetAvailableGifts
from .get_user_gifts import GetUserGifts
from .sell_gift import SellGift
from .send_gift import SendGift
from .toggle_gift_is_saved import ToggleGiftIsSaved
class TelegramBusiness(
AnswerPreCheckoutQuery,
AnswerShippingQuery,
GetBusinessConnection,
GetAvailableGifts,
GetUserGifts,
SellGift,
SendGift,
ToggleGiftIsSaved,
):
pass

View file

@ -1,44 +0,0 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
#
# 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 <http://www.gnu.org/licenses/>.
from typing import List
import pyrogram
from pyrogram import raw, types
class GetAvailableGifts:
async def get_available_gifts(
self: "pyrogram.Client",
) -> List["types.Gift"]:
"""Get all gifts that can be sent to other users.
.. include:: /_includes/usable-by/users.rst
Returns:
List of :obj:`~pyrogram.types.Gift`: On success, a list of star gifts is returned.
Example:
.. code-block:: python
app.get_available_gifts()
"""
r = await self.invoke(
raw.functions.payments.GetStarGifts(hash=0)
)
return types.List([await types.Gift._parse(self, gift) for gift in r.gifts])

View file

@ -1,97 +0,0 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
#
# 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 <http://www.gnu.org/licenses/>.
from typing import Union, Optional, AsyncGenerator
import pyrogram
from pyrogram import raw, types
class GetUserGifts:
async def get_user_gifts(
self: "pyrogram.Client",
user_id: Union[int, str],
offset: str = "",
limit: int = 0,
) -> Optional[AsyncGenerator["types.StarGift", None]]:
"""Get gifts saved to profile by the given user.
.. include:: /_includes/usable-by/users.rst
Parameters:
user_id (``int`` | ``str``):
Unique identifier (int) or username (str) of the target user.
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).
offset (``str``, *optional*):
Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results.
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.
Returns:
``Generator``: A generator yielding :obj:`~pyrogram.types.UserGift` objects.
Example:
.. code-block:: python
async for user_gift in app.get_user_gifts(user_id):
print(user_gift)
"""
peer = await self.resolve_peer(user_id)
if not isinstance(peer, (raw.types.InputPeerUser, raw.types.InputPeerSelf)):
raise ValueError("user_id must belong to a user.")
current = 0
total = abs(limit) or (1 << 31) - 1
limit = min(100, total)
while True:
r = await self.invoke(
raw.functions.payments.GetUserStarGifts(
user_id=peer,
offset=offset,
limit=limit
),
sleep_threshold=60
)
users = {u.id: u for u in r.users}
user_gifts = [
await types.StarGift._parse_user_star_gift(self, gift, users)
for gift in r.gifts
]
if not user_gifts:
return
for user_gift in user_gifts:
yield user_gift
current += 1
if current >= total:
return
offset = r.next_offset
if not offset:
return

View file

@ -1,67 +0,0 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
#
# 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 <http://www.gnu.org/licenses/>.
from typing import Union
import pyrogram
from pyrogram import raw
class SellGift:
async def sell_gift(
self: "pyrogram.Client",
sender_user_id: Union[int, str],
message_id: int
) -> bool:
"""Sells a gift received by the current user for Telegram Stars.
.. include:: /_includes/usable-by/users.rst
Parameters:
sender_user_id (``int`` | ``str``):
Unique identifier (int) or username (str) of the user that sent the gift.
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).
message_id (``int``):
Unique identifier of the message with the gift in the chat with the user.
Returns:
``bool``: On success, True is returned.
Example:
.. code-block:: python
# Convert gift
app.sell_gift(sender_user_id=user_id, message_id=123)
"""
peer = await self.resolve_peer(sender_user_id)
if not isinstance(peer, (raw.types.InputPeerUser, raw.types.InputPeerSelf)):
raise ValueError("sender_user_id must belong to a user.")
r = await self.invoke(
raw.functions.payments.ConvertStarGift(
user_id=peer,
msg_id=message_id
)
)
return r

View file

@ -1,110 +0,0 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
#
# 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 <http://www.gnu.org/licenses/>.
from typing import Optional, Union, List
import pyrogram
from pyrogram import raw, types, enums, utils
class SendGift:
async def send_gift(
self: "pyrogram.Client",
user_id: Union[int, str],
gift_id: int,
pay_for_upgrade: Optional[bool] = None,
text: Optional[str] = None,
parse_mode: Optional["enums.ParseMode"] = None,
entities: Optional[List["types.MessageEntity"]] = None,
is_private: Optional[bool] = None,
) -> bool:
"""Sends a gift to another user.
.. include:: /_includes/usable-by/users.rst
Parameters:
user_id (``int`` | ``str``):
Unique identifier (int) or username (str) of the user that will receive the gift.
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).
gift_id (``int``):
Unique identifier of the gift to send.
pay_for_upgrade (``bool``, *optional*):
Pass True to pay for the gift upgrade from the sender's balance, thereby making the upgrade free for the receiver.
text (``str``, *optional*):
Text of the message to be sent. 0-``gift_text_length_max`` characters.
parse_mode (:obj:`~pyrogram.enums.ParseMode`, *optional*):
By default, texts are parsed using both Markdown and HTML styles.
You can combine both syntaxes together.
entities (List of :obj:`~pyrogram.types.MessageEntity`, *optional*):
List of special entities that appear in message text, which can be specified instead of *parse_mode*.
Only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities are allowed.
is_private (``bool``, *optional*):
Pass True to show the current user as sender and gift text only to the gift receiver; otherwise, everyone will be able to see them.
Returns:
``bool``: On success, True is returned.
Raises:
RPCError: In case of a Telegram RPC error.
Example:
.. code-block:: python
# Send gift
app.send_gift(user_id=user_id, gift_id=123)
"""
peer = await self.resolve_peer(user_id)
if not isinstance(peer, (raw.types.InputPeerUser, raw.types.InputPeerSelf)):
raise ValueError("user_id must belong to a user.")
text, entities = (await utils.parse_text_entities(self, text, parse_mode, entities)).values()
invoice = raw.types.InputInvoiceStarGift(
user_id=peer,
gift_id=gift_id,
hide_name=is_private,
include_upgrade=pay_for_upgrade,
message=raw.types.TextWithEntities(
text=text, entities=entities or []
) if text else None
)
form = await self.invoke(
raw.functions.payments.GetPaymentForm(
invoice=invoice
)
)
await self.invoke(
raw.functions.payments.SendStarsForm(
form_id=form.form_id,
invoice=invoice
)
)
return True

View file

@ -1,71 +0,0 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
#
# 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 <http://www.gnu.org/licenses/>.
from typing import Union
import pyrogram
from pyrogram import raw
class ToggleGiftIsSaved:
async def toggle_gift_is_saved(
self: "pyrogram.Client",
sender_user_id: Union[int, str],
message_id: int,
is_saved: bool
) -> bool:
"""Toggles whether a gift is shown on the current user's profile page.
.. include:: /_includes/usable-by/users.rst
Parameters:
sender_user_id (``int`` | ``str``):
Unique identifier (int) or username (str) of the target user that sent the gift.
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).
message_id (``int``):
Unique message identifier of the message with the gift in the chat with the user.
is_saved (``bool``):
Pass True to display the gift on the user's profile page; pass False to remove it from the profile page.
Returns:
``bool``: On success, True is returned.
Example:
.. code-block:: python
# Hide gift
app.toggle_gift_is_saved(sender_user_id=user_id, message_id=123, is_saved=False)
"""
peer = await self.resolve_peer(sender_user_id)
if not isinstance(peer, (raw.types.InputPeerUser, raw.types.InputPeerSelf)):
raise ValueError("sender_user_id must belong to a user.")
r = await self.invoke(
raw.functions.payments.SaveStarGift(
user_id=peer,
msg_id=message_id,
unsave=not is_saved
)
)
return r

View file

@ -19,45 +19,45 @@
from .apply_gift_code import ApplyGiftCode
from .check_giftcode import CheckGiftCode
from .convert_star_gift import ConvertStarGift
from .convert_gift import ConvertGift
from .create_invoice_link import CreateInvoiceLink
from .get_payment_form import GetPaymentForm
from .get_star_gifts import GetStarGifts
from .get_available_gifts import GetAvailableGifts
from .get_stars_transactions import GetStarsTransactions
from .get_stars_transactions_by_id import GetStarsTransactionsById
from .get_user_star_gifts_count import GetUserStarGiftsCount
from .get_user_star_gifts import GetUserStarGifts
from .hide_star_gift import HideStarGift
from .get_user_gifts_count import GetUserGiftsCount
from .get_user_gifts import GetUserGifts
from .hide_gift import HideGift
from .refund_stars_payment import RefundStarPayment
from .send_invoice import SendInvoice
from .send_paid_media import SendPaidMedia
from .send_paid_reaction import SendPaidReaction
from .send_payment_form import SendPaymentForm
from .send_star_gift import SendStarGift
from .show_star_gift import ShowStarGift
from .transfer_star_gift import TransferStarGift
from .upgrade_star_gift import UpgradeStarGift
from .send_gift import SendGift
from .show_gift import ShowGift
from .transfer_gift import TransferGift
from .upgrade_gift import UpgradeGift
class Payments(
ApplyGiftCode,
CheckGiftCode,
ConvertStarGift,
ConvertGift,
CreateInvoiceLink,
GetPaymentForm,
GetStarGifts,
GetAvailableGifts,
GetStarsTransactions,
GetStarsTransactionsById,
GetUserStarGiftsCount,
GetUserStarGifts,
HideStarGift,
GetUserGiftsCount,
GetUserGifts,
HideGift,
RefundStarPayment,
SendPaidReaction,
SendPaidMedia,
SendInvoice,
SendPaymentForm,
SendStarGift,
ShowStarGift,
TransferStarGift,
UpgradeStarGift
SendGift,
ShowGift,
TransferGift,
UpgradeGift
):
pass

View file

@ -20,6 +20,8 @@
import re
import pyrogram
from pyrogram import raw
class ApplyGiftCode:
async def apply_gift_code(
self: "pyrogram.Client",

View file

@ -24,8 +24,8 @@ import pyrogram
from pyrogram import raw
class ConvertStarGift:
async def convert_star_gift(
class ConvertGift:
async def convert_gift(
self: "pyrogram.Client",
message_id: int
) -> bool:
@ -44,7 +44,7 @@ class ConvertStarGift:
.. code-block:: python
# Convert gift
app.convert_star_gift(message_id=123)
app.convert_gift(message_id=123)
"""
r = await self.invoke(
raw.functions.payments.ConvertStarGift(

View file

@ -23,24 +23,24 @@ import pyrogram
from pyrogram import raw, types
class GetStarGifts:
async def get_star_gifts(
class GetAvailableGifts:
async def get_available_gifts(
self: "pyrogram.Client",
) -> List["types.StarGift"]:
) -> List["types.Gift"]:
"""Get all available star gifts to send.
.. include:: /_includes/usable-by/users.rst
Returns:
List of :obj:`~pyrogram.types.StarGift`: On success, a list of star gifts is returned.
List of :obj:`~pyrogram.types.Gift`: On success, a list of star gifts is returned.
Example:
.. code-block:: python
app.get_star_gifts()
app.get_available_gifts()
"""
r = await self.invoke(
raw.functions.payments.GetStarGifts(hash=0)
)
return types.List([await types.StarGift._parse(self, gift) for gift in r.gifts])
return types.List([await types.Gift._parse(self, gift) for gift in r.gifts])

View file

@ -22,8 +22,8 @@ import pyrogram
from pyrogram import raw, types
class GetUserStarGifts:
async def get_user_star_gifts(
class GetUserGifts:
async def get_user_gifts(
self: "pyrogram.Client",
chat_id: Union[int, str],
limit: int = 0,
@ -46,12 +46,12 @@ class GetUserStarGifts:
Maximum amount of star gifts to be returned.
Returns:
``Generator``: A generator yielding :obj:`~pyrogram.types.UserStarGift` objects.
``Generator``: A generator yielding :obj:`~pyrogram.types.Gift` objects.
Example:
.. code-block:: python
async for gift in app.get_user_star_gifts(chat_id):
async for gift in app.get_user_gifts(chat_id):
print(gift)
"""
peer = await self.resolve_peer(chat_id)
@ -76,15 +76,13 @@ class GetUserStarGifts:
users = {u.id: u for u in r.users}
user_star_gifts = [
await types.UserStarGift._parse(self, gift, users)
await types.Gift._parse_user(self, gift, users)
for gift in r.gifts
]
if not user_star_gifts:
return
offset = r.next_offset
for gift in user_star_gifts:
yield gift
@ -92,3 +90,8 @@ class GetUserStarGifts:
if current >= total:
return
offset = r.next_offset
if not offset:
return

View file

@ -25,8 +25,8 @@ from pyrogram import raw
log = logging.getLogger(__name__)
class GetUserStarGiftsCount:
async def get_user_star_gifts_count(
class GetUserGiftsCount:
async def get_user_gifts_count(
self: "pyrogram.Client",
chat_id: Union[int, str]
) -> int:
@ -46,7 +46,7 @@ class GetUserStarGiftsCount:
Example:
.. code-block:: python
await app.get_user_star_gifts_count(chat_id)
await app.get_user_gifts_count(chat_id)
"""
peer = await self.resolve_peer(chat_id)

View file

@ -21,8 +21,8 @@ import pyrogram
from pyrogram import raw
class HideStarGift:
async def hide_star_gift(
class HideGift:
async def hide_gift(
self: "pyrogram.Client",
message_id: int
) -> bool:
@ -41,7 +41,7 @@ class HideStarGift:
.. code-block:: python
# Hide gift
app.hide_star_gift(message_id=123)
app.hide_gift(message_id=123)
"""
r = await self.invoke(
raw.functions.payments.SaveStarGift(

View file

@ -24,15 +24,16 @@ import pyrogram
from pyrogram import raw, types, enums, utils
class SendStarGift:
async def send_star_gift(
class SendGift:
async def send_gift(
self: "pyrogram.Client",
chat_id: Union[int, str],
star_gift_id: int,
gift_id: int,
text: Optional[str] = None,
parse_mode: Optional["enums.ParseMode"] = None,
entities: Optional[List["types.MessageEntity"]] = None,
hide_my_name: Optional[bool] = None,
pay_for_upgrade: Optional[bool] = None
) -> bool:
"""Send star gift.
@ -44,7 +45,7 @@ class SendStarGift:
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).
star_gift_id (``int``):
gift_id (``int``):
Unique identifier of star gift.
text (``str``, *optional*):
@ -59,6 +60,11 @@ class SendStarGift:
hide_my_name (``bool``, *optional*):
If True, your name will be hidden from visitors to the gift recipient's profile.
pay_for_upgrade (``bool``, *optional*):
If True, gift upgrade will be paid from the bots balance, thereby making the upgrade free for the receiver.
For bots only.
Defaults to None.
Returns:
``bool``: On success, True is returned.
@ -67,7 +73,7 @@ class SendStarGift:
.. code-block:: python
# Send gift
app.send_star_gift(chat_id=chat_id, star_gift_id=123)
app.send_gift(chat_id=chat_id, star_gift_id=123)
"""
peer = await self.resolve_peer(chat_id)
@ -78,8 +84,9 @@ class SendStarGift:
invoice = raw.types.InputInvoiceStarGift(
user_id=peer,
gift_id=star_gift_id,
gift_id=gift_id,
hide_name=hide_my_name,
include_upgrade=pay_for_upgrade,
message=raw.types.TextWithEntities(text=text, entities=entities) if text else None
)

View file

@ -20,8 +20,8 @@ import pyrogram
from pyrogram import raw
class ShowStarGift:
async def show_star_gift(
class ShowGift:
async def show_gift(
self: "pyrogram.Client",
message_id: int
) -> bool:
@ -40,7 +40,7 @@ class ShowStarGift:
.. code-block:: python
# Show gift
app.show_star_gift(message_id=123)
app.show_gift(message_id=123)
"""
r = await self.invoke(
raw.functions.payments.SaveStarGift(

View file

@ -19,47 +19,66 @@
from typing import Union
import pyrogram
from pyrogram import raw
from pyrogram import raw, errors
class TransferStarGift:
async def transfer_star_gift(
class TransferGift:
async def transfer_gift(
self: "pyrogram.Client",
chat_id: Union[int, str],
message_id: int,
to_chat_id: Union[int, str],
) -> bool:
"""Transfer star gift to another user.
.. include:: /_includes/usable-by/users.rst
Parameters:
chat_id (``int`` | ``str``):
message_id (``int``):
Unique message identifier of star gift.
to_chat_id (``int`` | ``str``):
Unique identifier (int) or username (str) of the target chat you want to transfer the star gift to.
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).
message_id (``int``):
Unique message identifier of star gift.
Returns:
``bool``: On success, True is returned.
Example:
.. code-block:: python
# Show gift
app.transfer_star_gift(chat_id=123, message_id=123)
# Transfer gift to another user
app.transfer_gift(message_id=123, to_chat_id=123)
"""
peer = await self.resolve_peer(chat_id)
peer = await self.resolve_peer(to_chat_id)
if not isinstance(peer, (raw.types.InputPeerUser, raw.types.InputPeerSelf)):
raise ValueError("chat_id must belong to a user.")
await self.invoke(
raw.functions.payments.TransferStarGift(
msg_id=message_id,
keep_original_details=keep_details
try:
await self.invoke(
raw.functions.payments.TransferStarGift(
msg_id=message_id,
to_id=peer
)
)
except errors.PaymentRequired:
invoice = raw.types.InputInvoiceStarGiftTransfer(
msg_id=message_id,
to_id=peer
)
)
return True # TODO:
form = await self.invoke(
raw.functions.payments.GetPaymentForm(
invoice=invoice
)
)
await self.invoke(
raw.functions.payments.SendStarsForm(
form_id=form.form_id,
invoice=invoice
)
)
return True

View file

@ -19,11 +19,11 @@
from typing import Optional
import pyrogram
from pyrogram import raw
from pyrogram import raw, errors
class UpgradeStarGift:
async def upgrade_star_gift(
class UpgradeGift:
async def upgrade_gift(
self: "pyrogram.Client",
message_id: int,
keep_details: Optional[bool] = None
@ -36,20 +36,42 @@ class UpgradeStarGift:
message_id (``int``):
Unique message identifier of star gift.
keep_details (``bool``):
Pass True if you want to keep the original details of the gift like caption.
Returns:
``bool``: On success, True is returned.
Example:
.. code-block:: python
# Show gift
app.upgrade_star_gift(message_id=123)
# Upgrade gift
app.upgrade_gift(message_id=123)
"""
await self.invoke(
raw.functions.payments.UpgradeStarGift(
try:
await self.invoke(
raw.functions.payments.UpgradeStarGift(
msg_id=message_id,
keep_original_details=keep_details
)
)
except errors.PaymentRequired:
invoice = raw.types.InputInvoiceStarGiftUpgrade(
msg_id=message_id,
keep_original_details=keep_details
)
)
return True # TODO:
form = await self.invoke(
raw.functions.payments.GetPaymentForm(
invoice=invoice
)
)
await self.invoke(
raw.functions.payments.SendStarsForm(
form_id=form.form_id,
invoice=invoice
)
)
return True

View file

@ -415,7 +415,7 @@ class Message(Object, Update):
Service message: gift code information.
Contains a `Telegram Premium giftcode link <https://core.telegram.org/api/links#premium-giftcode-links>`_.
star_gift (:obj:`~pyrogram.types.StarGift`, *optional*):
gift (:obj:`~pyrogram.types.Gift`, *optional*):
Service message: star gift information.
gifted_premium (:obj:`~pyrogram.types.GiftedPremium`, *optional*):
@ -498,7 +498,7 @@ class Message(Object, Update):
chat_wallpaper_updated: "types.ChatWallpaper" = None,
contact_registered: "types.ContactRegistered" = None,
gift_code: "types.GiftCode" = None,
star_gift: "types.StarGift" = None,
gift: "types.Gift" = None,
screenshot_taken: "types.ScreenshotTaken" = None,
invoice: "types.Invoice" = None,
story: Union["types.MessageStory", "types.Story"] = None,
@ -619,7 +619,7 @@ class Message(Object, Update):
self.chat_wallpaper_updated = chat_wallpaper_updated
self.contact_registered = contact_registered
self.gift_code = gift_code
self.star_gift = star_gift
self.gift = gift
self.screenshot_taken = screenshot_taken
self.invoice = invoice
self.story = story
@ -783,7 +783,7 @@ class Message(Object, Update):
chat_wallpaper_updated = None
contact_registered = None
gift_code = None
star_gift = None
gift = None
screenshot_taken = None
service_type = None
@ -901,8 +901,8 @@ class Message(Object, Update):
gift_code = types.GiftCode._parse(client, action, chats)
service_type = enums.MessageServiceType.GIFT_CODE
elif isinstance(action, (raw.types.MessageActionStarGift, raw.types.MessageActionStarGiftUnique)):
star_gift = await types.StarGift._parse_action(client, message, users)
service_type = enums.MessageServiceType.STAR_GIFT
gift = await types.Gift._parse_action(client, message, users)
service_type = enums.MessageServiceType.GIFT
elif isinstance(action, raw.types.MessageActionScreenshotTaken):
screenshot_taken = types.ScreenshotTaken()
service_type = enums.MessageServiceType.SCREENSHOT_TAKEN
@ -943,7 +943,7 @@ class Message(Object, Update):
giveaway_launched=giveaway_launched,
giveaway_result=giveaway_result,
successful_payment=successful_payment,
star_gift=star_gift,
gift=gift,
payment_refunded=payment_refunded,
boosts_applied=boosts_applied,
chat_theme_updated=chat_theme_updated,

View file

@ -20,6 +20,7 @@
from .extended_media_preview import ExtendedMediaPreview
from .checked_gift_code import CheckedGiftCode
from .gift import Gift
from .gift_attribute import GiftAttribute
from .gift_code import GiftCode
from .gifted_premium import GiftedPremium
from .input_stars_transaction import InputStarsTransaction
@ -30,8 +31,6 @@ from .payment_form import PaymentForm
from .payment_info import PaymentInfo
from .payment_refunded import PaymentRefunded
from .purchased_paid_media import PurchasedPaidMedia
from .star_gift import StarGift
from .star_gift_attribute import StarGiftAttribute
from .stars_status import StarsStatus
from .stars_transaction import StarsTransaction
from .successful_payment import SuccessfulPayment
@ -40,6 +39,7 @@ __all__ = [
"ExtendedMediaPreview",
"CheckedGiftCode",
"Gift",
"GiftAttribute",
"GiftCode",
"GiftedPremium",
"InputStarsTransaction",
@ -50,8 +50,6 @@ __all__ = [
"PaymentInfo",
"PaymentRefunded",
"PurchasedPaidMedia",
"StarGift",
"StarGiftAttribute",
"StarsStatus",
"StarsTransaction",
"SuccessfulPayment",

View file

@ -1,69 +1,132 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Pyrofork - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
# Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>
#
# This file is part of Pyrogram.
# This file is part of Pyrofork.
#
# Pyrogram is free software: you can redistribute it and/or modify
# Pyrofork 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,
# Pyrofork 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 <http://www.gnu.org/licenses/>.
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import Optional
from typing import Optional, List, Union
import pyrogram
from pyrogram import raw, types, utils
from pyrogram import raw
from pyrogram import types
from pyrogram import utils
from ..object import Object
class Gift(Object):
"""Describes a gift that can be sent to another user.
"""A star gift.
Parameters:
id (``int``):
Unique identifier of the gift.
Unique star gift identifier.
sticker (:obj:`~pyrogram.types.Sticker`):
The sticker representing the gift.
sticker (:obj:`~pyrogram.types.Sticker`, *optional*):
Information about the star gift sticker.
star_count (``int``):
Number of Telegram Stars that must be paid for the gift.
caption (``str``, *optional*):
Text message.
default_sell_star_count (``int``):
Number of Telegram Stars that can be claimed by the receiver instead of the gift by default. If the gift was paid with just bought Telegram Stars, then full value can be claimed.
caption_entities (List of :obj:`~pyrogram.types.MessageEntity`, *optional*):
For text messages, special entities like usernames, URLs, bot commands, etc. that appear in the text.
remaining_count (``int``, *optional*):
Number of remaining times the gift can be purchased by all users; None if not limited or the gift was sold out.
message_id (``int``, *optional*):
Unique message identifier.
total_count (``int``, *optional*):
Number of total times the gift can be purchased by all users; None if not limited.
upgrade_message_id (``int``, *optional*):
Unique message identifier.
For unique gifts only.
upgrade_star_count (``int``, *optional*):
Number of Telegram Stars that must be paid to upgrade the gift; 0 if upgrade isn't possible.
title (``str``, *optional*):
Title of the star gift.
For unique gifts only.
is_for_birthday (``bool``, *optional*):
True, if the gift is a birthday gift.
number (``int``, *optional*):
Collectible number of the star gift.
For unique gifts only.
first_send_date (:py:obj:`~datetime.datetime`, *optional*):
Point in time (Unix timestamp) when the gift was send for the first time; for sold out gifts only.
attributes (List of :obj:`~pyrogram.types.GiftAttribute`, *optional*):
Attributes of the star gift.
For unique gifts only.
last_send_date (:py:obj:`~datetime.datetime`, *optional*):
Point in time (Unix timestamp) when the gift was send for the last time; for sold out gifts only.
date (``datetime``, *optional*):
Date when the star gift was received.
first_sale_date (``datetime``, *optional*):
Date when the star gift was first purchased.
last_sale_date (``datetime``, *optional*):
Date when the star gift was last purchased.
from_user (:obj:`~pyrogram.types.User`, *optional*):
User who sent the star gift.
price (``int``, *optional*):
Price of this gift in stars.
convert_price (``int``, *optional*):
The number of stars you get if you convert this gift.
upgrade_price (``int``, *optional*):
The number of stars you need to upgrade this gift.
transfer_price (``int``, *optional*):
The number of stars you need to transfer this gift.
available_amount (``int``, *optional*):
The number of gifts available for purchase.
Returned only if is_limited is True.
total_amount (``int``, *optional*):
Total amount of gifts.
Returned only if is_limited is True.
can_upgrade (``bool``, *optional*):
True, if the gift can be upgraded.
can_export_at (``datetime``, *optional*):
Date when the gift can be exported via blockchain.
is_limited (``bool``, *optional*):
True, if the number of gifts is limited.
is_name_hidden (``bool``, *optional*):
True, if the sender's name is hidden.
is_saved (``bool``, *optional*):
True, if the star gift is saved in profile.
is_sold_out (``bool``, *optional*):
True, if the star gift is sold out.
is_converted (``bool``, *optional*):
True, if the gift was converted to Telegram Stars.
Only for the receiver of the gift.
is_upgraded (``bool``, *optional*):
True, if the gift was upgraded.
is_refunded (``bool``, *optional*):
True, if the gift was refunded.
is_transferred (``bool``, *optional*):
True, if the gift was transferred.
is_birthday (``bool``, *optional*):
True, if the gift is a birthday gift.
"""
def __init__(
@ -71,32 +134,68 @@ class Gift(Object):
*,
client: "pyrogram.Client" = None,
id: int,
sticker: "types.Sticker",
star_count: int,
default_sell_star_count: int,
remaining_count: Optional[int] = None,
total_count: Optional[int] = None,
upgrade_star_count: int,
is_for_birthday: Optional[bool] = None,
first_send_date: Optional[datetime] = None,
last_send_date: Optional[datetime] = None,
sticker: "types.Sticker" = None,
caption: Optional[str] = None,
caption_entities: List["types.MessageEntity"] = None,
message_id: Optional[int] = None,
date: Optional[datetime] = None,
first_sale_date: Optional[datetime] = None,
last_sale_date: Optional[datetime] = None,
from_user: Optional["types.User"] = None,
price: Optional[int] = None,
convert_price: Optional[int] = None,
upgrade_price: Optional[int] = None,
transfer_price: Optional[int] = None,
upgrade_message_id: Optional[int] = None,
title: Optional[str] = None,
number: Optional[int] = None,
attributes: Optional[List["types.GiftAttribute"]] = None,
available_amount: Optional[int] = None,
total_amount: Optional[int] = None,
can_upgrade: Optional[bool] = None,
can_export_at: Optional[datetime] = None,
is_limited: Optional[bool] = None,
is_name_hidden: Optional[bool] = None,
is_saved: Optional[bool] = None,
is_sold_out: Optional[bool] = None,
is_converted: Optional[bool] = None,
is_upgraded: Optional[bool] = None,
is_refunded: Optional[bool] = None,
is_transferred: Optional[bool] = None,
is_birthday: Optional[bool] = None
):
super().__init__(client)
self.id = id
self.sticker = sticker
self.star_count = star_count
self.default_sell_star_count = default_sell_star_count
self.remaining_count = remaining_count
self.total_count = total_count
self.upgrade_star_count = upgrade_star_count
self.is_for_birthday = is_for_birthday
self.first_send_date = first_send_date
self.last_send_date = last_send_date
self.caption = caption
self.caption_entities = caption_entities
self.message_id = message_id
self.date = date
self.first_sale_date = first_sale_date
self.last_sale_date = last_sale_date
self.from_user = from_user
self.price = price
self.convert_price = convert_price
self.upgrade_price = upgrade_price
self.transfer_price = transfer_price
self.upgrade_message_id = upgrade_message_id
self.title = title
self.number = number
self.attributes = attributes
self.available_amount = available_amount
self.total_amount = total_amount
self.can_upgrade = can_upgrade
self.can_export_at = can_export_at
self.is_limited = is_limited
self.is_name_hidden = is_name_hidden
self.is_saved = is_saved
self.is_sold_out = is_sold_out
self.is_converted = is_converted
self.is_upgraded = is_upgraded
self.is_refunded = is_refunded
self.is_transferred = is_transferred
self.is_birthday = is_birthday
@staticmethod
async def _parse(
@ -109,15 +208,229 @@ class Gift(Object):
return Gift(
id=star_gift.id,
sticker=await types.Sticker._parse(client, doc, attributes),
star_count=star_gift.stars,
default_sell_star_count=star_gift.convert_stars,
remaining_count=getattr(star_gift, "availability_remains", None),
total_count=getattr(star_gift, "availability_total", None),
first_send_date=utils.timestamp_to_datetime(getattr(star_gift, "first_sale_date", None)),
last_send_date=utils.timestamp_to_datetime(getattr(star_gift, "last_sale_date", None)),
price=star_gift.stars,
convert_price=star_gift.convert_stars,
upgrade_price=getattr(star_gift, "upgrade_stars", None),
available_amount=getattr(star_gift, "availability_remains", None),
total_amount=getattr(star_gift, "availability_total", None),
is_limited=getattr(star_gift, "limited", None),
is_sold_out=getattr(star_gift, "sold_out", None),
upgrade_star_count=getattr(star_gift, "upgrade_stars", 0),
is_for_birthday=getattr(star_gift, "birthday", None),
is_birthday=getattr(star_gift, "birthday", None),
first_sale_date=utils.timestamp_to_datetime(getattr(star_gift, "first_sale_date", None)),
last_sale_date=utils.timestamp_to_datetime(getattr(star_gift, "last_sale_date", None)),
client=client
)
@staticmethod
async def _parse_unique(
client,
star_gift: "raw.types.StarGiftUnique",
users
) -> "Gift":
return Gift(
id=star_gift.id,
title=star_gift.title,
number=star_gift.num,
attributes=types.List(
[await types.GiftAttribute._parse(client, attr, users) for attr in star_gift.attributes]
) or None,
available_amount=getattr(star_gift, "availability_issued", None),
total_amount=getattr(star_gift, "availability_total", None),
is_upgraded=True,
client=client
)
@staticmethod
async def _parse_user(
client,
user_star_gift: "raw.types.UserStarGift",
users: dict
) -> "Gift":
caption, caption_entities = (
utils.parse_text_with_entities(
client, getattr(user_star_gift, "message", None), users
)
).values()
if isinstance(user_star_gift.gift, raw.types.StarGift):
parsed_gift = await Gift._parse(client, user_star_gift.gift)
elif isinstance(user_star_gift.gift, raw.types.StarGiftUnique):
parsed_gift = await Gift._parse_unique(client, user_star_gift.gift, users)
parsed_gift.date = utils.timestamp_to_datetime(user_star_gift.date)
parsed_gift.is_name_hidden = getattr(user_star_gift, "name_hidden", None)
parsed_gift.is_saved = not user_star_gift.unsaved if getattr(user_star_gift, "unsaved", None) else None
parsed_gift.is_refunded = getattr(user_star_gift, "refunded", None)
parsed_gift.can_upgrade = getattr(user_star_gift, "can_upgrade", None)
parsed_gift.from_user = types.User._parse(client, users.get(user_star_gift.from_id))
parsed_gift.caption = caption
parsed_gift.caption_entities = caption_entities
parsed_gift.message_id = getattr(user_star_gift, "msg_id", None)
parsed_gift.convert_price = getattr(user_star_gift, "convert_stars", None)
parsed_gift.upgrade_price = getattr(user_star_gift, "upgrade_stars", None)
parsed_gift.transfer_price = getattr(user_star_gift, "transfer_stars", None)
parsed_gift.can_export_at = utils.timestamp_to_datetime(getattr(user_star_gift, "can_export_at", None))
return parsed_gift
@staticmethod
async def _parse_action(
client,
message: "raw.base.Message",
users: dict
) -> "Gift":
action = message.action # type: raw.types.MessageActionStarGift
if isinstance(action, raw.types.MessageActionStarGift):
parsed_gift = await Gift._parse(client, action.gift)
caption, caption_entities = (
utils.parse_text_with_entities(
client, getattr(action, "message", None), users
)
).values()
parsed_gift.is_name_hidden = getattr(action, "name_hidden", None)
parsed_gift.is_saved = getattr(action, "saved", None)
parsed_gift.is_converted = getattr(action, "converted", None)
parsed_gift.is_upgraded = getattr(action, "upgraded", None)
parsed_gift.is_refunded = getattr(action, "refunded", None)
parsed_gift.can_upgrade = getattr(action, "can_upgrade", None)
parsed_gift.caption = caption
parsed_gift.caption_entities = caption_entities
parsed_gift.convert_price = getattr(action, "convert_stars", None)
parsed_gift.upgrade_price = getattr(action, "upgrade_stars", None)
parsed_gift.upgrade_message_id = getattr(action, "upgrade_msg_id", None)
elif isinstance(action, raw.types.MessageActionStarGiftUnique):
parsed_gift = await Gift._parse_unique(client, action.gift, users)
parsed_gift.is_upgraded = getattr(action, "upgrade", None)
parsed_gift.is_transferred = getattr(action, "transferred", None)
parsed_gift.is_saved = getattr(action, "saved", None)
parsed_gift.is_refunded = getattr(action, "refunded", None)
parsed_gift.can_export_at = utils.timestamp_to_datetime(getattr(action, "can_export_at", None))
parsed_gift.transfer_price = getattr(action, "transfer_stars", None)
parsed_gift.date = utils.timestamp_to_datetime(message.date)
parsed_gift.from_user = types.User._parse(client, users.get(utils.get_raw_peer_id(message.peer_id)))
parsed_gift.message_id = message.id
return parsed_gift
async def show(self) -> bool:
"""Bound method *show* of :obj:`~pyrogram.types.Gift`.
Use as a shortcut for:
.. code-block:: python
await client.show_gift(
message_id=message_id
)
Example:
.. code-block:: python
await gift.show()
Returns:
``bool``: On success, True is returned.
"""
return await self._client.show_gift(
message_id=self.message_id
)
async def hide(self) -> bool:
"""Bound method *hide* of :obj:`~pyrogram.types.Gift`.
Use as a shortcut for:
.. code-block:: python
await client.hide_gift(
message_id=message_id
)
Example:
.. code-block:: python
await gift.hide()
Returns:
``bool``: On success, True is returned.
"""
return await self._client.hide_gift(
message_id=self.message_id
)
async def convert(self) -> bool:
"""Bound method *convert* of :obj:`~pyrogram.types.Gift`.
Use as a shortcut for:
.. code-block:: python
await client.convert_gift(
message_id=message_id
)
Example:
.. code-block:: python
await gift.convert()
Returns:
``bool``: On success, True is returned.
"""
return await self._client.convert_gift(
message_id=self.message_id
)
async def upgrade(self) -> bool:
"""Bound method *upgrade* of :obj:`~pyrogram.types.Gift`.
Use as a shortcut for:
.. code-block:: python
await client.upgrade_gift(
message_id=message_id
)
Example:
.. code-block:: python
await gift.upgrade()
Returns:
``bool``: On success, True is returned.
"""
return await self._client.upgrade_gift(
message_id=self.message_id
)
async def transfer(self, to_chat_id: Union[int, str]) -> bool:
"""Bound method *transfer* of :obj:`~pyrogram.types.Gift`.
Use as a shortcut for:
.. code-block:: python
await client.transfer_gift(
message_id=message_id,
to_chat_id=to_chat_id
)
Example:
.. code-block:: python
await gift.transfer(to_chat_id=123)
Returns:
``bool``: On success, True is returned.
"""
return await self._client.transfer_gift(
message_id=self.message_id,
to_chat_id=to_chat_id
)

View file

@ -0,0 +1,161 @@
# Pyrofork - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
# Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>
#
# This file is part of Pyrofork.
#
# Pyrofork 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.
#
# Pyrofork 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 Pyrofork. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import Optional, List
import pyrogram
from pyrogram import raw
from pyrogram import types
from pyrogram import enums
from pyrogram import utils
from ..object import Object
class GiftAttribute(Object):
"""Contains information about a star gift attribute.
Parameters:
type (:obj:`~pyrogram.enums.GiftAttributeType`):
Type of the attribute.
name (``str``, *optional*):
Name of the attribute.
rarity (``int``, *optional*):
Rarity of the attribute in permilles.
For example, 15 means 1.5%. So only 1.5% of such collectibles have this attribute.
date (``datetime``, *optional*):
Date when the gift was received.
Available only if the original details are available.
caption (``str``, *optional*):
Text message.
Available only if the original details are available.
caption_entities (List of :obj:`~pyrogram.types.MessageEntity`, *optional*):
For text messages, special entities like usernames, URLs, bot commands, etc. that appear in the text.
Available only if the original details are available.
from_user (:obj:`~pyrogram.types.User`, *optional*):
User who sent the gift.
Available only if the original details are available.
to_user (:obj:`~pyrogram.types.User`, *optional*):
User who received the gift.
Available only if the original details are available.
center_color (``int``, *optional*):
Center color of the gift in decimal format.
Available only if the backdrop attribute is available.
edge_color (``int``, *optional*):
Edge color of the gift in decimal format.
Available only if the backdrop attribute is available.
pattern_color (``int``, *optional*):
Pattern color of the gift in decimal format.
Available only if the backdrop attribute is available.
text_color (``int``, *optional*):
Text color of the gift in decimal format.
Available only if the backdrop attribute is available.
sticker (:obj:`~pyrogram.types.Sticker`, *optional*):
Information about the sticker.
"""
def __init__(
self,
*,
client: "pyrogram.Client" = None,
type: "enums.GiftAttributeType",
name: Optional[str] = None,
rarity: Optional[int] = None,
date: Optional[datetime] = None,
caption: Optional[str] = None,
caption_entities: Optional[List["types.MessageEntity"]] = None,
from_user: Optional["types.User"] = None,
to_user: Optional["types.User"] = None,
sticker: Optional["types.Sticker"] = None,
center_color: Optional[int] = None,
edge_color: Optional[int] = None,
pattern_color: Optional[int] = None,
text_color: Optional[int] = None
):
super().__init__(client)
self.name = name
self.type = type
self.rarity = rarity
self.date = date
self.caption = caption
self.caption_entities = caption_entities
self.from_user = from_user
self.to_user = to_user
self.sticker = sticker
self.center_color = center_color
self.edge_color = edge_color
self.pattern_color = pattern_color
self.text_color = text_color
@staticmethod
async def _parse(
client,
attr: "raw.base.StarGiftAttribute",
users
) -> "GiftAttribute":
caption = None
caption_entities = None
sticker = None
from_user = None
to_user = None
if hasattr(attr, "document"):
doc = attr.document
attributes = {type(i): i for i in doc.attributes}
sticker = await types.Sticker._parse(client, doc, attributes)
if isinstance(attr, raw.types.StarGiftAttributeOriginalDetails):
caption, caption_entities = (utils.parse_text_with_entities(
client, attr.message, users
)).values()
from_user = types.User._parse(client, users.get(attr.sender_id))
to_user = types.User._parse(client, users.get(attr.recipient_id))
return GiftAttribute(
name=getattr(attr, "name", None),
type=enums.GiftAttributeType(type(attr)),
rarity=getattr(attr, "rarity_permille", None),
date=utils.timestamp_to_datetime(getattr(attr, "date", None)),
caption=caption,
caption_entities=caption_entities,
from_user=from_user,
to_user=to_user,
sticker=sticker,
center_color=getattr(attr, "center_color", None),
edge_color=getattr(attr, "edge_color", None),
pattern_color=getattr(attr, "pattern_color", None),
text_color=getattr(attr, "text_color", None),
client=client
)

View file

@ -1,443 +0,0 @@
# Pyrofork - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
# Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>
#
# This file is part of Pyrofork.
#
# Pyrofork 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.
#
# Pyrofork 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 Pyrofork. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import Optional, List
import pyrogram
from pyrogram import raw
from pyrogram import types
from pyrogram import utils
from ..object import Object
class StarGift(Object):
"""A star gift.
Parameters:
id (``int``):
Unique star gift identifier.
sticker (:obj:`~pyrogram.types.Sticker`, *optional*):
Information about the star gift sticker.
caption (``str``, *optional*):
Text message.
caption_entities (List of :obj:`~pyrogram.types.MessageEntity`, *optional*):
For text messages, special entities like usernames, URLs, bot commands, etc. that appear in the text.
message_id (``int``, *optional*):
Unique message identifier.
upgrade_message_id (``int``, *optional*):
Unique message identifier.
For unique gifts only.
title (``str``, *optional*):
Title of the star gift.
For unique gifts only.
number (``int``, *optional*):
Collectible number of the star gift.
For unique gifts only.
model (:obj:`~pyrogram.types.StarGiftAttribute`, *optional*):
Information about the star gift model.
For unique gifts only.
backdrop (:obj:`~pyrogram.types.StarGiftAttribute`, *optional*):
Information about the star gift backdrop.
For unique gifts only.
symbol (:obj:`~pyrogram.types.StarGiftAttribute`, *optional*):
Information about the star gift symbol.
For unique gifts only.
date (``datetime``, *optional*):
Date when the star gift was received.
first_sale_date (``datetime``, *optional*):
Date when the star gift was first purchased.
last_sale_date (``datetime``, *optional*):
Date when the star gift was last purchased.
from_user (:obj:`~pyrogram.types.User`, *optional*):
User who sent the star gift.
price (``int``, *optional*):
Price of this gift in stars.
convert_price (``int``, *optional*):
The number of stars you get if you convert this gift.
upgrade_price (``int``, *optional*):
The number of stars you need to upgrade this gift.
transfer_price (``int``, *optional*):
The number of stars you need to transfer this gift.
available_amount (``int``, *optional*):
The number of gifts available for purchase.
Returned only if is_limited is True.
total_amount (``int``, *optional*):
Total amount of gifts.
Returned only if is_limited is True.
can_upgrade (``bool``, *optional*):
True, if the gift can be upgraded.
can_export_at (``datetime``, *optional*):
Date when the gift can be exported via blockchain.
is_limited (``bool``, *optional*):
True, if the number of gifts is limited.
is_name_hidden (``bool``, *optional*):
True, if the sender's name is hidden.
is_saved (``bool``, *optional*):
True, if the star gift is saved in profile.
is_sold_out (``bool``, *optional*):
True, if the star gift is sold out.
is_converted (``bool``, *optional*):
True, if the gift was converted to Telegram Stars.
Only for the receiver of the gift.
is_upgraded (``bool``, *optional*):
True, if the gift was upgraded.
is_refunded (``bool``, *optional*):
True, if the gift was refunded.
is_transferred (``bool``, *optional*):
True, if the gift was transferred.
is_unique (``bool``, *optional*):
True, if the gift is unique.
"""
def __init__(
self,
*,
client: "pyrogram.Client" = None,
id: int,
sticker: "types.Sticker" = None,
caption: Optional[str] = None,
caption_entities: List["types.MessageEntity"] = None,
message_id: Optional[int] = None,
date: Optional[datetime] = None,
first_sale_date: Optional[datetime] = None,
last_sale_date: Optional[datetime] = None,
from_user: Optional["types.User"] = None,
price: Optional[int] = None,
convert_price: Optional[int] = None,
upgrade_price: Optional[int] = None,
transfer_price: Optional[int] = None,
upgrade_message_id: Optional[int] = None,
title: Optional[str] = None,
number: Optional[int] = None,
model: Optional["types.StarGiftAttribute"] = None,
backdrop: Optional["types.StarGiftAttribute"] = None,
symbol: Optional["types.StarGiftAttribute"] = None,
available_amount: Optional[int] = None,
total_amount: Optional[int] = None,
can_upgrade: Optional[bool] = None,
can_export_at: Optional[datetime] = None,
is_limited: Optional[bool] = None,
is_name_hidden: Optional[bool] = None,
is_saved: Optional[bool] = None,
is_sold_out: Optional[bool] = None,
is_converted: Optional[bool] = None,
is_upgraded: Optional[bool] = None,
is_refunded: Optional[bool] = None,
is_transferred: Optional[bool] = None,
is_unique: Optional[bool] = None
):
super().__init__(client)
self.id = id
self.sticker = sticker
self.caption = caption
self.caption_entities = caption_entities
self.message_id = message_id
self.date = date
self.first_sale_date = first_sale_date
self.last_sale_date = last_sale_date
self.from_user = from_user
self.price = price
self.convert_price = convert_price
self.upgrade_price = upgrade_price
self.transfer_price = transfer_price
self.upgrade_message_id = upgrade_message_id
self.title = title
self.number = number
self.model = model
self.backdrop = backdrop
self.symbol = symbol
self.available_amount = available_amount
self.total_amount = total_amount
self.can_upgrade = can_upgrade
self.can_export_at = can_export_at
self.is_limited = is_limited
self.is_name_hidden = is_name_hidden
self.is_saved = is_saved
self.is_sold_out = is_sold_out
self.is_converted = is_converted
self.is_upgraded = is_upgraded
self.is_refunded = is_refunded
self.is_transferred = is_transferred
self.is_unique = is_unique
@staticmethod
async def _parse(
client,
star_gift: "raw.types.StarGift",
) -> "StarGift":
doc = star_gift.sticker
attributes = {type(i): i for i in doc.attributes}
return StarGift(
id=star_gift.id,
sticker=await types.Sticker._parse(client, doc, attributes),
price=star_gift.stars,
convert_price=star_gift.convert_stars,
available_amount=getattr(star_gift, "availability_remains", None),
total_amount=getattr(star_gift, "availability_total", None),
is_limited=getattr(star_gift, "limited", None),
first_sale_date=utils.timestamp_to_datetime(getattr(star_gift, "first_sale_date", None)),
last_sale_date=utils.timestamp_to_datetime(getattr(star_gift, "last_sale_date", None)),
is_sold_out=getattr(star_gift, "sold_out", None),
client=client
)
@staticmethod
async def _parse_user_star_gift(
client,
user_star_gift: "raw.types.UserStarGift",
users: dict
) -> "StarGift":
caption, caption_entities = (
utils.parse_text_with_entities(
client, getattr(user_star_gift, "message", None), users
)
).values()
if isinstance(user_star_gift.gift, raw.types.StarGift):
doc = user_star_gift.gift.sticker
attributes = {type(i): i for i in doc.attributes}
return StarGift(
id=user_star_gift.gift.id,
sticker=await types.Sticker._parse(client, doc, attributes),
price=user_star_gift.gift.stars,
convert_price=user_star_gift.gift.convert_stars,
available_amount=getattr(user_star_gift.gift, "availability_remains", None),
total_amount=getattr(user_star_gift.gift, "availability_total", None),
date=utils.timestamp_to_datetime(user_star_gift.date),
is_limited=getattr(user_star_gift.gift, "limited", None),
is_name_hidden=getattr(user_star_gift, "name_hidden", None),
is_saved=not user_star_gift.unsaved if getattr(user_star_gift, "unsaved", None) else None,
is_refunded=getattr(user_star_gift, "refunded", None),
can_upgrade=getattr(user_star_gift, "can_upgrade", None),
can_export_at=utils.timestamp_to_datetime(getattr(user_star_gift, "can_export_at", None)),
upgrade_price=getattr(user_star_gift, "upgrade_stars", None),
transfer_price=getattr(user_star_gift, "transfer_stars", None),
from_user=types.User._parse(client, users.get(user_star_gift.from_id)) if getattr(user_star_gift, "from_id", None) else None,
message_id=getattr(user_star_gift, "msg_id", None),
caption=caption,
caption_entities=caption_entities,
client=client
)
elif isinstance(user_star_gift.gift, raw.types.StarGiftUnique):
gift = user_star_gift.gift
attributes = {type(i): i for i in gift.attributes}
model = None
backdrop = None
symbol = None
for key, value in attributes.items():
if isinstance(key, raw.types.StarGiftAttributeModel):
model = await types.StarGiftAttribute._parse(client, value)
elif isinstance(key, raw.types.StarGiftAttributeBackdrop):
backdrop = await types.StarGiftAttribute._parse(client, value)
elif isinstance(key, raw.types.StarGiftAttributePattern):
symbol = await types.StarGiftAttribute._parse(client, value)
return StarGift(
id=user_star_gift.gift.id,
available_amount=getattr(user_star_gift.gift, "availability_issued", None),
total_amount=getattr(user_star_gift.gift, "availability_total", None),
date=utils.timestamp_to_datetime(user_star_gift.date),
model=model,
backdrop=backdrop,
symbol=symbol,
title=gift.title,
number=gift.num,
is_unique=True,
is_name_hidden=getattr(user_star_gift, "name_hidden", None),
is_saved=not user_star_gift.unsaved if getattr(user_star_gift, "unsaved", None) else None,
is_refunded=getattr(user_star_gift, "refunded", None),
can_upgrade=getattr(user_star_gift, "can_upgrade", None),
can_export_at=utils.timestamp_to_datetime(getattr(user_star_gift, "can_export_at", None)),
upgrade_price=getattr(user_star_gift, "upgrade_stars", None),
transfer_price=getattr(user_star_gift, "transfer_stars", None),
from_user=types.User._parse(client, users.get(user_star_gift.from_id)) if getattr(user_star_gift, "from_id", None) else None,
message_id=getattr(user_star_gift, "msg_id", None),
caption=caption,
caption_entities=caption_entities,
client=client
)
@staticmethod
async def _parse_action(
client,
message: "raw.base.Message",
users: dict
) -> "StarGift":
action = message.action # type: raw.types.MessageActionStarGift
caption, caption_entities = (
utils.parse_text_with_entities(
client, getattr(action, "message", None), users
)
).values()
if isinstance(action, raw.types.MessageActionStarGift):
doc = action.gift.sticker
attributes = {type(i): i for i in doc.attributes}
return StarGift(
id=action.gift.id,
sticker=await types.Sticker._parse(client, doc, attributes),
price=action.gift.stars,
convert_price=action.gift.convert_stars,
available_amount=getattr(action.gift, "availability_remains", None),
total_amount=getattr(action.gift, "availability_total", None),
date=utils.timestamp_to_datetime(message.date),
can_upgrade=getattr(action, "can_upgrade", None),
is_limited=getattr(action.gift, "limited", None),
is_name_hidden=getattr(action, "name_hidden", None),
is_saved=getattr(action, "saved", None),
is_converted=getattr(action, "converted", None),
is_upgraded=getattr(action, "upgraded", None),
is_refunded=getattr(action, "refunded", None),
from_user=types.User._parse(client, users.get(utils.get_raw_peer_id(message.peer_id))),
message_id=message.id,
upgrade_message_id=getattr(action, "upgrade_msg_id", None),
upgrade_price=getattr(action, "upgrade_stars", None),
caption=caption,
caption_entities=caption_entities,
client=client
)
elif isinstance(action, raw.types.MessageActionStarGiftUnique):
gift = action.gift
attributes = {type(i): i for i in gift.attributes}
model = None
backdrop = None
symbol = None
for key, value in attributes.items():
if key is raw.types.StarGiftAttributeModel:
model = await types.StarGiftAttribute._parse(client, value)
elif key is raw.types.StarGiftAttributeBackdrop:
backdrop = await types.StarGiftAttribute._parse(client, value, True)
elif key is raw.types.StarGiftAttributePattern:
symbol = await types.StarGiftAttribute._parse(client, value)
return StarGift(
id=action.gift.id,
available_amount=getattr(action.gift, "availability_issued", None),
total_amount=getattr(action.gift, "availability_total", None),
date=utils.timestamp_to_datetime(message.date),
is_unique=True,
from_user=types.User._parse(client, users.get(utils.get_raw_peer_id(message.peer_id))),
message_id=message.id,
caption=caption,
caption_entities=caption_entities,
title=gift.title,
number=gift.num,
model=model,
backdrop=backdrop,
symbol=symbol,
is_upgraded=getattr(action, "upgrade", None),
is_transferred=getattr(action, "transferred", None),
is_saved=getattr(action, "saved", None),
is_refunded=getattr(action, "refunded", None),
can_export_at=utils.timestamp_to_datetime(getattr(action, "can_export_at", None)),
transfer_price=getattr(action, "transfer_stars", None),
client=client
)
async def show(self) -> bool:
"""Bound method *show* of :obj:`~pyrogram.types.StarGift`.
Use as a shortcut for:
.. code-block:: python
await client.show_star_gift(
chat_id=message.chat.id,
message_id=message_id
)
Example:
.. code-block:: python
await star_gift.show()
Returns:
``bool``: On success, True is returned.
"""
return await self._client.show_star_gift(
chat_id=self.from_user.id,
message_id=self.message_id
)
async def hide(self) -> bool:
"""Bound method *hide* of :obj:`~pyrogram.types.StarGift`.
Use as a shortcut for:
.. code-block:: python
await client.hide_star_gift(
chat_id=message.chat.id,
message_id=message_id
)
Example:
.. code-block:: python
await star_gift.hide()
Returns:
``bool``: On success, True is returned.
"""
return await self._client.hide_star_gift(
chat_id=self.from_user.id,
message_id=self.message_id
)

View file

@ -1,84 +0,0 @@
# Pyrofork - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
# Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>
#
# This file is part of Pyrofork.
#
# Pyrofork 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.
#
# Pyrofork 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 Pyrofork. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import Optional, List
import pyrogram
from pyrogram import raw
from pyrogram import types
from pyrogram import enums
from pyrogram import utils
from ..object import Object
class StarGiftAttribute(Object):
"""Contains information about a star gift attribute.
Parameters:
name (``str``):
Name of the attribute.
type (:obj:`~pyrogram.enums.StarGiftAttributeType`):
Type of the attribute.
rarity (``int``):
Rarity of the attribute in permilles.
For example, 15 means 1.5%. So only 1.5% of such collectibles have this attribute.
sticker (:obj:`~pyrogram.types.Sticker`):
Information about the sticker.
"""
def __init__(
self,
*,
client: "pyrogram.Client" = None,
name: str,
type: "enums.StarGiftAttributeType",
rarity: int,
sticker: "types.Sticker",
):
super().__init__(client)
self.name = name
self.type = type
self.rarity = rarity
self.sticker = sticker
# TODO: Add support for raw.types.StarGiftAttributeOriginalDetails
@staticmethod
async def _parse(
client,
attr: "raw.base.StarGiftAttribute",
backdrop: bool = False,
) -> "StarGiftAttribute":
sticker = None
if not backdrop:
doc = attr.document
attributes = {type(i): i for i in doc.attributes}
sticker = await types.Sticker._parse(client, doc, attributes)
return StarGiftAttribute(
name=attr.name,
type=enums.StarGiftAttributeType(type(attr)),
sticker=sticker,
rarity=attr.rarity_permille,
client=client
)