Complete Computing Environment: Google Calendar

Table of Contents

Getting Org-mode scheduled events from Google Calendar

org-gcal1 lets you pull Google Calendar data in to and out of Org-mode. I used org-caldav for the longest time, but this seems like it is more featureful and reliable than that, so we're going to try this for a while. Make sure you follow the directions, it relies on creating a Google developer account and supplying a client id and client secret which you can use to OAuth with.

(provide 'cce-gcal)
(install-pkgs '(org-gcal))
(require 'org-gcal)

I only use my work calendars right now for this, and I keep the values in the Customize system to keep them out of Git.

(setq org-gcal-auto-archive t)
(setq org-gcal-down-days 30)
(setq org-gcal-up-days 30)

org-gcal can provide some pretty messy output, especially when people try to fit formatting in to the calendar bodies. We do some BS to make it all work and work cleanly, as well as adding a FILETAG property to the top of the files so that my Work Agenda will pick them up.

(defun cce/clean-up-gcal-timestamps ()
  (interactive)
  (dolist (cal-cons org-gcal-file-alist)
    (let ((filename (cdr cal-cons)))
      (with-current-buffer (find-file-noselect filename t)
        (revert-buffer t t)
        (beginning-of-buffer)
        (insert "#+FILETAGS: WORK\n")
        (cce/gcal-fix-bad-events)
        (save-buffer)))))

(defun cce/gcal-fix-bad-events ()
  (when (re-search-forward "[a-zA-Z0-9 ]+\\*" nil t)
    (backward-char 1)
    (insert "\n")
    (cce/gcal-fix-bad-events)))

I have a simple function defined for org-gcal-fetch-event-filters which looks for events I've either declined, or are some boilerplate recurring events I know I won't attend.

(defun cce/filter-gcal-event-maybe (event)
  "Function for [org-gcal-fetch-event-filters]."
  (let* ((case-fold-search t)
         (attendees (plist-get event :attendees))
         (my-response (when attendees
                        (reduce (lambda (last next)
                                  (if (plist-get next :self) next last))
                                attendees
                                :initial-value nil))))
    (cond ((string-match "office hour" (plist-get event :summary))
           nil)
          ((string-equal (plist-get my-response :responseStatus) "declined")
           nil)
          (t t))))

(add-to-list 'org-gcal-fetch-event-filters #'cce/filter-gcal-event-maybe)

Getting Org-mode scheduled events from Facebook and Meetup

(defun cce/fetch-private-calendars ()
  (interactive)
  (save-window-excursion
    (async-shell-command "awk -f ~/org/ical2org.awk <(curl $(cat ~/sync/private-files/meetup-private-url)) > meetup.org" (get-buffer-create " *meetup fetch*")))
  (save-window-excursion
    (async-shell-command "awk -f ~/org/ical2org.awk <(curl $(cat ~/sync/private-files/facebook-private-url)) > fb.org" (get-buffer-create " *fb fetch*"))))

Footnotes:

Author: Ryan Rix

Created: 2019-04-23 Tue 16:51

Validate XHTML 1.0