2
0
mirror of https://github.com/pyrogram/pyrogram synced 2025-08-29 05:18:10 +00:00

Document the new features

This commit is contained in:
Dan 2018-04-11 03:16:48 +02:00
parent 84b1e697bb
commit 472ed8e355
17 changed files with 322 additions and 120 deletions

View File

@ -297,7 +297,7 @@ def start():
"{}: {}{}".format( "{}: {}{}".format(
arg_name, arg_name,
"``optional`` ".format(flag_number) if is_optional else "", "``optional`` ".format(flag_number) if is_optional else "",
get_docstring_arg_type(arg_type) get_docstring_arg_type(arg_type, is_pyrogram_type=c.namespace == "pyrogram")
) )
) )

View File

@ -0,0 +1,6 @@
Filters
=======
.. autoclass:: pyrogram.Filters
:members:
:undoc-members:

View File

@ -1,6 +0,0 @@
InputMedia
==========
.. autoclass:: pyrogram.InputMedia
:members:
:undoc-members:

View File

@ -0,0 +1,6 @@
InputMediaPhoto
===============
.. autoclass:: pyrogram.InputMediaPhoto
:members:
:undoc-members:

View File

@ -0,0 +1,6 @@
InputMediaVideo
===============
.. autoclass:: pyrogram.InputMediaVideo
:members:
:undoc-members:

View File

@ -0,0 +1,6 @@
MessageHandler
==============
.. autoclass:: pyrogram.MessageHandler
:members:
:undoc-members:

View File

@ -0,0 +1,6 @@
\RawUpdateHandler
================
.. autoclass:: pyrogram.RawUpdateHandler
:members:
:undoc-members:

View File

@ -9,9 +9,36 @@ the same parameters as well, thus offering a familiar look to Bot developers.
.. toctree:: .. toctree::
Client Client
MessageHandler
RawUpdateHandler
Filters
ChatAction ChatAction
ParseMode ParseMode
InputMedia
Error Error
Types
-----
.. toctree::
../types/pyrogram/User
../types/pyrogram/Chat
../types/pyrogram/Message
../types/pyrogram/MessageEntity
../types/pyrogram/PhotoSize
../types/pyrogram/Audio
../types/pyrogram/Document
../types/pyrogram/Video
../types/pyrogram/Voice
../types/pyrogram/VideoNote
../types/pyrogram/Contact
../types/pyrogram/Location
../types/pyrogram/Venue
../types/pyrogram/UserProfilePhotos
../types/pyrogram/ChatPhoto
../types/pyrogram/ChatMember
InputMediaPhoto
InputMediaVideo
../types/pyrogram/Sticker
.. _Telegram Bot API: https://core.telegram.org/bots/api#available-methods .. _Telegram Bot API: https://core.telegram.org/bots/api#available-methods

View File

@ -34,5 +34,5 @@ from .client.input_media_photo import InputMediaPhoto
from .client.input_media_video import InputMediaVideo from .client.input_media_video import InputMediaVideo
from .client.input_phone_contact import InputPhoneContact from .client.input_phone_contact import InputPhoneContact
from .client import Emoji from .client import Emoji
from .client.handler import MessageHandler, RawUpdateHandler from .client.handlers import MessageHandler, RawUpdateHandler
from .client.filters import Filters from .client.filters import Filters

View File

@ -51,7 +51,6 @@ from pyrogram.session import Auth, Session
from pyrogram.session.internals import MsgId from pyrogram.session.internals import MsgId
from . import message_parser from . import message_parser
from .dispatcher import Dispatcher from .dispatcher import Dispatcher
from .handler import Handler
from .input_media import InputMedia from .input_media import InputMedia
from .style import Markdown, HTML from .style import Markdown, HTML
from .utils import decode from .utils import decode
@ -204,6 +203,19 @@ class Client:
self.update_handler = None self.update_handler = None
def on_message(self, filters=None, group: int = 0): def on_message(self, filters=None, group: int = 0):
"""Use this decorator to automatically register a function for handling
messages. This does the same thing as :meth:`add_handler` using the
MessageHandler.
Args:
filters (:obj:`Filters <pyrogram.Filters>`):
Pass one or more filters to allow only a subset of messages to be passed
in your function.
group (``int``, optional):
The group identifier, defaults to 0.
"""
def decorator(func): def decorator(func):
self.add_handler(pyrogram.MessageHandler(func, filters), group) self.add_handler(pyrogram.MessageHandler(func, filters), group)
return func return func
@ -211,13 +223,35 @@ class Client:
return decorator return decorator
def on_raw_update(self, group: int = 0): def on_raw_update(self, group: int = 0):
"""Use this decorator to automatically register a function for handling
raw updates. This does the same thing as :meth:`add_handler` using the
RawUpdateHandler.
Args:
group (``int``, optional):
The group identifier, defaults to 0.
"""
def decorator(func): def decorator(func):
self.add_handler(pyrogram.RawUpdateHandler(func), group) self.add_handler(pyrogram.RawUpdateHandler(func), group)
return func return func
return decorator return decorator
def add_handler(self, handler: Handler, group: int = 0): def add_handler(self, handler, group: int = 0):
"""Use this method to register an event handler.
You can register multiple handlers, but at most one handler within a group
will be used for a single event. To handle the same event more than once, register
your handler using a different group id (lower group id == higher priority).
Args:
handler (:obj:`Handler <pyrogram.handler.Handler>`):
The handler to be registered.
group (``int``, optional):
The group identifier, defaults to 0.
"""
self.dispatcher.add_handler(handler, group) self.dispatcher.add_handler(handler, group)
def start(self): def start(self):

View File

@ -25,9 +25,7 @@ from threading import Thread
import pyrogram import pyrogram
from pyrogram.api import types from pyrogram.api import types
from .. import message_parser from .. import message_parser
from ..handler import ( from ..handlers import RawUpdateHandler
Handler, RawUpdateHandler
)
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -62,7 +60,7 @@ class Dispatcher:
for _ in range(self.workers): for _ in range(self.workers):
self.updates.put(None) self.updates.put(None)
def add_handler(self, handler: Handler, group: int): def add_handler(self, handler, group: int):
if group not in self.groups: if group not in self.groups:
self.groups[group] = [] self.groups[group] = []
self.groups = OrderedDict(sorted(self.groups.items())) self.groups = OrderedDict(sorted(self.groups.items()))

View File

@ -29,10 +29,71 @@ def build(name: str, func: callable, **kwargs) -> type:
class Filters: class Filters:
"""This class provides access to all the Filters available in Pyrogram.
It is intended to be used when adding an handler."""
text = build("Text", lambda _, m: bool(m.text and not m.text.startswith("/"))) text = build("Text", lambda _, m: bool(m.text and not m.text.startswith("/")))
"""Filter text messages."""
reply = build("Reply", lambda _, m: bool(m.reply_to_message))
"""Filter messages that are replies to other messages."""
forwarded = build("Forwarded", lambda _, m: bool(m.forward_date))
"""Filter messages that are forwarded."""
caption = build("Caption", lambda _, m: bool(m.caption))
"""Filter media messages that contain captions."""
edited = build("Edited", lambda _, m: bool(m.edit_date))
"""Filter edited messages."""
audio = build("Audio", lambda _, m: bool(m.audio))
"""Filter messages that contain an :obj:`Audio <pyrogram.Audio>`."""
document = build("Document", lambda _, m: bool(m.document))
"""Filter messages that contain a :obj:`Document <pyrogram.Document>`."""
photo = build("Photo", lambda _, m: bool(m.photo))
"""Filter messages that contain a :obj:`Photo <pyrogram.Photo>`."""
sticker = build("Sticker", lambda _, m: bool(m.sticker))
"""Filter messages that contain a :obj:`Sticker <pyrogram.Sticker>`."""
video = build("Video", lambda _, m: bool(m.video))
"""Filter messages that contain a :obj:`Video <pyrogram.Video>`."""
voice = build("Voice", lambda _, m: bool(m.voice))
"""Filter messages that contain a :obj:`Voice <pyrogram.Voice>` note."""
video_note = build("Voice", lambda _, m: bool(m.video_note))
"""Filter messages that contain a :obj:`VideoNote <pyrogram.VideoNote>`."""
contact = build("Contact", lambda _, m: bool(m.contact))
"""Filter messages that contain a :obj:`Contact <pyrogram.Contact>`."""
location = build("Location", lambda _, m: bool(m.location))
"""Filter messages that contain a :obj:`Location <pyrogram.Location>`."""
venue = build("Venue", lambda _, m: bool(m.venue))
"""Filter messages that contain a :obj:`Venue <pyrogram.Venue>`."""
private = build("Private", lambda _, m: bool(m.chat.type == "private"))
"""Filter messages sent in private chats."""
group = build("Group", lambda _, m: bool(m.chat.type in {"group", "supergroup"}))
"""Filter messages sent in group or supergroup chats."""
channel = build("Channel", lambda _, m: bool(m.chat.type == "channel"))
"""Filter messages sent in channels."""
@staticmethod @staticmethod
def command(command: str or list): def command(command: str or list):
"""Filter commands, i.e.: text messages starting with '/'.
Args:
command (``str`` | ``list``):
The command or list of commands as strings the filter should look for.
"""
return build( return build(
"Command", "Command",
lambda _, m: bool( lambda _, m: bool(
@ -47,28 +108,17 @@ class Filters:
) )
) )
reply = build("Reply", lambda _, m: bool(m.reply_to_message))
forwarded = build("Forwarded", lambda _, m: bool(m.forward_date))
caption = build("Caption", lambda _, m: bool(m.caption))
edited = build("Edited", lambda _, m: bool(m.edit_date))
audio = build("Audio", lambda _, m: bool(m.audio))
document = build("Document", lambda _, m: bool(m.document))
photo = build("Photo", lambda _, m: bool(m.photo))
sticker = build("Sticker", lambda _, m: bool(m.sticker))
video = build("Video", lambda _, m: bool(m.video))
voice = build("Voice", lambda _, m: bool(m.voice))
video_note = build("Voice", lambda _, m: bool(m.video_note))
contact = build("Contact", lambda _, m: bool(m.contact))
location = build("Location", lambda _, m: bool(m.location))
venue = build("Venue", lambda _, m: bool(m.venue))
private = build("Private", lambda _, m: bool(m.chat.type == "private"))
group = build("Group", lambda _, m: bool(m.chat.type in {"group", "supergroup"}))
channel = build("Channel", lambda _, m: bool(m.chat.type == "channel"))
@staticmethod @staticmethod
def regex(pattern, flags: int = 0): def regex(pattern, flags: int = 0):
"""Filter messages that match a given RegEx pattern.
Args:
pattern (``str``):
The RegEx pattern.
flags (``int``, optional):
RegEx flags.
"""
return build( return build(
"Regex", lambda _, m: bool(_.p.search(m.text or "")), "Regex", lambda _, m: bool(_.p.search(m.text or "")),
p=re.compile(pattern, flags) p=re.compile(pattern, flags)
@ -76,6 +126,12 @@ class Filters:
@staticmethod @staticmethod
def user(user: int or str or list): def user(user: int or str or list):
"""Filter messages coming from specific users.
Args:
user (``int`` | ``str`` | ``list``):
The user or list of user IDs (int) or usernames (str) the filter should look for.
"""
return build( return build(
"User", "User",
lambda _, m: bool(m.from_user lambda _, m: bool(m.from_user
@ -91,6 +147,12 @@ class Filters:
@staticmethod @staticmethod
def chat(chat: int or str or list): def chat(chat: int or str or list):
"""Filter messages coming from specific chats.
Args:
chat (``int`` | ``str`` | ``list``):
The chat or list of chat IDs (int) or usernames (str) the filter should look for.
"""
return build( return build(
"Chat", "Chat",
lambda _, m: bool(m.chat lambda _, m: bool(m.chat
@ -104,32 +166,53 @@ class Filters:
) )
) )
class _Service(Filter):
new_chat_members = build("NewChatMembers", lambda _, m: bool(m.new_chat_members)) new_chat_members = build("NewChatMembers", lambda _, m: bool(m.new_chat_members))
"""Filter service messages for new chat members."""
left_chat_member = build("LeftChatMember", lambda _, m: bool(m.left_chat_member)) left_chat_member = build("LeftChatMember", lambda _, m: bool(m.left_chat_member))
"""Filter service messages for members that left the chat."""
new_chat_title = build("NewChatTitle", lambda _, m: bool(m.new_chat_title)) new_chat_title = build("NewChatTitle", lambda _, m: bool(m.new_chat_title))
"""Filter service messages for new chat titles."""
new_chat_photo = build("NewChatPhoto", lambda _, m: bool(m.new_chat_photo)) new_chat_photo = build("NewChatPhoto", lambda _, m: bool(m.new_chat_photo))
"""Filter service messages for new chat photos."""
delete_chat_photo = build("DeleteChatPhoto", lambda _, m: bool(m.delete_chat_photo)) delete_chat_photo = build("DeleteChatPhoto", lambda _, m: bool(m.delete_chat_photo))
"""Filter service messages for deleted photos."""
group_chat_created = build("GroupChatCreated", lambda _, m: bool(m.group_chat_created)) group_chat_created = build("GroupChatCreated", lambda _, m: bool(m.group_chat_created))
"""Filter service messages for group chat creations."""
supergroup_chat_created = build("SupergroupChatCreated", lambda _, m: bool(m.supergroup_chat_created)) supergroup_chat_created = build("SupergroupChatCreated", lambda _, m: bool(m.supergroup_chat_created))
"""Filter service messages for supergroup chat creations."""
channel_chat_created = build("ChannelChatCreated", lambda _, m: bool(m.channel_chat_created)) channel_chat_created = build("ChannelChatCreated", lambda _, m: bool(m.channel_chat_created))
"""Filter service messages for channel chat creations."""
migrate_to_chat_id = build("MigrateToChatId", lambda _, m: bool(m.migrate_to_chat_id)) migrate_to_chat_id = build("MigrateToChatId", lambda _, m: bool(m.migrate_to_chat_id))
"""Filter service messages that contain migrate_to_chat_id."""
migrate_from_chat_id = build("MigrateFromChatId", lambda _, m: bool(m.migrate_from_chat_id)) migrate_from_chat_id = build("MigrateFromChatId", lambda _, m: bool(m.migrate_from_chat_id))
"""Filter service messages that contain migrate_from_chat_id."""
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."""
def __call__(self, message): service = build(
return bool( "Service",
self.new_chat_members(message) lambda _, m: bool(
or self.left_chat_member(message) _.new_chat_members(m)
or self.new_chat_title(message) or _.left_chat_member(m)
or self.new_chat_photo(message) or _.new_chat_title(m)
or self.delete_chat_photo(message) or _.new_chat_photo(m)
or self.group_chat_created(message) or _.delete_chat_photo(m)
or self.supergroup_chat_created(message) or _.group_chat_created(m)
or self.channel_chat_created(message) or _.supergroup_chat_created(m)
or self.migrate_to_chat_id(message) or _.channel_chat_created(m)
or self.migrate_from_chat_id(message) or _.migrate_to_chat_id(m)
or self.pinned_message(message) or _.migrate_from_chat_id(m)
or _.pinned_m(m)
) )
)
service = _Service() """Filter all service messages"""

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 .handler import Handler
class MessageHandler(Handler):
def __init__(self, callback: callable, filters=None):
super().__init__(callback, filters)
def check(self, message):
return (
self.filters(message)
if self.filters
else True
)

View File

@ -1,24 +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 .handler import Handler
class RawUpdateHandler(Handler):
def __init__(self, callback: callable):
super().__init__(callback)

View File

@ -16,6 +16,4 @@
# 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 .handler import Handler from .handlers import MessageHandler, RawUpdateHandler
from .message_handler import MessageHandler
from .raw_update_handler import RawUpdateHandler

View File

@ -0,0 +1,93 @@
# 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 .handler import Handler
class MessageHandler(Handler):
"""The Message handler class. It is used to handle text, media and service messages coming from
any chat (private, group, channel).
Args:
callback (``callable``):
Pass a function that will be called when a new Message arrives. It takes *(client, message)*
as positional arguments (look at the section below for a detailed description).
filters (:obj:`Filters <pyrogram.Filters>`):
Pass one or more filters to allow only a subset of messages to be passed
in your callback function.
Other parameters:
client (:obj:`Client <pyrogram.Client>`):
The Client itself, useful when you want to call other API methods inside the message handler.
message (:obj:`Message <pyrogram.Message>`):
The received message.
"""
def __init__(self, callback: callable, filters=None):
super().__init__(callback, filters)
def check(self, message):
return (
self.filters(message)
if self.filters
else True
)
class RawUpdateHandler(Handler):
"""The Raw Update handler class. It is used to handle raw updates.
Args:
callback (``callable``):
A function that will be called when a new update is received from the server. It takes
*(client, update, users, chats)* as positional arguments (look at the section below for
a detailed description).
Other Parameters:
client (:class:`Client <pyrogram.Client>`):
The Client itself, useful when you want to call other API methods inside the update handler.
update (``Update``):
The received update, which can be one of the many single Updates listed in the *updates*
field you see in the :obj:`Update <pyrogram.api.types.Update>` type.
users (``dict``):
Dictionary of all :obj:`User <pyrogram.api.types.User>` mentioned in the update.
You can access extra info about the user (such as *first_name*, *last_name*, etc...) by using
the IDs you find in the *update* argument (e.g.: *users[1768841572]*).
chats (``dict``):
Dictionary of all :obj:`Chat <pyrogram.api.types.Chat>` and
:obj:`Channel <pyrogram.api.types.Channel>` mentioned in the update.
You can access extra info about the chat (such as *title*, *participants_count*, etc...)
by using the IDs you find in the *update* argument (e.g.: *chats[1701277281]*).
Note:
The following Empty or Forbidden types may exist inside the *users* and *chats* dictionaries.
They mean you have been blocked by the user or banned from the group/channel.
- :obj:`UserEmpty <pyrogram.api.types.UserEmpty>`
- :obj:`ChatEmpty <pyrogram.api.types.ChatEmpty>`
- :obj:`ChatForbidden <pyrogram.api.types.ChatForbidden>`
- :obj:`ChannelForbidden <pyrogram.api.types.ChannelForbidden>`
"""
def __init__(self, callback: callable):
super().__init__(callback)