pyrofork: Add search_gifts_for_resale, send_resold_gift, set_gift_resale_price, set_pinned_gifts methods

Co-authored-by: "ALi.w" <aminnimaj@gmail.com>
Signed-off-by: wulan17 <wulan17@komodos.id>
This commit is contained in:
KurimuzonAkuma 2025-06-10 21:49:47 +07:00 committed by wulan17
parent 3d343a49ff
commit 78467e30a2
No known key found for this signature in database
GPG key ID: 737814D4B5FF0420
9 changed files with 433 additions and 0 deletions

View file

@ -365,11 +365,15 @@ def pyrogram_api():
get_chat_gifts
hide_gift
refund_star_payment
search_gifts_for_resale
send_invoice
send_paid_media
send_paid_reaction
send_payment_form
send_gift
send_resold_gift
set_gift_resale_price
set_pinned_gift
show_gift
transfer_gift
upgrade_gift

View file

@ -0,0 +1,8 @@
GiftAttributeType
=================
.. autoclass:: pyrogram.enums.GiftForResaleOrder()
:members:
.. raw:: html
:file: ./cleanup.html

View file

@ -27,6 +27,7 @@ from .chat_type import ChatType
from .client_platform import ClientPlatform
from .folder_color import FolderColor
from .gift_attribute_type import GiftAttributeType
from .gift_for_resale_order import GiftForResaleOrder
from .listerner_types import ListenerTypes
from .message_entity_type import MessageEntityType
from .message_media_type import MessageMediaType
@ -55,6 +56,7 @@ __all__ = [
'ClientPlatform',
'FolderColor',
'GiftAttributeType',
'GiftForResaleOrder',
'ListenerTypes',
'MessageEntityType',
'MessageMediaType',

View file

@ -0,0 +1,35 @@
# 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 enum import auto
from .auto_name import AutoName
class GiftForResaleOrder(AutoName):
"""Describes order in which upgraded gifts for resale will be sorted. Used in :meth:`~pyrogram.Client.search_gifts_for_resale`."""
PRICE = auto()
"The gifts will be sorted by their price from the lowest to the highest"
CHANGE_DATE = auto()
"The gifts will be sorted by the last date when their price was changed from the newest to the oldest"
NUMBER = auto()
"The gifts will be sorted by their number from the smallest to the largest"

View file

@ -31,11 +31,15 @@ from .get_chat_gifts_count import GetChatGiftsCount
from .get_chat_gifts import GetChatGifts
from .hide_gift import HideGift
from .refund_stars_payment import RefundStarPayment
from .search_gifts_for_resale import SearchGiftsForResale
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_gift import SendGift
from .send_resold_gift import SendResoldGift
from .set_gift_resale_price import SetGiftResalePrice
from .set_pinned_gift import SetPinnedGift
from .show_gift import ShowGift
from .transfer_gift import TransferGift
from .upgrade_gift import UpgradeGift
@ -55,11 +59,15 @@ class Payments(
GetChatGifts,
HideGift,
RefundStarPayment,
SearchGiftsForResale,
SendPaidReaction,
SendPaidMedia,
SendInvoice,
SendPaymentForm,
SendGift,
SendResoldGift,
SetGiftResalePrice,
SetPinnedGift,
ShowGift,
TransferGift,
UpgradeGift

View file

@ -0,0 +1,110 @@
# 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 typing import List, Optional
import pyrogram
from pyrogram import enums, raw, types
class SearchGiftsForResale:
async def search_gifts_for_resale(
self: "pyrogram.Client",
gift_id: int,
order: "enums.GiftForResaleOrder" = enums.GiftForResaleOrder.CHANGE_DATE,
attributes: Optional[List["types.UpgradedGiftAttributeId"]] = None,
limit: int = 0,
offset: str = ""
):
"""Get upgraded gifts that can be bought from other owners.
.. include:: /_includes/usable-by/users.rst
Parameters:
gift_id (``int``):
Identifier of the regular gift that was upgraded to a unique gift.
order (:obj:`~pyrogram.enums.GiftForResaleOrder`):
Order in which the results will be sorted.
attributes (List of :obj:`~pyrogram.types.UpgradedGiftAttributeId`, *optional*):
Attributes used to filter received gifts.
If multiple attributes of the same type are specified, then all of them are allowed.
If none attributes of specific type are specified, then all values for this attribute type are allowed.
limit (``int``, *optional*):
The maximum number of gifts to return. Default is 0 (no limit).
offset (``str``, *optional*):
The offset from which to start returning results. Default is "" (no offset).
Returns:
``Generator``: A generator yielding :obj:`~pyrogram.types.Gift` objects.
Example:
.. code-block:: python
async for gift in app.search_gifts_for_resale(gift_id=123456):
print(gift)
# Buy first gift from resale market
async for gift in app.search_gifts_for_resale(gift_id=123456, limit=1):
await app.send_resold_gift(gift_link=gift.link, new_owner_chat_id="me") # or just use await gift.buy()
"""
current = 0
total = abs(limit) or (1 << 31) - 1
limit = min(100, total)
while True:
r = await self.invoke(
raw.functions.payments.GetResaleStarGifts(
gift_id=gift_id,
offset=offset,
limit=limit,
sort_by_price=order == enums.GiftForResaleOrder.PRICE,
sort_by_num=order == enums.GiftForResaleOrder.NUMBER,
attributes=[attr.write() for attr in attributes] if attributes else None,
),
sleep_threshold=60
)
users = {i.id: i for i in r.users}
chats = {i.id: i for i in r.chats}
gifts = [
await types.Gift._parse(self, gift, users, chats)
for gift in r.gifts
]
if not gifts:
return
for gift in gifts:
yield gift
current += 1
if current >= total:
return
offset = r.next_offset
if not offset:
return

View file

@ -0,0 +1,89 @@
# 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 typing import Optional, Union
import pyrogram
from pyrogram import raw, types, utils
class SendResoldGift:
async def send_resold_gift(
self: "pyrogram.Client",
gift_link: str,
new_owner_chat_id: Union[int, str],
) -> Optional["types.Message"]:
"""Send an upgraded gift that is available for resale to another user or channel chat.
.. note::
Gifts already owned by the current user must be transferred using :meth:`~pyrogram.Client.transfer_gift` and can't be passed to this method.
.. include:: /_includes/usable-by/users.rst
Parameters:
gift_link (``str``):
Link to the gift.
new_owner_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).
Returns:
:obj:`~pyrogram.types.Message`: On success, the sent message is returned.
Example:
.. code-block:: python
# Transfer gift to another user
await app.send_resold_gift(gift_link="https://t.me/nft/NekoHelmet-9215", new_owner_chat_id=123)
"""
match = self.UPGRADED_GIFT_RE.match(gift_link)
if not match:
raise ValueError(
"Invalid gift link provided."
)
peer = await self.resolve_peer(new_owner_chat_id)
invoice = raw.types.InputInvoiceStarGiftResale(
slug=match.group(1),
to_id=peer
)
r = await self.invoke(
raw.functions.payments.SendStarsForm(
form_id=(await self.invoke(
raw.functions.payments.GetPaymentForm(
invoice=invoice
),
)).form_id,
invoice=invoice
),
)
messages = await utils.parse_messages(
client=self,
messages=r.updates if isinstance(r, raw.types.payments.PaymentResult) else r
)
return messages[0] if messages else None

View file

@ -0,0 +1,82 @@
# 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/>.
import re
import pyrogram
from pyrogram import raw
class SetGiftResalePrice:
async def set_gift_resale_price(
self: "pyrogram.Client",
owned_gift_id: str,
resale_star_count: int
) -> bool:
"""Change resale price of a unique gift owned by the current user.
.. include:: /_includes/usable-by/users.rst
Parameters:
owned_gift_id (``str``):
Unique identifier of the target gift.
For a user gift, you can use the message ID (int) of the gift message.
For a channel gift, you can use the packed format `chatID_savedID` (str).
For a upgraded gift, you can use the gift link.
resale_star_count (``int``):
The new price for the unique gift. Pass 0 to disallow gift resale.
Returns:
``bool``: On success, True is returned.
Example:
.. code-block:: python
# Change resale price of a unique gift
await app.set_gift_resale_price(owned_gift_id="123456", resale_star_count=100)
"""
if not isinstance(owned_gift_id, str):
raise ValueError(f"owned_gift_id has to be str, but {type(owned_gift_id)} was provided")
saved_gift_match = re.match(r"^(-\d+)_(\d+)$", owned_gift_id)
slug_match = self.UPGRADED_GIFT_RE.match(owned_gift_id)
if saved_gift_match:
stargift = raw.types.InputSavedStarGiftChat(
peer=await self.resolve_peer(saved_gift_match.group(1)),
saved_id=int(saved_gift_match.group(2))
)
elif slug_match:
stargift = raw.types.InputSavedStarGiftSlug(
slug=slug_match.group(1)
)
else:
stargift = raw.types.InputSavedStarGiftUser(
msg_id=int(owned_gift_id)
)
await self.invoke(
raw.functions.payments.UpdateStarGiftPrice(
stargift=stargift,
resell_stars=resale_star_count
)
)
return True

View file

@ -0,0 +1,95 @@
# 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/>.
import re
from typing import List, Union
import pyrogram
from pyrogram import raw
class SetPinnedGifts:
async def set_pinned_gifts(
self: "pyrogram.Client",
owner_id: Union[int, str],
owned_gift_ids: List[str],
) -> bool:
"""Change the list of pinned gifts on the current user.
.. include:: /_includes/usable-by/users.rst
Parameters:
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).
owned_gift_ids (List of ``str``):
New list of pinned gifts.
All gifts must be upgraded and saved on the profile page first.
For a user gift, you can use the message ID (int) of the gift message.
For a channel gift, you can use the packed format `chatID_savedID` (str).
For a upgraded gift, you can use the gift link.
Returns:
``bool``: On success, True is returned.
Example:
.. code-block:: python
# Set pinned gifts in user profile
await app.set_pinned_gifts(received_gift_ids=["123", "456"])
"""
stargifts = []
for gift in owned_gift_ids:
if not isinstance(gift, str):
raise ValueError(f"gift id has to be str, but {type(gift)} was provided")
saved_gift_match = re.match(r"^(-\d+)_(\d+)$", gift)
slug_match = self.UPGRADED_GIFT_RE.match(gift)
if saved_gift_match:
stargifts.append(
raw.types.InputSavedStarGiftChat(
peer=await self.resolve_peer(saved_gift_match.group(1)),
saved_id=int(saved_gift_match.group(2))
)
)
elif slug_match:
stargifts.append(
raw.types.InputSavedStarGiftSlug(
slug=slug_match.group(1)
)
)
else:
stargifts.append(
raw.types.InputSavedStarGiftUser(
msg_id=int(gift)
)
)
r = await self.invoke(
raw.functions.payments.ToggleStarGiftsPinnedToTop(
peer=await self.resolve_peer(owner_id),
stargift=stargifts
)
)
return r