I am building an SPFx app and I need to read the rooms and their events from Outlook, our company has 25 conference rooms that can be used to book events in a SharePoint calendar, we need to make sure the room is available in outlook and also be able create the event in outlook when submitted in the SharePoint form
I was able to get the list of all the rooms using the SharePoint context and querying the Microsoft Graph API like this:
const [outlookRooms, setOutlookRooms] = useState<any[]>([]);
React.useEffect(() =>{
const context = props.context;
context.msGraphClientFactory
.getClient('3')
.then((client: MSGraphClientV3): void => {
client
.api('/places/microsoft.graph.room')
.get((response: any, error: any) => {
console.log(response);
console.log(error);
setOutlookRooms(response);
});
});
},[]);
that part is working fine but when I try to get the room events I am getting a 404, this is my code for getting the room events:
const [roomEvents, setRoomEvents] = useState<any[]>([]);
React.useEffect(() =>{
const context = props.context;
context.msGraphClientFactory
.getClient('3')
.then((client: MSGraphClientV3): void => {
client
.api('/groups/roomid/calendarView?startDateTime=2024-01-01T19:00:00-08:00&endDateTime=2024-06-01T19:00:00.00-08:00')
.get((response: any) => {
setRoomEvents(response.value);
console.log(response);
})
;
});
},[]);
I couldn't find a way to get the events for rooms directly from the SPFX, what I end up doing was to create an Azure Function to get the events from Outlook, then I can call the azure function from the SPFX app, you have to enable CORS in the azure function to accept SharePoint calls, the azure function looks like this:
import { app, HttpRequest, HttpResponseInit } from "@azure/functions";
import axios from "axios";
import { Context } from "vm";
const tenantId = "mytenantid";
const clientId = "appclientid";
const clientSecret = "appclientsecret";
const scopes = "https://graph.microsoft.com/.default";
export async function GetEvents(req: HttpRequest, context: Context): Promise<HttpResponseInit> {
context.log(`Http function processed request for url "${req.url}"`);
const startDate = req.query.get('startdate') || await req.text();
const endDate = req.query.get('enddate') || await req.text();
const roomEmail = req.query.get('roomemail') || await req.text();
if(startDate ==='' || endDate ==='' || roomEmail ===''){
return { body: 'Parameters missing startdate: ' + startDate + 'enddate: ' +endDate+ 'room: '+ roomEmail}
}
const params = new URLSearchParams();
params.append('client_id', clientId);
params.append('client_secret', clientSecret);
params.append('scope', scopes);
params.append('grant_type', 'client_credentials');
let loginResponse = await axios.post(`https://login.microsoftonline.com/{tenantid}/oauth2/v2.0/token`, params);
if (loginResponse.status == 200) {
let accessToken: string = loginResponse.data.access_token;
let getPlaceResponse = await axios({
method: 'post',
url: `https://graph.microsoft.com/v1.0/users/{useridwithpermissionstorooms}/calendar/getSchedule`,
headers: { Authorization: "Bearer " + accessToken },
data: {
Schedules: [roomEmail],
StartTime: {
dateTime: startDate,
timeZone: "America/Denver"
},
EndTime: {
dateTime: endDate,
timeZone: "America/Denver"
},
availabilityViewInterval: "30"
}
});
if(getPlaceResponse.status == 200){
context.res = getPlaceResponse.data.value[0].scheduleItems;
}
else{
context.res = {
status: 500,
body: {
message: "Get Schedule Error"
}
};
}
}
else {
context.res = {
status: 500,
body: {
message: "Auth Error"
}
};
}
let result = JSON.stringify(context.res);
return {body: result};
};
app.http('GetEvents', {
methods: ['GET', 'POST'],
authLevel: 'anonymous',
handler: GetEvents
});