Using office-js I am developing an Outlook add-in, consisting in a taskpane where I need to get all the information (basic info, body and attachments) about the current item (email) to send it to a web service. I am using Angular 8 and referencing the API with: <script type="text/javascript" src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js"></script>
I have no problem getting the body using the function Office.item.body.getAsync(options, callbackFunction)
and I am able to get the attachments using
Office.item.getAttachmentContentAsync(item.attachments[i], options, callbackFunction)
.
The problem comes when I leave the Outlook Web opened in the same message for a few minutes. After that, when I execute my add-in, calls to Office.item.getAttachmentContentAsync
start to fail, writing in the console the error: Uncaught (in promise) TypeError: Failed to fetch
. The main problem is that I am not able to catch the exception, so my add-in gets stuck waiting forever, because the callbackFunction is never called, and adding a surrounding try catch doesn't work, because the error seems to be in an internal promise of the office-js library. Note that even in this situation, calls to get the body still work without problem.
As I can see using the Chrome tools, the normal behaviour of the call to Office.item.getAttachmentContentAsync
is one request to:
https://attachment.outlook.live.net/owa/MSA:[...]/service.svc/s/GetFileAttachment?id=[...]
returning a 200 status code.
But when the session is "expired", the request to https://attachment.outlook.live.net/owa/MSA:[...]/service.svc/s/GetFileAttachment?id=[...]
returns a 302 to https://outlook.live.com/owa/MSA:[...]/service.svc/s/GetAttachmentDownloadToken?redirect=[...]
that returns a 440 Login Timeout.
I would like to know if there is any way I can avoid the error (check if the session is already expired, force to refresh the session, etc.) or if there is any way to catch the error (avoiding the add-in to be get stuck), in order to notify the user about the problem.
The callbackFunction is quite simple:
private static callbackFunction(asyncResult: Office.AsyncResult<any>){
if (asyncResult.status == Office.AsyncResultStatus.Succeeded){
[...]
}
else{
//Never called
}
}
Edit: I just realized that using the add-in in the Outlook for Android, with the same code there is no way to get a response from Office.item.getAttachmentContentAsync
, but I do get the body content of the email. In Outlook Web refreshing the page temporary fixes the problem, but in Outlook for Android restarting the app doesn't help. I am not sure if the error is the same 440 Login timeout in Android, as I am not able to debug the add-in there.
Edit2: In Outlook Desktop for Windows I am unable to reproduce the issue, it works fine.
As an alternative, I changed my code to start using the REST API instead of Office.context.mailbox.item.getAttachmentContentAsync
.
This code, adapted from the example in https://learn.microsoft.com/en-us/javascript/api/outlook/office.mailbox?view=outlook-js-preview#resturl, always works, even in Android/iOS, that don't support the RequerimentSet 1.8 (needed to use getAttachmentContentAsync
).
Office.context.mailbox.getCallbackTokenAsync({ isRest: true }, function (result) {
var ewsId = Office.context.mailbox.item.itemId;
var token = result.value;
var restId = Office.context.mailbox.convertToRestId(ewsId, Office.MailboxEnums.RestVersion.v2_0);
var getAttachmentsUrl = Office.context.mailbox.restUrl + '/v2.0/me/messages/' + restId + '/attachments';
var headers = { 'Authorization' : 'Bearer ' + token };
var options = { headers: headers };
myContext.httpClient.get<AttachmentsResponse>(getAttachmentsUrl, options)
.subscribe(...);
});