My use case is: make a script that will run every hour to extract information about a user's calendar.
My script runs in Python and I get a token but I am unable to get the user's events. I have registered my app in the Microsoft Application Registration Portal and given the Calendar.read application permission. An administrator gave consent by accessing the /adminconsent
endpoint.
Here is my code to get the token (documentation here):
url = 'https://login.microsoftonline.com/common/oauth2/v2.0/token'
data = {
'grant_type': 'client_credentials',
'client_id': app_id,
'scope': 'https://graph.microsoft.com/.default', <--- Really not sure about this here
'client_secret': client_secret,
}
r = requests.post(url, data=data)
token = r.json().get('access_token')
What scope am I suppose to use? The documentation only speaks of the one above.
And to read the user's calendar:
url = 'https://outlook.office.com/api/v2.0/users/{}/events'.format(user_email)
headers = {
'Authorization': 'Bearer {}'.format(token)
}
r = requests.get(url, headers=headers)
I am not sure of the users/{user_email}/
part.
I get an access token but I get the following error when trying to read the user's calendar:
Response [401]
The access token is acquired using an authentication method that is too weak to allow access for this application. Presented auth strength was 1, required is 2.
I have finally found it. I was very close.
I had to use Microsoft Graph API endpoint instead of Outlook Unified API endpoint.
The final code looks like:
import requests
# Get a token
url = 'https://login.microsoftonline.com/common/oauth2/v2.0/token'
data = {
'grant_type': 'client_credentials',
'client_id': app_id,
'scope': 'https://graph.microsoft.com/.default'
'client_secret': client_secret,
}
r = requests.post(url, data=data)
token = r.json().get('access_token')
# ...
# Use the token using microsoft graph endpoints
url = 'https://graph.microsoft.com/v1.0/users/{}/events'.format(user_email) # can also use the user_id (e.g. 12345-abcde-...)
headers = {
'Authorization': 'Bearer {}'.format(token)
}
r = requests.get(url, headers=headers)
Microsoft's documentation really needs clarification. It has too many different APIs that do very similar things.