I'm trying to create a meeting as a application, add attendees, determine time availability.
This is what I have so far :
Auth
private async Task<ClientCredentialProvider> GetToken()
{
var confidentialClientApplication = ConfidentialClientApplicationBuilder
.Create(_microsoftAppId)
.WithTenantId(_microsoftTenantId)
.WithClientSecret(_microsoftAppPassword)
.Build();
ClientCredentialProvider authProvider = new ClientCredentialProvider(confidentialClientApplication);
return authProvider;
}
Meeting request
public async Task GetMeetingtime()
{
var authProvider = await GetToken();
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
var attendees = new List<AttendeeBase>()
{
new AttendeeBase
{
Type = AttendeeType.Required,
EmailAddress = new EmailAddress
{
Name = "john doe",
Address = "john.doe@onmicrosoft.com"
}
},
new AttendeeBase
{
Type = AttendeeType.Required,
EmailAddress = new EmailAddress
{
Name = "john toe",
Address = "john.toe@onmicrosoft.com"
}
}
};
var locationConstraint = new LocationConstraint
{
IsRequired = false,
SuggestLocation = false,
Locations = new List<LocationConstraintItem>()
{
new LocationConstraintItem
{
ResolveAvailability = false,
DisplayName = "Conf room Hood"
}
}
};
var timeConstraint = new TimeConstraint
{
ActivityDomain = ActivityDomain.Work,
TimeSlots = new List<TimeSlot>()
{
new TimeSlot
{
Start = new DateTimeTimeZone
{
DateTime = "2020-12-10T09:00:00",
TimeZone = "Pacific Standard Time"
},
End = new DateTimeTimeZone
{
DateTime = "2020-12-10T17:00:00",
TimeZone = "Pacific Standard Time"
}
}
}
};
var isOrganizerOptional = false;
var meetingDuration = new Duration("PT1H");
var returnSuggestionReasons = true;
var minimumAttendeePercentage = (double)100;
await graphClient
.Me
.FindMeetingTimes(attendees, locationConstraint, timeConstraint, meetingDuration, null, isOrganizerOptional, returnSuggestionReasons, minimumAttendeePercentage)
.Request()
.Header("Prefer", "outlook.timezone=\"Pacific Standard Time\"")
.PostAsync();
}
This is the error I get:
Current authenticated context is not valid for this request. This occurs when a request is made to an endpoint that requires user sign-in. For example, /me requires a signed-in user. Acquire a token on behalf of a user to make requests to these endpoints. Use the OAuth 2.0 authorization code flow for mobile and native apps and the OAuth 2.0 implicit flow for single-page web apps.
How can I solve this?
According to docs, the findMeetingTimes API does not support application-only access: https://docs.microsoft.com/en-us/graph/api/user-findmeetingtimes?view=graph-rest-1.0&tabs=http.
It can only be called in the context of a signed-in user.
Now, you could try to use .Users["user-id"]
instead of .Me
just in case the docs are wrong about this.
"me" only makes sense when calling the API on behalf of a user, which you are not.
Calendar events can be created as an application that has write access to the users' calendars.
Hello and thank for your answer. I've tried to use .Users["something"] , but really I don't know how do I get a
user-id
, also can it be any user-id? Can you provide an example?It's usually the objectId of the user. You can get those through the /users API or from Azure Portal user properties.
I've managed to get my
user-id
. But I'm getting this error401 - Unauthorized: Access is denied due to invalid credentials.
It is possible then that the scenario is simply not supported when using an application with no signed in user.