51

I would like to have alarms set off based on org-mode events associated with specific times (or start times). Ideally these would be audio and visual, and able to be customised to some extent. I used to use Sauron, but I can't get it to work with org-mode events (or email notificiations) anymore. What are other good methods?

(I'm particularly interested in having the notification be displayed not only on screen via the notification daemon, but also spoken (text-to-speech). I'm on Linux.)

7
  • 2
  • @Constantine - this seems rather different to me. I'm not asking for tools for making this, but rather ready-made solutions that already exist. Further, I'm actually interested not in alarms for DEADLINEs, but rather for events associated with (start) times. Commented Nov 24, 2014 at 2:37
  • OK; I edited my comment. (I think we both agree that your question is related to the one I linked to.) Commented Nov 24, 2014 at 2:41
  • 1
    Related: emacs-fu.blogspot.nl/2009/11/showing-pop-ups.html
    – abo-abo
    Commented Nov 24, 2014 at 18:00
  • 2
    If you have use the builtin appt system to import appointments from your org-agenda files using the function org-agenda-to-appt. Then you can customize appt-disp-window-function to notify you the way you want (which can include calling external programs). Commented Nov 30, 2014 at 12:30

3 Answers 3

20

I am quite happy with the system I use, which does (I think) exactly what you want. It has two parts: an Emacs part that uses appt.el to schedule the reminders and a small shell program (I'm using Linux) that creates the popup + sound notification. Here I share the code for both parts.

A) Code in ~/.emacs.d/init.el

(require 'appt)
(appt-activate t)

(setq appt-message-warning-time 5) ; Show notification 5 minutes before event
(setq appt-display-interval appt-message-warning-time) ; Disable multiple reminders
(setq appt-display-mode-line nil)

; Use appointment data from org-mode
(defun my-org-agenda-to-appt ()
  (interactive)
  (setq appt-time-msg-list nil)
  (org-agenda-to-appt))

; Update alarms when...
; (1) ... Starting Emacs
(my-org-agenda-to-appt)

; (2) ... Everyday at 12:05am (useful in case you keep Emacs always on)
(run-at-time "12:05am" (* 24 3600) 'my-org-agenda-to-appt)

; (3) ... When TODO.txt is saved
(add-hook 'after-save-hook
          '(lambda ()
             (if (string= (buffer-file-name) (concat (getenv "HOME") "/ideas/TODO.txt"))
                 (my-org-agenda-to-appt))))

; Display appointments as a window manager notification
(setq appt-disp-window-function 'my-appt-display)
(setq appt-delete-window-function (lambda () t))

(setq my-appt-notification-app (concat (getenv "HOME") "/bin/appt-notification"))

(defun my-appt-display (min-to-app new-time msg)
  (if (atom min-to-app)
    (start-process "my-appt-notification-app" nil my-appt-notification-app min-to-app msg)
  (dolist (i (number-sequence 0 (1- (length min-to-app))))
    (start-process "my-appt-notification-app" nil my-appt-notification-app (nth i min-to-app) (nth i msg)))))

B) Code in ~/bin/appt-notification

#!/bin/sh

TIME="$1"
MSG="$2"

notify-send -t 0 "<br>Appointment in $TIME minutes:<br>$MSG<br>"
play "~/bin/alarm.wav"

To get voice notifications you could replace the last line (play) with the following:

espeak "Appointment in $TIME minutes: $MSG"
3
  • I added a case for auto-updating appts when quitting org-agenda: ; (4) ... Quitting org-agenda. (advice-add 'org-agenda-quit :after #'hw-org-agenda-to-appt) Commented Oct 11, 2016 at 16:03
  • Note: updating around midnight is important for night owls since org-agenda-to-appt only creates appts for current day. Commented Oct 11, 2016 at 16:12
  • +1 This is great. Thank you for sharing. I have modified this a little to use alert.el instead. One question, though: have you ever had any luck getting it to work with the org "APPT_WARNTIME" property to set a custom warning time for each event? I can't seem to get it to work.
    – Joseph R.
    Commented Apr 26, 2019 at 5:33
12

You can use notifications in Emacs > 24:

(require 'notifications)

(notifications-notify :title "Achtung!"
                      :body (format "You have an appointment in %d minutes" 10)
                      :app-name "Emacs: Org"
                      :sound-name "alarm-clock-elapsed")
1
  • 16
    This seems very useful. Do you know how to integrate it with org-mode?
    – erikstokes
    Commented Mar 5, 2015 at 17:55
4

This is what I ended up coming up with:

;;; org-to-appt

;; based on http://emacs-fu.blogspot.nl/2009/11/showing-pop-ups.html
(defun talky-popup (title msg &optional icon sound)  
  "Show a popup if we're on X, or echo it otherwise; TITLE is the title
of the message, MSG is the context. Optionally, you can provide an ICON and
a sound to be played"

  (interactive)
  ;;verbal warning



  (shell-command
   ;;  (concat "espeak -v mb-en1 -k5 -s125 " "'" title " " msg "'" " --stdout | paplay") ;; use local espeak
   (concat "echo " "'" title "'" " " "'" msg "'" " |text-to-speech en-gb")  ;; use remote Google voices
    ;; text-to-speech is from https://github.com/taylorchu/speech-to-text-text-to-speech
   )
  (if (eq window-system 'x)
    (shell-command (concat "notify-send -u critical -t 1800000  " 

                     (if icon (concat "-i " icon) "")
                     " '" title "' '" msg "'"))
    ;; text only version

    (message (concat title ": " msg))))

;; the appointment notification facility
(setq
  appt-message-warning-time 15 ;; warn 15 min in advance

  appt-display-mode-line t     ;; show in the modeline
  appt-display-format 'window) ;; use our func
(appt-activate 1)              ;; active appt (appointment notification)
(display-time)                 ;; time display is required for this...

 ;; update appt each time agenda opened

(add-hook 'org-finalize-agenda-hook 'org-agenda-to-appt)

;; our little façade-function for talky-popup
 (defun talky-appt-display (min-to-app new-time msg)
    (talky-popup (format "In %s minute(s):" min-to-app) msg 
  ;;    "/usr/share/icons/gnome/32x32/status/appointment-soon.png"   ;; optional icon

  ;;    "/usr/share/sounds/ubuntu/stereo/phone-incoming-call.ogg"    ;; optional sound

        ))
  (setq appt-disp-window-function (function talky-appt-display))

It's not dissimilar to scaramouche's setup.

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