I am trying to accomplish what I believed to be a simple task, but has turned into nothing short of a nightmare. My goal is to create an AWS Lambda function that will be invoked whenever a user submits an inquiry form on my website.
The form includes an event date, and I want the function to use that date to retrieve all the events on my personal Outlook calendar for that day.
I found a query that works in the graph explorer, but every combination of permissions and flows I've tried on the Lambda and my local machine results in any one of a vast array of authentication errors.
Here is my most recent attempt:
import axios from 'axios';
export const handler = async (event) => {
const clientId = process.env.CLIENT_ID;
const clientSecret = process.env.CLIENT_SECRET;
const tenantId = process.env.TENANT_ID;
const tokenUrl = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`;
//const calendarUrl = 'https://graph.microsoft.com/v1.0/me/calendar/events';
const authParams = new URLSearchParams({
grant_type: 'client_credentials',
client_id: clientId,
client_secret: clientSecret,
scope: 'https://graph.microsoft.com/.default'
});
try {
const tokenResponse = await axios.post(tokenUrl, authParams);
const accessToken = tokenResponse.data.access_token;
//const calendarUrl = 'https://graph.microsoft.com/v1.0/me/calendarView';
const calendarUrl = "https://graph.microsoft.com/v1.0/users('{my-user-princpial-name}')/calendarView";
const date = event.date; // The date for which you want to retrieve events
const calendarParams = {
startDateTime: `${date}T00:00:00-08:00Z`,
endDateTime: `${date}T23:59:59-08:00Z`
};
const config = {
headers: {
Authorization: `Bearer ${accessToken}`,
},
params: calendarParams
};
const calendarResponse = await axios.get(calendarUrl, config);
const events = calendarResponse.data.value;
return {
statusCode: 200,
body: JSON.stringify(events)
};
} catch (error) {
console.error('Error:', error.response.data.error);
return {
statusCode: 500,
body: JSON.stringify({ error: 'An error occurred' })
};
}
};
This particular piece of code produces the error message: "The tenant for tenant guid '{my-tenant-id}' does not exist."
Not entirely sure what this means, as the tenant quite certainly does exist, and the user I am attempting to access is the only user assigned to it.
And as for the overall function, I know it is valid, because when I switch the calendarUrl to the "/me" query and copy and paste the token from the graph explorer, it works exactly as intended.
Basically the problem is that Microsoft refuses to hand over the necessary token no matter what combination of application/delegation permissions I try.
Is this all because I'm using a personal account? I've seen some things online that suggest that the API only works with personal accounts when the user manually logs in every time a request is made, but that would basically undermine the whole purpose of my use case. I may as well just manually check my calendar myself at that point.
There must be some way around this or some flow that would get me the token I need, if anyone has been through this before and could shed some light on what to do I would be very grateful.
It doesn't have to be a fix for this particular code, really just any solution to get calendar events from my personal outlook calendar programmatically.
At this point I'm considering attempting to get the info I need by using a webdriver to scrape it directly from the web app, or migrating my entire calendar to a different calendar service with a more user-friendly API. For obvious reasons, neither of these solutions is ideal. But they're starting to look more worthwhile the deeper into this I get.