Skip to content

Instantly share code, notes, and snippets.

@davecra
Created July 3, 2017 15:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save davecra/6936ee56464d38c0907ae7e9c0712654 to your computer and use it in GitHub Desktop.
Save davecra/6936ee56464d38c0907ae7e9c0712654 to your computer and use it in GitHub Desktop.
EasyEws v1
/*!
* easyEWS JavaScript Library v1.0.1
* http://davecra.com
*
* Copyright David E. Craig and other contributors
* Released under the MIT license
* https://tldrlegal.com/license/mit-license
*
* Date: 2016-04-18T19:14EST
*/
var easyEws = (function () {
"use strict";
var easyEws = {};
easyEws.initialize = function () {
// PRIVATE: creates a SOAP EWS wrapper
function getSoapHeader(request) {
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:m="http://schemas.microsoft.com/exchange/services/2006/messages"' +
' 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>' + request + '</soap:Body>' +
'</soap:Envelope>';
return result;
};
// PRIVATE: makes an EWS callback with promise
function asyncEws(soap, successCallback, errorCallback) {
Office.context.mailbox.makeEwsRequestAsync(soap, function (ewsResult) {
if (ewsResult.status == "succeeded") {
var xmlDoc = $.parseXML(ewsResult.value);
successCallback(xmlDoc);
} else {
if (errorCallback != null)
errorCallback(ewsResult);
}
});
};
// PUBLIC: updates the x-headers in the mail item
// RETUNS: 'succeeded' if call completed successfully
// SEE: https://msdn.microsoft.com/en-us/library/office/dn596091(v=exchg.150).aspx
easyEws.updateEwsHeader = function (mailItemId, headerName, headerValue, successCallback, errorCallback) {
var soap =
'<m:UpdateItem MessageDisposition="SaveOnly" ConflictResolution="AlwaysOverwrite">' +
' <m:ItemChanges>' +
' <t:ItemChange>' +
' <t:ItemId Id="' + mailItemId + '"/>' +
' <t:Updates>' +
' <t:SetItemField>' +
' <t:ExtendedFieldURI DistinguishedPropertySetId="InternetHeaders"' +
' PropertyName="' + headerName + '"' +
' PropertyType="String" />' +
' <t:Message>' +
' <t:ExtendedProperty>' +
' <t:ExtendedFieldURI DistinguishedPropertySetId="InternetHeaders"' +
' PropertyName="' + headerName + '"' +
' PropertyType="String" />' +
' <t:Value>' + headerValue + '</t:Value>' +
' </t:ExtendedProperty>' +
' </t:Message>' +
' </t:SetItemField>' +
' </t:Updates>' +
' </t:ItemChange>' +
' </m:ItemChanges>' +
'</m:UpdateItem>';
soap = getSoapHeader(soap);
// make the EWS call
asyncEws(soap, function (xmlDoc) {
successCallback("succeeded");
}, function (errorDetails) {
if (errorCallback != null)
errorCallback(errorDetails);
});
};
// PUBLIC: returns a list of items in the folder
// RETURNS: an array of ItemIds
easyEws.getFolderItemIds = function (folderId, successCallback, errorCallback) {
var soap =
'<m:FindItem Traversal="Shallow">' +
' <m:ItemShape> ' +
' <t:BaseShape>IdOnly</t:BaseShape>' +
' </m:ItemShape>' +
' <m:ParentFolderIds>' +
' <t:FolderId Id="' + folderId + '"/>' +
' </m:ParentFolderIds>' +
'</m:FindItem>';
var returnArray = [];
soap = getSoapHeader(soap);
// call ews
asyncEws(soap, function (xmlDoc) {
$.each(xmlDoc.getElementsByTagName("t:ItemId"), function (index, value) {
returnArray.push(value.getAttribute("Id"));
});
successCallback(returnArray);
}, function (errorDetails) {
if (errorCallback != null) {
errorCallback(errorDetails);
}
});
}
// PUBLIC: gets the details for a specific item by ID
// RETURNS: a Dictionary of key/value pairs for the mail item
easyEws.getMailItem = function(ItemId, successCallback, errorCallback) {
var soap =
'<m:GetItem>' +
' <m:ItemShape>' +
' <t:BaseShape>Default</t:BaseShape>' +
' <t:IncludeMimeContent>true</t:IncludeMimeContent>' +
' </m:ItemShape>' +
' <m:ItemIds>' +
' <t:ItemId Id="' + ItemId + '" />' +
' </m:ItemIds>' +
'</m:GetItem>';
soap = getSoapHeader(soap);
// make call to EWS
asyncEws(soap, function (xmlDoc) {
var item = new MailItem(xmlDoc);
successCallback(item);
}, function (errorDetails) {
if(errorCallback != null) {
errorCallback(errorDetails);
}
});
}
// PUBLIC: expand a group and returns all the members
// NOTE: does not enumerate groups in groups
// RETURNS: An array of Email Addresses
easyEws.expandGroup = function (group, successCallback, errorCallback) {
var soap =
'<m:ExpandDL>' +
' <m:Mailbox>' +
' <t:EmailAddress>" + group + "</t:EmailAddress>' +
' </m:Mailbox>' +
'</m:ExpandDL>';
soap = getSoapHeader(soap);
// make the EWS call
var returnArray = [];
asyncEws(soap, function (xmlDoc) {
var extendedProps = xmlDoc.getElementsByTagName("EmailAddress");
$.each(extendedProps, function (index, value) {
returnArray.push(value);
});
successCallback(returnArray);
}, function (errorDetails) {
if (errorCallback != null)
errorCallback(errorDetails);
});
};
// PUBLIC: Find a given conversation by the ID
// RETURNS: An array of ItemID
easyEws.findConversationItems = function (conversationId, successCallback, errorCallback) {
// NOTE: search for parent:
// http://stackoverflow.com/questions/19008696/exchange-find-items-in-ews-conversation-using-xml-request
// http://www.outlookcode.com/codedetail.aspx?id=1714
// https://msdn.microsoft.com/en-us/library/office/dn610351(v=exchg.150).aspx
var soap =
' <m:GetConversationItems>' +
' <m:ItemShape>' +
' <t:BaseShape>IdOnly</t:BaseShape>' +
' <t:AdditionalProperties>' +
' <t:FieldURI FieldURI="item:Subject" />' +
' <t:FieldURI FieldURI="item:DateTimeReceived" />' +
' </t:AdditionalProperties>' +
' </m:ItemShape>' +
' <m:FoldersToIgnore>' +
' <t:DistinguishedFolderId Id="deleteditems" />' +
' <t:DistinguishedFolderId Id="drafts" />' +
' </m:FoldersToIgnore>' +
' <m:SortOrder>TreeOrderDescending</m:SortOrder>' +
' <m:Conversations>' +
' <t:Conversation>' +
' <t:ConversationId Id="' + conversationId + '" />' +
' </t:Conversation>' +
' </m:Conversations>' +
' </m:GetConversationItems>';
soap = getSoapHeader(soap);
// Make EWS call
asyncEws(soap, function (xmlDoc) {
var returnArray = [];
$.each(xmlDoc.getElementsByTagName("t:ItemId"), function (index, value) {
returnArray.push(value.getAttribute("Id"));
});
successCallback(returnArray);
}, function (errorDetails) {
if (errorCallback != null)
errorCallback(errorDetails);
});
};
// PUBLIC Gets Internet headers for a spific item
// RETURNS: a Dictionary of key value pairs
// SEE: https://msdn.microsoft.com/en-us/library/office/aa566013(v=exchg.150).aspx
easyEws.getEwsHeaders = function (itemId, successCallback, errorCallback) {
var soap =
' <m:GetItem>' +
' <m:ItemShape>' +
' <t:BaseShape>AllProperties</t:BaseShape>' +
' <t:IncludeMimeContent>true</t:IncludeMimeContent>' +
' </m:ItemShape>' +
' <m:ItemIds>' +
' <t:ItemId Id="' + itemId + '" />' +
' </m:ItemIds>' +
' </m:GetItem>';
soap = getSoapHeader(soap);
// Make the EWS call
var returnArray = new Dictionary();
asyncEws(soap, function (xmlDoc) {
for (var item in xmlDoc.getElementsByTagName("t:InternetMessageHeader")) {
returnArray.add(item.getAttribute("HeaderName"), item.textContent);
}
successCallback(returnArray);
}, function (errorDetails) {
if (errorCallback != null)
errorCallback(errorDetails);
});
};
// PUBLIC: updates a folder property
// RETURNS: 'succeeded' is process completed successfully
easyEws.updateFolderProperty = function (folderId, propName, propValue, successCallback, errorCallback) {
var soap =
' <m:UpdateFolder>' +
' <m:FolderChanges>' +
' <t:FolderChange>' +
' <t:FolderId Id="' + folderId + '" />' +
' <t:Updates>' +
' <t:SetFolderField>' +
' <t:ExtendedFieldURI ' +
' DistinguishedPropertySetId="PublicStrings" ' +
' PropertyName="' + propName + '" ' +
' PropertyType="String" />' +
' <t:Folder>' +
' <t:ExtendedProperty>' +
' <t:ExtendedFieldURI ' +
' DistinguishedPropertySetId="PublicStrings" ' +
' PropertyName="' + propName + '" ' +
' PropertyType="String" />' +
' <t:Value>' + propValue + '</t:Value>' +
' </t:ExtendedProperty>' +
' </t:Folder>' +
' </t:SetFolderField>' +
' </t:Updates>' +
' </t:FolderChange>' +
' </m:FolderChanges>' +
' </m:UpdateFolder>';
soap = getSoapHeader(soap);
// make the EWS call
asyncEws(soap, successCallback, errorCallback);
}
// PUBLIC: gets a folder property
// RETURNS: property value if process completed successfully
easyEws.getFolderProperty = function (folderId, propName, successCallback, errorCallback) {
var soap =
'<m:GetFolder>' +
'<m:FolderShape>' +
'<t:BaseShape>IdOnly</t:BaseShape>' +
'<t:AdditionalProperties>' +
'<t:ExtendedFieldURI ' +
' DistinguishedPropertySetId="PublicStrings" ' +
' PropertyName="' + propName + '" ' +
' PropertyType="String" />' +
'</t:AdditionalProperties>' +
'</m:FolderShape>' +
'<m:FolderIds>' +
'<t:FolderId Id="' + folderId + '"/>' +
'</m:FolderIds>' +
'</m:GetFolder>';
soap = getSoapHeader(soap);
// make the EWS call
asyncEws(soap, function(xmlDoc) {
successCallback(xmlDoc.getElementsByTagName("t:Value")[0].textContent);
}, errorCallback);
}
// PUBLIC: Gets the folder id by the given name from the store
// RETURNS: a string with ID of the folder
easyEws.getFolderId = function (folderName, successCallback, errorCallback) {
var soap =
' <m:GetFolder>' +
' <m:FolderShape>' +
' <t:BaseShape>IdOnly</t:BaseShape>' +
' </m:FolderShape>' +
' <m:FolderIds>' +
' <t:DistinguishedFolderId Id="' + folderName + '" />' +
' </m:FolderIds>' +
' </m:GetFolder>';
soap = getSoapHeader(soap);
// make EWS callback
asyncEws(soap, function (xmlDoc) {
var id = xmlDoc.getElementsByTagName("t:FolderId")[0].getAttribute("Id");
successCallback(id);
}, function (errorDetails) {
if (errorCallback != null)
errorCallback(errorDetails);
});
}
}
return easyEws;
})();
/* HELPER FUNCTIONS AND CLASSES */
function MailItem(value) {
this.value = value || {};
MailItem.prototype.MimeContent = function () {
return this.value.getElementsByTagName("t:MimeContent")[0].textContent;
};
MailItem.prototype.MimeContent.CharacterSet = function () {
return this.value.getElementsByTagName("t:MimeContent")[0].getAttribute("CharacterSet");
};
MailItem.prototype.Subject = function () {
return this.value.getElementsByTagName("t:Subject")[0].textContent;
};
}
function Dictionary(values) {
this.values = values || {};
var forEachIn = function (object, action) {
for (var property in object) {
if (Object.prototype.hasOwnProperty.call(object, property))
action(property, object[property]);
}
};
Dictionary.prototype.containsKey = function (key) {
return Object.prototype.hasOwnProperty.call(this.values, key) &&
Object.prototype.propertyIsEnumerable.call(this.values, key);
};
Dictionary.prototype.forEach = function (action) {
forEachIn(this.values, action);
};
Dictionary.prototype.lookup = function (key) {
return this.values[key];
};
Dictionary.prototype.add = function (key, value) {
this.values[key] = value;
};
Dictionary.prototype.length = function () {
var len = 0;
forEachIn(this.values, function () { len++ });
return len;
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment