Search code examples
azureazure-active-directorymicrosoft-graph-api

Scheduling meetings using graph API


I have several users with corresponding email addresses in my Microsoft 365 organization.

I'd like to be able to schedule meeting between users, as the organization admin, not as one of the users.

Every authentication method I try using ms graph api results in an error stating that calendar scheduling is only available in delegated mode.

Not sure what's the correct approach here, I require a fully programmatic way to control my organization users' calendars. Solution which require the user to authenticate using oauth2 (requires a user interaction) is not suitable in this case.

Here the code, currently with certificate authentication.


const tenantId = '###';
const clientId = '###';
const certificatePath = 'file.pem';


const credential = new ClientCertificateCredential(
    tenantId,
    clientId,
    certificatePath,
);

// @microsoft/microsoft-graph-client/authProviders/azureTokenCredentials
const authProvider = new TokenCredentialAuthenticationProvider(credential, {
    scopes: ['https://graph.microsoft.com/.default'],
});

const graphClient = Client.initWithMiddleware({ authProvider: authProvider });
const event = {
    subject: 'Testing meeting scheduling',
    body: {
        contentType: 'HTML',
        content: 'Is it working?',
    },
    start: {
        dateTime: '2024-05-22T11:00:00',
        timeZone: 'Pacific Standard Time',
    },
    end: {
        dateTime: '2024-05-22T12:00:00',
        timeZone: 'Pacific Standard Time',
    },
    location: {
        displayName: 'Room 22',
    },
    attendees: [
        {
            emailAddress: {
                address: '[email protected]',
                name: 'User A',
            },
            type: 'required',
        },
        {
            emailAddress: {
                address: '[email protected]',
                name: 'User B',
            },
            type: 'required',
        },
    ],
    transactionId: '?',
};

const calendarId = '################';


console.log("Scheduling....")

graphClient.api(`/me/calendars/${calendarId}/events`).post(event)
  .then(response => {
      console.log('Event created successfully:', response);
  })
  .catch(error => {
      console.error('Error creating event:', error);
  });

Getting the error:

{
  "code": "BadRequest",
  "message": "/me request is only valid with delegated authentication flow.",
  "innerError": {
    "date": "2024-04-30T09:04:28",
    "request-id": "921c1689-14a7-4452-8870",
    "client-request-id": "2dd01605-5566-0f41"
  }
}

Solution

  • The error usually occurs if you call /me endpoint with token generated with client credentials flow.

    I registered one Entra ID application and added Calendars.ReadWrite permission of Application type as below:

    enter image description here

    When I called /me endpoint with token generated with client credentials flow, I too got same error as below:

    const calendarId = '################';
    
    console.log("Scheduling....")
    
    graphClient.api(`/me/calendars/${calendarId}/events`).post(event)
      .then(response => {
          console.log('Event created successfully:', response);
      })
      .catch(error => {
          console.error('Error creating event:', error);
      });
    

    Response:

    enter image description here

    To resolve the error, replace /me with "/users/userId" in the code as client credentials flow is not a delegated flow to support /me endpoint.

    When I ran the code again after replacing it with /users/userId, I got the response where event created successfully as below:

    const calendarId = '################';
    
    console.log("Scheduling....")
    
    graphClient.api(`/users/userId/calendars/${calendarId}/events`).post(event)
      .then(response => {
          console.log('Event created successfully:', response);
      })
      .catch(error => {
          console.error('Error creating event:', error);
      });
    

    Response:

    enter image description here