10

I would like to integrate the calendar from my outlook into my orgmode agenda.

I am looking for a solution with the following features

  • Should be implemented in elisp only, so that I can run this on any system that has emacs
  • Should use Microsoft Exchange EWS Webservices to retrieve the calendar items.
  • Should create an org file containing the items for a predefined period (i.e. next two weeks or similar...)
  • Should be compatible with Office 365

I found some solutions, that come close, but are not quite there.

  • The ews-orgmode solution (see https://github.com/kautsig/ews-orgmode). This is implemented in python and generates an org file. This is problematic, because this obviously requires a python implementation and a scheduling solution. This makes this hard to use across platforms (e.g. windows vs linux) and requires significant effort to set up.

  • excorporate (see https://github.com/emacsmirror/excorporate). This is implemented in elisp, but does not provide any orgmode integration. I can create a buffer containing the calendar entries for a specific date, but cannot integrate it into the org agenda, because the buffer is not persisted and I am not aware of any way to call excorporate on agenda creation (with a specific date or date range) and to show those entries in the agenda

Is there any way to achieve an exchange calendar integration into the agenda using excorporate or something similar?

2 Answers 2

16

I solved this myself using excorporate. To activate and integrate excorporate I used the following configuration in my .spacemacs (since I am using spacemacs)

I added excorporate to dotspacemacs-additional-packages and added the following to the user-config section of .spacemacs

;; configure excorporate
;; allow opening the exchange calendar with 'e' from calendar 
(evil-define-key 'motion calendar-mode-map "e" #'exco-calendar-show-day)

(setq-default
 ;; configure email address and office 365 exchange server adddress for exchange web services
 excorporate-configuration
  (quote
   ("[email protected]" . "https://outlook.office365.com/EWS/Exchange.asmx"))
  ;; integrate emacs diary entries into org agenda
  org-agenda-include-diary t
  )

;; activate excorporate and request user/password to start connection
(excorporate)

;; enable the diary integration (i.e. write exchange calendar to emacs diary file -> ~/.emacs.d/diary must exist)
(excorporate-diary-enable)
(defun ab/agenda-update-diary ()
  "call excorporate to update the diary for today"
  (exco-diary-diary-advice (calendar-current-date) (calendar-current-date) #'message "diary updated"))

;; update the diary every time the org agenda is refreshed
(add-hook 'org-agenda-cleanup-fancy-diary-hook 'ab/agenda-update-diary )

With this configuration, the exchange calendar is added to the emacs diary and the diary is integrated into the orgmode agenda. The exchange calendar is update every time my agenda is refreshed.

Only the exchange calendar for today is added to the diary.

If I want to see the calendar for a different day, I use the calendar, navigate to the desired date and press 'e'. The appointment for that day are then displayed in a orgmode formatted buffer

The user and password for the exchange server is requested on emacs startup..

3
  • 1
    So this is a one-way connection, where you can see your Office 365 agenda in your local emacs - you cannot add new org mode events and sync them to the exchange server, correct? Thanks for sharing!
    – AstroFloyd
    Commented May 29, 2019 at 19:19
  • @bombadil: any idea how to efficiently retrieve meetings all the displayed date in org-mode agenda?
    – M. Toya
    Commented Jul 1, 2021 at 12:58
  • Excorporate does not work, when multi factor authentication is active. I am not using it anymore..
    – bombadil
    Commented May 12, 2022 at 18:10
0

I been trying to do the same thing and found this article. I had to make several adjustments due to the fact excorporate runs asynchronously using a finite state machine and as wired above it would kickoff 7 state machines (one per day in week mode) that would fight over the diary buffers and typically end up with 6-7 duplicate entries. The code below has a backoff to only update if the diary is older than a minute since last mod and hooked to only update when entering agenda mode which is a better model for my workflow. I tend to open when needed and don't want to recontact the server when I switch between day and week view.

Also to use you have to wait for the excorporate messages to finish before selecting you mode after typing org-agenda OR do a refresh since the process is async.

One quirk for below: I've added a final callback that kills the diary buffers because it clutters up tab-line. Remove or alter my-diary-cleanup as desired for your own workflow.

(use-package excorporate :after org-agenda)

;; Track whether we've turned excorporate on or not
(setq my-calendar-init nil)

;; setup a callback to cleanup the diary buffers for use below
(defun my-diary-cleanup ()
  (when (get-buffer "diary")
    (kill-buffer "diary"))
  (when (get-buffer "diary-excorporate-transient")
    (kill-buffer "diary-excorporate-transient"))
  (when (get-buffer "diary-excorporate-today")
    (kill-buffer "diary-excorporate-today"))
  (org-agenda-maybe-redo)
  (message "Cleaned up diary buffers"))  


;; Load today's org agenda with excorporate. 
;; excorporate uses the fsm (finite-state-machine) to do most operations aysnc
;; Wired in via advice below
(defun my-agenda-update-diary (&optional args)
  "call excorporate to update the diary for today"

  ;; onetime setup
  (when (not my-calendar-init)
    (progn
      (message "excorporate setup starting")
      ;; turn off diarying for this call
      (excorporate)
      (message "excorporate setup done")
      (setq my-calendar-init t)))
  
  ;; skip if the file was updated within the last minute
  (message "my diary update started %s" (current-time-string))
  (when (> (time-convert (time-subtract (current-time) (file-attribute-modification-time
                            (file-attributes "~/.emacs.d/excorporate/diary-excorporate-today"))) 'integer) 60)
    
    (exco-diary-diary-advice (calendar-current-date) (calendar-current-date) #'my-diary-cleanup)))

;; Setup advice so the agenda update runs before the org-agenda command
(advice-add 'org-agenda :before #'my-agenda-update-diary)

;; import emacs calendar/diary entries in org
(setq org-agenda-include-diary t)

Long term I would love to have a mode that directly translated into org agenda files and skipped the diary which requires a lot of advice under the covers and touches a bunch of files. Likewise a finalizer callback for (excorporate) or some sync mechanism would be really useful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.