Search code examples
pythonmicrosoft-graph-api

Python msgraph API, retrieve calendar for rooms


I am sitting with the new Python msgraph package and trying to navigate my way through the Microsoft GraphAPI but it seems I am missing something.

What I want to do:

  1. Retrieve the list of meeting rooms (done)
  2. Retrieve the calendar for those rooms for the last week to find booked meetings and their planned attendance (not working)

What I did so far:

  1. Set up application credentials in Azure for the application with the Bookings.Read.All Calendars.Read Calendars.ReadBasic.All Group.Read.All Place.Read.All User.Read permissions.
  2. Set up a certificate for logging in.
  3. Login with msgraph using the certificate and get a list of rooms

What I need:

  1. Get a calendar from each room in the list I retrieve for a specific period.

I found a tutorial that uses the client.me endpoint but it is not possible to read through for an application.

Does anyone know how to fix that? (get_schedule_for_room to get the calendar from the room ID or room email) as a application.

Here is the code so far:

    #!/usr/bin/env python3
    
    import asyncio
    from msgraph.generated.models.room import Room
    from msgraph.generated.users.item.calendar.get_schedule.get_schedule_request_builder import GetScheduleRequestBuilder
    from msgraph.generated.users.item.calendar.get_schedule.get_schedule_post_request_body import GetSchedulePostRequestBody
    from msgraph import GraphServiceClient
    
    from azure.identity import DeviceCodeCredential, CertificateCredential, AuthorizationCodeCredential

    config = {
      'client_id': '<something>',
      'tenant_id': '<something>',
      'client_secret': '<something>',
      'authority': 'https://login.microsoftonline.com/<something>',
      'scope': ['https://graph.microsoft.com/.default'],
      'certificate_path': 'msal_crt_n_key.pem',
    }
    
    async def get_schedule_for_room(graph_client, room_id):
        result = await graph_client.users.by_user_id(room_id).calendar.events.get()
        # DOES NOT WORK
        return result
    
    async def get_rooms(graph_client):
        return await graph_client.places.graph_room.get()
    
    async def main():
        # azure.identity.aio
        print("Login using certificate")
        credential = CertificateCredential(
            tenant_id=config['tenant_id'],
            client_id=config['client_id'],
            certificate_path=config['certificate_path'])
    
        graph_client = GraphServiceClient(credential, config['scope']) # type: ignore
        print("Get list of rooms")
        rooms = await get_rooms(graph_client)
        print(f"Rooms: {rooms}")
    
        room_ids = [r.id for r in rooms.value]
        print(f"Rooms IDs: {room_ids}")
    
        for id_ in room_ids:
            # The part below does not work
            calendar = await get_schedule_for_room(graph_client, id_)
            print(calendars)
            print(type(calendars))
    
    asyncio.run(main())

Solution

  • I would suggest to use room's emailAddress instead of the id. The id of the room returned by graph_client.places.graph_room.get() is no the same ss id of the room in the users collection.

    Try to change this room_ids = [r.id for r in rooms.value] print(f"Rooms IDs: {room_ids}")

    for id_ in room_ids:
        # The part below does not work
        calendar = await get_schedule_for_room(graph_client, id_)
        print(calendars)
        print(type(calendars))
    

    to

    room_emails = [r.emailAddress for r in rooms.value]
    print(f"Rooms emails: {room_emails}")
    
    for email_ in room_emails:
        events = await get_schedule_for_room(graph_client, email_)
        print(events)
        print(type(events))
    

    Also there can be a company access policy limiting app access to specific mailboxes. https://learn.microsoft.com/en-us/graph/auth-limit-mailbox-access