diff --git a/compiler/docs/compiler.py b/compiler/docs/compiler.py index 81c0bbae..185f5435 100644 --- a/compiler/docs/compiler.py +++ b/compiler/docs/compiler.py @@ -506,6 +506,7 @@ def pyrogram_api(): BoostsStatus Giveaway GiveawayResult + Invoice GiftCode CheckedGiftCode SuccessfulPayment diff --git a/pyrogram/enums/message_media_type.py b/pyrogram/enums/message_media_type.py index c6844716..0d93ceec 100644 --- a/pyrogram/enums/message_media_type.py +++ b/pyrogram/enums/message_media_type.py @@ -77,3 +77,6 @@ class MessageMediaType(AutoName): STORY = auto() "Story media" + + INVOICE = auto() + "Invoice media" diff --git a/pyrogram/types/bots_and_keyboards/inline_keyboard_button.py b/pyrogram/types/bots_and_keyboards/inline_keyboard_button.py index d016ea2b..467e8ebc 100644 --- a/pyrogram/types/bots_and_keyboards/inline_keyboard_button.py +++ b/pyrogram/types/bots_and_keyboards/inline_keyboard_button.py @@ -161,6 +161,11 @@ class InlineKeyboardButton(Object): ) ) + if isinstance(b, raw.types.KeyboardButtonBuy): + return InlineKeyboardButton( + text=b.text + ) + async def write(self, client: "pyrogram.Client"): if self.callback_data is not None: # Telegram only wants bytes, but we are allowed to pass strings too, for convenience. diff --git a/pyrogram/types/messages_and_media/__init__.py b/pyrogram/types/messages_and_media/__init__.py index cf8fdc80..b4ca8a49 100644 --- a/pyrogram/types/messages_and_media/__init__.py +++ b/pyrogram/types/messages_and_media/__init__.py @@ -34,6 +34,7 @@ from .game import Game from .general_forum_topic_hidden import GeneralTopicHidden from .general_forum_topic_unhidden import GeneralTopicUnhidden from .gift_code import GiftCode +from .invoice import Invoice from .giveaway import Giveaway from .giveaway_result import GiveawayResult from .location import Location @@ -76,6 +77,7 @@ __all__ = [ "GeneralTopicUnhidden", "GiftCode", "Giveaway", + "Invoice", "GiveawayResult", "Location", "Message", diff --git a/pyrogram/types/messages_and_media/invoice.py b/pyrogram/types/messages_and_media/invoice.py new file mode 100644 index 00000000..3ff7e691 --- /dev/null +++ b/pyrogram/types/messages_and_media/invoice.py @@ -0,0 +1,85 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present Dan +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . + +from typing import Optional + +from pyrogram import raw +from ..object import Object + + +class Invoice(Object): + """This object contains basic information about an invoice. + + Parameters: + title (``str``): + Product name. + + description (``str``): + Product description. + + start_parameter (``str``): + Unique bot deep-linking parameter that can be used to generate this invoice. + + currency (``str``): + Three-letter ISO 4217 `currency `_ code. + + total_amount (``int``): + Total price in the smallest units of the currency (integer, **not** float/double). For example, for a price of ``US$ 1.45`` pass ``amount = 145``. See the exp parameter in `currencies.json `_, it shows the number of digits past the decimal point for each currency (2 for the majority of currencies). + + is_shipping_address_requested (``bool``, *optional*): + True, if the shipping address should be specified. + + is_test (``bool``, *optional*): + True, if the invoice is a test invoice. + """ + + def __init__( + self, + *, + client: "pyrogram.Client" = None, + title: str, + description: str, + currency: str, + total_amount: int, + start_parameter: Optional[str] = None, + is_shipping_address_requested: Optional[bool] = None, + is_test: Optional[bool] = None + ): + super().__init__(client) + + self.title = title + self.description = description + self.is_shipping_address_requested = is_shipping_address_requested + self.currency = currency + self.start_parameter = start_parameter + self.total_amount = total_amount + self.is_test = is_test + + @staticmethod + def _parse(client, invoice: "raw.types.MessageMediaInvoice") -> "Invoice": + return Invoice( + title=invoice.title, + description=invoice.description, + currency=invoice.currency, + total_amount=invoice.total_amount, + start_parameter=invoice.start_param or None, + is_shipping_address_requested=getattr(invoice, "shipping_address_requested", None), + is_test=getattr(invoice, "test", None), + client=client + # TODO: Add photo and extended media + ) diff --git a/pyrogram/types/messages_and_media/message.py b/pyrogram/types/messages_and_media/message.py index 376e2b6d..0332d699 100644 --- a/pyrogram/types/messages_and_media/message.py +++ b/pyrogram/types/messages_and_media/message.py @@ -210,6 +210,10 @@ class Message(Object, Update): giveaway (:obj:`~pyrogram.types.Giveaway`, *optional*): Message is a giveaway, information about the giveaway. + invoice (:obj:`~pyrogram.types.Invoice`, *optional*): + Message is a invoice, information about the invoice. + `More about payments ยป `_ + story (:obj:`~pyrogram.types.Story`, *optional*): Message is a story, information about the story. @@ -401,7 +405,7 @@ class Message(Object, Update): Generate a link to this message, only for groups and channels. """ - # TODO: Add game missing field. Also invoice, successful_payment, connected_website + # TODO: Add game missing field. Also successful_payment, connected_website def __init__( self, @@ -453,6 +457,7 @@ class Message(Object, Update): game: "types.Game" = None, giveaway: "types.Giveaway" = None, giveaway_result: "types.GiveawayResult" = None, + invoice: "types.Invoice" = None, story: "types.Story" = None, video: "types.Video" = None, voice: "types.Voice" = None, @@ -560,6 +565,7 @@ class Message(Object, Update): self.game = game self.giveaway = giveaway self.giveaway_result = giveaway_result + self.invoice = invoice self.story = story self.video = video self.voice = voice @@ -900,6 +906,7 @@ class Message(Object, Update): game = None giveaway = None giveaway_result = None + invoice = None story = None audio = None voice = None @@ -939,6 +946,9 @@ class Message(Object, Update): elif isinstance(media, raw.types.MessageMediaGiveawayResults): giveaway_result = await types.GiveawayResult._parse(client, media, users, chats) media_type = enums.MessageMediaType.GIVEAWAY_RESULT + elif isinstance(media, raw.types.MessageMediaInvoice): + invoice = types.Invoice._parse(client, media) + media_type = enums.MessageMediaType.INVOICE elif isinstance(media, raw.types.MessageMediaStory): if media.story: story = await types.Story._parse(client, media.story, users, chats, media.peer) @@ -1087,6 +1097,7 @@ class Message(Object, Update): game=game, giveaway=giveaway, giveaway_result=giveaway_result, + invoice=invoice, story=story, video=video, video_note=video_note,