def attach_media(self, msg: Message, attachment: Dict[str, Any]): """ Attach an attachment to a message. Args: msg: Message to be attached to attachment: Dict of information of the attachment ``fbchat`` entity is not used as it is not completed. """ self.logger.debug("[%s] Trying to attach media: %s", msg.uid, attachment) blob_attachment: Dict[str, Any] = attachment.get('mercury', {}).get('blob_attachment', {}) attachment_type: str = blob_attachment.get("__typename", None) if 'sticker_attachment' in attachment.get('mercury', {}): attachment_type = '__Sticker' if 'extensible_attachment' in attachment.get('mercury', {}): attachment_type = '__Link' extensible_type = get_value(attachment, ('mercury', 'extensible_attachment', 'story_attachment', 'target', '__typename')) if extensible_type == 'MessageLocation': attachment_type = 'MessageLocation' elif extensible_type == 'MessageLiveLocation': attachment_type = 'MessageLocation' # TODO: Change if live location is supported by framework. self.logger.debug("[%s] The attachment has type %s", msg.uid, attachment_type) msg.filename = attachment.get('filename', None) msg.mime = attachment.get('mimeType', None) if attachment_type == "MessageAudio": msg.type = MsgType.Voice msg.filename = msg.filename or 'audio.mp3' msg.mime = msg.mime or 'audio/mpeg' ext = os.path.splitext(msg.filename)[1] msg.file = NamedTemporaryFile(suffix=ext) msg.file.write(requests.get(blob_attachment['playable_url']).content) msg.file.seek(0) msg.path = Path(msg.file.name) elif attachment_type == 'MessageImage': msg.type = MsgType.Image msg.filename = msg.filename or 'image.png' msg.mime = msg.mime or 'image/png' attribution_app = get_value(blob_attachment, ('attribution_app', 'name')) if attribution_app: if msg.text: msg.text += " (via %s)" % attribution_app else: msg.text = "via %s" % attribution_app ext = os.path.splitext(msg.filename)[1] msg.file = NamedTemporaryFile(suffix=ext) url = self.fetchImageUrl(attachment['id']) msg.file.write(requests.get(url).content) msg.file.seek(0) msg.path = Path(msg.file.name) elif attachment_type == 'MessageAnimatedImage': msg.type = MsgType.Animation msg.filename = msg.filename or 'image.gif' msg.mime = msg.mime or 'image/gif' ext = os.path.splitext(msg.filename)[1] msg.file = NamedTemporaryFile(suffix=ext) msg.file.write(requests.get(blob_attachment['animated_image']['uri'], allow_redirects=True).content) msg.file.seek(0) msg.path = Path(msg.file.name) elif attachment_type == 'MessageFile': msg.type = MsgType.File msg.filename = msg.filename or 'file' msg.mime = msg.mime or 'application/octet-stream' ext = os.path.splitext(msg.filename)[1] msg.file = NamedTemporaryFile(suffix=ext) msg.file.write(requests.get(self.process_url(blob_attachment['url'], True), allow_redirects=True).content) msg.file.seek(0) msg.path = Path(msg.file.name) elif attachment_type == 'MessageVideo': msg.type = MsgType.Image msg.filename = msg.filename or 'video.mp4' msg.mime = msg.mime or 'video/mpeg' ext = os.path.splitext(msg.filename)[1] msg.file = NamedTemporaryFile(suffix=ext) msg.file.write(requests.get(blob_attachment['playable_url'], allow_redirects=True).content) msg.file.seek(0) msg.path = Path(msg.file.name) elif attachment_type == '__Sticker': if get_value(attachment, ('mercury', 'sticker_attachment', 'pack', 'id')) == "227877430692340": self.logger.debug("[%s] Sticker received is a \"Like\" sticker. Converting message to text.", msg.uid) sticker_id = get_value(attachment, ('mercury', 'sticker_attachment', 'id')) for i in EmojiSize: if sticker_id == i.value: msg.type = MsgType.Text msg.text = "👍 (%s)" % i.name[0] return msg.type = MsgType.Sticker url = attachment['mercury']['sticker_attachment']['url'] msg.text = attachment['mercury']['sticker_attachment'].get('label', '') filename = os.path.split(urllib.parse.urlparse(url).path)[1] msg.filename = filename ext = os.path.splitext(filename)[1] response = requests.get(url) msg.mime = response.headers['content-type'] msg.file = NamedTemporaryFile(suffix=ext) msg.file.write(response.content) msg.file.seek(0) msg.path = Path(msg.file.name) elif attachment_type == '__Link': msg.type = MsgType.Link link_information = get_value(attachment, ('mercury', 'extensible_attachment', 'story_attachment'), {}) title = get_value(link_information, ('title_with_entities', 'text'), '') description = get_value(link_information, ('description', 'text'), '') source = get_value(link_information, ('source', 'text'), None) if source: description += " (via %s)" % source preview = get_value(link_information, ('media', 'playable_url'), None) if \ get_value(link_information, ('media', 'is_playable'), False) else None preview = preview or get_value(link_information, ('media', 'image', 'uri'), None) url = link_information.get('url', preview) msg.attributes = LinkAttribute(title=title, description=description, image=self.process_url(preview), url=self.process_url(url)) elif attachment_type == 'MessageLocation': msg.type = MsgType.Location link_information = get_value(attachment, ('mercury', 'extensible_attachment', 'story_attachment'), {}) title = get_value(link_information, ('title_with_entities', 'text'), '') description = get_value(link_information, ('description', 'text'), '') msg.text = '\n'.join([title, description]) preview = get_value(link_information, ('media', 'image', 'uri'), None) matches = re.search(r'markers=([\d.-]+)%2C([\d.-]+)', preview) if matches: latitude, longitude = map(float, matches.groups()) else: msg.type = MsgType.Unsupported msg.text = self._("Message type unsupported.\n{content}").format(msg.text) return msg.attributes = LocationAttribute( latitude=latitude, longitude=longitude ) else: msg.type = MsgType.Unsupported msg.text = self._("Message type unsupported.\n{content}").format(msg.text)
def attach_msg_type(self, msg: Message, attachment: Dict[str, Any]): """ Attach message_type to a message. Args: msg: Message to be attached to attachment: Dict of information of the attachment ``fbchat`` entity is not used as it is not completed. """ blob_attachment: Dict[str, Any] = attachment.get('mercury', {}).get('blob_attachment', attachment) attachment_type: str = blob_attachment.get("__typename", None) if 'sticker_attachment' in attachment.get('mercury', {}): attachment_type = '__Sticker' if 'extensible_attachment' in attachment.get('mercury', {}): attachment_type = '__Link' if get_value(attachment, ('mercury', 'extensible_attachment', 'story_attachment', 'target', '__typename')) == 'MessageLocation': attachment_type = 'MessageLocation' if attachment_type == "MessageAudio": msg.type = MsgType.Voice elif attachment_type == 'MessageImage': msg.type = MsgType.Image elif attachment_type == 'MessageAnimatedImage': msg.type = MsgType.Image elif attachment_type == 'MessageFile': msg.type = MsgType.File elif attachment_type == 'MessageVideo': msg.type = MsgType.Image elif attachment_type == '__Sticker': msg.type = MsgType.Sticker msg.text = attachment['mercury']['sticker_attachment'].get('label', '') elif attachment_type == '__Link': msg.type = MsgType.Link link_information = get_value(attachment, ('mercury', 'extensible_attachment', 'story_attachment'), {}) title = get_value(link_information, ('title_with_entities', 'text'), '') description = get_value(link_information, ('description', 'text'), '') source = get_value(link_information, ('source', 'text'), None) if source: description += " (via %s)" % source preview = get_value(link_information, ('media', 'playable_url'), None) if \ get_value(link_information, ('media', 'is_playable'), False) else None preview = preview or get_value(link_information, ('media', 'image', 'uri'), None) url = link_information['media'].get('url', preview) msg.attributes = LinkAttribute(title=title, description=description, image=self.process_url(preview), url=self.process_url(url)) elif attachment_type == 'MessageLocation': msg.type = MsgType.Location link_information = get_value(attachment, ('mercury', 'extensible_attachment', 'story_attachment'), {}) title = get_value(link_information, ('title_with_entities', 'text'), '') description = get_value(link_information, ('description', 'text'), '') msg.text = '\n'.join([title, description]) preview = get_value(link_information, ('media', 'image', 'uri'), None) matches = re.search(r'markers=([\d.-]+)%2C([\d.-]+)', preview) if matches: latitude, longitude = map(float, matches.groups()) else: msg.type = MsgType.Unsupported msg.text = self._("Message type unsupported.\n{content}").format(msg.text) return msg.attributes = LocationAttribute( latitude=latitude, longitude=longitude ) else: msg.type = MsgType.Unsupported msg.text = self._("Message type unsupported.\n{content}").format(msg.text)