Manage Office365 contacts folders with Ruby
TL;DR; — always set your folder type when operating with folders through EWS.
Have you ever had the need to manage contacts folders in the Office365 environment? We recently had to implement synchronisation daemon that had to operate with contacts and a special contacts sub-folder.
While this looks trivial if you’re using the REST API that Azure Active directory provides, it’s a bit tricky when you have to do it through Exchange Web Services (EWS). EWS provides access to much of the same data that is made available through Microsoft OfficeOutlook using SOAP protocol through HTTP.
Long story short
We had requirements to create a sub-folder for each user in a given network and sync contacts to this sub-folder. The tricky part was the folder creation itself. We had to use delegated access permission to every single user, which by itself is a huge point of failure as well.
SOAP is a XML based protocol and lucky enough Ruby comes with awesome tools like Nokogiri which is a life saver when you have to deal with XML documents. I won’t go into too much details about the XML structure, but the Microsoft documentation about it is quite unclear and not helpful when it comes to folder creation for example.
Someone had already stumbled upon similar task and created a nice EWS client wrapper (https://github.com/WinRb/Viewpoint). Easy peasy right?
We just have to use the Viewpoint library, do our job and forget that we had to deal with EWS. Well not quite :).
The main problem we faced here was that even if we create our folder, it won’t appear anywhere under users contacts. In fact it won’t appear anywhere at all. Naturally I went through quite some documentation about the folder creation and it’s XML structure in order to understand what’s going on under the hood. There is a nice example of folder creation using Viewpoint :
# make a folder under Inbox
my_folder = cli.make_folder 'My Stuff', parent: :inbox
So in our case we wanted contacts subfolder — lets try this out then:
# make a folder under Inbox
my_folder = cli.make_folder 'MyAwesomeContacts', parent: :contacts
The response is success but our folder does not show up anywhere. Later on we figured out that those folders appear only if you use Outlook under Windows but only when you’re browsing for folders — not in the regular list with folders. So what’s the problem then? It took us some time and reading to realise that we need to define that the folder we’re creating is an actual contacts folder by defining it’s type (https://msdn.microsoft.com/en-us/library/jj191154.aspx). It appears like the EWS won’t apply the correct folder type based on it’s parent and you end up with a some kind of unknown folder under your main contacts folder. So what we needed is
parent = viewpoint.get_folder :contacts, act_as: user
viewpoint.make_folder 'MyAwesomeContacts', type: :contacts, parent: main_folder.id
act_as: user is needed because we use impersonation, and the magical
folder_type: :contacts parameter which placed our new folder on it’s right place
Hopefully this post will save someone else time and headaches dealing with EWS documentation. Got similar problem — we at Evermore can help! Feel free to approach us, as we already feel like the gods of EWS! Cheers!