Search code examples
office-jsoutlook-addinoffice-addinsoutlook-web-addinsoutlook-restapi

Outlook Javascript API get MIME content of email


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.


Solution

  • 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).