diff --git a/aiogram/api.py b/aiogram/api.py index c44cbfb1..80d1f3a2 100644 --- a/aiogram/api.py +++ b/aiogram/api.py @@ -7,6 +7,9 @@ from .exceptions import ValidationError, TelegramAPIError log = logging.getLogger(__name__) +API_URL = "https://api.telegram.org/bot{token}/{method}" +FILE_URL = "https://api.telegram.org/file/bot{token}/{file_id}" + def check_token(token): if any(x.isspace() for x in token): @@ -119,7 +122,6 @@ class ApiMethods: EDIT_MESSAGE_CAPTION = 'editMessageCaption' EDIT_MESSAGE_REPLY_MARKUP = 'editMessageReplyMarkup' DELETE_MESSAGE = 'deleteMessage' - - -API_URL = "https://api.telegram.org/bot{token}/{method}" -FILE_URL = "https://api.telegram.org/file/bot{token}/{file_id}" + SEND_INVOICE = 'sendInvoice' + ANSWER_SHIPPING_QUERY = 'answerShippingQuery' + ANSWER_PRE_CHECKOUT_QUERY = 'answerPreCheckoutQuery' diff --git a/aiogram/bot.py b/aiogram/bot.py index cf3cd180..a4fe37eb 100644 --- a/aiogram/bot.py +++ b/aiogram/bot.py @@ -348,3 +348,32 @@ class Bot: await self.request(api.ApiMethods.DELETE_MESSAGE, payload) return True + + async def send_invoice(self, chat_id: int, title: str, description: str, payload: str, provider_token: str, + start_parameter: str, currency: str, prices: [types.LabeledPrice], photo_url: str = None, + photo_size: int = None, photo_width: int = None, photo_height: int = None, + need_name: bool = None, need_phone_number: bool = None, need_email: bool = None, + need_shipping_address: bool = None, is_flexible: bool = None, + disable_notification: bool = None, reply_to_message_id: int = None, + reply_markup: types.InlineKeyboardMarkup = None) -> types.Message: + if reply_markup and hasattr(reply_markup, 'to_json'): + reply_markup = json.dumps(reply_markup.to_json()) + prices = json.dumps([item.to_json() for item in prices]) + + payload_ = generate_payload(**locals()) + + message = await self.request(api.ApiMethods.SEND_INVOICE, payload_) + return self.prepare_object(types.Message.de_json(message)) + + async def answer_shipping_query(self, shipping_query_id: str, ok: bool, + shipping_options: [types.ShippingOption] = None, error_message: str = None) -> None: + shipping_options = json.dumps([item.to_json() for item in shipping_options]) + + payload = generate_payload(**locals()) + + return await self.request(api.ApiMethods.ANSWER_SHIPPING_QUERY, payload) + + async def answer_pre_checkout_query(self, pre_checkout_query_id: str, ok: bool, error_message: str = None) -> bool: + payload = generate_payload(**locals()) + + return await self.request(api.ApiMethods.ANSWER_PRE_CHECKOUT_QUERY, payload) diff --git a/aiogram/types/__init__.py b/aiogram/types/__init__.py index 31f977eb..c706a915 100644 --- a/aiogram/types/__init__.py +++ b/aiogram/types/__init__.py @@ -22,6 +22,7 @@ from .inline_query_result import InlineQueryResult, InlineQueryResultArticle, In InputLocationMessageContent, InputMessageContent, InputTextMessageContent, InputTextMessageContent, \ InputVenueMessageContent, InputVenueMessageContent from .invoice import Invoice +from .labeled_price import LabeledPrice from .location import Location from .message import Message, ContentType, ParseMode from .message_entity import MessageEntity @@ -30,6 +31,7 @@ from .photo_size import PhotoSize from .pre_checkout_query import PreCheckoutQuery from .reply_keyboard import KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove from .shipping_address import ShippingAddress +from .shipping_option import ShippingOption from .shipping_query import ShippingQuery from .sticker import Sticker from .successful_payment import SuccessfulPayment @@ -96,6 +98,7 @@ __all__ = [ 'InputVenueMessageContent', 'Invoice', 'KeyboardButton', + 'LabeledPrice', 'Location', 'Message', 'MessageEntity', @@ -106,6 +109,7 @@ __all__ = [ 'ReplyKeyboardMarkup', 'ReplyKeyboardRemove', 'ShippingAddress', + 'ShippingOption', 'ShippingQuery', 'Sticker', 'SuccessfulPayment', diff --git a/aiogram/types/base.py b/aiogram/types/base.py index 37206d1b..2604af07 100644 --- a/aiogram/types/base.py +++ b/aiogram/types/base.py @@ -18,10 +18,10 @@ class Serializable: """ Returns a JSON string representation of this class. - This function must be overridden by subclasses. - :return: a JSON formatted string. + :return: a JSON. """ - raise NotImplementedError + return {k: v.to_json() if hasattr(v, 'to_json') else v for k, v in self.__dict__.items() if + not k.startswith('_')} class Deserializable: diff --git a/aiogram/types/labeled_price.py b/aiogram/types/labeled_price.py new file mode 100644 index 00000000..f6c5db69 --- /dev/null +++ b/aiogram/types/labeled_price.py @@ -0,0 +1,7 @@ +from .base import Serializable + + +class LabeledPrice(Serializable): + def __init__(self, label, amount): + self.label = label + self.amount = amount diff --git a/aiogram/types/shipping_option.py b/aiogram/types/shipping_option.py new file mode 100644 index 00000000..5bc539bd --- /dev/null +++ b/aiogram/types/shipping_option.py @@ -0,0 +1,8 @@ +from .base import Serializable + + +class ShippingOption(Serializable): + def __init__(self, id, title, prices): + self.id = id + self.title = title + self.prices = prices