Skip to content

legalnonsense/org-timed-alerts

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 

Repository files navigation

org-timed-alerts.el

Receive warnings and alerts via alert.el for upcoming events in your day.

Ever look at your clock 10 minutes before a scheduled phone call, keep working on something else, and then not look at your clock until 2 minutes after the phone call was supposed to begin?

I do it all the time. It must stop.

org-timed-alerts scans your agenda files, finds any timestamps (active, deadline, or scheduled) with a time-of-day specification, and sends event warnings via alert.el according to whatever intervals you specify with custom alert messages.

WARNING: This package is under development. It is close to complete and stable for my daily use.

Usage

Install the dependencies:

alert
https://github.com/jwiegley/alert.

Test alert by evaluating: (alert "test"). Did you see a notification? If so, proceed.

dash.el
https://github.com/magnars/dash.el
org-ql
https://github.com/alphapapa/org-ql
ts.el
https://github.com/alphapapa/ts.el

Installation

Clone this repository into your load path.

git clone https://github.com/legalnonsense/org-timed-alerts.git

Use-package example

Use-package declaration with all custom variables set to the default values:

(use-package org-timed-alerts
  :after (org)
  :custom
  (org-timed-alerts-alert-function # 'alert)
  (org-timed-alerts-tag-exclusions nil)
  (org-timed-alerts-default-alert-props nil)
  (org-timed-alerts-warning-times '(-10 -5))
  (org-timed-alerts-agenda-hook-p t)
  (org-timed-alert-final-alert-string "IT IS %alert-time\n\n%todo %headline")
  (org-timed-alert-warning-string (concat "%todo %headline\n at %alert-time\n "
                                          "it is now %current-time\n "
                                          "*THIS IS YOUR %warning-time MINUTE WARNING*"))
  :config
  (add-hook 'org-mode-hook #'org-timed-alerts-mode))

Without use-package

There is no reason not to use use-package, but if you refuse, you can minimally use:

(require 'org-timed-alerts)
(add-hook 'org-mode-hook #'org-timed-alerts-mode)

Adding (org-timed-alerts-mode) to org-mode-hook will activate the alert timers the next time you run org-agenda. It will not add timers until you run org-agenda.

Customization

Custom variablesDescriptionDefault value
org-timed-alerts-todo-exclusionsList of TODO states to ignore when generating the alert list. E.g., ‘(“DONE”)nilb
org-timed-alerts-warning-timesList of integers representing the intervals of warnings preceding the event. E.g., ‘(-10 -5) means you want to be warned 10 minutes, 5 minutes, and 2 minutes before the event. nil means no warning. There is no difference between positive and negative numbers, i.e., 10 and -10 both mean to send an alert 10 minutes before the event. A final notification is automatically sent at the time the event begins.’(-10 -5)
org-timed-alert-final-alert-stringMessage to display in the alert shown at the time event begins (see below)“IT IS %alert-time\n\nTIME FOR:\n%todo %headline”
org-timed-alert-warning-stringMessage to be displayed for warnings that precede the event (see below)“%todo %headline\n at %alert-time\n it is now %current-time\n * THIS IS YOUR %warning-time MINUTE WARNING *”
Less frequently needed custom variablesDescriptionDefault value
org-timed-alerts-agenda-hook-pAutomatically add org-timed-alerts-set-all-timers to org-agenda-hook? If you turn this off, the minor mode is effectively meaningless and you’ll need to find another suitable way to call org-timed-alerts-set-all-timers.t
org-timed-alerts-default-alert-propsSee the documentation for the function alert. This plist will be used to set the default for any of those properties. Any value of this list can be a function which will be called with the point at the org-heading. See description below.nil
org-timed-alerts-alert-commandFunction to call when invoking the alert. See alert.el for other possibilities, e.g., #'alert-libnotify-notify, #'alert-growl-notify. Use these specific functions only if you don’t want to use the default alert specified in alert-default-style.#’alert

alert strings

org-timed-alert-final-alert-string and org-timed-alert-warning-string are strings that allow the following substitutions:

stringsubstitution
%todothe TODO state of the the heading, if any
%headlinethe headline text of the heading
%alert-timethe time of the event
%warning-timethe current number of minutes before the event
%current-timethe time the alert is actually sent to the user
%categorythe category property of the org heading, or the name of the file if none

For example, consider the heading:

* TODO phone conference I don't want to have
:PROPERTIES:
:CATEGORY: annoying-client
:END:
<2020-11-23 Mon 15:45>

The following string: %todo %headline\n at %alert-time\n it is now %current-time\n * THIS IS YOUR %warning-time MINUTE WARNING * Will use these substitutions when it send a 5 minute warning:

stringsubstitution
%todo“TODO”
%headline“phone conference I don’t want to have”
%alert-time“20:05”
%warning-time“5”
%current-time“20:00”
%category“annoying-client”

And will display a warning that looks like this: ./images/sample-alert.png

Unless the :title property is overridden by org-timed-alerts-default-alert-props, the title of an alert defaults to the category property of the org heading.

Special property for custom alert intervals

Any heading can set custom alert intervals by setting the property :ORG-TIMED-ALERTS: For example:

* Lunch meeting
:PROPERTIES:
:ORG-TIMED-ALERTS: 5 4 3 2 1
:END:
<2020-11-29 Sun 11:36>

Will override org-timed-alerts-warning-times and send alert notifications 5, 4, 3, 2, and 1 minute before the appointment time.

Note about org-timed-alerts-default-alert-props

As stated above, the value of any property can be a function that is run at the underlying org heading. If you want more advanced customization of the alert properties, you can take advantage of this. For example, suppose you wanted the title of each alert to show the text of the root heading in the tree:

(setq org-timed-alerts-default-alert-props
      '(:title 
        (lambda () (save-excursion
                     ;; Move to the root heading
                     (while (org-up-heading-safe))
                     ;; Return its headline, without tags, todo, etc.
                     (org-get-heading t t t t)))))

Or suppose you wanted to customize the icon for an alert depending on the priority of the heading:

(setq org-timed-alerts-default-alert-props
      '(:icon 
        (lambda ()
          (if (string= "A" (org-entry-get (point) "PRIORITY"))
              "/path/to/some/icon"
            "/path/to/some/other/icon"))))

Updating the timers

org-timed-alerts updates itself via org-agenda-hook. This is fast enough that I don’t notice much speed difference when generating an agenda. You can turn this off by setting org-timed-alerts-agenda-hook-p to nil. If you do that, you can update manually with org-timed-alerts-set-all-timers or find another suitable hook (the package only schedules timers for the current day, so you’ll need to update at least daily and after any relevant timestamp changes).

How it works

  1. Run an org-ql query to get all active timestamps, scheduled timestamps, and deadlines on the current date.
  2. For each of these events which has an associated time:
    1. Create a timer to send an alert at that time via alert.el. This alert will use the string org-timed-alert-final-alert-string
    2. Create warning timers according to the intervals specified in org-timed-alerts-warning-times and using the string org-timed-alert-warning-string
  3. Update all timers any time the user runs org-agenda. You can update manually with org-timed-alerts-set-all-timers. You can disable all timers with org-timed-alerts-cancel-all-timers or by disabling the minor mode.

Other efforts

This pacakge is meant to do what I want and and nothing more; I tried to abstract a bit so others might find it useful. I have included my notes on other similar packages. Apologies to the authors if they are not accurate.

org-alert. See https://github.com/spegoraro/org-alert. Org-alert checks for items which are scheduled or with deadlines for the current date, and then sends notification of those items immediately and simultaneously. It will resend notifications if you run org-alert-check. It serves a different purpose than this package.

org-notify. See https://code.orgmode.org/bzg/org-mode/raw/master/contrib/lisp/org-notify.el. Org-notify allows notifications to be scheduled and customized, but requires a special property to be set for each org heading for which an alert is desired. It also does not seem to use alert.el by default but appears it could be customized to do so. There are a lot of nice customization options here, but it asks a lot of the user with regard to setting special properties. By contrast, the goal of org-timed-alerts is to stay out of the way of the user by not requiring setting any special properties. In short, I feared getting this package set up for my purposes would be less enjoyable than writing a custom solution.

org-wild-notifier. See https://github.com/akhramov/org-wild-notifier.el. Org-wild-notifier is the closest to org-timed-alerts. The biggest drawback I saw was the inability to customize the alert message. See /akhramov/org-wild-notifier.el#43. Otherwise, this package may serve your purposes.

Changelog

  • [2020-12-03 Thu] Add support for repeating timestamps
  • [2020-12-04 Fri] Add support for excluding TODO states in org-timed-alerts-todo-exclusions

About

Orgmode notification warnings of upcoming events

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages