A Reminders informational macro
August 26, 2017 at 7:30 AM by Dr. Drang
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:
- When I send out an invoice, a reminder is automatically created in a list called Invoices.
- The reminder includes
- the job name;
- the invoice number;
- the invoice amount; and
- the date on which I’ll follow up with the client if payment hasn’t been received.
- There’s also a recurrence relation for the reminder date, but I have to create it manually because Reminders doesn’t have a way to automate that.
- When I follow up with a client, I click the corresponding reminders button, which “completes” it and generates a new version with an updated reminder date according to the recurrence relation.
- When an invoice is paid, I delete the reminder.
The job name, invoice number, and invoice amount are all in the reminder’s name, which is formatted this way:
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.
The macro has only one action, which is this JXA script:
javascript:
1: var app = Application('Reminders')
2:
3: // get the names of the invoice reminders
4: var invoices = app.lists.byName('Invoices').reminders.whose({completed: false}).name()
5:
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: }
16:
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.
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.