From 1beb821b2c545ba0427c1eecd80a3ad4078b822a Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Thu, 21 Sep 2017 23:58:50 +0200 Subject: [PATCH] Added function to fetch url from image id Fixes #84 --- fbchat/client.py | 27 +++++++++++++++++++++------ fbchat/models.py | 6 +++++- fbchat/utils.py | 9 +++++++++ 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/fbchat/client.py b/fbchat/client.py index dc95cba..d2fa490 100644 --- a/fbchat/client.py +++ b/fbchat/client.py @@ -771,6 +771,23 @@ class Client(object): "unseen_threads": j['payload']['unseen_thread_ids'] } + def fetchImageUrl(self, image_id): + """Fetches the url to the original image from an image attachment ID + + :param image_id: The image you want to fethc + :type image_id: str + :return: An url where you can download the original image + :rtype: str + :raises: Exception if request failed + """ + image_id = str(image_id) + j = checkRequest(self._get(ReqUrl.ATTACHMENT_PHOTO, query={'photo_id': str(image_id)})) + + url = get_jsmods_require(j, 3) + if url is None: + raise Exception('Could not fetch image url from: {}'.format(j)) + return url + """ END FETCH METHODS """ @@ -833,12 +850,10 @@ class Client(object): except (KeyError, IndexError) as e: raise Exception('Error when sending message: No message IDs could be found: {}'.format(j)) - # update JS token if receive from response - if ('jsmods' in j) and ('require' in j['jsmods']): - try: - self.payloadDefault['fb_dtsg'] = j['jsmods']['require'][0][3][0] - except (KeyError, IndexError) as e: - log.warning("Error when update fb_dtsg. Facebook might have changed protocol.") + # update JS token if received in response + fb_dtsg = get_jsmods_require(j, 2) + if fb_dtsg is not None: + self.payloadDefault['fb_dtsg'] = fb_dtsg return message_id diff --git a/fbchat/models.py b/fbchat/models.py index 48d0ca4..4ac72af 100644 --- a/fbchat/models.py +++ b/fbchat/models.py @@ -220,7 +220,11 @@ class ImageAttachment(Attachment): animated_preview_height = int def __init__(self, original_extension=None, width=None, height=None, is_animated=None, thumbnail_url=None, preview=None, large_preview=None, animated_preview=None, **kwargs): - """Represents an image that has been sent as a Facebook attachment""" + """ + Represents an image that has been sent as a Facebook attachment + To retrieve the full image url, use: :func:`fbchat.Client.fetchImageUrl`, + and pass it the uid of the image attachment + """ super(ImageAttachment, self).__init__(**kwargs) self.original_extension = original_extension self.width = width diff --git a/fbchat/utils.py b/fbchat/utils.py index 1c0ddad..899f0a1 100644 --- a/fbchat/utils.py +++ b/fbchat/utils.py @@ -112,6 +112,7 @@ class ReqUrl(object): MESSAGE_REACTION = "https://www.facebook.com/webgraphql/mutation" TYPING = "https://www.facebook.com/ajax/messaging/typ.php" GRAPHQL = "https://www.facebook.com/api/graphqlbatch/" + ATTACHMENT_PHOTO = "https://www.facebook.com/mercury/attachments/photo/" facebookEncoding = 'UTF-8' @@ -191,3 +192,11 @@ def checkRequest(r, do_json_check=True): return j else: return content + +def get_jsmods_require(j, index): + if j.get('jsmods') and j['jsmods'].get('require'): + try: + return j['jsmods']['require'][0][index][0] + except (KeyError, IndexError) as e: + log.warning('Error when getting jsmods_require: {}. Facebook might have changed protocol'.format(j)) + return None