Question in short: how to get Facebook API access_token with permission
I want to read the reach for specific ad settings from the Facebook API using Python. In order to do so, I need a facebook access token with extended permissions. I use the following function to get a new access token, but the token I get does not have the proper permission levels. So: how to get an access_token with custom permissions, like you can do manually here?
Python example below (problem is actually language independent):
import requests
import json
from facebookads.adobjects.adaccount import AdAccount
from facebookads.api import FacebookAdsApi
from facebookads.adobjects.adset import AdSet
app_id = 'xxxx'
app_secret = 'xxxx'
account_id = 'xxxx'
def get_fb_token(app_id, app_secret):
payload = {'grant_type': 'client_credentials',
'client_id': app_id,
'client_secret': app_secret,
}
file = requests.post('https://graph.facebook.com/oauth/access_token?', params = payload)
string = file.content.decode('utf-8')
json_obj = json.loads(string)
return json_obj['access_token']
access_token = get_fb_token(app_id, app_secret)
account = AdAccount(account_id)
# initiate API
FacebookAdsApi.init(app_id, app_secret, access_token)
# Request reach
targeting_spec = {
'geo_locations': {
'countries': ['nl']
},
}
fb_params = {
'currency': 'EUR',
'optimize_for': AdSet.OptimizationGoal.offsite_conversions,
'targeting_spec': targeting_spec,
}
reach_estimate = account.get_reach_estimate(params=fb_params)
And the error message I get:
(#278) Reading advertisements requires an access token with the extended permission ads_read
Help is highly appreciated!
Try this:
payload = {
'grant_type': 'client_credentials',
'client_id': app_id,
'client_secret': app_secret,
'scope': 'ads_read'
}
file = requests.post('https://graph.facebook.com/oauth/access_token?', params = payload)
Also, you need to redirect to the correct endpoint (https://www.facebook.com/v2.xy/dialog/oauth), not POST to it. You cannot get a User token without user interaction.
Related
To get an authorization code from the Spotify web api I use this code:
AUTH_URL = 'https://accounts.spotify.com/authorize'
TOKEN_URL = 'https://accounts.spotify.com/api/token'
BASE_URL = 'https://api.spotify.com/v1/'
CLIENT_ID = '******'
CLIENT_SECRET = '*****'
auth_code = requests.get(AUTH_URL, {
'client_id': CLIENT_ID,
'response_type': 'code',
'redirect_uri': 'uri',
'scope': 'playlist-modify-private',
})
auth_header = base64.urlsafe_b64encode((CLIENT_ID + ':' + CLIENT_SECRET).encode())
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic %s' % auth_header.decode('ascii')
}
payload = {
'grant_type': 'authorization_code',
'code': auth_code,
'redirect_uri': 'uri',
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
}
access_token_request = requests.post(url=TOKEN_URL, data=payload, headers=headers)
access_token_response_data = access_token_request.json()
access_token = access_token_response_data['access_token']
Only the auth_code for getting the code from Spotify gives <Response 200> instead the code. What could be wrong?
I tried to print the auto code but it gives <Response 200> back. This is ultimately used in the call to Spotify for the token.
Authorization Code Flow in spotify needs a server feature at application side.
It can get code value from spotify server, then request token with code.
In code flow diagram, explain detail here
I will demo with Flask
File save as spotify-client.py
from flask import Flask, request, redirect
from requests_oauthlib import OAuth2Session
from requests.auth import HTTPBasicAuth
import requests
import json
app = Flask(__name__)
AUTH_URL = 'https://accounts.spotify.com/authorize'
TOKEN_URL = 'https://accounts.spotify.com/api/token'
REDIRECT_URI = '<your callback URI>' # my case is 'http://localhost:3000/callback'
CLIENT_ID = "<your client id>"
CLIENT_SECRET = "<your client secret>"
SCOPE = [
"user-read-email",
"playlist-read-collaborative"
]
#app.route("/login")
def login():
spotify = OAuth2Session(CLIENT_ID, scope=SCOPE, redirect_uri=REDIRECT_URI)
authorization_url, state = spotify.authorization_url(AUTH_URL)
return redirect(authorization_url)
#app.route("/callback", methods=['GET'])
def callback():
code = request.args.get('code')
res = requests.post(TOKEN_URL,
auth=HTTPBasicAuth(CLIENT_ID, CLIENT_SECRET),
data={
'grant_type': 'authorization_code',
'code': code,
'redirect_uri': REDIRECT_URI
})
return json.dumps(res.json())
if __name__ == '__main__':
app.run(port=3000,debug=True)
Steps
#1 Run Application
python spotify-client.py
#2 Open Browser and access this URL
http://localhost:3000/login
#3 Login with your Spotify credential
This login screen automatically shows to you.
#4 The access-token will shows on your browser if success login.
Using the documentation for authorisation, There are 2 steps in getting a Spotify OAuth Token
App requests authorization and receives a authorization code.
App posts a request to receive a OAuth Token.
https://developer.spotify.com/documentation/general/guides/authorization-guide/
When I try to POST a request to receive an Oath Token I get a 400 error. The code is a a bit dirty, sorry about that.
import json
import requests
from urllib.parse import urlencode
#credentials
USER_ID = '31......fbq'
CLIENT_ID = '553b......9dd'
CLIENT_SECRET = '16c40......24067b'
# encodes and prints URL
auth_url = 'https://accounts.spotify.com/authorize'
scopes_params = urlencode({
'client_id': CLIENT_ID,
'scope': 'playlist-modify-private',
'redirect_uri': 'http://localhost:8000',
'response_type': 'code'
})
scope_url = auth_url + '?' + scopes_params
print(scope_url)
response = requests.get(scope_url)
# Authorization code is copy pasted here
authorization_code = input('Enter Authorization_Code: ')
request_body_token = json.dumps({
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'grant_type': 'authorization_code',
'code': authorization_code,
'redirect_uri': 'http://localhost:8000'
})
access_token_request = requests.post(url='https://accounts.spotify.com/api/token',
data=request_body_token)
print(access_token_request.status_code)
This is the section of the authorization code I copy paste in from the redirect URI
Let me know if any additional information is needed.
I found out the issue. The request_body_token doesn't need to be converted from JSON to Python using json.dumps method, the dictionary can already be parsed in the data/body. Solution Below:
import json
import requests
from urllib.parse import urlencode
#credentials
USER_ID = '31ldam........w3wwfbq'
CLIENT_ID = '553bc4.........c0b3f09dd'
CLIENT_SECRET = '16c400........a24067b'
ENPOINT = f'https://api.spotify.com/v1/users/{USER_ID}/playlists'
# encodes and prints URL
auth_url = 'https://accounts.spotify.com/authorize'
scopes_params = urlencode({
'client_id': CLIENT_ID,
'scope': 'playlist-modify-private',
'redirect_uri': 'http://localhost:8000',
'response_type': 'code'
})
scope_url = auth_url + '?' + scopes_params
print(scope_url)
# Authorization code is copy pasted here
response = requests.get(scope_url)
authorization_code = input('Enter Authorization_Code: ')
# Here is where the error was, json.dump removed
request_body_token = {
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'grant_type': 'authorization_code',
'code': authorization_code,
'redirect_uri': 'http://localhost:8000'
}
access_token_request = requests.post(url='https://accounts.spotify.com/api/token', data=request_body_token)
print(access_token_request.status_code)
access_token = access_token_request.json()['access_token']
I am writing a command line script accessing LinkedIN API via Library but having issues with it. Here is my code:
from linkedin import linkedin
import requests
RETURN_URL = "http://localhost"
authentication = linkedin.LinkedInAuthentication(CLIENT_ID, CLIENT_SECRET, RETURN_URL,
linkedin.PERMISSIONS.enums.values())
print(authentication.authorization_url)
get_code = authentication.authorization_url
application = linkedin.LinkedInApplication(authentication)
authentication.authorization_code = 'AQQfHou58eyVEJmbabHk1njdl-AY0bqfDjkZeosAn6DR-DiTnH7raJoDcign2U3w5w1YieYU4cjfTz3Ab-wa7cm3KwwctjzU-SoAWchjj_odArFM7q1W1CCU_15Q7gLDRrZoMCo5ivXnkisR5gYfGS0V2E_jsQ&state=74abc361c20313f5bc87d43f42f88b53#!'
# authentication.get_access_token()
data = {
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'grant_type': 'authorization_code',
'redirect_uri': RETURN_URL,
'code': 'AQTqmP0g4PWGJpNnSysqvH4TCXTusoWsjbx1f3R7TPazYP4pCB81a4FrRJRUNjeJzH5yoN2XTrIT4YO-mu2VBQkhL12kwJZ09Xm_WHh97nyok0tqKHh8k54c3dCc075hrsJ8KYw02X-2XSMD-TkxQWKrUXPsMw&state=82d8d2bbbc80ba485812d2fe500cf3e9#!'
}
url = 'https://www.linkedin.com/uas/oauth2/accessToken'
r = requests.post(url, data=data)
print(r.text)
The error I get:
https://www.linkedin.com/uas/oauth2/authorization?client_id=862ztaa9740mst&redirect_uri=http%3A//localhost&scope=rw_company_admin%20r_emailaddress%20r_basicprofile%20w_share&response_type=code&state=d8e7aaefdbd32211fb7d342b238a84dc
{"error_description":"missing required parameters, includes an invalid parameter value, parameter more than once. : Unable to retrieve access token : appId or redirect uri does not match authorization code or authorization code expired","error":"invalid_request"}
Also, how to get code part dynamically?
I'm trying to make an app that makes requests to Dynamics CRM Web API from python using urllib2.
So far I can login an user with an Azure application by making a post request to https://login.microsoftonline.com/common/oauth2/authorize
then with the retrieved authorization_code I can get the access_token, refresh_token and others with urllib2
url = 'https://login.microsoftonline.com/common/oauth2/token'
post_fields = {'grant_type': 'authorization_code',
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'redirect_uri': REDIRECT_URI,
'resource': 'https://graph.microsoft.com',
'code': code}
request = Request(url, urlencode(post_fields).encode())
resp = urlopen(request).read().decode()
resp = json.loads(resp)
refresh_token = resp['refresh_token']
id_token = resp['id_token']
id_token = jwt.decode(id_token,verify=False)
access_token = resp['access_token']
Then I tried to make another post request by using the access_token but had no luck.
I keep getting:
HTTP Error 401: Unauthorized
Just as a test I make a post directly to .dynamics.com/api/data/v8.1/leads
as follows:
url = 'https://<company_uri>.dynamics.com/api/data/v8.1/leads'
post_fields = {"name": "Sample Account",
"creditonhold": "false",
"address1_latitude": 47.639583,
"description": "This is the description of the sample account",
"revenue": 5000000,
"accountcategorycode": 1
}
request = Request(url, urlencode(post_fields).encode())
request.add_header('Authorization', 'Bearer ' + access_token )
request.add_header("Content-Type", "application/json; charset=utf-8")
request.add_header('OData-MaxVersion','4.0')
request.add_header('OData-Version','4.0')
request.add_header('Accept','application/json')
resp = urlopen(request).read().decode()
But i keep getting the same 401 error code.
I've looked all over msdn documentation but didn't find the way to do this directly without using any library, I just want to use a simple post request.
Since the error code says Unauthorized I think the access_token must be sent in some other way.
Can someone help me on how to correctly use the access_token on Dynamics CRM?
Thanks!
The access token you got back is for the Azure AD Graph API. Not Dynamics CRM.
To call that, you must ask for an access token with resource set to Dynamics CRM API's App ID URI, not https://graph.windows.net.
According to documentation you should set resource to https://<company_uri>.crm.dynamics.com.
So when you are retrieving token:
url = 'https://login.microsoftonline.com/common/oauth2/token'
post_fields = {'grant_type': 'authorization_code',
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'redirect_uri': REDIRECT_URI,
'resource': 'https://<company_uri>.crm.dynamics.com',
'code': code}
I am trying to request an authorization code as documented here.
I am using Python requests package to do this and have the following example code:
import requests
auth_endpoint = 'https://login.microsoftonline.com/%s/oauth2/authorize?api-version=1.0' % TENANT_ID
payload = {
'client_id': CLIENT_ID,
'response_type': 'code',
'resource': APP_ID_URI,
'redirect_uri': REPLY_URL
}
response = requests.get(url=auth_endpoint, data=payload)
However, when I run the code above, I get back HTML in the body and not the response I'm expecting. It seems like the HTML code is for a login page.
When I take the formatted endpoint URI and plug it into a browser, I am able to get the auth code from the redirect URI. But, is there a way to get this from the body of the response while still using the requests package?
Please use session class of requests module to implement your requirement. Please refer to the following code sample:
import requests
s = requests.Session()
USERNAME = '<username_email>'
PASSWORD = '<userpassword>'
s.auth = (USERNAME, PASSWORD)
TENANT_ID = '<tenant_id>'
# Authorize URL
authorize_url = 'https://login.microsoftonline.com/%s/oauth2/authorize' % TENANT_ID
# Token endpoint.
token_url = 'https://login.microsoftonline.com/%s/oauth2/token' % TENANT_ID
payload = { 'response_type': 'code',
'client_id': '<tenant_id>',
'redirect_uri': 'http://localhost',
'authority' :'authority'
}
response = s.get(authorize_url, params=payload ,allow_redirects=True)
print response
print response.url
Any further concern, please feel free to let me know.