diff --git a/compiler/api/compiler.py b/compiler/api/compiler.py index f3dc0aac..25a2a3e6 100644 --- a/compiler/api/compiler.py +++ b/compiler/api/compiler.py @@ -493,7 +493,14 @@ def start(): f.write("\n 0xb0700014: \"pyrogram.client.types.UserProfilePhotos\",") f.write("\n 0xb0700015: \"pyrogram.client.types.ChatPhoto\",") f.write("\n 0xb0700016: \"pyrogram.client.types.ChatMember\",") - f.write("\n 0xb0700017: \"pyrogram.client.types.Sticker\"") + f.write("\n 0xb0700017: \"pyrogram.client.types.Sticker\",") + + f.write("\n 0xb0700018: \"pyrogram.client.types.reply_markup.ForceReply\",") + f.write("\n 0xb0700019: \"pyrogram.client.types.reply_markup.InlineKeyboardButton\",") + f.write("\n 0xb0700020: \"pyrogram.client.types.reply_markup.InlineKeyboardMarkup\",") + f.write("\n 0xb0700021: \"pyrogram.client.types.reply_markup.KeyboardButton\",") + f.write("\n 0xb0700022: \"pyrogram.client.types.reply_markup.ReplyKeyboardMarkup\",") + f.write("\n 0xb0700023: \"pyrogram.client.types.reply_markup.ReplyKeyboardRemove\"") f.write("\n}\n") diff --git a/docs/source/pyrogram/types/index.rst b/docs/source/pyrogram/types/index.rst index 491810bc..55c6d8b3 100644 --- a/docs/source/pyrogram/types/index.rst +++ b/docs/source/pyrogram/types/index.rst @@ -24,4 +24,10 @@ Types InputMediaPhoto InputMediaVideo InputPhoneContact - Sticker \ No newline at end of file + Sticker + reply_markup/ForceReply + reply_markup/InlineKeyboardButton + reply_markup/InlineKeyboardMarkup + reply_markup/KeyboardButton + reply_markup/ReplyKeyboardMarkup + reply_markup/ReplyKeyboardRemove \ No newline at end of file diff --git a/docs/source/pyrogram/types/reply_markup/ForceReply.rst b/docs/source/pyrogram/types/reply_markup/ForceReply.rst new file mode 100644 index 00000000..db70a834 --- /dev/null +++ b/docs/source/pyrogram/types/reply_markup/ForceReply.rst @@ -0,0 +1,5 @@ +ForceReply +========== + +.. autoclass:: pyrogram.ForceReply + :members: diff --git a/docs/source/pyrogram/types/reply_markup/InlineKeyboardButton.rst b/docs/source/pyrogram/types/reply_markup/InlineKeyboardButton.rst new file mode 100644 index 00000000..2e536596 --- /dev/null +++ b/docs/source/pyrogram/types/reply_markup/InlineKeyboardButton.rst @@ -0,0 +1,5 @@ +InlineKeyboardButton +==================== + +.. autoclass:: pyrogram.InlineKeyboardButton + :members: diff --git a/docs/source/pyrogram/types/reply_markup/InlineKeyboardMarkup.rst b/docs/source/pyrogram/types/reply_markup/InlineKeyboardMarkup.rst new file mode 100644 index 00000000..7ffa2582 --- /dev/null +++ b/docs/source/pyrogram/types/reply_markup/InlineKeyboardMarkup.rst @@ -0,0 +1,5 @@ +InlineKeyboardMarkup +==================== + +.. autoclass:: pyrogram.InlineKeyboardMarkup + :members: diff --git a/docs/source/pyrogram/types/reply_markup/KeybaordButton.rst b/docs/source/pyrogram/types/reply_markup/KeybaordButton.rst new file mode 100644 index 00000000..69488656 --- /dev/null +++ b/docs/source/pyrogram/types/reply_markup/KeybaordButton.rst @@ -0,0 +1,5 @@ +KeyboardButton +============== + +.. autoclass:: pyrogram.KeyboardButton + :members: diff --git a/docs/source/pyrogram/types/reply_markup/ReplyKeyboardMarkup.rst b/docs/source/pyrogram/types/reply_markup/ReplyKeyboardMarkup.rst new file mode 100644 index 00000000..2b1e6d16 --- /dev/null +++ b/docs/source/pyrogram/types/reply_markup/ReplyKeyboardMarkup.rst @@ -0,0 +1,5 @@ +ReplyKeyboardMarkup +=================== + +.. autoclass:: pyrogram.ReplyKeyboardMarkup + :members: diff --git a/docs/source/pyrogram/types/reply_markup/ReplyKeyboardRemove.rst b/docs/source/pyrogram/types/reply_markup/ReplyKeyboardRemove.rst new file mode 100644 index 00000000..4146d564 --- /dev/null +++ b/docs/source/pyrogram/types/reply_markup/ReplyKeyboardRemove.rst @@ -0,0 +1,5 @@ +ReplyKeyboardRemove +=================== + +.. autoclass:: pyrogram.ReplyKeyboardRemove + :members: diff --git a/pyrogram/__init__.py b/pyrogram/__init__.py index e71fc0dd..0b261922 100644 --- a/pyrogram/__init__.py +++ b/pyrogram/__init__.py @@ -26,7 +26,16 @@ __license__ = "GNU Lesser General Public License v3 or later (LGPLv3+)" __version__ = "0.7.1" from .api.errors import Error -from .client.types import * +from .client.types import ( + Audio, Chat, ChatMember, ChatPhoto, Contact, Document, InputMediaPhoto, + InputMediaVideo, InputPhoneContact, Location, Message, MessageEntity, + PhotoSize, Sticker, Update, User, UserProfilePhotos, Venue, Video, + VideoNote, Voice +) +from .client.types.reply_markup import ( + ForceReply, InlineKeyboardButton, InlineKeyboardMarkup, + KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove +) from .client import ( Client, ChatAction, ParseMode, Emoji, MessageHandler, RawUpdateHandler, Filters diff --git a/pyrogram/api/core/object.py b/pyrogram/api/core/object.py index 8a757f35..7f0c7d2f 100644 --- a/pyrogram/api/core/object.py +++ b/pyrogram/api/core/object.py @@ -76,7 +76,7 @@ class Encoder(JSONEncoder): if o is not None: if o.startswith("pyrogram.client"): - r = remove_none(OrderedDict([i for i in content.items()])) + r = remove_none(OrderedDict([("_", o)] + [i for i in content.items()])) r.pop("client", None) return r diff --git a/pyrogram/client/types/reply_markup/__init__.py b/pyrogram/client/types/reply_markup/__init__.py new file mode 100644 index 00000000..62ce7152 --- /dev/null +++ b/pyrogram/client/types/reply_markup/__init__.py @@ -0,0 +1,24 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2018 Dan Tès +# +# 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 .force_reply import ForceReply +from .inline_keyboard_button import InlineKeyboardButton +from .inline_keyboard_markup import InlineKeyboardMarkup +from .keyboard_button import KeyboardButton +from .reply_keyboard_markup import ReplyKeyboardMarkup +from .reply_keyboard_remove import ReplyKeyboardRemove diff --git a/pyrogram/client/types/reply_markup/force_reply.py b/pyrogram/client/types/reply_markup/force_reply.py new file mode 100644 index 00000000..0aa4c134 --- /dev/null +++ b/pyrogram/client/types/reply_markup/force_reply.py @@ -0,0 +1,48 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2018 Dan Tès +# +# 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 pyrogram.api.core import Object +from pyrogram.api.types import ReplyKeyboardForceReply + + +class ForceReply(Object): + """Upon receiving a message with this object, Telegram clients will display a reply interface to the user + (act as if the user has selected the bot's message and tapped 'Reply'). + This can be extremely useful if you want to create user-friendly step-by-step interfaces without having to + sacrifice privacy mode. + + Attributes: + ID: ``0xb0700018`` + + Args: + selective (``bool``, optional): + Use this parameter if you want to force reply from specific users only. Targets: + 1) users that are @mentioned in the text of the Message object; + 2) if the bot's message is a reply (has reply_to_message_id), sender of the original message. + """ + + ID = 0xb0700018 + + def __init__(self, selective: bool = None): + self.selective = selective + + def write(self): + return ReplyKeyboardForceReply( + single_use=True, + selective=self.selective or None + ) diff --git a/pyrogram/client/types/reply_markup/inline_keyboard_button.py b/pyrogram/client/types/reply_markup/inline_keyboard_button.py new file mode 100644 index 00000000..7eb851db --- /dev/null +++ b/pyrogram/client/types/reply_markup/inline_keyboard_button.py @@ -0,0 +1,97 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2018 Dan Tès +# +# 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 pyrogram.api.core import Object + +from pyrogram.api.types import ( + KeyboardButtonUrl, KeyboardButtonCallback, + KeyboardButtonSwitchInline +) + + +class InlineKeyboardButton(Object): + """This object represents one button of an inline keyboard. You must use exactly one of the optional fields. + + Attributes: + ID: ``0xb0700019`` + + Args: + text (``str``): + Label text on the button. + + url (``str``, optional): + HTTP url to be opened when button is pressed. + + callback_data (``str``, optional): + Data to be sent in a callback query to the bot when button is pressed, 1-64 bytes. + + switch_inline_query (``str``, optional): + If set, pressing the button will prompt the user to select one of their chats, open that chat and insert + the bot's username and the specified inline query in the input field. Can be empty, in which case just + the bot's username will be inserted.Note: This offers an easy way for users to start using your bot in + inline mode when they are currently in a private chat with it. Especially useful when combined with + switch_pm… actions – in this case the user will be automatically returned to the chat they switched from, + skipping the chat selection screen. + + switch_inline_query_current_chat (``str``, optional): + If set, pressing the button will insert the bot's username and the specified inline query in the current + chat's input field. Can be empty, in which case only the bot's username will be inserted.This offers a + quick way for the user to open your bot in inline mode in the same chat – good for selecting something + from multiple options. + + callback_game (:obj:`CallbackGame `, optional): + Description of the game that will be launched when the user presses the button.NOTE: This type of button + must always be the first button in the first row. + + pay (``bool``, optional): + Specify True, to send a Pay button.NOTE: This type of button must always be the first button in the + first row. + """ + + ID = 0xb0700019 + + def __init__( + self, + text: str, + url: str = None, + callback_data: str = None, + switch_inline_query: str = None, + switch_inline_query_current_chat: str = None, + callback_game=None, + pay: bool = None + ): + self.text = text + self.url = url + self.callback_data = callback_data + self.switch_inline_query = switch_inline_query + self.switch_inline_query_current_chat = switch_inline_query_current_chat + self.callback_game = callback_game + self.pay = pay + + def write(self): + if self.url: + return KeyboardButtonUrl(self.text, self.url) + + if self.callback_data: + return KeyboardButtonCallback(self.text, self.callback_data.encode()) + + if self.switch_inline_query: + return KeyboardButtonSwitchInline(self.text, self.switch_inline_query) + + if self.switch_inline_query_current_chat: + return KeyboardButtonSwitchInline(self.text, self.switch_inline_query_current_chat, same_peer=True) diff --git a/pyrogram/client/types/reply_markup/inline_keyboard_markup.py b/pyrogram/client/types/reply_markup/inline_keyboard_markup.py new file mode 100644 index 00000000..79bc0c37 --- /dev/null +++ b/pyrogram/client/types/reply_markup/inline_keyboard_markup.py @@ -0,0 +1,45 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2018 Dan Tès +# +# 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 pyrogram.api.core import Object + +from pyrogram.api.types import ReplyInlineMarkup, KeyboardButtonRow + + +class InlineKeyboardMarkup(Object): + """This object represents an inline keyboard that appears right next to the message it belongs to. + + Attributes: + ID: ``0xb0700020`` + + Args: + inline_keyboard (List of List of :obj:`InlineKeyboardButton `): + Array of button rows, each represented by an Array of InlineKeyboardButton objects. + """ + + ID = 0xb0700020 + + def __init__(self, inline_keyboard: list): + self.inline_keyboard = inline_keyboard + + def write(self): + return ReplyInlineMarkup( + [KeyboardButtonRow( + [j.write() for j in i] + ) for i in self.inline_keyboard] + ) diff --git a/pyrogram/client/types/reply_markup/keyboard_button.py b/pyrogram/client/types/reply_markup/keyboard_button.py new file mode 100644 index 00000000..e4b12de5 --- /dev/null +++ b/pyrogram/client/types/reply_markup/keyboard_button.py @@ -0,0 +1,62 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2018 Dan Tès +# +# 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 pyrogram.api.core import Object + +from pyrogram.api.types import KeyboardButton as RawKeyboardButton +from pyrogram.api.types import KeyboardButtonRequestPhone, KeyboardButtonRequestGeoLocation + + +class KeyboardButton(Object): + """This object represents one button of the reply keyboard. + For simple text buttons String can be used instead of this object to specify text of the button. + Optional fields are mutually exclusive. + + Attributes: + ID: ``0xb0700021`` + + Args: + text (``str``): + Text of the button. If none of the optional fields are used, it will be sent as a message when + the button is pressed. + + request_contact (``bool``, optional): + If True, the user's phone number will be sent as a contact when the button is pressed. + Available in private chats only. + + request_location (``bool``, optional): + If True, the user's current location will be sent when the button is pressed. + Available in private chats only. + """ + + ID = 0xb0700021 + + def __init__(self, text: str, request_contact: bool = None, request_location: bool = None): + self.text = text + self.request_contact = request_contact + self.request_location = request_location + + def write(self): + # TODO: Enforce optional args mutual exclusiveness + + if self.request_contact: + return KeyboardButtonRequestPhone(self.text) + elif self.request_location: + return KeyboardButtonRequestGeoLocation(self.text) + else: + return RawKeyboardButton(self.text) diff --git a/pyrogram/client/types/reply_markup/reply_keyboard_markup.py b/pyrogram/client/types/reply_markup/reply_keyboard_markup.py new file mode 100644 index 00000000..c4a5be25 --- /dev/null +++ b/pyrogram/client/types/reply_markup/reply_keyboard_markup.py @@ -0,0 +1,77 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2018 Dan Tès +# +# 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 pyrogram.api.core import Object + +from pyrogram.api.types import KeyboardButtonRow, KeyboardButton +from pyrogram.api.types import ReplyKeyboardMarkup as RawReplyKeyboardMarkup + + +class ReplyKeyboardMarkup(Object): + """This object represents a custom keyboard with reply options (see Introduction to bots for details and examples). + + Attributes: + ID: ``0xb0700022`` + + Args: + keyboard (List of List of :obj:`KeyboardButton `): + Array of button rows, each represented by an Array of KeyboardButton objects. + + resize_keyboard (``bool``, optional): + Requests clients to resize the keyboard vertically for optimal fit (e.g., make the keyboard smaller if + there are just two rows of buttons). Defaults to false, in which case the custom keyboard is always of + the same height as the app's standard keyboard. + + one_time_keyboard (``bool``, optional): + Requests clients to hide the keyboard as soon as it's been used. The keyboard will still be available, + but clients will automatically display the usual letter-keyboard in the chat – the user can press a + special button in the input field to see the custom keyboard again. Defaults to false. + + selective (``bool``, optional): + Use this parameter if you want to show the keyboard to specific users only. Targets: + 1) users that are @mentioned in the text of the Message object; + 2) if the bot's message is a reply (has reply_to_message_id), sender of the original message. + Example: A user requests to change the bot's language, bot replies to the request with a keyboard to + select the new language. Other users in the group don't see the keyboard. + """ + + ID = 0xb0700022 + + def __init__( + self, + keyboard: list, + resize_keyboard: bool = None, + one_time_keyboard: bool = None, + selective: bool = None + ): + self.keyboard = keyboard + self.resize_keyboard = resize_keyboard + self.one_time_keyboard = one_time_keyboard + self.selective = selective + + def write(self): + return RawReplyKeyboardMarkup( + rows=[KeyboardButtonRow( + [KeyboardButton(j) + if isinstance(j, str) else j.write() + for j in i] + ) for i in self.keyboard], + resize=self.resize_keyboard or None, + single_use=self.one_time_keyboard or None, + selective=self.selective or None + ) diff --git a/pyrogram/client/types/reply_markup/reply_keyboard_remove.py b/pyrogram/client/types/reply_markup/reply_keyboard_remove.py new file mode 100644 index 00000000..dc4f8c60 --- /dev/null +++ b/pyrogram/client/types/reply_markup/reply_keyboard_remove.py @@ -0,0 +1,50 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2018 Dan Tès +# +# 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 pyrogram.api.core import Object +from pyrogram.api.types import ReplyKeyboardHide + + +class ReplyKeyboardRemove(Object): + """Upon receiving a message with this object, Telegram clients will remove the current custom keyboard and + display the default letter-keyboard. By default, custom keyboards are displayed until a new keyboard is sent + by a bot. An exception is made for one-time keyboards that are hidden immediately after the user presses a + button (see ReplyKeyboardMarkup). + + Attributes: + ID: ``0xb0700023`` + + Args: + selective (``bool``, optional): + Use this parameter if you want to remove the keyboard for specific users only. Targets: + 1) users that are @mentioned in the text of the Message object; + 2) if the bot's message is a reply (has reply_to_message_id), sender of the original message. + Example: A user votes in a poll, bot returns confirmation message in reply to the vote and removes the + keyboard for that user, while still showing the keyboard with poll options to users who haven't voted yet. + """ + + ID = 0xb0700002 + + def __init__(self, selective: bool = None): + self.selective = selective + + def write(self): + return ReplyKeyboardHide( + selective=self.selective or None + )