Search code examples
azure-active-directorymicrosoft-graph-apiazure-ad-msalazure-ad-graph-api

Query OnlineMeetings from MS graph API V1.0


I'm a data analysis freelancer and basically, work with python all the time. However, I'm not well quietened with backend development and am new to MS Azure platform.

I want to make a python script to access my MS teams, retrieve all meetings details and save it to a .CSV file. Right now I'm stuck between the type of authentication to make and the permissions to request.

What I have done for now:

  • Registered an app with Azure AD.
  • Granted an Access policy to the app
  • granted required permissions as deligated
  • Built a script for: authentication and token gaining query and result gain

The code has two problems:

  1. Can't get the token to form any query if I authenticated using 'ConfidentialClientApplication.acquire_token_by_auth_code_flow'. This funcion requires authentication response as a dictionary and I can't get it.
  2. Can't get permission to query OnlineMeeting using WebJoinURL if used 'ConfidentialClient.acquire_token_by_authorization_code'. This methode is now depricated in MSAL-python and it doesn't grant application permissions.

If one of these two problems is solved I believe I can advance with the project. Thanks in advance.


import requests
import webbrowser
from msal import ConfidentialClientApplication

# Global variables

app_id = '8f34\*\*\*\*\*\*\*\*\*\*\*'
tenant_id = '83d6cd3e-\****1'
client_secret = 'q7q8Q\~***
auth_url = f'https://login.microsoftonline.com/%7Btenant_id%7D/'
redirect_uri = 'http://localhost:5000/getAToken'

scopes = \['User.Read',
'User.Read.All', 'User.ReadWrite.All',
'Directory.ReadWrite.All', 'Directory.Read.All',
'Calendars.Read', 'Calendars.ReadWrite',
'OnlineMeetingArtifact.Read.All',
'OnlineMeetings.Read', 'OnlineMeetings.ReadWrite'
\]

# Authentication

client_instance = ConfidentialClientApplication(
client_id=app_id,
client_credential=client_secret,
authority=auth_url,
)
auth_code_flow = client_instance.initiate_auth_code_flow(scopes=scopes, redirect_uri=redirect_uri, response_mode='query')
response_token = client_instance.acquire_token_by_auth_code_flow(auth_code_flow)

# try with code flow

access_token_id = response_token\['access_token'\]

# Query formation

base_url = 'https://graph.microsoft.com/v1.0/'
team_id = '60ceb0ef-a240-49e2-8e5c-699f5e5412a0'
member_id = '[email protected]'
meeting_id = '319f92bd-c51c-4b06-8a5b-855a37cece02'
meeting_url = 'https://teams.microsoft.com/l/meetup-join/19%3a11e577f766f546a7853aea1e850e3750%40thread.tacv2/1668153593347?context=%7b%22Tid%22%3a%2283d6cd3e-ef7a-4380-9d01-cf12a8a47931%22%2c%22Oid%22%3a%22540d95bb-40b4-4b06-a84d-7b70c9fd1f23%22%7d'

members = 'users/'
events = f'{members}/{member_id}events?$select=isOnlineMeeting,onlineMeeting,attendees,start,end,'
meeting_attendance_report = f'me/onlineMeetings/{meeting_id}/attendanceReports'

headers = {'Authorization': 'Bearer ' + access_token_id}

# Save values from query response

# 1. Query to retrieve all subscribed Users' ids

users_lst: list = \[\]
end_point = base_url + members
response = requests.get(end_point, headers=headers)
print(response)  # \<Response \[200\]\>
print(response.json())
if response.ok:
\[users_lst.append(user\['id'\]) for user in response.json()\['value'\]\]
response.close()

# 2. Query to retrieve any calendar meeting happened for this user

# Keeps the meeting join url to use while retrieving attendance records.

meetings: list = \[\]
end_point = base_url + events
response = requests.get(end_point, headers=headers)
print(response)  # \<Response \[200\]\>
print(response.json())
if response.ok:
for event in response.json()\['value'\]:
if event\['isOnlineMeeting'\]:
event_record = {
'meeting_url': event\['onlineMeeting'\]\['joinUrl'\],
'attendees': event\['attendees'\],
'start_time': event\['start'\],
'end_time': event\['end'\],
}
meetings.append(event_record)

# 3. Report

report_lst: dict
end_point = base_url + f"/me/onlineMeetings?$filter=JoinWebUrl%20eq%20'{meeting_url}'"
response = requests.get(end_point, headers=headers)
print(response)
print(response.json())

Solution

  • I tried to reproduce the same in my environment and got the results like below:

    If you want to Generate the Access token without the user interaction, then make use of Client-Credential Flow Grant Type.

    To Query Online Meetings from Microsoft Graph API, I created an Azure AD Application and granted the Application API Permissions like below:

    enter image description here

    Based on your requirement, Grant the Application API Permissions OnlineMeetingArtifact.Read.All, OnlineMeetings.ReadWrite.All.

    By referring to the documents provided by Mariam Abd Eltwab, I generated the Access Token using the below code:

    import msal
    
    ClientId = '50adf559-f68e-4a75-8710-XXXXXXXXX'
    ClientSecret = '***************'
    authorityurl = 'https://login.microsoftonline.com/fb134080-e4d2-45f4-9562-XXXXXXXXX'
    scope = ['https://graph.microsoft.com/.default']
    
    client = msal.ConfidentialClientApplication(ClientId, authority=authorityurl, client_credential=ClientSecret)
    token = client.acquire_token_silent(scope, account=None)
    
    if token:
    access = 'Bearer ' + token['access_token']
    print('Access token was loaded from cache')
    if  not token:
    token_result = client.acquire_token_for_client(scopes=scope)
    access_token = 'Bearer ' + token_result['access_token']
    
    print('Access token acquired from Azure AD')
    print(access_token)
    

    enter image description here

    Using the above generated access, you can get OnlineMeetings from Microsoft Graph API:

    GET https://graph.microsoft.com/v1.0/communications/onlineMeetings/?$filter=filter
    

    enter image description here

    Reference:

    Get onlineMeeting - Microsoft Graph v1.0