In How to Create Real Recurring Location-based iOS Reminders, I described a method using IFTTT to mark location-based reminders as incomplete. Shortly after that post, I upgraded my iPhone to iOS 13 and quickly discovered that the update broke then IFTTT iOS Reminders service. All triggers and actions in the service no longer worked as expected (or at all), including IFTTT’s Reminder Completed in List trigger. So I was back to dismissing my recurring location-based reminders without marking them as complete. And on top of that, despite the additional functionality of the new Reminders app, I started encountering all sorts of issues, including the fact that Reminders in Notification Center started randomly turning itself off. While I haven’t found a solution to that and other new Reminders issues, I did come up with a solution to replace IFTTT’s broken Reminder Completed in List trigger. Read on to discover how…
Note, there are fewer requirements than the original post.
- An always-on Mac
- iCloud synchronized Reminders (on both iPhone and Mac)
- [OPTIONAL] An IFTTT account
We will use IFTTT as an example, but you can supply a webhook to any service that listens for webhook calls. For example, mine calls my Node Red installation on my Raspberry Pi, but that’s a much steeper learning curve than IFTTT, so we’ll stick to IFTTT in this blog post. For information on how to set up IFTTT‘s webhook service so that you can post webhook calls to trigger IFTTT applets, refer to IFTTT’s documentation on its webhook service.
- In your Reminders app from either your iCloud-reminder-synched iOS device or your computer, create a new list with a unique name
- On a mac computer that you always keep running, download the completion_notifier.scpt Applescript (from the github gist shown below). Save it in a convenient place. I suggest creating a Scripts folder in your home directory.
- In a new Terminal.app window, enter the following command (customizing it as indicated below):
osascript ~/Scripts/completion_notifier.scpt "~/Scripts/recently_completed_reminders.txt" "" -1
- Make these changes to the command based on your circumstances:
- Change the script path to wherever you saved the script from step 2. Please use a path that contains no folders that have a space in their name, as that might cause the script to not work properly (as I didn’t make it sophisticated enough to handle spaces).
- Change the `recently_completed_reminders.txt` file name and path to whatever you like.
- For your information…
- osascript is a command-line executable that comes on MacOS and allows you to execute AppleScripts from the command line.
- Note that your browser might change the double-quotes to smart quotes, so you may have to delete and re-type them in the terminal.
- The purpose of executing this command is both to create the `recently_completed_reminders.txt` file, initialized with a starting time so that when it runs in the cron-job, it will find newly completed reminders since its last execution, and to prompt your system to grant permission to the script to have access to your Reminders.
- We will customize the last 2 arguments when we set up the cron job, so leave their values as-is for now.
- If you are presented with a dialog (or dialogs) asking you if you want to allow access to your reminders, click OK.
- Next, we need to set up this script so that it will run every so often to check for newly completed reminders. The more frequently you set it to run, the sooner your automations will run after you complete a reminder.
- Obtain your webhook URL from IFTTT by clicking on the Documentation link at the top right. Enter a name for this action that will receive calls from your applescript and then copy the updated URL at the bottom starting from https (ignore the curl command in front of it).
- In Terminal.app, execute the following command:
- This opens up an editor where we need to enter our repeated command. The default editor interface is called `vi`, so I will quickly show you what to type just to accomplish our task (do not use the enter/return key):
i 0 0 0 ? * * * osascript ~/Scripts/completion_notifier.scpt "~/Scripts/recently_completed_reminders.txt" "https://maker.ifttt.com/trigger/your_webhook_name/with/key/your_key" "-1" "reminder list name 1" "reminder list name 2" esc (i.e. the escape key on your keyboard) :wq
- Edit the paths and file names as you did in step 3
- This runs the script once a day at midnight. If you would like to change the frequency, you must change the values where it shows “o o o ? * * * “. Use the cron expression generator to determine what to enter.
- You can change the “-1” to 1 or 2 in order to ignore reminders with that priority or lower (priorities are 1 through 3 and show in the app as a number of exclamation points). The value “-1” turns off this feature and all reminders are included whether they have a set priority or not. There is currently no way to only ignore reminders that have no set priority.
- If you want to limit the script to only take into account certain reminder lists, you can add each list to the end of the command where I have 2 examples “reminder list name 1” and “reminder list name 2”. If you want it to consider all lists, you can remove those 2 sample list names (and their surrounding quotes). Make sure that any list names you supply are surrounded in quotes and match exactly the actual list names in the reminders app. You can event enter separate lines for different lists or to call different/multiple webhooks.
- You may again be prompted one more time with a dialog asking to allow access to your Reminders once the cron job runs the script. It will stay on the screen until the next time you log back in. After that, you should not be asked again.
The above will allow you to trigger anything via IFTTT, but to set up IFTTT to mark geofence reminders as incomplete, refer to the original blog post and complete steps 1 through 9. Step 10 will be modified by what we’ve done above. Instead of using IFTTT’s “Reminder completed in list” trigger, we will use a webhook that is what the above process calls. No json parameters in that case are necessary. Note that technically, you could modify the AppleScript in this blogpost to mark the reminders as incomplete, thereby making it unnecessary to call IFTTT via webhook, but by calling IFTTT, it makes it possible to do more than just mark reminders as incomplete.
Note, you can test out the script call (starting from osascript to the end of the line) by executing them manually on the command line. Simply add a test reminder in one of the lists supplied at the end of the command, complete it, and then execute the command. You can then go to any IFTTT applet you create to be triggered by this webhook and look at its activity (and click “check now”) to ensure that the script made the webhook call.
If you want the webhook to include any json parameters, you will have to edit the AppleScript, but note that multiple reminders may be completed between the times that the script checks and its currently only coded to call the webhook once, after it has found any completed reminder(s). So if you want to include the reminder title, you will have to edit the code to make multiple webhook calls.
Note that this script is not foolproof. If you have multiple devices on which you synch and complete reminders and any one of them goes offline (like if you turn on airplane mode), the script will not catch that completion until the device goes back online. This would be especially susceptible to miss reminders if you edit the code to make a webhook call for each reminder and complete reminders in the following order of events:
- Turn on airplane mode on your phone
- Complete reminder 1 on your phone
- Complete reminder 2 on your (online) computer
- Turn off airplane mode on your phone
There’s a chance, depending on how much time passes between reminder completions (and how frequently you set the script to run), that there would be no webhook call for reminder 1, because the script only looks for reminders completed since the last time it checked and the completion date of reminder 1 is before reminder 2.
This is done to make the check quick. If you’ve been using the reminders app for a long time, checking all reminders for a new reminder could take many minutes. However, limiting the check to only the most recent reminders is fast.
Additionally, there are various pitfalls to be aware of. You can either upgrade your reminders everywhere (iOS 13 and macOS Catalina) or you can not upgrade your reminders and continue to use a macOS prior to Catalina, however you may run into problems. For example, I need to keep my computer on which I run this script at Mojave since I depend on a 32 bit app (which Catalina no longer supports). And for whatever reason, editing old recurring reminders via AppleScript on that computer seems to corrupt the geofence settings every time it runs, until I set the geofence settings on that computer. You may experience similar weird Reminders issues that came about when iOS 13 and the new Reminders features were released.
This solution only works if you keep a computer running all the time, on which you can install this script. If you want your webhook calls to run quickly after reminder completion, you can make the script run every minute or less, but I wouldn’t recommend it. Sometimes AppleScript can get hung up and if that happens, this can bog your computer down. I have mine set to every 30 minutes, and I have not noticed any problems.
Using a cron job isn’t the only means by which you can initiate the script. You could create IFTTT applets to create files in a Dropbox folder and attach a script to that folder on your computer. This would be especially useful for geofence reminders. If you set up a clever way of initiating the script, please comment below to share!