Synchronization of outlook messages attributes (Flag, IsRead) and deletion status - microsoft-graph-api

According to this documentation Synchronize messages API users have ability to synchronize messages with pretty simple skipToken mechanics. And it works well for fetching new messages in folders.
But! What I'm also interested is how to sync flags and status like is message read or not.
For example I synced all messages from Inbox folder. After that user goes to his Outlook account and reads message and set some flag for this message.
How can I get this info? Should I resync all messages to get only those changes?
Also how I get notion about message removal? If some user deleted message from inbox, how I get to know which message was deleted without fetching all messages again?

You should use the Microsoft Graph API and move away from using the Outlook Rest API as it has been deemphasized with no more effort being put into the developer experience.
Use Microsoft Graph to synchronize and track changes by using the Delta query feature.
An initial sync call will happen with a Delta query. Make sure you select the properties you care about:
GET https://graph.microsoft.com/v1.0/me/mailfolders/AQMkADNkNAAAgEMAAAA/messages/delta?$select=subject,sender,isRead
Prefer: odata.maxpagesize=50
If the response has an #odata.nextlink in the response JSON object, GET that URL to the next page of results.
If the response has an #odata.deltaLink in the response JSON object, cache that URL until the next time you want to check for changes.

Related

Outlook REST API Flagging Message losing start date

I'm building an Outlook Add-In and using the Outlook REST API 2.0. When updating a mail message to flag the message for follow-up, the update is accepted and in the Outlook Web client it briefly shows the start and due dates, but within a few seconds the start date goes away. When looking at the message through the API, the start date is completely removed, even though it was successfully added.
The API is PATCH Office.context.mailbox.restUrl + '/v2.0/me/messages/' + messageId ...
EDIT: I confirmed that this same behavior is exhibited in the Graph API as well.
As soon as the API is called, the UI on the message is updated:
Shortly after that (sometimes within a second, sometimes a little longer), the UI changes to:
And once the UI updates, if you query the API for the message and look at the Flag property, the StartDateTime object is completely gone.
Has anyone seen this or know why it might be happening?
Checked it on Graph with the following payload for PATCH-Message call and it seems to be working fine.
{"flag":{"dueDateTime":{"dateTime":"2020-08-20T00:00:00.0000000","timeZone":"Asia/Kolkata"},"flagStatus":"flagged","startDateTime":{"dateTime":"2020-08-14T00:00:00.0000000","timeZone":"Asia/Kolkata"}}}
I suspect that there is another application/outlook add-in that's removing this flag. Can you check once?

How to start using Delta function in Microsoft graph by skipping initial data

Microsoft recommends to use delta function in combination with Subscriptions/Notifications to synchronize mailbox. So my plan is:
Create subscription
Receive notification about new mail in inbox
Use delta function to get latest changes in the inbox
My mailbox already has several thousands of letters. If I run the query
https://graph.microsoft.com/v1.0/users/{id}/mailFolders/inbox/messages/delta
It will return in response #odata.nextLink with $skiptoken param many times and only after I get all the thousands of emails in my mailbox I will receive response with $deltatoken to track new changes.
Is there a way to get deltatoken after the first request? I don't want to synchronize the old messages. I want to skip all old messages in inbox and have a fresh start.
Today the delta query functionality does not support this scenario. To request new features please post ideas to uservoice
This is supported for some endpoints. You can use $deltaToken=latest to get just a deltaToken without any resource data. It's not, as far as I can tell, available for mailboxes… but who knows, maybe it will be soon.
This is not documented anywhere in the documentation for the specific APIs that do support it, but is instead documented in the Overview for change tracking. Why? Because Microsoft wants you to be sad all the time.

/me/activities request Microsoft Graph Explorer successful 200 response but empty "value":[ ]

I am trying to retrieve the list of entries that can be seen in the Windows 10 timeline view via the User Activities API in Microsoft Graph.
I have selected the UserActivity.ReadWrite.CreatedByApp permission and am getting an HTTP 200 Success response, but the value returned is empty. I am signed in with a Work Account (O365)
https://graph.microsoft.com/beta/me/activities/recent?$top=5
When I look in the timeline view in Windows 10, I see a comprehensive history of activity. The machine is signed in using the same Work Account.
Any help greatly appreciated.
According to the documentation, only activities created by the current AppID will be returned:
The UserActivity.ReadWrite.CreatedByApp permission will also apply extra filtering to the response, so that only activities created by your application are returned. This server-side filtering might result in empty pages if the user is particularly active and other applications have created more recent activities. To get your application's activities, use the nextLink property to paginate.
I'd suggest dropping the $top parameter and following the nextLink URIs to see if your app's activities show up deeper down the stack.

What is clientChangeTokenData in CKModifyRecordsOperation?

I am working on CloudKit sync in my app ("Tiny data, all devices" model, with a custom zone in the private database).
CKModifyRecordsOperation contains clientChangeTokenData property of NSData type which is described in the docs as follows:
When you modify records from a fetch operation, specify a client-generated data token using this property to indicate which version of the record you last modified. Compare the data token you supplied to the data token in the next record fetch to confirm the server has successfully received the device’s last modify request.
I don't get why I should bother given that with each request, I get a completion block which tells me whether the server has successfully received my request. Why do I need to manually compare this client token?
Is specifying clientChangeTokenData required to handle my use case correctly? I track local data changes and push everything in the queue on each data change. Remote changes are tracked via zone subscription.
If it is required, how do I generate this token correctly given that I have all kinds of record changes in my CKModifyRecordsOperation (my API usage aims for batch operations). What is the general workflow here?
Thank you.
It's unclear from the docs so I'd guess the clientChangeTokenData is useful in the case of sending up a large modify records operation, e.g. deleting 100 records. Then say your app sends a fetch request in another operation with a query (or fetch changes) result set that would be affected by the modifications which either:
is started and is running concurrently to the existing modify operation which hasn't finished yet.
is started before the server has finished processing the results of the previous modifications (the docs tend to allude to a processing delay).
If the fetch completion contains a different clientChangeTokenData to the one sent with the modify then you know it hasn't received (or finished processing?) the changes yet. In this situation you could either error, with an alert to say the server needs more time, or automatically retry the fetch after some time.
By the way in my tests, this token is per-device.
You would only have a reason to check the token if you had local changes that you want to write to CloudKit and you want to make sure that your changes are based on the latest version of the data in CloudKit.
You could also just ignore the token and save the data anyway. If the data has changed in the mean time, you will get a CloudKit error and you could handle it then.

Pushing updates to the view in (close to) real-time

Say my user is viewing messages/index, and someone else sends him a message. I'd like the user's view to update in real-time to reflect the new message, kind of like how Twitter lets me know there are more messages on my timeline. Are there any examples of this being done in Rails?
You can either use AJAX to poll the server for updates on a regular basis (pull model), or use the Juggernaut plugin or similar to enable the server to send updates to the client (push model). Note that this requires Flash to be installed on the client.
DUI.stream from digg might be the solution you are looking for. It keeps an open xhr stream that you can keep on adding objects to to send to the user. It has a ruby client example

Resources