Enhancing Reminders with AppleScript and Macros

As The Omni Group keeps working on OmniFocus 2 for Mac and Apple continues seeding new betas of iOS 7 and OS X Mavericks to developers, I have been reconsidering Reminders’ simplicity and enjoying the built-in iCloud sync, which, unlike other types of iCloud, is working fine for me. However, two things I miss from OmniFocus are the possibility to integrate the app with a web browser through bookmarklets and the system-wide Quick Entry panel; I use both tools on a daily basis to easily save a browser’s tab into OmniFocus’ Inbox, or to bring up a text field where I can jot down an idea and know that, no matter the app I’m using, it’ll be saved into OmniFocus. Luckily for me, Apple’s Reminders app comes with a good AppleScript Dictionary, which is likely something that Reminders’ core mainstream audience won’t ever care about, but that we can leverage to extend the app’s capabilities and input areas beyond Mountain Lion’s leather-and-paper window.

Reminders’ AppleScript Dictionary (viewable in AppleScript Editor -> ⌘⇧O or through File > Open Dictionary…) allows us to fetch the app’s configured accounts, list names, and, more importantly, to create new reminders with specific parameters. Through AppleScript, we can programmatically create reminders that have specific names, attached notes, priorities, and dates. For this tutorial, I’m only going to focus on creating reminders with names and notes set by AppleScript, leaving other parameters to your discretion (and imagination for script personalizations).

My first requirement was to create a script that would send the current browser tab to Reminders using a webpage’s title as name and URL as note. With AppleScript and Google Chrome, that’s extremely easy to accomplish:

tell application "Google Chrome"
set tabname to get title of active tab of window 1
set taburl to get URL of active tab of window 1
tell application "Reminders"
set newremin to make new reminder
set name of newremin to tabname
set body of newremin to taburl
end tell
end tell

For Safari users, the basic idea is the same, but note how the AppleScript Dictionary changes title to name and active to current for tabs. I have no idea why Google went for this minor difference when building AppleScript support into Chrome.

tell application "Safari"
set tabname to get name of current tab of window 1
set taburl to get URL of current tab of window 1
tell application "Reminders"
set newremin to make new reminder
set name of newremin to tabname
set body of newremin to taburl
end tell
end tell

Because this is an AppleScript, it can be executed by a variety of modern OS X launchers that have the advantage of letting you set your own keyboard shortcuts for system-wide actions. For instance, here’s how you would create a workflow for Alfred to launch the script in Chrome with ⌘2 and post a notification upon completion:

As MacStories readers know, though, my preferred solution for this kind of OS X automation is Keyboard Maestro, which I believe has a clearer interface for workflows (I prefer the top-to-bottom approach to visualizing actions than Alfred’s “canvas” metaphor) and that comes with handy if/then blocks to check for active apps and frontmost windows. So here’s how the same AppleScript looks when converted to a Keyboard Maestro macro:

As you can see, the macro is only activated after I hit the ⌘1 shortcut and if Google Chrome is at the front (the macro is also assigned to a Chrome-only macro group); I’m using the same AppleScript, but I’ve added a native notification to be displayed after a reminder has been successfully added. Thanks to Keyboard Maestro 6, we can customize the text that will be shown by Notification Center using a mix of plain text and tokens dynamically generated by %ChromeTitle% and %ChromeURL%.

Replicating OmniFocus’ Quick Entry panel is a bit trickier, but still doable thanks to AppleScript. I have put together a script that, when launched, will tell OS X to display a dialog with an empty text field where we can type the name of the reminder we want to add. This dialog can be activated at any time, much like OmniFocus’ Quick Entry.

The empty text field is generated by the blank default answer and the dialog is automatically cancelled after 20 seconds thanks to giving up after. I think the nicest touch is the custom dialog icon, which is Reminders’ own icon fetched through with icon path to resource – the key is to tell AppleScript to go look in bundle.

tell application "System Events"
display dialog "Create a new reminder" default answer "" cancel button "Cancel" giving up after 20 with icon path to resource "Reminders.icns" in bundle (path to application "Reminders")
set reminTitle to text returned of result
tell application "Reminders"
set newremin to make new reminder
set name of newremin to reminTitle
end tell
end tell

The result is straightforward and barebones, but better than seeing a generic application icon:

The downside of interacting with dialogs generated by OS X is that you can’t have the fancy custom interface of OmniFocus’ panel; you’re limited in the number of buttons you can add; and it’s moderately complex to customize the dialog window with additional options for things like notes or dates (which I have purposefully advoided to keep the script as simple as possible). If you’re looking for more advanced AppleScript solutions that work around natural language parsing for date and time, I’m sure you can find some online.

You can download the Keyboard Maestro macros here.