0

I have a need to get content of the email as EML (preferable base64 as I need to send it to 3-th party system).

I am using such solution but it has limitation to 1MB.

var soapEnvelope = ... // initialize soap envelope

Office.context.mailbox.makeEwsRequestAsync(soapEnvelope, function(result){
  var parser = new DOMParser();
  var doc = parser.parseFromString(result.value, "text/xml");
  var values = doc.getElementsByTagName("t:MimeContent");
  var subject = doc.getElementsByTagName("t:Subject");
  console.log(subject[0].textContent)
});

It works, but with 1 MB limitation.

I have managed to build a solution that makes a direct call to EWS. Here is a JavaScript solution (could be useful to others as I could not find such example).

Office.context.mailbox.getCallbackTokenAsync(function(result) {
  var token = result.value;
  var ewsurl = Office.context.mailbox.ewsUrl;
  var itemId = Office.context.mailbox.item.itemId;
  var envelope = getSoapEnvelope(itemId);

  var xhttp = new XMLHttpRequest();
  xhttp.open("POST", ewsurl, true);
  xhttp.setRequestHeader("Content-type", "application/soap+xml");
  xhttp.setRequestHeader("Authorization", "Bearer " + token);
  xhttp.send(envelope);

  xhttp.onload = function() {
  // never comes here
  };

  xhttp.onprogress = function(event) {
  // never comes here
  };

  xhttp.onerror = function() {
  // COMES HERE IMMEDIATELY and ERROR ABOUT CORS IN CONSOLE
  };
});

and XML SOAP request looks like this

function getSoapEnvelope(itemId) {
  // Wrap an Exchange Web Services request in a SOAP envelope.
  var result =

  '<?xml version="1.0" encoding="utf-8"?>' +
  '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' +
  '               xmlns:xsd="http://www.w3.org/2001/XMLSchema"' +
  '               xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"' +
  '               xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">' +
  '  <soap:Header>' +
  '    <RequestServerVersion Version="Exchange2013" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" soap:mustUnderstand="0" />' +
  '  </soap:Header>' +
  '  <soap:Body>' +

  '  <GetItem xmlns="http://schemas.microsoft.com/exchange/services/2006/messages">' +
  '    <ItemShape>' +
  '      <t:BaseShape>IdOnly</t:BaseShape>' +
  '      <t:IncludeMimeContent>true</t:IncludeMimeContent>' +
  '      <AdditionalProperties xmlns="http://schemas.microsoft.com/exchange/services/2006/types">' +
  '        <FieldURI FieldURI="item:Subject" />' +
  '      </AdditionalProperties>' +
  '    </ItemShape>' +
  '    <ItemIds>' +
  '      <t:ItemId Id="' + itemId + '" />' +
  '    </ItemIds>' +
  '  </GetItem>' +
  '  </soap:Body>' +
  '</soap:Envelope>';

  return result;
}

This work if I do simulate request with PostMan but otherwise CORS.

Access to XMLHttpRequest at 'https://outlook.office365.com/EWS/Exchange.asmx' from origin 'https://myorg.github.io' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

I have a domain that executes requests in the manifest

<AppDomains>
  <AppDomain>https://myorg.github.io</AppDomain>
</AppDomains>

What could be an issue?

We use Exchange Online

Thanks.

Dmytro Pastovenskyi
  • 5,240
  • 5
  • 37
  • 56
  • 1
    I think your are on the right track with the 2nd suggestion. After you get all the the information you mentioned above, you need the server to make the SOAP call to EWS from your backend, bypassing the 1MB limitation. You can refer to [this example](https://learn.microsoft.com/en-us/office/dev/add-ins/outlook/get-attachments-of-an-outlook-item) of how to get attachments of an Outlook item from the server – Outlook Add-ins Team - MSFT Nov 19 '21 at 19:38
  • But could you please add an example? I tried to play with soap and it did not work – Dmytro Pastovenskyi Nov 21 '21 at 11:28
  • @OutlookAdd-insTeam-MSFT I can't make requests (see updated code). I get 401 access issue. – Dmytro Pastovenskyi Nov 21 '21 at 16:01
  • 1
    Do you have more details on the 401? Could you see from the network trace if it's a response from Exchange and if so if there are response headers? 2 things come to mind: 1. Check if you are hitting CORS error (see debugger console for the addin). This approach of using EWS token and making EWS call is meant for the addin backend to make the call directly to Exchange. 2. Only GetItem and GetAttachment EWS calls are supported with this token, I believe this is using GetItem, but want to be sure. – Outlook Add-ins Team - MSFT Nov 22 '21 at 18:19
  • Hi @OutlookAdd-insTeam-MSFT - I have managed to make a call to EWS but now facing error with CORS (though my manifest includes domain). Things work if I use postman properly, so issue with 401 is resolved. Could you please see my post (it's updated, manifest part) and let me know what is wrong? – Dmytro Pastovenskyi Nov 23 '21 at 11:23
  • I have create another question and this is a bit another issue now https://stackoverflow.com/questions/70081708/outlook-addin-getting-cors-when-making-request-to-ewsurl – Dmytro Pastovenskyi Nov 23 '21 at 13:24

1 Answers1

0

I have updated the original post. I managed to build proper SOAP request but faced another issue (CORS).

I could not solve the CORS problem instead I followed suggestion from @outlookAdd-insTeam-MSFT and moved logic that pull email to my server (where email have to be stored anyway). So the code runs on server now instead of frontend (addin).

Dmytro Pastovenskyi
  • 5,240
  • 5
  • 37
  • 56