Using Microsoft Graph API to Extract Microsoft Booking Data

808 Views Asked by At

I am trying to call the Microsoft Graph API, in an automated way using application permissions, to extract the Microsoft Bookings data.

The AAD app has the Bookings.Read.All permissions as explained here: https://learn.microsoft.com/en-us/graph/api/bookingbusiness-list?view=graph-rest-1.0

This is how I am getting a token:

import msal

client_id = 'x'
client_secret = 'x'
authority = 'https://login.microsoftonline.com/x'
scope = ['https://graph.microsoft.com/.default']

client = msal.ConfidentialClientApplication(client_id, authority=authority, client_credential=client_secret)

token_result = client.acquire_token_silent(scope, account=None)

if token_result:
  access_token = 'Bearer ' + token_result['access_token']
  print('Access token was loaded from cache')

if not token_result:
  token_result = client.acquire_token_for_client(scopes=scope)
  access_token = 'Bearer ' + token_result['access_token']
  print('New access token was acquired from Azure AD')

print(access_token)

This is how I am calling the Graph API. However, it returns error 500 with a message saying "An error has occurred"

import requests

url = 'https://graph.microsoft.com/v1.0/solutions/bookingBusinesses'
headers = {
  'Authorization': access_token
}

graph_result = requests.get(url=url, headers=headers)

print(graph_result)

What is wrong here?

Update 1

Calling some other endpoints does work, which suggest the Python is okay, and the access token is okay. For example, if I use the Get bookingBusiness, instead of the List bookingBusiness, which is basically the company ID on the endpoint, it works and returns data. But obviously that doesn't solve the problem. So this example endpoint would work:

booking_business_endpoint = "/solutions/bookingBusinesses/[email protected]"

Update 2

The AAD App permissions are configured as shown here: AAD Permissions

Update 3

The solution posted below by Venkatesan works for generating an authorization code, and the code can be converted into an access token, albeit manually, however the access token doesn't work when calling the API. Error 401 is returned with this message:

b'{"error":{"code":"","message":"Authorization has been denied for this request.","innerError":{"date":"2023-04-12T10:35:49","request-id":"b8904cad-c994-4a91-bd61-6bfbcb87bbaa","client-request-id":"b8904cad-c994-4a91-bd61-6bfbcb87bbaa"}}}'
1

There are 1 best solutions below

10
Venkatesan On

I tried in my environment and got the below results.

Initially, I got the same error as got an access token with a 500 error.

jQeYP81SRbbh0PaBVD1ceKfyPzySsF2AArPlq8xFU-z3dZueSmHTifmEkSDcR3Cu-LZfw
b'{"error":{"code":"","message":"An error has occurred.","innerError":{"date":"2023-04-05T10:30:49","request-id":"e3f5bc5f-db7d-468d-92ef-abe33abc25c9","client-request-id":"e3f5bc5f-db7d-468d-92ef-abe33abc25c9"}}}'
500

enter image description here

The above error occurs when you tried with client credentials flow for delegated permission (Bookings.Read.All, BookingsAppointment.ReadWrite.All, Bookings.ReadWrite.All, Bookings.Manage.All).

For delegated permission, you need to use the authorization code flow process. You can use the below code to get the access token and bookingBusiness using Python.

Code:

import requests
from urllib.parse import urlencode

# define the OAuth 2.0 parameters
client_id = ''
client_secret = ''
redirect_uri = 'https://jwt.ms'
auth_url = 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize'
token_url = 'https://login.microsoftonline.com/common/oauth2/v2.0/token'

# generate the authorization URL
auth_params = {
    'client_id': client_id,
    'redirect_uri': redirect_uri,
    'scope':'https://graph.microsoft.com/.default',
    'response_type': 'code'
}
auth_url_with_params = auth_url + '?' + urlencode(auth_params)

# display the authorization URL to the user
print('Please go to the following URL and authorize the app:')
print(auth_url_with_params)

# once the user authorizes the app, they will be redirected to the callback URL
# with an authorization code as a parameter
authorization_code = input('Enter the authorization code: ')

# exchange the authorization code for an access token
token_params = {
    'grant_type': 'authorization_code',
    'client_id': client_id,
    'client_secret': client_secret,
    'redirect_uri': redirect_uri,
    'scope':'https://graph.microsoft.com/.default',
    'code': authorization_code
}
response = requests.post(token_url, data=token_params)

# extract the access token from the response
access_token = response.json()['access_token']
print("accesstoken",access_token)

import requests

url = 'https://graph.microsoft.com/v1.0/solutions/bookingBusinesses'
headers = {
  'Authorization': 'Bearer ' + access_token
}

graph_result = requests.get(url=url, headers=headers)

print(graph_result.content)
print(graph_result.status_code)

Output:

b'{"@odata.context":"https://graph.microsoft.com/v1.0/$metadata#solutions/bookingBusinesses","value":[{"id":"[email protected]","displayName":"Fourth Coffee"}]}'
200

enter image description here

Reference:

List bookingBusinesses - Microsoft Graph v1.0 | Microsoft Learn