From 91133812a718e669ae30570652f355960c994d5e Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 27 Mar 2018 12:22:57 +0200 Subject: [PATCH] Add support for service messages --- pyrogram/client/client.py | 18 +++++++++++ pyrogram/client/utils.py | 67 ++++++++++++++++++++++++++++++++------- pyrogram/crypto/aes.py | 54 +------------------------------ 3 files changed, 74 insertions(+), 65 deletions(-) diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index cb585566..ebb87dd3 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -727,6 +727,24 @@ class Client: ) else: continue + elif isinstance(message, types.MessageService): + m = utils.parse_message_service(message, users, chats) + + if isinstance(message.action, types.MessageActionPinMessage): + pm = self.get_messages(m.chat.id, [message.reply_to_msg_id]) + + message = pm.messages[0] + + if isinstance(message, types.Message): + m.pinned_message = utils.parse_message( + message, + {i.id: i for i in pm.users}, + {i.id: i for i in pm.chats} + ) + else: + continue + else: + continue else: continue diff --git a/pyrogram/client/utils.py b/pyrogram/client/utils.py index 5d5b37ba..053b06f7 100644 --- a/pyrogram/client/utils.py +++ b/pyrogram/client/utils.py @@ -43,6 +43,15 @@ def parse_user(user: types.User): ) if user else None +def parse_chat(peer: types.PeerUser or types.PeerChat or types.PeerChannel, users: dict, chats: dict): + if isinstance(peer, types.PeerUser): + return parse_user_chat(users[peer.user_id]) + elif isinstance(peer, types.PeerChat): + return parse_chat_chat(chats[peer.chat_id]) + else: + return parse_channel_chat(chats[peer.channel_id]) + + def parse_user_chat(user: types.User): return pyrogram.Chat( id=user.id, @@ -58,7 +67,7 @@ def parse_chat_chat(chat: types.Chat): id=-chat.id, type="group", title=chat.title, - all_members_are_administrators=chat.admins_enabled + all_members_are_administrators=not chat.admins_enabled ) @@ -72,15 +81,6 @@ def parse_channel_chat(channel: types.Channel): def parse_message(message: types.Message, users: dict, chats: dict): - from_user = users.get(message.from_id, None) # type: types.User - - if isinstance(message.to_id, types.PeerUser): - chat = parse_user_chat(users[message.to_id.user_id]) - elif isinstance(message.to_id, types.PeerChat): - chat = parse_chat_chat(chats[message.to_id.chat_id]) - else: - chat = parse_channel_chat(chats[message.to_id.channel_id]) - entities = parse_entities(message.entities) forward_from = None @@ -104,8 +104,8 @@ def parse_message(message: types.Message, users: dict, chats: dict): return pyrogram.Message( message_id=message.id, date=message.date, - chat=chat, - from_user=parse_user(from_user), + chat=parse_chat(message.to_id, users, chats), + from_user=parse_user(users.get(message.from_id, None)), text=message.message or None if message.media is None else None, caption=message.message or None if message.media is not None else None, entities=entities or None if message.media is None else None, @@ -118,3 +118,46 @@ def parse_message(message: types.Message, users: dict, chats: dict): forward_date=forward_date, edit_date=message.edit_date ) + + +def parse_message_service(message: types.MessageService, users: dict, chats: dict): + action = message.action + + new_chat_members = None + left_chat_member = None + new_chat_title = None + delete_chat_photo = None + migrate_to_chat_id = None + migrate_from_chat_id = None + group_chat_created = None + + if isinstance(action, types.MessageActionChatAddUser): + new_chat_members = [parse_user(users[i]) for i in action.users] + elif isinstance(action, types.MessageActionChatJoinedByLink): + new_chat_members = [parse_user(users[action.inviter_id])] + elif isinstance(action, types.MessageActionChatDeleteUser): + left_chat_member = parse_user(users[action.user_id]) + elif isinstance(action, types.MessageActionChatEditTitle): + new_chat_title = action.title + elif isinstance(action, types.MessageActionChatDeletePhoto): + delete_chat_photo = True + elif isinstance(action, types.MessageActionChatMigrateTo): + migrate_to_chat_id = action.channel_id + elif isinstance(action, types.MessageActionChannelMigrateFrom): + migrate_from_chat_id = action.chat_id + elif isinstance(action, types.MessageActionChatCreate): + group_chat_created = True + + return pyrogram.Message( + message_id=message.id, + date=message.date, + chat=parse_chat(message.to_id, users, chats), + from_user=parse_user(users.get(message.from_id, None)), + new_chat_members=new_chat_members, + left_chat_member=left_chat_member, + new_chat_title=new_chat_title, + delete_chat_photo=delete_chat_photo, + migrate_to_chat_id=migrate_to_chat_id, + migrate_from_chat_id=migrate_from_chat_id, + group_chat_created=group_chat_created + ) diff --git a/pyrogram/crypto/aes.py b/pyrogram/crypto/aes.py index 8ca72535..a5b0c3c8 100644 --- a/pyrogram/crypto/aes.py +++ b/pyrogram/crypto/aes.py @@ -1,53 +1 @@ -# 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 . - -try: - import tgcrypto -except ImportError as e: - e.msg = ( - "TgCrypto is missing and Pyrogram can't run without. " - "Please install it using \"pip3 install tgcrypto\". " - "More info: https://docs.pyrogram.ml/resources/TgCrypto" - ) - - raise e - - -class AES: - @classmethod - def ige_encrypt(cls, data: bytes, key: bytes, iv: bytes) -> bytes: - return tgcrypto.ige_encrypt(data, key, iv) - - @classmethod - def ige_decrypt(cls, data: bytes, key: bytes, iv: bytes) -> bytes: - return tgcrypto.ige_decrypt(data, key, iv) - - @staticmethod - def ctr_decrypt(data: bytes, key: bytes, iv: bytes, offset: int) -> bytes: - replace = int.to_bytes(offset // 16, 4, "big") - iv = iv[:-4] + replace - - return tgcrypto.ctr_decrypt(data, key, iv) - - @staticmethod - def xor(a: bytes, b: bytes) -> bytes: - return int.to_bytes( - int.from_bytes(a, "big") ^ int.from_bytes(b, "big"), - len(a), - "big", - ) +# 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 . try: import tgcrypto except ImportError as e: e.msg = ( "TgCrypto is missing and Pyrogram can't run without. " "Please install it using \"pip3 install tgcrypto\". " "More info: https://docs.pyrogram.ml/resources/TgCrypto" ) raise e class AES: @classmethod def ige_encrypt(cls, data: bytes, key: bytes, iv: bytes) -> bytes: return tgcrypto.ige_encrypt(data, key, iv) @classmethod def ige_decrypt(cls, data: bytes, key: bytes, iv: bytes) -> bytes: return tgcrypto.ige_decrypt(data, key, iv) @staticmethod def ctr_decrypt(data: bytes, key: bytes, iv: bytes, offset: int) -> bytes: replace = int.to_bytes(offset // 16, 4, "big") iv = iv[:-4] + replace return tgcrypto.ctr_decrypt(data, key, iv) @staticmethod def xor(a: bytes, b: bytes) -> bytes: return int.to_bytes( int.from_bytes(a, "big") ^ int.from_bytes(b, "big"), len(a), "big", ) \ No newline at end of file