Excorporate: EWS support for Emacs

I use Exchange at work for calendaring. I also use terminal-mode emacsclient when I’m logged in from another machine. In that scenario I can’t easily open a web browser to use Outlook Web Access. It annoyed me that I couldn’t check my schedule from within a terminal Emacs session. Thus, I did the only sensible thing and implemented full Exchange Web Services API support for Emacs.

Excorporate terminal screenshot

The result is a library called Excorporate that has proof-of-concept Calendar integration to show today’s meetings. It’s all written in Elisp, making it cross-platform. It’s also cross-Emacs; I tested it on Emacs 24.1 through Emacs 24.4, on GNU/Linux and MS-Windows. It works on all Emacs versions that support packages.

The tricky parts were:

  • extending soap-client to support all the XML Schema (XSD) datatypes required by the EWS WSDL file,
  • asynchronous URL retrieval without blocking the Emacs main loop,
  • autodiscovery of Exchange server settings from an email address, and,
  • implementing NTLMv2 authentication in Elisp.

I’m trying to get it into GNU ELPA so that other modes can always count on its core APIs being available from a default Emacs installation. I haven’t put it on GitHub yet, to keep it hidden from the ruthless efficiency of MELPA. I was impressed and appreciative when MELPA bundled slime-volleyball shortly after I released it. But I’d prefer to keep Excorporate in GNU ELPA only for now.

Anyway, I’m publishing this mode in the hope that it’s useful to other Emacs-and-Exchange users.

Join the Conversation


  1. Thank you for your great work.

    I use Emacs only within tmux sessions and your library will be a great addition to the list of packages that I have installed.

    Per your discussion on the emacs-devel list, I think that you should put it on Github for now, as well as on MELPA. Because GNU ELPA is about non-proprieatary software, the chances are close to zero that it will ever be published there. Still your work is extremely useful for many people who have to interact with MS Exchange, and it would be great to have at least the code in Github.

  2. “Thus, I did the only sensible thing and implemented full Exchange Web Services API support for Emacs.”
    Thank you. It’s this attitude that has made emacs great.

    I will definitely be trying this out.

    1. That’s an interesting case. You can try changing exco–autodiscovery-templates to replace the %s with the domain of your Exchange server, inlined. Then Excorporate will attempt to autodiscover settings from your actual Exchange server.

      1. I too have the problem where my exchange server is at domain.com whereas my email address is @sub.domain.com. I tried resetting exco–autodiscovery-templates but it still kept trying to contact sub.domain.com addresses. I ended up modifying your “define-state-machine exco–fsm” macro call where the domain is being set in the let statement to instead read:
        (domain (if (boundp ‘exco-override-domain) exco-override-domain
        (cadr (split-string identifier “@”))))

        That fixed which domain it was using but I’m not sure the rest of the discovery went too well. I don’t get any further messages in *Messages* beyond contacting autodiscovery URL. I believe that is because while the URL is now correct, it then requires a login to access… or was that why the package was prompting for username & password?

        1. Yes, when things are working you will be prompted for your Exchange credentials twice: once for the autodiscovery URL, and once for the EWS URL that was autodiscovered.

          Just to be clear, given that your Exchange server is at “domain.com”, I’m saying do this:

          (require ‘excorporate)
          (setq exco–autodiscovery-templates

          Is that what you meant by “tried resetting exco–autodiscovery-templates”?

          1. I did do a setq on the exco–autodiscovery-templates but perhaps I was doing it before loading the excorporate library. That example above works but I’m still only prompted once for my password. I found the *fsm-debug* buffer and can send it along if you’d like to help debug. Looks like it is exco–fsm is failing when it enters :retrieving-service-xml.

    1. No plans for that at the moment. I think most people are able to access Exchange over IMAP for email. My short term goals are to get Excorporate into GNU ELPA, and to get autodiscovery (or failing that, manual configuration) working for as many people as possible. My main interest with EWS is calendaring and scheduling support. But I’ve tried to create a simple core API for people wanting to write modes for other aspects of EWS.

    1. Thanks for trying autodiscovery and providing feedback.

      I want people to use autodiscovery wherever possible because when it works it’s really convenient. I’ve received reports that it just works for others, in which case there is zero customization required.

      I’ve been collecting the ways in which autodiscovery fails:

      – Behind a proxy: Emacs doesn’t have CONNECT support, meaning it can’t tunnel SSL through a proxy, which breaks NTLM authentication. I think this one is fixable by adding CONNECT support to the Emacs URL package (TRAMP has it already).

      – No autodiscovery available on the Exchange installation. This one requires convincing your Exchange admin to enable autodiscovery, or autodiscovery override in Excorporate.

      – Email address is: someone@sub.domain.com, autodiscovery URL is on domain.com. This one is fixable by running autodiscovery on sub.domain.com, then if that fails, running it on domain.com.

      – Email address is: someone@domain1.com, autodiscovery URL is on domain2.com. I think this is your case, correct? This one could be worked around by re-querying the user for the “Autodiscovery domain” if the domain1.com attempt fails. But at that point it ceases to be “auto”discovery. I can’t think of another way Excorporate could know to try domain2.com. I think the user should just have to customize ‘(mail-address service-url) (i.e., override autodiscovery).

      – Another package breaks soap-client (this was Jon Miller’s case, in the comments): emacs -Q worked around this one; not sure what the specific bad interaction was.

      – Authentication is Kerberos/GSSAPI, not NTLMv2. This could be fixed with Emacs Kerberos/GSSAPI support, but I’m not sure what’s involved in setting that up. There is a module there, but it calls out to an external program.

      For the next release I’ll implement autodiscovery override but I’ll implore people to try autodiscovery first and provide feedback, especially if their failure is different from one of these known ones (which I’ll document in the comment header). I may also implement sub.domain.com -> domain.com reattempts. I wanted to get Excorporate in GNU ELPA before the next release, but I’m waiting on copyright assignment for url-http-ntlm so it might take a while, and people are requesting this override feature. I guess I’ll do another release at fitzsim.org, as soon as I can.

  3. Hello, in your description above you don’t mention compatibility with Emacs 24.5. Do you have any plans to add that compatibility? This description sounds terrific. It would solve a big problem I have making my Exchange calendar more accessible from within Emacs and hopefully org-mode.

    1. Yes, I do have plans for 24.5 support. I’m close to having Excorporate fully packaged in GNU Elpa — it has a bunch of dependencies that have to go in first. But since this is the second request for 24.5 support, I guess I’ll do another non-Elpa point release in the mean time. I’ll try to get that out this week.

    2. Here is Excorporate 0.6.1:


      The only changes for this release are support for Emacs 24.5, and removing a url-http redirection hack that is no longer needed for Emacs master tip (Emacs 25). Anyone on an older version of Emacs 25 (pre 325200ac1dcf5bed6918ea827d8a48d89487e083, committed 2015-09-23) will want to continue using Excorporate 0.6.0 until they update to master tip.

Leave a comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.