With recent changes to Exchange Online, the ExpandDL functionality has been added to the makeEwsRequestAsync function. As such this function, which was previously “advertised” in easyEws (but marked as **DO NOT USE**), now functions as designed.
To use the new function:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
I have been working with Outlook Web Add-ins and Compose Message integration for Office Outlook Web Access for a while now. That is, Outlook add-ins that present themselves when the user is composing an email. This scenario is not seemingly as common. But one of my customers has been completely gung-ho about getting all of their COM add-ins converted to the new Office.js model. Some of their solutions will be able to make it there, and some will not. We are finding some roadblocks with mail compose apps.
One area that is currently failing is setting X-headers on an email item. I developed a JavaScript library to assist with this: easyEws. I blogged about it here. The one specific EWS SOAP call my customer wants to use from that library is this one:
updateEwsHeader: Updated the named x-header in the message.
This function works great in two conditions:
Outlook Web Access (or Office 365 Outlook Online), and
Outlook client – Online mode only
If you use Outlook client (Outlook 2016) in cached mode, this call will seem to work (because it does), but the x-headers will be missing when the user presses “Send.” The problem is that while the currently composed item is saved to the drafts folder and the custom x-headers are written to it via the EWS call (server side), the current Outlook Inspector/session is NOT updated. The cached Drafts folder may take (depending on network latency) anywhere from 1 to 3 minutes to be updated, but regardless the item in the current inspector session will NOT ever be updated. So when the user presses SEND, the item in the drafts folder will be overwritten with one that does not contain the custom x-headers and then sent.
There is no way around this limitation. And I have confirmed this with the Exchange and Office.js teams that this is a limitation of cached mode in Outlook. If you have a need for custom x-headers with an Outlook add-in your only option for now is to create (or keep your existing) COM/VSTO add-in.
If you are running into this limitation, please let me know by commenting below.
The EWSEditor tool has been around a while and is managed/developed by some of my co-workers that sit on the Outlook Developer Support Team. As I have been developing more and more Office Web Add-ins for Outlook, I have found knowing and using EWS to be a very important skill.
EWSEditor helps in this regard. It is a very powerful, full featured EWS test bed. To get started you download this and extract the contents of the ZIP to a folder. From there you launch it and from the File menu, click Next Exchange Service enter in your email address and then select password and click Ok. Then viola, you are connected:
Once connected, you can start browsing your mailbox using EWS. To get to your Inbox, for example, you select TopOfInformationStore and then select Inbox:
From there you can go to different folders and look at the items, properties, and values stored in your mailbox. It is quite handy to understand how these things are structured and stored.
Next, you can click Tools, EWS Post and test your EWS skills. What I did was entered in my information to connect to my server and filled it in as such:
And when I hit run, I got a response you see above. It is that simple. And there are also lots of examples as well. If you click Load Example you will see a lot of XML SOAP requests you can test with:
A requirement in an Outlook Web Add-in I am working on required the ability to send an email to an alias with another email as an attachment. I found this a bit challenging as the makeEwsRequestAsync() function limits us to only a handful of EWS functions (EWS operations that add-ins support). This means I was unable to use a lot of the samples I found on the web. However, with the UpdateItem method, I found a way.
First, let me say, I have been asked – why is easyEWS.js not on GitHub. Well, now it is:
Next, so I updated the functionality in easeEws via two function:
easyEws.getMailItemMimeContent – we use this function to get the MIME content of a specified mail item by the ID.
easyEws.sendPlainTextEmailWithAttachment – this function, although a tad more complicated, will create a very simple plain text email and add an attachment send it and save it to the drafts folder.
Here are the two new updates:
[code lang=”javascript” collapse=”true” title=”click to expand if the docs.com embedding below is not visible.”]
// PUBLIC: creates a new emails message with a single attachment and sends it
// RETURNS: ‘success’ is compelted successfully
easyEws.sendPlainTextEmailWithAttachment = function (subject, body, to, attachmentName, attachmentMime, successCallback, errorCallback) {
var soap = ‘<m:CreateItem MessageDisposition="SendAndSaveCopy">’ +
‘ <m:Items>’ +
‘ <t:Message>’ +
‘ <t:Subject>’ + subject + ‘</t:Subject>’ +
‘ <t:Body BodyType="Text">’ + body + ‘</t:Body>’ +
‘ <t:Attachments>’ +
‘ <t:ItemAttachment>’ +
‘ <t:Name>’ + attachmentName + ‘</t:Name>’ +
‘ <t:IsInline>false</t:IsInline>’ +
‘ <t:Message>’ +
‘ <t:MimeContent CharacterSet="UTF-8">’ + attachmentMime + ‘</t:MimeContent>’ +
‘ </t:Message>’ +
‘ </t:ItemAttachment>’ +
‘ </t:Attachments>’ +
‘ <t:ToRecipients><t:Mailbox><t:EmailAddress>’ + to + ‘</t:EmailAddress></t:Mailbox></t:ToRecipients>’ +
‘ </t:Message>’ +
‘ </m:Items>’ +
‘</m:CreateItem>’;
soap = getSoapHeader(soap);
// make the EWS call
asyncEws(soap, function (xmlDoc) {
// Get the required response, and if it’s NoError then all has succeeded, so tell the user.
// Otherwise, tell them what the problem was. (E.G. Recipient email addresses might have been
// entered incorrectly — try it and see for yourself what happens!!)
var result = xmlDoc.getElementsByTagName("ResponseCode")[0].textContent;
if (result == "NoError") {
successCallback(result);
}
else {
successCallback("The following error code was recieved: " + result);
}
}, function (errorDetails) {
if (errorCallback != null)
errorCallback(errorDetails);
});
};
// PUBLIC: gets the mail item as raw MIME data
// RETURNS: the entire email message as a MIME Base64 string
easyEws.getMailItemMimeContent = function (mailItemId, successCallback, errorCallback) {
var soap =
‘<m:GetItem>’ +
‘ <m:ItemShape>’ +
‘ <t:BaseShape>IdOnly</t:BaseShape>’ +
‘ <t:IncludeMimeContent>true</t:IncludeMimeContent>’ +
‘ </m:ItemShape>’ +
‘ <m:ItemIds>’ +
‘ <t:ItemId Id="’ + mailItemId + ‘"/>’ +
‘ </m:ItemIds>’ +
‘</m:GetItem>’;
soap = getSoapHeader(soap);
// make the EWS call
asyncEws(soap, function (xmlDoc) {
//var content = xmlDoc.getElementsByTagName("MimeContent")[0].textContent;
successCallback(xmlDoc);
}, function (errorDetails) {
if (errorCallback != null)
errorCallback(errorDetails);
});
};
[/code]
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Once added, you can use EasyEWS.js on your projects. In my particular project, I used the following code, which does the following:
Gets the current mail item (entirely) as a base64 encoded string. This is the full MIME representation of the message.
It then creates a new mail item and sends it with a comment from the user to the email address specified with an attachment (which is the base64 string we got in the first step).
This is all done with EWS and because of easyEWS.js, it is done in very few lines of code:
[code lang=”javascript” collapse=”true” title=”click to expand if the docs.com embedding below is not visible.”]
// Loads the form items to attach to events
function loadForm() {
$("#forward-button").click(function () {
getCurrentMessage();
});
}
// This function handles the click event of the sendNow button.
// It retrieves the current mail item, so that we can get its itemId property
// ans also get the MIME content
// It also retrieves the mailbox, so that we can make an EWS request
// to get more properties of the item.
function getCurrentMessage() {
var item = Office.context.mailbox.item;
itemId = item.itemId;
mailbox = Office.context.mailbox;
try{
easyEws.getMailItemMimeContent(itemId, sendMessageCallback, showErrorCallback);
} catch (error) {
showNotification("Unspecified error.", err.Message);
}
}
// This function is the callback for the getMailItemMimeContent method
// in the getCurrentMessage function.
// In brief, it first checks for an error repsonse, but if all is OK
// t:ItemId element.
// Recieves: mail message content as a Base64 MIME string
function sendMessageCallback(content) {
var toAddress = "bob@contoso.com";
var comment = $("#forward-comment").val();
if (comment == null || comment == ”) {
comment = "[user provided no comment]";
}
try{
easyEws.sendPlainTextEmailWithAttachment("Message with Item Attachment",
comment,
toAddress,
"Email Attachment",
content,
successCallback,
showErrorCallback);
}
catch (error) {
showNotification("Unspecified error.", err.Message);
}
}
// This function is the callback for the easyEws sendPlainTextEmailWithAttachment
// Recieves: a message that the result was successful.
function successCallback(result) {
showNotification("Success", result);
}
// This function will display errors that occur
// we use this as a callback for errors in easyEws
function showErrorCallback(error) {
showNotification("Error", error);// .error.message);
}
[/code]
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
If you have done any work with Outlook Add-ins using the Office JavaScript API’s, you might have found a nifty function that allows you to poll the Exchange Server using EWS calls. The function: makeEwsRequestAsync(). However, this function is not the easiest thing to use. You have to formulate an EWS SOAP message that you send to the service. Getting those correct, writing the code for them, and processing the results are a real beast. But, even worse is finding exactly how to formulate the SOAP message from the existing documentation. It is something I personally did NOT look forward to as I was working on my customers solutions.
My frustration is your benefit (I hope). I created a JavaScript class called easyEws, that makes certain calls very easy. I posted the project on GitHub (previously, I had posted this on CodePlex):