I'm looking to write events to a users calendar that correspond objects in my system. I also want the ability to update and/or delete those that change between runs of the process that updates the user's calendar.
To this end I'm using Open Extensions to write additional data onto the Calendar Events that I'm creating. This is working nicely and I can see the Extension data being written.
I can use a $filter to query for events that I have written to the user's calendar:
/v1.0/me/events?$filter=Extensions/any(f: f/id eq '{id}')
This works fine and I'm seeing the results I expect. It's worth noting that the id in this query works just fine with either the fully qualified form of Microsoft.OutlookServices.OpenTypeExtension.{extensionName} or just using the short form of {extensionName}
However I cannot get the events to return with the $expanded Extension. I've tried the examples from the docs but using this query it fails:
/me/events?$filter=Extensions/any(f: f/id eq '{id}')&$expand=Extensions($filter=id eq '{id}')
Like this:
{
"error": {
"code": "BadRequest",
"message": "Parsing Select and Expand failed.",
"innerError": {
"date": "2020-06-19T17:14:59",
"request-id": "d1125156-05a6-499a-b9a4-6c66e5ce377d"
}
}
}
I need the expanded Extension data to correlate the Calendar event back to the objects in my system to allow for updates or deletes as needed.
Does anyone know what might be happening or how to resolve this?
I got an answer through another question: Receiving 400s and 500s when attempting to get singleValueExtendedProperties
The issue is that the = symbol inside the $expand expression needs to be uriEncoded. The correct query to use is: /me/events?$filter=Extensions/any(f: f/id eq '{id}')&$expand=Extensions($filter%3Did eq '{id}')
Related
I am trying to retrieve Calendar View for a user using end point GET : https://graph.microsoft.com/v1.0/users/{UserEmail}/calendarView?startDateTime=2020-09-25T19:00:00-08:00&endDateTime=2020-10-02T19:00:00-08:00 and it returns
`{
"error": {
"code": "ErrorItemNotFound",
"message": "The specified object was not found in the store.",
"innerError": {
"date": "2020-10-23T15:11:51",
"request-id": "20409ad4-2f27-48bd-8fe8-690580ccd4e9"
}
}
}`
This is happening only for some users on our client environment.
Initially we thought, its an issue related to Permissions OR Access Token but both looks fine like user has all the permissions to read/write calendar and Access Token also looks valid too as some other end points which gives valid result with same access token.
So I tried Investigating it further more and found, if user has an exception type of Event on his outlook calendar then only /CalendarView end point returns 404.
For Example : This particular User has Exception type of Event on his calendar on Date 10/01/2020. So if I query Graph with same end point with different date range like GET : https://graph.microsoft.com/v1.0/users/{email}/calendarView?startDateTime=2020-09-25T19:00:00-08:00&endDateTime=2020-09-29T19:00:00-08:00 it works fine and it gives all the events between date ranges but if I change the endDateTime = 2020-10-02T19:00:00-08:00 it gives 404 response.
To validate this I tried to switch different end point
GET : https://graph.microsoft.com/v1.0/users/{email}/calendar/events?$filter=start/datetime ge '2020-10-01' and end/dateTime lt '2020-10-02'
Which works fine like it gives me the series Master Event
So I thought to use instances end point GET : https://graph.microsoft.com/v1.0/users/{UserEmail}/events/{EventId}/instances?startDateTime=2020-09-29T19:00:00-08:00&endDateTime=2020-10-26T19:00:00-08:00 to get all the instances of the Series Master Event but surprisingly it fails to return Exception type of event from this end point too. According to their documentation it supposed to return Occurrences and Exception of Series Master but for this user it only returns all Occurrence type of Event and failed to return Exception type of event which is on 10/01.
After that I tried one more end point POST : https://graph.microsoft.com/v1.0/me/calendar/getSchedule and found that specific event scheduled on his calendar.
but it only gives some information about the event.
Does any one knows how to solve this?
Situation:
We have an old application that is creating events in outlook (via MAPI). To identify the events the custom property 'CTOID' is set with a specific value by which the events can be found again.
For a newer application we would like to use the Graph API but the application should still be able to read/find the events created by the old application. So I created a test event with a specific CTOID and I can already use the graph client to get the mentioned event with the according property and its value (queryOptions is just some start-/enddate restrictions).
// Initialize the GraphServiceClient.
GraphServiceClient client = await m_MicrosoftGraphClient.GetGraphServiceClient();
// Load user events.
var request = client.Users[userId].CalendarView.Request(queryOptions).Expand("singleValueExtendedProperties($filter=id%20eq%20'Double%20{00020329-0000-0000-C000-000000000046}%20Name%20CTOID')");
var result = await request.GetAsync();
var calendarEvents = result.CurrentPage;
Result:
The event gets fetched correctly including the value for the CTOID property.
Problem:
I can "Expand" events so they contain the value for the CTOID property. But how do I find an event with a specific CTOID value? And specifically, how do I do this with the Graph client in C#?
According to the documentation and this Stackoverflow post, the following REST call should work:
GET /users/{id|userPrincipalName}/events?$filter=singleValueExtendedProperties/Any(ep: ep/id eq '{id_value}' and ep/value eq '{property_value}')
So I tried this in the online Graph Explorer:
https://graph.microsoft.com/v1.0/users/[MY_USER_ID]/events?$filter=singleValueExtendedProperties/Any(ep: ep/id eq 'Double {00020329-0000-0000-C000-000000000046} Name CTOID' and ep/value eq '229236')
But all I get as response is:
{
"error": {
"code": "ErrorInvalidUrlQueryFilter",
"message": "The filter expression for $filter does not match to a single extended property and a value restriction.",
"innerError": {
"date": "2020-08-03T12:44:05",
"request-id": "33e82c77-92ea-4865-a8d0-00cfc2f99154"
}
}
}
What am I doing wrong? I'm out of ideas and any help would be greatly appreciated.
(Also if you have any idea how to do this with the Graph client in C# and not just the bare REST call).
Additional Information:
Don't know if it's important, but the following permissions are set for our application:
In your filter you need to cast the value to a Double eg
https://graph.microsoft.com/v1.0/users/[MY_USER_ID]/events?$filter=singleValueExtendedProperties/Any(ep: ep/id eq 'Double {00020329-0000-0000-C000-000000000046} Name CTOID' and cast(ep/value, Edm.Double) eq 229236)
For anything other then a String in a filter you need to do this
When I select the properties allowExternalSenders or autoSubscribeNewMembers for a group synced from an on-premise Active Directory, I get the following error via Graph API SDK:
403 Forbidden
Graph service exception Error code: AppOnlyAccessNotEnabledForTarget
Error message: App Only access is not allowed for target resource: 'a1d0c98e-fb7e-40c4-a7b5-ccf6d96cba57#34f0717f-f1a0-4894-b310-d379993504b9'.
The Graph Explorer displays the following 404 error, even though it is not a mailbox:
{
"error": {
"code": "MailboxNotEnabledForRESTAPI",
"message": "REST API is not yet supported for this mailbox.",
"innerError": {
"request-id": "5beae8eb-4a59-404f-bd42-0c6aa2a25abd",
"date": "2020-03-31T13:02:11"
}
}
}
An example request looks like this:
https://graph.microsoft.com/v1.0/groups/{id}?$select=id,deletedDateTime,assignedLicenses,description,displayName,groupTypes,licenseProcessingState,mail,mailEnabled,mailNickname,onPremisesLastSyncDateTime,onPremisesSecurityIdentifier,onPremisesSyncEnabled,onPremisesDomainName,onPremisesSamAccountName,preferredDataLocation,securityEnabled,securityIdentifier,visibility,resourceProvisioningOptions,allowExternalSenders,autoSubscribeNewMembers
Which property should I use to decide if I should try to select these properties or not? I want to avoid missing the properties for groups which actually do expose these properties, so I do not simply want to guess.
Slightly different take on this answer, Microsoft even thought only providing one API for groups, there are effectively two different objects returned, SecurityEnabled = True or False. If Security = True then you can not ask for the follow attributes
(allowExternalSenders,autoSubscribeNewMembers,hideFromAddressLists,hideFromOutlookClients)
Is this ok, NO its not ok, Microsoft needs to return null instead of providing THE WRONG ERROR MESSAGE and sending people like us into multi hour head scratchers.
In my code, I now check if securityEnabled is true or false and have a different set of attributes depending.
The mailbox is on a dedicated (on premise) Microsoft Exchange Server or is not a valid (configured) Office 365 mailbox. Contact your Exchange or Office admin to apply any of these recommended solutions.
To filter Office 365 groups you can do this:
https://graph.microsoft.com/v1.0/groups?$filter=groupTypes/any(c:c eq 'Unified')
How can I filter by multiple IDs using the Office 365 Service Communications API?
I'm getting the current status using https://manage.office.com/api/v1.0/{tenent}/ServiceComms/CurrentStatus which gives me incident IDs. I'm trying to use those IDs to get the messages affiliated but the message endpoint /ServiceComms/Messages is not working well with the filters.
The documentation shows:
I've tried:
/ServiceComms/Messages?ID=CR555555,/ServiceComms/Messages?ID='CR555555', /ServiceComms/Messages?Id=CR555555,/ServiceComms/Messages?Id='CR555555' - Returns everything (doesn't filter)
/ServiceComms/Messages?$filter=ID eq 'CR555555' - Returns Error
/ServiceComms/Messages?$filter=Id eq 'CR555555' - Returns 1 result
/ServiceComms/Messages?$filter=Id eq 'CR555555' or Id eq 'CR555556' - Returns error
I was able to get an AND result using
$filter=MessageType eq Microsoft.Office365ServiceComms.ExposedContracts.MessageType'Incident' and EndTime ge 2019-07-25T00:00:00Z but OR always errors with the message "Filter {filter} is invalid. Expected '<Item> <operator> <Value>' pattern."
You need to use Microsoft.Office365ServiceComms.ExposedContracts.MessageType'Incident' as your MessageType.
A request to /Messages should return you a odata context at the top of the response. For example:
{
"#odata.context": "https://office365servicecomms-prod.cloudapp.net/api/v1.0/{{TenantID}}/$metadata#Messages",
...
}
If you query that, you receive the metadata along with the possible filters. I cannot give you an example as of today (2020-02-16) a query returns a 500 Internal Server Error. Microsoft is working on a fix. Maybe it works again by the time you read my reply.
Complete example:
https://manage.office.com/api/v1.0/{{TenantID}}/ServiceComms/Messages?$filter=MessageType eq Microsoft.Office365ServiceComms.ExposedContracts.MessageType'Incident' and LastUpdatedTime ge 2020-02-13T00:00:00.000Z
And yes, the ID filter must be written 'Id'. Microsofts documentation has a lot of wrong information in it.
According to the document, I can list the Office 365 Groups by using the following Graph API:
GET https://graph.microsoft.com/v1.0/groups
I have a C# Web application, and there is a input for searching by the Group DisplayName. Any idea how to query groups based on the DisplayName?
I have tried the following URL: https://graph.microsoft.com/v1.0/groups?$search="displayName:Test" in the MS Graph Explorer which didn't work.
I get the following error.
{
"error": {
"code": "Request_UnsupportedQuery",
"message": "This query is not supported.",
"innerError": {
"request-id": "35d90412-03f3-44e7-a7a4-d33cee155101",
"date": "2018-10-25T05:32:53"
}
}
Any suggestion is welcomed.
Thanks in advance.
According to your description, I assume you want to search the Group by the DisplayName using the search parameters.
Based on this document, we can currently search only message and person collections. So we couldn't use the search parameter.
We can use the filter query parameter to search the Group by DisplayName. For example, we can search the groups whose displayName is start with 'Test',the request url like this:
https://graph.microsoft.com/v1.0/groups?$filter=startswith(displayName,'Test')
Here is C# code that I wrote to get a group using the DisplayName. This code requires a reference to the OfficeDevPnP.Core.
private static async Task<Group> GetGroupByName(string accessToken, string groupName)
{
var graphClient = GraphUtility.CreateGraphClient(accessToken);
var targetGroupCollection = await graphClient.Groups.Request()
.Filter($"startsWith(displayName,'{groupName}')")
.GetAsync();
var targetGroup = targetGroupCollection.ToList().Where(g => g.DisplayName == groupName).FirstOrDefault();
if (targetGroup != null)
return targetGroup;
return null;
}
UPDATE
I see that the answer has already been accepted, but I came across the same issue and found that this answer is out of date. For the next person, this is the update:
The 'search' functionality does work. Whether it was fixed along the way or always has, I am not sure.
'groups' support search,
both the v1 and beta api support search,
search only works on 'displayName' and 'description' fields,
searching on 'directory objects' require a special header: 'ConsistencyLevel: eventual'
Point number 4 is what tripped me up!
Your request would look like this:
https://graph.microsoft.com/v1.0/groups?$search="displayName:Test"
With the request header:
ConsistencyLevel: eventual
There is another catch: You can only specify the first 21 characters and the search always uses 'startsWith'. You're out of luck if you specify more than that: The search always fails.