Merge branch 'develop' into asyncio

# Conflicts:
#	pyrogram/client/types/message.py
This commit is contained in:
Dan 2018-06-23 14:30:27 +02:00
commit 811e67c229
32 changed files with 245 additions and 202 deletions

View File

@ -12,12 +12,10 @@ Pyrogram |twitter|
@app.on_message(Filters.private) @app.on_message(Filters.private)
def hello(client, message): def hello(client, message):
client.send_message( message.reply("Hello {}".format(message.from_user.first_name))
message.chat.id, "Hello {}".format(message.from_user.first_name))
app.start() app.run()
app.idle()
**Pyrogram** is a brand new Telegram_ Client Library written from the ground up in Python and C. It can be used for building **Pyrogram** is a brand new Telegram_ Client Library written from the ground up in Python and C. It can be used for building
custom Telegram applications that interact with the MTProto API as both User and Bot. custom Telegram applications that interact with the MTProto API as both User and Bot.

View File

@ -44,8 +44,7 @@ Welcome to Pyrogram
@app.on_message(Filters.private) @app.on_message(Filters.private)
def hello(client, message): def hello(client, message):
message.reply_text( message.reply("Hello {}".format(message.from_user.first_name))
"Hello {}".format(message.from_user.first_name))
app.run() app.run()

View File

@ -19,6 +19,7 @@
import re import re
from .filter import Filter from .filter import Filter
from ..types.reply_markup import InlineKeyboardMarkup, ReplyKeyboardMarkup
def build(name: str, func: callable, **kwargs) -> type: def build(name: str, func: callable, **kwargs) -> type:
@ -131,7 +132,11 @@ class Filters:
pinned_message = build("PinnedMessage", lambda _, m: bool(m.pinned_message)) pinned_message = build("PinnedMessage", lambda _, m: bool(m.pinned_message))
"""Filter service messages for pinned messages.""" """Filter service messages for pinned messages."""
# TODO: Add filters for reply markups reply_keyboard = build("ReplyKeyboard", lambda _, m: isinstance(m.reply_markup, ReplyKeyboardMarkup))
"""Filter messages containing reply keyboard markups"""
inline_keyboard = build("InlineKeyboard", lambda _, m: isinstance(m.reply_markup, InlineKeyboardMarkup))
"""Filter messages containing inline keyboard markups"""
@staticmethod @staticmethod
def command(command: str or list, def command(command: str or list,

View File

@ -16,12 +16,16 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from .callback_query import CallbackQuery from .answer_callback_query import AnswerCallbackQuery
from .inline import Inline from .get_inline_bot_results import GetInlineBotResults
from .request_callback_answer import RequestCallbackAnswer
from .send_inline_bot_result import SendInlineBotResult
class Bots( class Bots(
CallbackQuery, AnswerCallbackQuery,
Inline GetInlineBotResults,
RequestCallbackAnswer,
SendInlineBotResult
): ):
pass pass

View File

@ -17,7 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from pyrogram.api import functions from pyrogram.api import functions
from ....ext import BaseClient from pyrogram.client.ext import BaseClient
class AnswerCallbackQuery(BaseClient): class AnswerCallbackQuery(BaseClient):

View File

@ -1,25 +0,0 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2018 Dan Tès <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 .answer_callback_query import AnswerCallbackQuery
class CallbackQuery(
AnswerCallbackQuery
):
pass

View File

@ -18,7 +18,7 @@
from pyrogram.api import functions, types from pyrogram.api import functions, types
from pyrogram.api.errors import UnknownError from pyrogram.api.errors import UnknownError
from ....ext import BaseClient from pyrogram.client.ext import BaseClient
class GetInlineBotResults(BaseClient): class GetInlineBotResults(BaseClient):

View File

@ -1,27 +0,0 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2018 Dan Tès <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 .get_inline_bot_results import GetInlineBotResults
from .send_inline_bot_result import SendInlineBotResult
class Inline(
SendInlineBotResult,
GetInlineBotResults
):
pass

View File

@ -0,0 +1,51 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2018 Dan Tès <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 pyrogram.api import functions
from pyrogram.client.ext import BaseClient
class RequestCallbackAnswer(BaseClient):
def request_callback_answer(self,
chat_id: int or str,
message_id: int,
callback_data: str):
"""Use this method to request a callback answer from bots. This is the equivalent of clicking an inline button
containing callback data. The answer contains info useful for clients to display a notification at the top of
the chat screen or as an alert.
Args:
chat_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).
For a private channel/supergroup you can use its *t.me/joinchat/* link.
message_id (``int``):
The message id the inline keyboard is attached on.
callback_data (``str``):
Callback data associated with the inline button you want to get the answer from.
"""
return self.send(
functions.messages.GetBotCallbackAnswer(
peer=self.resolve_peer(chat_id),
msg_id=message_id,
data=callback_data.encode()
)
)

View File

@ -17,7 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from pyrogram.api import functions from pyrogram.api import functions
from ....ext import BaseClient from pyrogram.client.ext import BaseClient
class SendInlineBotResult(BaseClient): class SendInlineBotResult(BaseClient):

View File

@ -16,22 +16,50 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from .action import Action from .delete_messages import DeleteMessages
from .edit_message_caption import EditMessageCaption
from .edit_message_reply_markup import EditMessageReplyMarkup
from .edit_message_text import EditMessageText
from .forward_messages import ForwardMessages from .forward_messages import ForwardMessages
from .get_history import GetHistory from .get_history import GetHistory
from .get_messages import GetMessages from .get_messages import GetMessages
from .media import Media from .send_audio import SendAudio
from .send_chat_action import SendChatAction
from .send_contact import SendContact
from .send_document import SendDocument
from .send_gif import SendGIF
from .send_location import SendLocation
from .send_media_group import SendMediaGroup
from .send_message import SendMessage from .send_message import SendMessage
from .update import Update from .send_photo import SendPhoto
from .send_sticker import SendSticker
from .send_venue import SendVenue
from .send_video import SendVideo
from .send_video_note import SendVideoNote
from .send_voice import SendVoice
class Messages( class Messages(
DeleteMessages,
EditMessageCaption,
EditMessageReplyMarkup,
EditMessageText,
ForwardMessages,
GetHistory, GetHistory,
GetMessages, GetMessages,
Action, SendAudio,
Media, SendChatAction,
Update, SendContact,
ForwardMessages, SendDocument,
SendMessage SendGIF,
SendLocation,
SendMediaGroup,
SendMessage,
SendPhoto,
SendSticker,
SendVenue,
SendVideo,
SendVideoNote,
SendVoice
): ):
pass pass

View File

@ -1,25 +0,0 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2018 Dan Tès <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 .send_chat_action import SendChatAction
class Action(
SendChatAction
):
pass

View File

@ -17,7 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from pyrogram.api import functions, types from pyrogram.api import functions, types
from ....ext import BaseClient from pyrogram.client.ext import BaseClient
class DeleteMessages(BaseClient): class DeleteMessages(BaseClient):

View File

@ -17,7 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from pyrogram.api import functions, types from pyrogram.api import functions, types
from ....ext import BaseClient, utils from pyrogram.client.ext import BaseClient, utils
class EditMessageCaption(BaseClient): class EditMessageCaption(BaseClient):

View File

@ -17,7 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from pyrogram.api import functions, types from pyrogram.api import functions, types
from ....ext import BaseClient, utils from pyrogram.client.ext import BaseClient, utils
class EditMessageReplyMarkup(BaseClient): class EditMessageReplyMarkup(BaseClient):

View File

@ -17,7 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from pyrogram.api import functions, types from pyrogram.api import functions, types
from ....ext import BaseClient, utils from pyrogram.client.ext import BaseClient, utils
class EditMessageText(BaseClient): class EditMessageText(BaseClient):

View File

@ -1,47 +0,0 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2018 Dan Tès <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 .send_audio import SendAudio
from .send_contact import SendContact
from .send_document import SendDocument
from .send_gif import SendGIF
from .send_location import SendLocation
from .send_media_group import SendMediaGroup
from .send_photo import SendPhoto
from .send_sticker import SendSticker
from .send_venue import SendVenue
from .send_video import SendVideo
from .send_video_note import SendVideoNote
from .send_voice import SendVoice
class Media(
SendContact,
SendVenue,
SendLocation,
SendMediaGroup,
SendVideoNote,
SendVoice,
SendVideo,
SendGIF,
SendSticker,
SendDocument,
SendAudio,
SendPhoto
):
pass

View File

@ -23,7 +23,7 @@ import struct
from pyrogram.api import functions, types from pyrogram.api import functions, types
from pyrogram.api.errors import FileIdInvalid, FilePartMissing from pyrogram.api.errors import FileIdInvalid, FilePartMissing
from ....ext import BaseClient, utils from pyrogram.client.ext import BaseClient, utils
class SendAudio(BaseClient): class SendAudio(BaseClient):

View File

@ -17,7 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from pyrogram.api import functions from pyrogram.api import functions
from ....ext import BaseClient, ChatAction from pyrogram.client.ext import BaseClient, ChatAction
class SendChatAction(BaseClient): class SendChatAction(BaseClient):

View File

@ -17,7 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from pyrogram.api import functions, types from pyrogram.api import functions, types
from ....ext import BaseClient, utils from pyrogram.client.ext import BaseClient, utils
class SendContact(BaseClient): class SendContact(BaseClient):

View File

@ -23,7 +23,7 @@ import struct
from pyrogram.api import functions, types from pyrogram.api import functions, types
from pyrogram.api.errors import FileIdInvalid, FilePartMissing from pyrogram.api.errors import FileIdInvalid, FilePartMissing
from ....ext import BaseClient, utils from pyrogram.client.ext import BaseClient, utils
class SendDocument(BaseClient): class SendDocument(BaseClient):

View File

@ -23,7 +23,7 @@ import struct
from pyrogram.api import functions, types from pyrogram.api import functions, types
from pyrogram.api.errors import FileIdInvalid, FilePartMissing from pyrogram.api.errors import FileIdInvalid, FilePartMissing
from ....ext import BaseClient, utils from pyrogram.client.ext import BaseClient, utils
class SendGIF(BaseClient): class SendGIF(BaseClient):

View File

@ -17,7 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from pyrogram.api import functions, types from pyrogram.api import functions, types
from ....ext import BaseClient, utils from pyrogram.client.ext import BaseClient, utils
class SendLocation(BaseClient): class SendLocation(BaseClient):

View File

@ -24,7 +24,7 @@ import struct
from pyrogram.api import functions, types from pyrogram.api import functions, types
from pyrogram.api.errors import FileIdInvalid from pyrogram.api.errors import FileIdInvalid
from pyrogram.client import types as pyrogram_types from pyrogram.client import types as pyrogram_types
from ....ext import BaseClient, utils from pyrogram.client.ext import BaseClient, utils
class SendMediaGroup(BaseClient): class SendMediaGroup(BaseClient):

View File

@ -22,7 +22,7 @@ import struct
from pyrogram.api import functions, types from pyrogram.api import functions, types
from pyrogram.api.errors import FileIdInvalid, FilePartMissing from pyrogram.api.errors import FileIdInvalid, FilePartMissing
from ....ext import BaseClient, utils from pyrogram.client.ext import BaseClient, utils
class SendPhoto(BaseClient): class SendPhoto(BaseClient):

View File

@ -22,7 +22,7 @@ import struct
from pyrogram.api import functions, types from pyrogram.api import functions, types
from pyrogram.api.errors import FileIdInvalid, FilePartMissing from pyrogram.api.errors import FileIdInvalid, FilePartMissing
from ....ext import BaseClient, utils from pyrogram.client.ext import BaseClient, utils
class SendSticker(BaseClient): class SendSticker(BaseClient):

View File

@ -17,7 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from pyrogram.api import functions, types from pyrogram.api import functions, types
from ....ext import BaseClient, utils from pyrogram.client.ext import BaseClient, utils
class SendVenue(BaseClient): class SendVenue(BaseClient):

View File

@ -23,7 +23,7 @@ import struct
from pyrogram.api import functions, types from pyrogram.api import functions, types
from pyrogram.api.errors import FileIdInvalid, FilePartMissing from pyrogram.api.errors import FileIdInvalid, FilePartMissing
from ....ext import BaseClient, utils from pyrogram.client.ext import BaseClient, utils
class SendVideo(BaseClient): class SendVideo(BaseClient):

View File

@ -23,7 +23,7 @@ import struct
from pyrogram.api import functions, types from pyrogram.api import functions, types
from pyrogram.api.errors import FileIdInvalid, FilePartMissing from pyrogram.api.errors import FileIdInvalid, FilePartMissing
from ....ext import BaseClient, utils from pyrogram.client.ext import BaseClient, utils
class SendVideoNote(BaseClient): class SendVideoNote(BaseClient):

View File

@ -23,7 +23,7 @@ import struct
from pyrogram.api import functions, types from pyrogram.api import functions, types
from pyrogram.api.errors import FileIdInvalid, FilePartMissing from pyrogram.api.errors import FileIdInvalid, FilePartMissing
from ....ext import BaseClient, utils from pyrogram.client.ext import BaseClient, utils
class SendVoice(BaseClient): class SendVoice(BaseClient):

View File

@ -1,31 +0,0 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2018 Dan Tès <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 .delete_messages import DeleteMessages
from .edit_message_caption import EditMessageCaption
from .edit_message_reply_markup import EditMessageReplyMarkup
from .edit_message_text import EditMessageText
class Update(
DeleteMessages,
EditMessageReplyMarkup,
EditMessageCaption,
EditMessageText
):
pass

View File

@ -17,6 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from pyrogram.api.core import Object from pyrogram.api.core import Object
from .reply_markup import InlineKeyboardMarkup, ReplyKeyboardMarkup
class Message(Object): class Message(Object):
@ -310,7 +311,7 @@ class Message(Object):
self.command = command self.command = command
self.reply_markup = reply_markup self.reply_markup = reply_markup
async def reply_text(self, async def reply(self,
text: str, text: str,
quote: bool = None, quote: bool = None,
parse_mode: str = "", parse_mode: str = "",
@ -460,3 +461,115 @@ class Message(Object):
) )
return True return True
async def click(self, x: int or str, y: int = None, quote: bool = None):
"""Use this method to click a button attached to the message.
It's a shortcut for:
- Clicking inline buttons:
.. code-block:: python
client.request_callback_answer(
chat_id=message.chat.id,
message_id=message.message_id,
callback_data=message.reply_markup[i][j].callback_data
)
- Clicking normal buttons:
.. code-block:: python
client.send_message(
chat_id=message.chat.id,
text=message.reply_markup[i][j].text
)
This method can be used in three different ways:
1. Pass one integer argument only (e.g.: ``.click(2)``, to click a button at index 2).
Buttons are counted left to right, starting from the top.
2. Pass two integer arguments (e.g.: ``.click(1, 0)``, to click a button at position (1, 0)).
The origin (0, 0) is top-left.
3. Pass one string argument only (e.g.: ``.click("Settings")``, to click a button by using its label).
Only the first matching button will be pressed.
Args:
x (``int`` | ``str``):
Used as integer index, integer abscissa (in pair with y) or as string label.
y (``int``, *optional*):
Used as ordinate only (in pair with x).
quote (``bool``, *optional*):
Useful for normal buttons only, where pressing it will result in a new message sent.
If ``True``, the message will be sent as a reply to this message.
Defaults to ``True`` in group chats and ``False`` in private chats.
Returns:
- The result of *request_callback_answer()* in case of inline callback button clicks.
- The result of *reply()* in case of normal button clicks.
- A string in case the inline button is an URL, switch_inline_query or switch_inline_query_current_chat
button.
Raises:
:class:`Error <pyrogram.Error>`
``ValueError``: If the provided index or position is out of range or the button label was not found.
"""
if isinstance(self.reply_markup, ReplyKeyboardMarkup):
if quote is None:
quote = self.chat.type != "private"
return await self.reply(x, quote=quote)
elif isinstance(self.reply_markup, InlineKeyboardMarkup):
if isinstance(x, int) and y is None:
try:
button = [
button
for row in self.reply_markup.inline_keyboard
for button in row
][x]
except IndexError:
raise ValueError("The button at index {} doesn't exist".format(x)) from None
elif isinstance(x, int) and isinstance(y, int):
try:
button = self.reply_markup.inline_keyboard[y][x]
except IndexError:
raise ValueError("The button at position ({}, {}) doesn't exist".format(x, y)) from None
elif isinstance(x, str):
x = x.encode("utf-16", "surrogatepass").decode("utf-16")
try:
button = [
button
for row in self.reply_markup.inline_keyboard
for button in row
if x == button.text
][0]
except IndexError:
raise ValueError(
"The button with label '{}' doesn't exists".format(
x.encode("unicode_escape").decode()
)
) from None
else:
raise ValueError("Invalid arguments")
if button.callback_data:
return await self._client.request_callback_answer(
chat_id=self.chat.id,
message_id=self.message_id,
data=button.callback_data
)
elif button.url:
return button.url
elif button.switch_inline_query:
return button.switch_inline_query
elif button.switch_inline_query_current_chat:
return button.switch_inline_query_current_chat
else:
raise ValueError("This button is not supported yet")
else:
raise ValueError("The message doesn't contain any keyboard")