Immediate synced to the server - saveAsync to get an itemId to use with EWS or the REST API
Note: This particular issue has significant impact on our customers, which translates to high business impact with direct consequences on revenue.
How can our Office add-in for Outlook, when a user interacts with our add-in while composing an email draft, minimize the amount of time it takes before the EWS GetItem API will return an OK response for the itemId we receive from Office.context.mailbox.item.saveAsync()?
If it turns out that our add-in has no control over when the item will be persisted to EWS, then what could an end-user do to speed this up?
We are looking for either (a) a technical solution, or (b) messaging to instruct our customers on how to mitigate/fix/work around this issue.
Some of our customers are unable to send emails using our Office add-in for Outlook, or have to wait an exceedingly long time (> 2 minutes) before their email will send.
We want all of our customers to be able to send emails using our add-in, without having to wait for an unreasonable amount of time.
Based on our logs and customer reports, this issue only exists in the Outlook 2016 for Windows desktop application. We have no evidence to suggest the issue is present in any other version of Outlook, including Outlook 2013 or Outlook for Mac, however it is possible that the issue may be present in those clients as well.
Overview of our add-in
Our add-in integrates with Compose mode to provide additional functionality while composing email messages, such as templates, follow-ups, open and click tracking, and scheduling.
Our add-in works in tandem with our SaaS product like this:
Our add-in sets EWS extended properties on the email message with metadata indicating which features are enabled on that message.
Our SaaS product, out of band, is configured to read from the customer's mailbox via the EWS API. When it encounters EWS extended properties our Office add-in has written, it triggers the code paths to satisfy the desired behavior.
Root Cause Analysis
The root cause of our problem is our interaction with EWS in Outlook 2016 for Windows. In order to successfully interact with EWS to read/write to a mailbox item, it must be aware of that item.
The documentation for Office.context.mailbox.item.saveAsync() says:
In Outlook Web App or Outlook in online mode, the item is saved to the server. In Outlook in cached mode, the item is saved to the local cache.
It goes on further to say:
Note: If your add-in calls saveAsync on an item in compose mode in order to get an itemId to use with EWS or the REST API, be aware that when Outlook is in cached mode, it may take some time before the item is actually synced to the server. Until the item is synced, using the itemId will return an error.
Thus, we have concluded that Office.context.mailbox.item.saveAsync(), although it does indeed return an eventually valid itemId, does not guarantee that any subsequent EWS interaction will succeed. So far, we have found no way to accelerate the process of the Outlook client actually making EWS aware of the mailbox item.
We have attempted to mitigate this problem by polling EWS GetItem to attempt to obtain a ChangeKey for the item with the itemId we receive from Office.context.mailbox.item.saveAsync(). While we have seen that this does eventually succeed, it may take a minute or longer before this occurs. That is simply far too much time for our customers to have to wait.
Understanding "online mode" vs "cached mode"
If the Outlook 2016 for Windows desktop client is in "cached mode", is there anything the user can do to:
…know whether the client is in "cached mode" or "online mode"?
…attempt to force the client into "online mode"?
Is there a solution to this? We have the very same issue in Outlook 365 on Windows only. Its interesting that things work properly everywhere I've tried (including Outlook on iOS and Android) aside from Microsofts very own platform. At the very least, give us the option of manually syncing items.
Rafal Boni commented
It would also be great to pass the change key back to the caller of the saveAsync(). We've seen the message sync to the server but actually contain an out-of-date version of the draft. Being able to determine that we have the right version at the backend would be fabulous.
Albert Lyubarsky commented
No solution so far