From e6c6bd839c2ceff278bfac3ef0e8a59f9e9c7eb7 Mon Sep 17 00:00:00 2001 From: Vitali Date: Tue, 19 Jun 2018 11:18:12 -0300 Subject: [PATCH 1/6] Add Handler to deleted messages update --- pyrogram/__init__.py | 4 +- pyrogram/client/__init__.py | 5 +- pyrogram/client/dispatcher/dispatcher.py | 31 ++++++++++- pyrogram/client/ext/utils.py | 16 ++++++ pyrogram/client/filters/filters.py | 6 +-- pyrogram/client/handlers/__init__.py | 1 + .../handlers/deleted_messages_handler.py | 52 +++++++++++++++++++ .../client/methods/decorators/__init__.py | 3 +- .../methods/decorators/on_deleted_messages.py | 42 +++++++++++++++ pyrogram/client/types/update.py | 10 ++++ 10 files changed, 161 insertions(+), 9 deletions(-) create mode 100644 pyrogram/client/handlers/deleted_messages_handler.py create mode 100644 pyrogram/client/methods/decorators/on_deleted_messages.py diff --git a/pyrogram/__init__.py b/pyrogram/__init__.py index 5581b969..531da722 100644 --- a/pyrogram/__init__.py +++ b/pyrogram/__init__.py @@ -38,6 +38,6 @@ from .client.types.reply_markup import ( ) from .client import ( Client, ChatAction, ParseMode, Emoji, - MessageHandler, CallbackQueryHandler, RawUpdateHandler, - DisconnectHandler, Filters + MessageHandler, DeletedMessagesHandler, CallbackQueryHandler, + RawUpdateHandler, DisconnectHandler, Filters ) diff --git a/pyrogram/client/__init__.py b/pyrogram/client/__init__.py index 21bde533..b345de94 100644 --- a/pyrogram/client/__init__.py +++ b/pyrogram/client/__init__.py @@ -20,6 +20,7 @@ from .client import Client from .ext import BaseClient, ChatAction, Emoji, ParseMode from .filters import Filters from .handlers import ( - MessageHandler, CallbackQueryHandler, - RawUpdateHandler, DisconnectHandler + MessageHandler, DeletedMessagesHandler, + CallbackQueryHandler, RawUpdateHandler, + DisconnectHandler ) diff --git a/pyrogram/client/dispatcher/dispatcher.py b/pyrogram/client/dispatcher/dispatcher.py index 51be2ebb..ffff16bd 100644 --- a/pyrogram/client/dispatcher/dispatcher.py +++ b/pyrogram/client/dispatcher/dispatcher.py @@ -25,7 +25,7 @@ from threading import Thread import pyrogram from pyrogram.api import types from ..ext import utils -from ..handlers import RawUpdateHandler, CallbackQueryHandler, MessageHandler +from ..handlers import RawUpdateHandler, CallbackQueryHandler, MessageHandler, DeletedMessagesHandler log = logging.getLogger(__name__) @@ -41,6 +41,11 @@ class Dispatcher: types.UpdateEditChannelMessage ) + DELETE_MESSAGE_UPDATES = ( + types.UpdateDeleteMessages, + types.UpdateDeleteChannelMessages + ) + MESSAGE_UPDATES = NEW_MESSAGE_UPDATES + EDIT_MESSAGE_UPDATES def __init__(self, client, workers): @@ -97,6 +102,9 @@ class Dispatcher: or update.edited_message or update.edited_channel_post) + deleted_messages = (update.deleted_channel_posts + or update.deleted_messages) + callback_query = update.callback_query if message and isinstance(handler, MessageHandler): @@ -104,6 +112,11 @@ class Dispatcher: continue args = (self.client, message) + elif deleted_messages and isinstance(handler, DeletedMessagesHandler): + if not handler.check(deleted_messages): + continue + + args = (self.client, deleted_messages) elif callback_query and isinstance(handler, CallbackQueryHandler): if not handler.check(callback_query): continue @@ -161,6 +174,22 @@ class Dispatcher: else None) ) ) + + elif isinstance(update, Dispatcher.DELETE_MESSAGE_UPDATES): + is_channel = hasattr(update, 'channel_id') + + messages = utils.parse_deleted_messages( + update.messages, + (update.channel_id if is_channel else None) + ) + + self.dispatch( + pyrogram.Update( + deleted_messages=(messages if not is_channel else None), + deleted_channel_posts=(messages if is_channel else None) + ) + ) + elif isinstance(update, types.UpdateBotCallbackQuery): self.dispatch( pyrogram.Update( diff --git a/pyrogram/client/ext/utils.py b/pyrogram/client/ext/utils.py index d7a09ee1..26017c90 100644 --- a/pyrogram/client/ext/utils.py +++ b/pyrogram/client/ext/utils.py @@ -711,6 +711,22 @@ def parse_messages( return parsed_messages if is_list else parsed_messages[0] +def parse_deleted_messages( + messages: list, + channel_id: int +) -> pyrogram_types.Messages: + parsed_messages = [] + + for message in messages: + m = pyrogram_types.Message( + message_id=message, + chat=(pyrogram_types.Chat(id=channel_id, type="channel") if channel_id is not None else None) + ) + parsed_messages.append(m) + + return pyrogram_types.Messages(len(parsed_messages), parsed_messages) + + def get_peer_id(input_peer) -> int: return ( input_peer.user_id if isinstance(input_peer, types.InputPeerUser) diff --git a/pyrogram/client/filters/filters.py b/pyrogram/client/filters/filters.py index e92948b6..26aa84c8 100644 --- a/pyrogram/client/filters/filters.py +++ b/pyrogram/client/filters/filters.py @@ -89,13 +89,13 @@ class Filters: venue = build("Venue", lambda _, m: bool(m.venue)) """Filter messages that contain :obj:`Venue ` objects.""" - private = build("Private", lambda _, m: bool(m.chat.type == "private")) + private = build("Private", lambda _, m: bool(m.chat and m.chat.type == "private")) """Filter messages sent in private chats.""" - group = build("Group", lambda _, m: bool(m.chat.type in {"group", "supergroup"})) + group = build("Group", lambda _, m: bool(m.chat and m.chat.type in {"group", "supergroup"})) """Filter messages sent in group or supergroup chats.""" - channel = build("Channel", lambda _, m: bool(m.chat.type == "channel")) + channel = build("Channel", lambda _, m: bool(m.chat and m.chat.type == "channel")) """Filter messages sent in channels.""" new_chat_members = build("NewChatMembers", lambda _, m: bool(m.new_chat_members)) diff --git a/pyrogram/client/handlers/__init__.py b/pyrogram/client/handlers/__init__.py index 38a8aeeb..d06b2a76 100644 --- a/pyrogram/client/handlers/__init__.py +++ b/pyrogram/client/handlers/__init__.py @@ -19,4 +19,5 @@ from .callback_query_handler import CallbackQueryHandler from .disconnect_handler import DisconnectHandler from .message_handler import MessageHandler +from .deleted_messages_handler import DeletedMessagesHandler from .raw_update_handler import RawUpdateHandler diff --git a/pyrogram/client/handlers/deleted_messages_handler.py b/pyrogram/client/handlers/deleted_messages_handler.py new file mode 100644 index 00000000..2f90d5da --- /dev/null +++ b/pyrogram/client/handlers/deleted_messages_handler.py @@ -0,0 +1,52 @@ +# 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 .handler import Handler + + +class DeletedMessagesHandler(Handler): + """The Deleted Message handler class. Used to handle deleted messages coming from any chat + (private, group, channel). It is intended to be used with + :meth:`add_handler() ` + + 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 `): + Pass one or more filters to allow only a subset of messages to be passed + in your callback function. + + Other parameters: + client (:obj:`Client `): + The Client itself, useful when you want to call other API methods inside the message handler. + + message (:obj:`Message `): + The received message. + """ + + def __init__(self, callback: callable, filters=None): + super().__init__(callback, filters) + + def check(self, messages): + return ( + self.filters(messages.messages[0]) + if self.filters + else True + ) diff --git a/pyrogram/client/methods/decorators/__init__.py b/pyrogram/client/methods/decorators/__init__.py index 6ece61ff..f84a922c 100644 --- a/pyrogram/client/methods/decorators/__init__.py +++ b/pyrogram/client/methods/decorators/__init__.py @@ -19,8 +19,9 @@ from .on_callback_query import OnCallbackQuery from .on_disconnect import OnDisconnect from .on_message import OnMessage +from .on_deleted_messages import OnDeletedMessages from .on_raw_update import OnRawUpdate -class Decorators(OnMessage, OnCallbackQuery, OnRawUpdate, OnDisconnect): +class Decorators(OnMessage, OnDeletedMessages, OnCallbackQuery, OnRawUpdate, OnDisconnect): pass diff --git a/pyrogram/client/methods/decorators/on_deleted_messages.py b/pyrogram/client/methods/decorators/on_deleted_messages.py new file mode 100644 index 00000000..4cc2d904 --- /dev/null +++ b/pyrogram/client/methods/decorators/on_deleted_messages.py @@ -0,0 +1,42 @@ +# 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 . + +import pyrogram +from ...ext import BaseClient + + +class OnDeletedMessages(BaseClient): + def on_deleted_messages(self, filters=None, group: int = 0): + """Use this decorator to automatically register a function for handling + deleted messages. This does the same thing as :meth:`add_handler` using the + DeletedMessagesHandler. + + Args: + filters (:obj:`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): + self.add_handler(pyrogram.DeletedMessagesHandler(func, filters), group) + return func + + return decorator diff --git a/pyrogram/client/types/update.py b/pyrogram/client/types/update.py index edd5d85c..05295285 100644 --- a/pyrogram/client/types/update.py +++ b/pyrogram/client/types/update.py @@ -30,12 +30,18 @@ class Update(Object): edited_message (:obj:`Message `, *optional*): New version of a message that is known to the bot and was edited. + deleted_messages (:obj:`Message `, *optional*): + Deleted messages. + channel_post (:obj:`Message `, *optional*): New incoming channel post of any kind — text, photo, sticker, etc. edited_channel_post (:obj:`Message `, *optional*): New version of a channel post that is known to the bot and was edited. + deleted_channel_posts (:obj:`Message `, *optional*): + Deleted channel posts. + inline_query (:obj:`InlineQuery `, *optional*): New incoming inline query. @@ -60,8 +66,10 @@ class Update(Object): self, message=None, edited_message=None, + deleted_messages=None, channel_post=None, edited_channel_post=None, + deleted_channel_posts=None, inline_query=None, chosen_inline_result=None, callback_query=None, @@ -70,8 +78,10 @@ class Update(Object): ): self.message = message self.edited_message = edited_message + self.deleted_messages = deleted_messages self.channel_post = channel_post self.edited_channel_post = edited_channel_post + self.deleted_channel_posts = deleted_channel_posts self.inline_query = inline_query self.chosen_inline_result = chosen_inline_result self.callback_query = callback_query From 872f4f865a281da0ba978b0a5e2ea683c48810b6 Mon Sep 17 00:00:00 2001 From: Vitali Date: Tue, 19 Jun 2018 11:27:34 -0300 Subject: [PATCH 2/6] Fix comments --- pyrogram/client/handlers/deleted_messages_handler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyrogram/client/handlers/deleted_messages_handler.py b/pyrogram/client/handlers/deleted_messages_handler.py index 2f90d5da..29bed259 100644 --- a/pyrogram/client/handlers/deleted_messages_handler.py +++ b/pyrogram/client/handlers/deleted_messages_handler.py @@ -37,8 +37,8 @@ class DeletedMessagesHandler(Handler): client (:obj:`Client `): The Client itself, useful when you want to call other API methods inside the message handler. - message (:obj:`Message `): - The received message. + messages (:obj:`Message `): + The received messages. """ def __init__(self, callback: callable, filters=None): From c5fb0d60790125997602e3fe8a3d9ef59c0b9d9e Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 20 Jun 2018 12:15:55 +0200 Subject: [PATCH 3/6] Use -100 prefix for channel ids --- pyrogram/client/ext/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/client/ext/utils.py b/pyrogram/client/ext/utils.py index 26017c90..6dda20b7 100644 --- a/pyrogram/client/ext/utils.py +++ b/pyrogram/client/ext/utils.py @@ -720,7 +720,7 @@ def parse_deleted_messages( for message in messages: m = pyrogram_types.Message( message_id=message, - chat=(pyrogram_types.Chat(id=channel_id, type="channel") if channel_id is not None else None) + chat=(pyrogram_types.Chat(id=int("-100" + str(channel_id)), type="channel") if channel_id is not None else None) ) parsed_messages.append(m) From afc0c87cd3e1d1cac3b92524f27e3d9456b48d4a Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 20 Jun 2018 12:19:32 +0200 Subject: [PATCH 4/6] Fix DeletedMessagesHandler docstrings --- pyrogram/client/handlers/deleted_messages_handler.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pyrogram/client/handlers/deleted_messages_handler.py b/pyrogram/client/handlers/deleted_messages_handler.py index 29bed259..6a1f7689 100644 --- a/pyrogram/client/handlers/deleted_messages_handler.py +++ b/pyrogram/client/handlers/deleted_messages_handler.py @@ -20,14 +20,14 @@ from .handler import Handler class DeletedMessagesHandler(Handler): - """The Deleted Message handler class. Used to handle deleted messages coming from any chat + """The Deleted Messages handler class. Used to handle deleted messages coming from any chat (private, group, channel). It is intended to be used with :meth:`add_handler() ` 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). + Pass a function that will be called when one or more Messages have been deleted. + It takes *(client, messages)* as positional arguments (look at the section below for a detailed description). filters (:obj:`Filters `): Pass one or more filters to allow only a subset of messages to be passed @@ -37,8 +37,8 @@ class DeletedMessagesHandler(Handler): client (:obj:`Client `): The Client itself, useful when you want to call other API methods inside the message handler. - messages (:obj:`Message `): - The received messages. + messages (:obj:`Messages `): + The deleted messages. """ def __init__(self, callback: callable, filters=None): From 1c4047f2c6d2b4a255d12c74f54d4c349e8a978a Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 20 Jun 2018 12:20:48 +0200 Subject: [PATCH 5/6] Fix Update docstrings --- pyrogram/client/types/update.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyrogram/client/types/update.py b/pyrogram/client/types/update.py index 05295285..c8959708 100644 --- a/pyrogram/client/types/update.py +++ b/pyrogram/client/types/update.py @@ -30,7 +30,7 @@ class Update(Object): edited_message (:obj:`Message `, *optional*): New version of a message that is known to the bot and was edited. - deleted_messages (:obj:`Message `, *optional*): + deleted_messages (:obj:`Messages `, *optional*): Deleted messages. channel_post (:obj:`Message `, *optional*): @@ -39,7 +39,7 @@ class Update(Object): edited_channel_post (:obj:`Message `, *optional*): New version of a channel post that is known to the bot and was edited. - deleted_channel_posts (:obj:`Message `, *optional*): + deleted_channel_posts (:obj:`Messages `, *optional*): Deleted channel posts. inline_query (:obj:`InlineQuery `, *optional*): From ff915965f158025aa3aac5f34fb4ab62fa70977f Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 21 Jun 2018 15:33:30 +0200 Subject: [PATCH 6/6] Minor style fixes --- pyrogram/client/ext/utils.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/pyrogram/client/ext/utils.py b/pyrogram/client/ext/utils.py index 6dda20b7..2913c38b 100644 --- a/pyrogram/client/ext/utils.py +++ b/pyrogram/client/ext/utils.py @@ -718,11 +718,14 @@ def parse_deleted_messages( parsed_messages = [] for message in messages: - m = pyrogram_types.Message( - message_id=message, - chat=(pyrogram_types.Chat(id=int("-100" + str(channel_id)), type="channel") if channel_id is not None else None) + parsed_messages.append( + pyrogram_types.Message( + message_id=message, + chat=(pyrogram_types.Chat(id=int("-100" + str(channel_id)), type="channel") + if channel_id is not None + else None) + ) ) - parsed_messages.append(m) return pyrogram_types.Messages(len(parsed_messages), parsed_messages)