A Reminders informational macro

My motivation for exploring JavaScript for Automation—as outlined in the last post—was the simple Keyboard Maestro macro we’ll talk about today.

Back in January, I wrote about how I use Reminders to keep track of outstanding invoices at work and remind me to follow up with clients who are late in paying. I’ve changed some of the details since then (which means there’ll probably be a post about that soon), but the basics are the same:

Invoice reminders

The job name, invoice number, and invoice amount are all in the reminder’s name, which is formatted this way:

Invoice reminder format

What I wanted was a way to see the number of outstanding invoices and the unpaid total. I can do that through our accounting system, of course, but that involves launching the accounting software. Doing it through Reminders, which is always running on my iMac, takes no time at all.

Here’s the Keyboard Maestro macro, which I’ve bound to the ⌃⌥⌘N keystroke combination and is set to run only when Reminders is the current application.

Keyboard Maestro invoice reminder macro

The macro has only one action, which is this JXA script:

 1:  var app = Application('Reminders')
 3:  // get the names of the invoice reminders
 4:  var invoices = app.lists.byName('Invoices').reminders.whose({completed: false}).name()
 6:  // extract the amounts and add them
 7:  var sum = 0.0
 8:  var invCount = invoices.length
 9:  for (var i = 0; i < invCount; i++) {
10:    var amtStart = invoices[i].lastIndexOf('$') + 1
11:    var amtEnd = invoices[i].lastIndexOf(')')
12:    var amt = invoices[i].slice(amtStart, amtEnd)
13:    amt = amt.replace(',', '')
14:    sum += parseFloat(amt)
15:  }
17:  invCount + " invoices for $" + sum.toLocaleString()

Lines 1 and 4 are what we talked about in the previous post; they generate an array of all the names of the active reminders in the Invoices list and put it in the variable invoices.

Line 7 initializes the variable sum, which is used to accumulate the unpaid total. Line 8 puts the number of unpaid invoices into invCount. Lines 9–15 loop through invoices, extracting the amount of each invoice and adding it to sum. I’m sure I could’ve used a clever regex to get the amount in one step, but I didn’t feel like taking the time to work that out.

Finally, Line 17 returns a string with the information I want. The toLocaleString method is convenient way to format the amount with a comma as the thousands separator.

Keyboard Maestro’s “display results briefly” setting (the popup menu just above the text field with the source code) puts the result in a notification box that slides out from the top right corner of my screen and slides back after a few seconds.

Keyboard Maestro notification

I decided to use JXA instead of AppleScript because I thought it would give me some JXA practice and because I hate doing text manipulation in AppleScript. I ended up with the utility I wanted, and I learned some things along the way.