Microsoft Graph User delta expand duplicate result handling - microsoft-graph-api

When using the user delta endpoint for the initial read with expand on Manager property the query returns duplicate results. Some of these differ by either having the Manager Id or not but in some cases there are exact copies in the result pages. Some processed data suggests that sometimes even key properties like DisplayName end up missing in one of the duplicates.
Anyone knows what is a reliable strategy to resolve these merge issues to arrive at a consistent state? Or ideally how to avoid having to do this at all?

$expand is not supported for users, groups and other identity entities with delta queries. I authored a pull request to fix the documentation. If you want to track changes for the manager you should use $select=manager instead.

Related

Get Change type in delta Events in Microsoft Graph Api

I am migrating from EWS to Microsoft graph and having problem in replacing flow "ExchangeService.syncFolderItems".
ChangeCollection<ItemChange> changedItems = exchangeService.syncFolderItems(calendarFolder.getId(),
FirstClassProperties, null, 512, NormalItems, syncState);
This gives me all the changes since last sync state with change type.
Now I need to replace this with Microsoft graph.
I saw Get delta api in Microsoft graph and also how to call it recursively using stale token. My query is, Get delta api is not returning the change Item type. Could someone suggest me the best way to implement this in Microsoft graph? Maybe the Apis that I need to use for this?
Note:This flow will be called by my service to get changes after fixed interval of time. Also I saw subscriptions ( https://learn.microsoft.com/en-us/graph/api/resources/subscription?view=graph-rest-1.0 )but not sure that could be used in my case as my service will be making a call to get changes for a meeting room after a fixed scheduled interval of time.
I am stuck here. Please help. Thanks in advance.
Deleted events will have a #removed property and only provide the id of the object as denoted here https://learn.microsoft.com/en-us/graph/delta-query-overview#resource-representation-in-the-delta-query-response
Updated objects will only include the updated properties and added objects should include all the data available. It's up to the 3rd party application (your app) to maintain a state on it's side to be able to differentiate between updated and created objects when using Delta queries.
Combining webhooks with Delta to trigger the sync instead of relying on a timer is a good approach to provide an end user experience that feels more real time

Microsoft Graph educationClass expand with select

I'm trying to grab only properties "id" and "userPrincipalName" from the teacher when getting educationClasses with $expand=teacher as parameter. But whatever I do, I keep getting the full teacher/user object.
https://graph.microsoft.com/v1.0/education/classes?$expand=teachers($select=id,userPrincipalName)
But it gives the same result as this one:
https://graph.microsoft.com/v1.0/education/classes?$expand=teachers
What am I doing wrong?
Or is this one of the endpoints where the expand+select feature is not fully supported? I don't want the full teacher object because it contains assignedLicenses, assignedPlans, provisionedPlans and a whole lot of stuff I will never need in this request.
And...it's production, so I'd like to avoid using the BETA endpoint if possible.
Yep, looks like the underlying AAD storage doesn't support expand plus select.
You can see what is happening under the covers by appending the &$whatif to your query.
Not a lot we can do about this, as the AAD team aren't investing in adding richness here right now.

Azure API Management issue with OData

We have an OData v4 API that we are putting behind an Azure API Management (AAM) service, but have run into a problem configuring the routes/oerations. In a nutshell, the issue is that AAM will reject a query for a route/operation unless it is explicitly configured (you get a 404 error), but with OData there can be a route for every attribute (property) of every operation (endpoint). The problem quickly becomes unmanageable.
OData allows you to query an individual attribute/property (eg GET ~/api/Person(1234)/FirstName. If we put this behind AAM, we need to define it as an operation. That's OK as long as there are only a few of these, but it potentially means you quickly have to define hundreds/thousands of operations (unless I've missed something). We have an API with about 35 top level operations. Each resource has 20 attributes on average. That's 700 operations we would need to define. Apart from the work involved, that would be a shocking experience for users of the AAM developer portal.
I'm hoping someone can tell me an easy way to get around this problem. I know I can script the creation of these. You an also get around this problem to some degree if you use an OData $select query parameter (which is what I've suggested in the meantime). I can't get over the feeling I've missed something here. Is there a way of defining some sort of wildcard portion to the operation (eg /Person/*)? I can't find anything like that in the AAM documentation.
Try using URL templates instead of writing them explicitly, i.e. define operations for /{entity}/{property} this way it'll match every entity and every property of every entity. And you could use wildcards as well if you want to capture multiple segments at the end of URL.

Get all user (+ direct manager, photo meta data and properties like 'AboutMe')

Until now we used a SharePoint on-premise custom web service which delivered all users (approx 15,000) inclusive properties like aboutMe, skills, etc. and the direct manager. That job took approx. 15 minutes.
All the data was stored in a Lucene search index.
Now we have to switch to O365.
I am able to get all the desired information from Microsoft Graph but it would take way too long (3 - 5 hours):
Fetch all users via /v1.0/users (with paging)
Iterate through the collection and
get manager for given user via /v1.0/[user-id]/manager
get properties like aboutMe, skills for given User via /v1.0/[user-Id]?$select=aboutMe,skills
Is there any efficient way to do that task?
Ideally, you should just call Microsoft Graph for the data you want on-demand rather than attempting to sync it to your own database.
Assuming you can't do that, you can deduce the time this takes using /delta endpoint (Get incremental changes for users). When you use a delta token, you will only get back resources that have changed (adds, deletes, edits) since your previous request. So your first pass might take a few hours, but subsequent passes should take seconds.
You can control which properties you're "tracking changes" against using the $select query parameter. For example, if you only care about changes to the displayName then using /v1.0/users/delta?$select=displayName will ensure you only receive changes to that property. From the documentation:
If a $select query parameter is used, the parameter indicates that the client prefers to only track changes on the properties or relationships specified in the $select statement. If a change occurs to a property that is not selected, the resource for which that property changed does not appear in the delta response after a subsequent request.
Also, consider batching requests to improve your processes' overall performance. Batching allows you to send multiple queries to Microsoft Graph in a single request and get the complete results back in a single response.

Get new emails with microsoft graph

I am trying to get only new emails with microsoft graph.
Iam doing this by checking date like
GET https://graph.microsoft.com/v1.0/me/messages?$filter=receivedDateTime+gt+2016-06-06T08:08:08Z
Is there any possibility to build query to get new messages but base on id instead of receivedDateTime? Something like: get messeges until you find id=....?
I think the delta query solution is pretty good (as suggested in a different answer). However, for my purposes, there were two major drawbacks: 1) it's in preview (beta) right now, so it makes it less than ideal for production code and 2) it doesn't seem to support the monitoring of all messages, just those in a particular folder.
I actually prefer the solution you're working with. The timestamp in the header of the response can be used to reset the time field in you query, so that if you have "receivedDateTime gt 12:00:00" and get back the server time of 12:01:00 for your request, you can use "receivedDateTime gt 12:01:00" next time.
The scenario you're looking for is specifically what the new Delta query is designed to support. Deltas allow you to retrieve changes to a given folder (i.e. Inbox) since you last polled that folder. Message IDs not static or consecutive so they're not a suitable property for determining new vs. old messages.

Resources