Add new apply_gift_code, check_gift_code, get_payment_form, and send_payment_form methods

Signed-off-by: wulan17 <wulan17@nusantararom.org>
This commit is contained in:
KurimuzonAkuma 2024-04-05 12:11:20 +03:00 committed by wulan17
parent 4e823b153e
commit b152bd9c84
No known key found for this signature in database
GPG key ID: 318CD6CD3A6AC0A5
11 changed files with 605 additions and 4 deletions

View file

@ -345,6 +345,13 @@ def pyrogram_api():
get_contacts get_contacts
get_contacts_count get_contacts_count
""", """,
payments="""
Payments
apply_gift_code
check_gift_code
get_payment_form
send_payment_form
""",
password=""" password="""
Password Password
enable_cloud_password enable_cloud_password
@ -537,7 +544,6 @@ def pyrogram_api():
ChatTheme ChatTheme
ChatWallpaper ChatWallpaper
ContactRegistered ContactRegistered
GiftCode
ReadParticipant ReadParticipant
ScreenshotTaken ScreenshotTaken
Wallpaper Wallpaper
@ -557,6 +563,12 @@ def pyrogram_api():
InputMediaArea InputMediaArea
InputMediaAreaChannelPost InputMediaAreaChannelPost
""", """,
payment="""
Payment
GiftCode
CheckedGiftCode
PaymentForm
""",
pyromod=""" pyromod="""
Pyromod Pyromod
Identifier Identifier

View file

@ -28,6 +28,7 @@ from .messages import Messages
from .password import Password from .password import Password
from .pyromod import Pyromod from .pyromod import Pyromod
from .stickers import Stickers from .stickers import Stickers
from .payments import Payments
from .users import Users from .users import Users
from .utilities import Utilities from .utilities import Utilities
from .business import TelegramBusiness from .business import TelegramBusiness
@ -40,6 +41,7 @@ class Methods(
Contacts, Contacts,
Password, Password,
Pyromod, Pyromod,
Payments,
Chats, Chats,
Stickers, Stickers,
Users, Users,

View file

@ -1,6 +1,3 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
#
# Pyrofork - 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) 2017-present Dan <https://github.com/delivrance>
# Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan> # Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>

View file

@ -0,0 +1,31 @@
# 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 .apply_gift_code import ApplyGiftCode
from .check_giftcode import CheckGiftCode
from .get_payment_form import GetPaymentForm
from .send_payment_form import SendPaymentForm
class Payments(
ApplyGiftCode,
CheckGiftCode,
GetPaymentForm,
SendPaymentForm
):
pass

View file

@ -0,0 +1,54 @@
# 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 ApplyGiftCode:
async def apply_gift_code(
self: "pyrogram.Client",
link: str,
) -> bool:
"""Apply a gift code.
.. include:: /_includes/usable-by/users.rst
Parameters:
link (``str``):
The gift code link.
Returns:
``bool``: On success, True is returned.
Raises:
ValueError: In case the gift code link is invalid.
Example:
.. code-block:: python
# apply a gift code
app.apply_gift_code("t.me/giftcode/abc1234567def")
"""
match = re.match(r"^(?:https?://)?(?:www\.)?(?:t(?:elegram)?\.(?:org|me|dog)/(?:giftcode/|\+))([\w-]+)$", link)
if match:
slug = match.group(1)
elif isinstance(link, str):
slug = link
else:
raise ValueError("Invalid gift code link")
await self.invoke(
raw.functions.payments.ApplyGiftCode(
slug=slug
)
)
return True

View file

@ -0,0 +1,69 @@
# 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, types
class CheckGiftCode:
async def check_gift_code(
self: "pyrogram.Client",
link: str,
) -> "types.CheckedGiftCode":
"""Get information about a gift code.
.. include:: /_includes/usable-by/users.rst
Parameters:
link (``str``):
The gift code link.
Returns:
:obj:`~pyrogram.types.CheckedGiftCode`: On success, a checked gift code is returned.
Raises:
ValueError: In case the gift code link is invalid.
Example:
.. code-block:: python
# get information about a gift code
app.check_gift_code("t.me/giftcode/abc1234567def")
"""
match = re.match(r"^(?:https?://)?(?:www\.)?(?:t(?:elegram)?\.(?:org|me|dog)/(?:giftcode/|\+))([\w-]+)$", link)
if match:
slug = match.group(1)
elif isinstance(link, str):
slug = link
else:
raise ValueError("Invalid gift code link")
r = await self.invoke(
raw.functions.payments.CheckGiftCode(
slug=slug
)
)
users = {i.id: i for i in r.users}
chats = {i.id: i for i in r.chats}
return types.CheckedGiftCode._parse(self, r, users, chats)

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/>.
import re
from typing import Union
import pyrogram
from pyrogram import raw, types
class GetPaymentForm:
async def get_payment_form(
self: "pyrogram.Client", *,
chat_id: Union[int, str] = None,
message_id: int = None,
invoice_link: str = None
) -> "types.PaymentForm":
"""Get information about a invoice or paid media.
.. include:: /_includes/usable-by/users.rst
Parameters:
chat_id (``int`` | ``str``):
Unique identifier (int) or username (str) of the target chat.
of the target channel/supergroup (in the format @username).
message_id (``int``):
Pass a message identifier or to get the invoice from message.
invoice_link (``str``):
Pass a invoice link in form of a *t.me/$...* link or slug itself to get the payment form from link.
Returns:
:obj:`~pyrogram.types.PaymentForm`: On success, a payment form is returned.
Example:
.. code-block:: python
# get payment form from message
app.get_payment_form(chat_id=chat_id, message_id=123)
# get payment form from link
app.get_payment_form(invoice_link="https://t.me/$xvbzUtt5sUlJCAAATqZrWRy9Yzk")
"""
if not any((all((chat_id, message_id)), invoice_link)):
raise ValueError("You should pass at least one parameter to this method.")
invoice = None
if message_id:
invoice = raw.types.InputInvoiceMessage(
peer=await self.resolve_peer(chat_id),
msg_id=message_id
)
elif invoice_link:
match = re.match(r"^(?:https?://)?(?:www\.)?(?:t(?:elegram)?\.(?:org|me|dog)/\$)([\w-]+)$", invoice_link)
if match:
slug = match.group(1)
else:
slug = invoice_link
invoice = raw.types.InputInvoiceSlug(
slug=slug
)
r = await self.invoke(
raw.functions.payments.GetPaymentForm(
invoice=invoice
)
)
return types.PaymentForm._parse(self, r)

View file

@ -0,0 +1,133 @@
# 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 Union, List
import pyrogram
from pyrogram import raw, types
class SendPaymentForm:
async def send_payment_form(
self: "pyrogram.Client", *,
chat_id: Union[int, str] = None,
message_id: int = None,
invoice_link: str = None
) -> List[Union["types.Photo", "types.Video"]]:
"""Pay an invoice.
.. note::
For now only stars invoices are supported.
.. include:: /_includes/usable-by/users.rst
Parameters:
chat_id (``int`` | ``str``):
Unique identifier (int) or username (str) of the target chat.
of the target channel/supergroup (in the format @username).
message_id (``int``):
Pass a message identifier or to get the invoice from message.
invoice_link (``str``):
Pass a invoice link in form of a *t.me/$...* link or slug itself to pay this invoice.
Returns:
List of :obj:`~pyrogram.types.Photo` | :obj:`~pyrogram.types.Video`: On success, the list of bought photos and videos is returned.
Example:
.. code-block:: python
# Pay invoice from message
app.send_payment_form(chat_id=chat_id, message_id=123)
# Pay invoice form from link
app.send_payment_form(invoice_link="https://t.me/$xvbzUtt5sUlJCAAATqZrWRy9Yzk")
"""
if not any((all((chat_id, message_id)), invoice_link)):
raise ValueError("You should pass at least one parameter to this method.")
form = None
invoice = None
if message_id:
invoice = raw.types.InputInvoiceMessage(
peer=await self.resolve_peer(chat_id),
msg_id=message_id
)
elif invoice_link:
match = re.match(r"^(?:https?://)?(?:www\.)?(?:t(?:elegram)?\.(?:org|me|dog)/\$)([\w-]+)$", invoice_link)
if match:
slug = match.group(1)
else:
slug = invoice_link
invoice = raw.types.InputInvoiceSlug(
slug=slug
)
form = await self.get_payment_form(chat_id=chat_id, message_id=message_id, invoice_link=invoice_link)
# if form.invoice.currency == "XTR":
r = await self.invoke(
raw.functions.payments.SendStarsForm(
form_id=form.id,
invoice=invoice
)
)
# TODO: Add support for regular invoices (credentials)
# else:
# r = await self.invoke(
# raw.functions.payments.SendPaymentForm(
# form_id=form.id,
# invoice=invoice,
# credentials=raw.types.InputPaymentCredentials(data=raw.types.DataJSON(data={}))
# )
# )
medias = []
if isinstance(r, raw.types.payments.PaymentResult):
for i in r.updates.updates:
if isinstance(i, raw.types.UpdateMessageExtendedMedia):
for ext_media in i.extended_media:
media = ext_media.media
if isinstance(media, raw.types.MessageMediaPhoto):
medias.append(types.Photo._parse(self, media.photo))
elif isinstance(media, raw.types.MessageMediaDocument):
doc = media.document
attributes = {type(i): i for i in doc.attributes}
file_name = getattr(
attributes.get(
raw.types.DocumentAttributeFilename, None
), "file_name", None
)
video_attributes = attributes[raw.types.DocumentAttributeVideo]
medias.append(types.Video._parse(self, doc, video_attributes, file_name))
return types.List(medias)
# elif isinstance(r, raw.types.payments.PaymentVerificationNeeded):

View file

@ -22,6 +22,7 @@ from .audio import Audio
from .available_effect import AvailableEffect from .available_effect import AvailableEffect
from .chat_theme import ChatTheme from .chat_theme import ChatTheme
from .chat_wallpaper import ChatWallpaper from .chat_wallpaper import ChatWallpaper
from .checked_gift_code import CheckedGiftCode
from .contact import Contact from .contact import Contact
from .contact_registered import ContactRegistered from .contact_registered import ContactRegistered
from .dice import Dice from .dice import Dice
@ -39,6 +40,7 @@ from .media_area_channel_post import MediaAreaChannelPost
from .media_area_coordinates import MediaAreaCoordinates from .media_area_coordinates import MediaAreaCoordinates
from .message import Message from .message import Message
from .message_entity import MessageEntity from .message_entity import MessageEntity
from .payment_form import PaymentForm
from .photo import Photo from .photo import Photo
from .poll import Poll from .poll import Poll
from .poll_option import PollOption from .poll_option import PollOption
@ -84,6 +86,7 @@ __all__ = [
"Document", "Document",
"Game", "Game",
"GiftCode", "GiftCode",
"CheckedGiftCode",
"GiftedPremium", "GiftedPremium",
"Giveaway", "Giveaway",
"GiveawayLaunched", "GiveawayLaunched",
@ -95,6 +98,7 @@ __all__ = [
"MediaAreaCoordinates", "MediaAreaCoordinates",
"Message", "Message",
"MessageEntity", "MessageEntity",
"PaymentForm",
"Photo", "Photo",
"Thumbnail", "Thumbnail",
"StrippedThumbnail", "StrippedThumbnail",

View file

@ -0,0 +1,93 @@
# 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 pyrogram import raw, types, utils
from ..object import Object
class CheckedGiftCode(Object):
"""Contains checked gift code data.
Parameters:
date (:py:obj:`~datetime.datetime`):
Date when the giveaway was launched.
months (``int``):
Number of months of subscription.
via_giveaway (``bool``, *optional*):
True if the gift code is received via giveaway.
from_chat (:obj:`~pyrogram.types.Chat`, *optional*):
The channel where the gift code was won.
winner (:obj:`~pyrogram.types.User`, *optional*):
The user who won the giveaway.
giveaway_message_id (``int``, *optional*):
Identifier of the message from chat where the giveaway was launched.
used_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the gift code was used.
"""
def __init__(
self,
*,
date: datetime,
months: int,
via_giveaway: bool = None,
from_chat: "types.Chat" = None,
winner: "types.User" = None,
giveaway_message_id: int = None,
used_date: datetime = None
):
super().__init__()
self.date = date
self.months = months
self.via_giveaway = via_giveaway
self.from_chat = from_chat
self.winner = winner
self.giveaway_message_id = giveaway_message_id
self.used_date = used_date
@staticmethod
def _parse(client, checked_gift_code: "raw.types.payments.CheckedGiftCode", users, chats):
from_chat = None
winner = None
if getattr(checked_gift_code, "from_id", None):
from_chat = types.Chat._parse_chat(
client, chats.get(utils.get_raw_peer_id(checked_gift_code.from_id))
)
if getattr(checked_gift_code, "to_id", None):
winner = types.User._parse(client, users.get(checked_gift_code.to_id))
return CheckedGiftCode(
date=utils.timestamp_to_datetime(checked_gift_code.date),
months=checked_gift_code.months,
via_giveaway=getattr(checked_gift_code, "via_giveaway", None),
from_chat=from_chat,
winner=winner,
giveaway_message_id=getattr(checked_gift_code, "giveaway_msg_id", None),
used_date=utils.timestamp_to_datetime(checked_gift_code.used_date) if getattr(checked_gift_code, "used_date") else None,
)

View file

@ -0,0 +1,117 @@
# 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
import pyrogram
from pyrogram import types, raw
from ..object import Object
class PaymentForm(Object):
"""This object contains basic information about an payment form.
Parameters:
id (``int``):
Form id.
bot (``str``):
Bot.
title (``str``):
Form title.
description (``str``):
Form description.
invoice (``str``):
Invoice.
provider (``str``, *optional*):
Payment provider.
url (``str``, *optional*):
Payment form URL.
can_save_credentials (``str``, *optional*):
Whether the user can choose to save credentials.
is_password_missing (``str``, *optional*):
Indicates that the user can save payment credentials,
but only after setting up a 2FA password
(currently the account doesn't have a 2FA password).
native_provider (``str``, *optional*):
Payment provider name.
raw (:obj:`~raw.base.payments.PaymentForm`, *optional*):
The raw object, as received from the Telegram API.
"""
def __init__(
self,
*,
client: "pyrogram.Client" = None,
id: int,
bot: "types.User",
title: str,
description: str,
invoice: "types.Invoice",
provider: Optional["types.User"] = None,
url: Optional[str] = None,
can_save_credentials: Optional[bool] = None,
is_password_missing: Optional[bool] = None,
native_provider: Optional[str] = None,
raw: "raw.base.payments.PaymentForm" = None,
# TODO: Add support for other params:
# native_params
# additional_params
# saved_info
# saved_credentials
):
super().__init__(client)
self.id = id
self.bot = bot
self.title = title
self.description = description
self.invoice = invoice
self.provider = provider
self.url = url
self.can_save_credentials = can_save_credentials
self.is_password_missing = is_password_missing
self.native_provider = native_provider
self.raw = raw
@staticmethod
def _parse(client, payment_form: "raw.base.payments.PaymentForm") -> "PaymentForm":
users = {i.id: i for i in payment_form.users}
return PaymentForm(
id=payment_form.form_id,
bot=types.User._parse(client, users.get(payment_form.bot_id)),
title=payment_form.title,
description=payment_form.description,
invoice=types.Invoice._parse(client, payment_form.invoice),
provider=types.User._parse(client, users.get(getattr(payment_form, "provider_id", None))),
url=getattr(payment_form, "url", None),
can_save_credentials=getattr(payment_form, "can_save_credentials", None),
is_password_missing=getattr(payment_form, "password_missing", None),
native_provider=getattr(payment_form, "native_provider", None),
raw=payment_form
)