From f8e4d1549c9e599efc8ab9c2b3c382c947a2b4a1 Mon Sep 17 00:00:00 2001 From: Toph Burns Date: Wed, 8 Jul 2015 17:07:42 -0700 Subject: [PATCH 1/3] Cleanup slashes in generated urls for put_event We were putting double slashes in some of our url requests. --- facebook/facebook.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/facebook/facebook.py b/facebook/facebook.py index 3243d9f..80f8c7d 100644 --- a/facebook/facebook.py +++ b/facebook/facebook.py @@ -92,7 +92,7 @@ def __init__(self, access_token=None, version=None): self.access_token = access_token self.version = version self.host = "graph.facebook.com/" - self.url = "https://{}".format( + self.url = "https://{}/".format( self.host ) if not self.version else "https://{0}{1}/".format( self.host, self.version @@ -169,11 +169,11 @@ def put_event(self, id=None, page_id=None, **data): """ if id: - path = '/%s' % id + path = '%s' % id elif page_id: - path = '/%s/events' % page_id + path = '%s/events' % page_id else: - path = '/me/events' + path = 'me/events' response = self.request(path, post_args=data) From 91018b3d4acd70eda9d800cd12443545e602fd51 Mon Sep 17 00:00:00 2001 From: Toph Burns Date: Wed, 8 Jul 2015 18:10:17 -0700 Subject: [PATCH 2/3] Publishing to Pages requires their own access token Update event publish so we can publish events to Pages on Facebook. From looking at the documentation it looks like Pages have separate access tokens. --- facebook/facebook.py | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/facebook/facebook.py b/facebook/facebook.py index 80f8c7d..0077b0a 100644 --- a/facebook/facebook.py +++ b/facebook/facebook.py @@ -158,7 +158,7 @@ def put_wall_post(self, message, attachment={}, profile_id="me"): """ return self.put_object(profile_id, "feed", message=message, **attachment) - def put_event(self, id=None, page_id=None, **data): + def put_event(self, id=None, page_id=None, fb_uid=None, **data): """Creates an event with a picture. We accept the params as per @@ -178,15 +178,42 @@ def put_event(self, id=None, page_id=None, **data): response = self.request(path, post_args=data) if 'picture' in data and isinstance(response, dict) and 'id' in response: + page_access_token = None + if page_id and fb_uid: + # Posts to Pages require their own access token. See: + # https://developers.facebook.com/docs/pages/access-tokens + # + # If a page_id is provided, fetch account information for this + # facebook user and fetch the access_token that corresponds with + # the page_id. + url = '{url}{fb_uid}/accounts'.format( + url=self.url, + fb_uid=fb_uid, + ) + account_response = requests.get( + url, + params={'access_token': self.access_token} + ) + account_data = account_response.json() + accounts = account_data.get('data') + for account in accounts: + if account['id'] == page_id: + page_access_token = account['access_token'] + # Upload the event picture to the facebook event + post_args = {} + post_args['cover_url'] = data['picture'] + if page_access_token: + post_args['access_token'] = page_access_token + else: + post_args['access_token'] = self.access_token + url = '{url}{id}/'.format( url=self.url, id=response['id'], ) - post_args = {} - post_args['access_token'] = self.access_token - post_args['cover_url'] = data['picture'] picture_response = requests.post(url, data=post_args) + # If there's an error, return the message to the calling code so we # can log it. Not raising a GraphAPIError here because we want the # event to publish even if there is an error in uploading the From 529eaaa24c2736b6c453e7ba2966388aa632eaf8 Mon Sep 17 00:00:00 2001 From: Toph Burns Date: Thu, 9 Jul 2015 09:22:26 -0700 Subject: [PATCH 3/3] Add some error checking for getting page access token --- facebook/facebook.py | 53 +++++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/facebook/facebook.py b/facebook/facebook.py index 0077b0a..7f65b21 100644 --- a/facebook/facebook.py +++ b/facebook/facebook.py @@ -158,6 +158,36 @@ def put_wall_post(self, message, attachment={}, profile_id="me"): """ return self.put_object(profile_id, "feed", message=message, **attachment) + def get_page_access_token(self, page_id, fb_uid): + """Get the access_token for this page.""" + # Posts to Pages require their own access token. See: + # https://developers.facebook.com/docs/pages/access-tokens + # + # If a page_id is provided, fetch account information for this + # facebook user and fetch the access_token that corresponds with + # the page_id. + page_access_token = None + url = '{url}{fb_uid}/accounts'.format( + url=self.url, + fb_uid=fb_uid, + ) + account_response = requests.get( + url, + params={'access_token': self.access_token} + ) + account_data = account_response.json() + + if account_response.status_code != 200: + error_message = account_data.get('error').get('message') + return page_access_token, error_message + + accounts = account_data.get('data') + for account in accounts: + if account['id'] == page_id: + page_access_token = account['access_token'] + + return page_access_token, None + def put_event(self, id=None, page_id=None, fb_uid=None, **data): """Creates an event with a picture. @@ -180,25 +210,12 @@ def put_event(self, id=None, page_id=None, fb_uid=None, **data): if 'picture' in data and isinstance(response, dict) and 'id' in response: page_access_token = None if page_id and fb_uid: - # Posts to Pages require their own access token. See: - # https://developers.facebook.com/docs/pages/access-tokens - # - # If a page_id is provided, fetch account information for this - # facebook user and fetch the access_token that corresponds with - # the page_id. - url = '{url}{fb_uid}/accounts'.format( - url=self.url, - fb_uid=fb_uid, - ) - account_response = requests.get( - url, - params={'access_token': self.access_token} + page_access_token, error_message = self.get_page_access_token( + page_id, + fb_uid ) - account_data = account_response.json() - accounts = account_data.get('data') - for account in accounts: - if account['id'] == page_id: - page_access_token = account['access_token'] + if error_message: + return response, error_message # Upload the event picture to the facebook event post_args = {}