def parse_messages(client, messages: list or types.Message or types.MessageService or types.MessageEmpty, users: dict, chats: dict, replies: int = 1) -> pyrogram_types.Message or list: is_list = isinstance(messages, list) messages = messages if is_list else [messages] parsed_messages = [] for message in messages: if isinstance(message, types.Message): entities = parse_entities(message.entities, users) forward_from = None forward_from_chat = None forward_from_message_id = None forward_signature = None forward_date = None forward_header = message.fwd_from # type: types.MessageFwdHeader if forward_header: forward_date = forward_header.date if forward_header.from_id: forward_from = parse_user(users[forward_header.from_id]) else: forward_from_chat = parse_channel_chat( chats[forward_header.channel_id]) forward_from_message_id = forward_header.channel_post forward_signature = forward_header.post_author photo = None location = None contact = None venue = None audio = None voice = None animation = None video = None video_note = None sticker = None document = None media = message.media if media: if isinstance(media, types.MessageMediaPhoto): photo = media.photo if isinstance(photo, types.Photo): sizes = photo.sizes photo_sizes = [] for size in sizes: if isinstance( size, (types.PhotoSize, types.PhotoCachedSize)): loc = size.location if isinstance(size, types.PhotoSize): file_size = size.size else: file_size = len(size.bytes) if isinstance(loc, types.FileLocation): photo_size = pyrogram_types.PhotoSize( file_id=encode( pack("<iiqqqqi", 2, loc.dc_id, photo.id, photo.access_hash, loc.volume_id, loc.secret, loc.local_id)), width=size.w, height=size.h, file_size=file_size) photo_sizes.append(photo_size) photo = pyrogram_types.Photo(id=b64encode( pack("<qq", photo.id, photo.access_hash), b"-_").decode().rstrip("="), date=photo.date, sizes=photo_sizes) elif isinstance(media, types.MessageMediaGeo): geo_point = media.geo if isinstance(geo_point, types.GeoPoint): location = pyrogram_types.Location( longitude=geo_point.long, latitude=geo_point.lat) elif isinstance(media, types.MessageMediaContact): contact = pyrogram_types.Contact( phone_number=media.phone_number, first_name=media.first_name, last_name=media.last_name or None, vcard=media.vcard or None, user_id=media.user_id or None) elif isinstance(media, types.MessageMediaVenue): venue = pyrogram_types.Venue( location=pyrogram_types.Location( longitude=media.geo.long, latitude=media.geo.lat), title=media.title, address=media.address, foursquare_id=media.venue_id or None, foursquare_type=media.venue_type) elif isinstance(media, types.MessageMediaDocument): doc = media.document if isinstance(doc, types.Document): attributes = {type(i): i for i in doc.attributes} file_name = getattr( attributes.get(types.DocumentAttributeFilename, None), "file_name", None) if types.DocumentAttributeAudio in attributes: audio_attributes = attributes[ types.DocumentAttributeAudio] if audio_attributes.voice: voice = pyrogram_types.Voice( file_id=encode( pack("<iiqq", 3, doc.dc_id, doc.id, doc.access_hash)), duration=audio_attributes.duration, mime_type=doc.mime_type, file_size=doc.size, waveform=audio_attributes.waveform, date=doc.date) else: audio = pyrogram_types.Audio( file_id=encode( pack("<iiqq", 9, doc.dc_id, doc.id, doc.access_hash)), duration=audio_attributes.duration, performer=audio_attributes.performer, title=audio_attributes.title, mime_type=doc.mime_type, file_size=doc.size, thumb=parse_thumb(doc.thumb), file_name=file_name, date=doc.date) elif types.DocumentAttributeAnimated in attributes: video_attributes = attributes.get( types.DocumentAttributeVideo, None) animation = pyrogram_types.Animation( file_id=encode( pack("<iiqq", 10, doc.dc_id, doc.id, doc.access_hash)), width=getattr(video_attributes, "w", 0), height=getattr(video_attributes, "h", 0), duration=getattr(video_attributes, "duration", 0), thumb=parse_thumb(doc.thumb), mime_type=doc.mime_type, file_size=doc.size, file_name=file_name, date=doc.date) elif types.DocumentAttributeVideo in attributes: video_attributes = attributes[ types.DocumentAttributeVideo] if video_attributes.round_message: video_note = pyrogram_types.VideoNote( file_id=encode( pack("<iiqq", 13, doc.dc_id, doc.id, doc.access_hash)), length=video_attributes.w, duration=video_attributes.duration, thumb=parse_thumb(doc.thumb), file_size=doc.size, mime_type=doc.mime_type, date=doc.date) else: video = pyrogram_types.Video( file_id=encode( pack("<iiqq", 4, doc.dc_id, doc.id, doc.access_hash)), width=video_attributes.w, height=video_attributes.h, duration=video_attributes.duration, thumb=parse_thumb(doc.thumb), mime_type=doc.mime_type, file_size=doc.size, file_name=file_name, date=doc.date) elif types.DocumentAttributeSticker in attributes: image_size_attributes = attributes.get( types.DocumentAttributeImageSize, None) sticker_attribute = attributes[ types.DocumentAttributeSticker] if isinstance(sticker_attribute.stickerset, types.InputStickerSetID): try: set_name = client.send( functions.messages.GetStickerSet( sticker_attribute.stickerset) ).set.short_name except StickersetInvalid: set_name = None else: set_name = None sticker = pyrogram_types.Sticker( file_id=encode( pack("<iiqq", 8, doc.dc_id, doc.id, doc.access_hash)), width=image_size_attributes.w if image_size_attributes else 0, height=image_size_attributes.h if image_size_attributes else 0, thumb=parse_thumb(doc.thumb), # TODO: mask_position set_name=set_name, emoji=sticker_attribute.alt or None, file_size=doc.size, mime_type=doc.mime_type, file_name=file_name, date=doc.date) else: document = pyrogram_types.Document( file_id=encode( pack("<iiqq", 5, doc.dc_id, doc.id, doc.access_hash)), thumb=parse_thumb(doc.thumb), file_name=file_name, mime_type=doc.mime_type, file_size=doc.size, date=doc.date) else: media = None reply_markup = message.reply_markup if reply_markup: if isinstance(reply_markup, types.ReplyKeyboardForceReply): reply_markup = pyrogram_types.ForceReply.read(reply_markup) elif isinstance(reply_markup, types.ReplyKeyboardMarkup): reply_markup = pyrogram_types.ReplyKeyboardMarkup.read( reply_markup) elif isinstance(reply_markup, types.ReplyInlineMarkup): reply_markup = pyrogram_types.InlineKeyboardMarkup.read( reply_markup) elif isinstance(reply_markup, types.ReplyKeyboardHide): reply_markup = pyrogram_types.ReplyKeyboardRemove.read( reply_markup) else: reply_markup = None m = pyrogram_types.Message( message_id=message.id, date=message.date, chat=parse_chat(message, users, chats), from_user=parse_user(users.get(message.from_id, None)), text=Str(message.message) or None if media is None else None, caption=Str(message.message) or None if media is not None else None, entities=entities or None if media is None else None, caption_entities=entities or None if media is not None else None, author_signature=message.post_author, forward_from=forward_from, forward_from_chat=forward_from_chat, forward_from_message_id=forward_from_message_id, forward_signature=forward_signature, forward_date=forward_date, mentioned=message.mentioned, media=bool(media) or None, edit_date=message.edit_date, media_group_id=message.grouped_id, photo=photo, location=location, contact=contact, venue=venue, audio=audio, voice=voice, animation=animation, video=video, video_note=video_note, sticker=sticker, document=document, views=message.views, via_bot=parse_user(users.get(message.via_bot_id, None)), outgoing=message.out, client=proxy(client), reply_markup=reply_markup) if m.text: m.text.init(m._client, m.entities or []) if m.caption: m.caption.init(m._client, m.caption_entities or []) if message.reply_to_msg_id and replies: try: m.reply_to_message = client.get_messages( m.chat.id, reply_to_message_ids=message.id, replies=replies - 1) except MessageIdsEmpty: pass elif isinstance(message, types.MessageService): 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 channel_chat_created = None new_chat_photo = 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[message.from_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 elif isinstance(action, types.MessageActionChannelCreate): channel_chat_created = True elif isinstance(action, types.MessageActionChatEditPhoto): photo = action.photo if isinstance(photo, types.Photo): sizes = photo.sizes photo_sizes = [] for size in sizes: if isinstance( size, (types.PhotoSize, types.PhotoCachedSize)): loc = size.location if isinstance(size, types.PhotoSize): file_size = size.size else: file_size = len(size.bytes) if isinstance(loc, types.FileLocation): photo_size = pyrogram_types.PhotoSize( file_id=encode( pack("<iiqqqqi", 2, loc.dc_id, photo.id, photo.access_hash, loc.volume_id, loc.secret, loc.local_id)), width=size.w, height=size.h, file_size=file_size) photo_sizes.append(photo_size) new_chat_photo = pyrogram_types.Photo(id=b64encode( pack("<qq", photo.id, photo.access_hash), b"-_").decode().rstrip("="), date=photo.date, sizes=photo_sizes) m = pyrogram_types.Message( message_id=message.id, date=message.date, chat=parse_chat(message, users, chats), from_user=parse_user(users.get(message.from_id, None)), service=True, new_chat_members=new_chat_members, left_chat_member=left_chat_member, new_chat_title=new_chat_title, new_chat_photo=new_chat_photo, delete_chat_photo=delete_chat_photo, migrate_to_chat_id=int("-100" + str(migrate_to_chat_id)) if migrate_to_chat_id else None, migrate_from_chat_id=-migrate_from_chat_id if migrate_from_chat_id else None, group_chat_created=group_chat_created, channel_chat_created=channel_chat_created, client=proxy(client) # TODO: supergroup_chat_created ) if isinstance(action, types.MessageActionPinMessage): try: m.pinned_message = client.get_messages( m.chat.id, reply_to_message_ids=message.id, replies=0) except MessageIdsEmpty: pass else: m = pyrogram_types.Message(message_id=message.id, client=proxy(client), empty=True) parsed_messages.append(m) return parsed_messages if is_list else parsed_messages[0]
def parse_message(client, message: types.Message, users: dict, chats: dict, replies: int = 1) -> pyrogram_types.Message: entities = parse_entities(message.entities, users) forward_from = None forward_from_chat = None forward_from_message_id = None forward_signature = None forward_date = None forward_header = message.fwd_from # type: types.MessageFwdHeader if forward_header: forward_date = forward_header.date if forward_header.from_id: forward_from = parse_user(users[forward_header.from_id]) else: forward_from_chat = parse_channel_chat( chats[forward_header.channel_id]) forward_from_message_id = forward_header.channel_post forward_signature = forward_header.post_author photo = None location = None contact = None venue = None audio = None voice = None video = None video_note = None sticker = None document = None media = message.media if media: if isinstance(media, types.MessageMediaPhoto): photo = media.photo if isinstance(photo, types.Photo): sizes = photo.sizes photo_sizes = [] for size in sizes: if isinstance(size, (types.PhotoSize, types.PhotoCachedSize)): loc = size.location if isinstance(size, types.PhotoSize): file_size = size.size else: file_size = len(size.bytes) if isinstance(loc, types.FileLocation): photo_size = pyrogram_types.PhotoSize( file_id=encode( pack("<iiqqqqi", 2, loc.dc_id, photo.id, photo.access_hash, loc.volume_id, loc.secret, loc.local_id)), width=size.w, height=size.h, file_size=file_size, date=photo.date) photo_sizes.append(photo_size) photo = photo_sizes elif isinstance(media, types.MessageMediaGeo): geo_point = media.geo if isinstance(geo_point, types.GeoPoint): location = pyrogram_types.Location(longitude=geo_point.long, latitude=geo_point.lat) elif isinstance(media, types.MessageMediaContact): contact = pyrogram_types.Contact(phone_number=media.phone_number, first_name=media.first_name, last_name=media.last_name or None, user_id=media.user_id or None) elif isinstance(media, types.MessageMediaVenue): venue = pyrogram_types.Venue(location=pyrogram_types.Location( longitude=media.geo.long, latitude=media.geo.lat), title=media.title, address=media.address, foursquare_id=media.venue_id or None) elif isinstance(media, types.MessageMediaDocument): doc = media.document if isinstance(doc, types.Document): attributes = {type(i): i for i in doc.attributes} file_name = getattr( attributes.get(types.DocumentAttributeFilename, None), "file_name", None) if types.DocumentAttributeAudio in attributes: audio_attributes = attributes[types.DocumentAttributeAudio] if audio_attributes.voice: voice = pyrogram_types.Voice( file_id=encode( pack("<iiqq", 3, doc.dc_id, doc.id, doc.access_hash)), duration=audio_attributes.duration, mime_type=doc.mime_type, file_size=doc.size, thumb=parse_thumb(doc.thumb), file_name=file_name, date=doc.date) else: audio = pyrogram_types.Audio( file_id=encode( pack("<iiqq", 9, doc.dc_id, doc.id, doc.access_hash)), duration=audio_attributes.duration, performer=audio_attributes.performer, title=audio_attributes.title, mime_type=doc.mime_type, file_size=doc.size, thumb=parse_thumb(doc.thumb), file_name=file_name, date=doc.date) elif types.DocumentAttributeAnimated in attributes: document = pyrogram_types.Document(file_id=encode( pack("<iiqq", 10, doc.dc_id, doc.id, doc.access_hash)), thumb=parse_thumb( doc.thumb), file_name=file_name, mime_type=doc.mime_type, file_size=doc.size, date=doc.date) elif types.DocumentAttributeVideo in attributes: video_attributes = attributes[types.DocumentAttributeVideo] if video_attributes.round_message: video_note = pyrogram_types.VideoNote( file_id=encode( pack("<iiqq", 13, doc.dc_id, doc.id, doc.access_hash)), length=video_attributes.w, duration=video_attributes.duration, thumb=parse_thumb(doc.thumb), file_size=doc.size, file_name=file_name, mime_type=doc.mime_type, date=doc.date) else: video = pyrogram_types.Video( file_id=encode( pack("<iiqq", 4, doc.dc_id, doc.id, doc.access_hash)), width=video_attributes.w, height=video_attributes.h, duration=video_attributes.duration, thumb=parse_thumb(doc.thumb), mime_type=doc.mime_type, file_size=doc.size, file_name=file_name, date=doc.date) elif types.DocumentAttributeSticker in attributes: image_size_attributes = attributes.get( types.DocumentAttributeImageSize, None) sticker_attribute = attributes[ types.DocumentAttributeSticker] if isinstance(sticker_attribute.stickerset, types.InputStickerSetID): try: set_name = client.send( functions.messages.GetStickerSet( sticker_attribute.stickerset) ).set.short_name except StickersetInvalid: set_name = None else: set_name = None sticker = pyrogram_types.Sticker( file_id=encode( pack("<iiqq", 8, doc.dc_id, doc.id, doc.access_hash)), width=image_size_attributes.w if image_size_attributes else 0, height=image_size_attributes.h if image_size_attributes else 0, thumb=parse_thumb(doc.thumb), # TODO: mask_position set_name=set_name, emoji=sticker_attribute.alt or None, file_size=doc.size, mime_type=doc.mime_type, file_name=file_name, date=doc.date) else: document = pyrogram_types.Document(file_id=encode( pack("<iiqq", 5, doc.dc_id, doc.id, doc.access_hash)), thumb=parse_thumb( doc.thumb), file_name=file_name, mime_type=doc.mime_type, file_size=doc.size, date=doc.date) else: media = None reply_markup = message.reply_markup if reply_markup: if isinstance(reply_markup, types.ReplyKeyboardForceReply): reply_markup = pyrogram_types.ForceReply.read(reply_markup) elif isinstance(reply_markup, types.ReplyKeyboardMarkup): reply_markup = pyrogram_types.ReplyKeyboardMarkup.read( reply_markup) elif isinstance(reply_markup, types.ReplyInlineMarkup): reply_markup = pyrogram_types.InlineKeyboardMarkup.read( reply_markup) elif isinstance(reply_markup, types.ReplyKeyboardHide): reply_markup = pyrogram_types.ReplyKeyboardRemove.read( reply_markup) else: reply_markup = None m = pyrogram_types.Message( message_id=message.id, date=message.date, chat=parse_chat(message, users, chats), from_user=parse_user(users.get(message.from_id, None)), text=message.message or None if media is None else None, caption=message.message or None if media is not None else None, entities=entities or None if media is None else None, caption_entities=entities or None if media is not None else None, author_signature=message.post_author, forward_from=forward_from, forward_from_chat=forward_from_chat, forward_from_message_id=forward_from_message_id, forward_signature=forward_signature, forward_date=forward_date, edit_date=message.edit_date, media_group_id=message.grouped_id, photo=photo, location=location, contact=contact, venue=venue, audio=audio, voice=voice, video=video, video_note=video_note, sticker=sticker, document=document, views=message.views, via_bot=parse_user(users.get(message.via_bot_id, None)), outgoing=message.out, client=proxy(client), reply_markup=reply_markup) if message.reply_to_msg_id and replies: m.reply_to_message = client.get_messages(m.chat.id, message.reply_to_msg_id, replies=replies - 1) return m