James Williams

Taming Google Calendar With Org-Mode

Over the past few weeks after setting up Org-Capture, I've been spending more of my raw time in Emacs but would have to context switch to a browser to look at my calendar events. That's no good. Luckily, we can solve this egregious problem by using a combination of Org-Capture, Org-Agenda, and Emacs-Calfw. Don't worry, the setup isn't as complicated as it sounds.

Setting Up Org-Capture

If you don't use Orgmode for your TODOs, you definitely SHOULD. Org-Capture allows you to quickly enter notes without a big context switch. You can even make templates for different types of data. I use Org-Capture templates for TODOs and logging food and exercise. The following snippet sets up the default location to store the notes you log and defines a shortcut as C-c c. I like to know what time I finished a task so org logs that as a property when the task is done. Lastly, I have template for TODOs. The first argument is the shortcut to log a TODO, in this case C-c c t. The other arguments specify the file where the TODO will be saved, what heading in the org-file it will be logged under, and the format of the template. Check out these links for more info about Org-Capture:


(setq org-default-notes-file "~/Dropbox/Org/notes.org")
(define-key global-map "\C-cc" 'org-capture)

; Log done state in TODOs
(setq org-log-done t)

; Set Org-Capture templates
(setq org-capture-templates
    `(("t" "todo" entry (file+headline "~/Dropbox/Org/notes.org" "Tasks")
        "** TODO %^{Task} %?")))

Setting Up Org-Agenda

Org-Agenda gives you multiple views to visualize data in Org files. These don't have to be all in one location and can be spread across multiple areas. I have one file for my calendar data and another for my TODOs that I set earlier. Org lets you schedule your TODOs with C-c . and these will show up on your agenda when you hit C-c a.

(setq org-agenda-files (list "~/Dropbox/Org/notes.org"
; Set key combos
(define-key global-map "\C-ca" 'org-agenda)

Emacs Calfw & Org-Gcal

The last piece of the puzzle is Emacs-Calfw (https://github.com/kiwanami/emacs-calfw) and its org-gcal integration (https://github.com/myuhe/org-gcal.el).

Calfw in Emacs

Calfw uses our Org-Capture and Agenda setup to give us a new calendar view. We can view an individual day or week and its associated events. Open a day's agenda by selecting it and hitting the space bar. Drop the following in your .emacs setup wherever that lives.

(add-to-list 'load-path "~/.emacs.d/emacs-calfw")
(require 'calfw)
(require 'calfw-org)

So far we can grab scheduled TODOs and see them populated on our calendar by opening an agenda buffer with C-c a and then running M-x cfw:open-org-calendar. For Google Calendar integration, you need to feel comfortable with the Google Developer Console. Follow the org-gcal setup instructions(https://github.com/myuhe/org-gcal.el) to get a client id and secret looking somewhat like the following to drop into your config files.

(require 'org-gcal)
(setq org-gcal-client-id "something.apps.googleusercontent.com"
      org-gcal-client-secret "something"
      org-gcal-file-alist '(("calendar@something.com" .  "~/Calendars/schedule.org")

As you can see, org-gcal dumps everything into an org file that Org-Agenda is aware of, which emacs-calfw knows about and it's turtles all the way down.

Refresh your listing of calendar events with M-x org-gcal-fetch. Sometimes you'll get prompted to refresh your OAuth token M-x org-gcal-refresh-token.

Org-gcal populates your org file with the event's location, video conference links, and a link to the event on GCal. With the day's agenda open (Space), you can see the properties of an event by moving your cursor to it and hitting TAB which takes you to that entry.

Add a entry to that file and run M-x org-gcal-post-at-point and an event will be created for you.


I don't generally use org-gcal-sync and only fetch events from my calendars. org-cal doesn't have a way to accept events or add other people to a calendar invite. That works for me because I don't generally reject things and merely go to the event or not.

You can not reserve rooms through org-gcal.

My next task is to setup a snippet to refresh my calendars on an interval.