I figured it out how to get the selected reminder from Reminders via AppleScript. The only issue now is that it doesn’t work in Hook, since it doesn’t have access to the Reminders database in the Privacy preference pane. The script works fine from apps which has access to the Reminders database, in this case Script Debugger, see the video below.
Questions is @LucB: how can I get Hook to request access to the Reminders database?
to findAndReplaceInText(theText, theSearchString, theReplacementString)
set AppleScript's text item delimiters to theSearchString
set theTextItems to every text item of theText
set AppleScript's text item delimiters to theReplacementString
set theText to theTextItems as string
set AppleScript's text item delimiters to ""
return theText
end findAndReplaceInText
tell application "System Events"
tell its application process "Reminders"
tell its window "Reminders"
tell its splitter group 1
tell its UI element 3
tell its UI element 2
tell its UI element 1
set reminderOutline to first UI element whose selected is true
set reminderDescription to accessibility description of UI element 1 of reminderOutline
end tell
end tell
end tell
end tell
end tell
end tell
end tell
if reminderDescription contains "Completed, " then
set theReminderName to findAndReplaceInText(reminderDescription, "Completed, ", "")
end if
if reminderDescription contains "Incomplete, " then
set theReminderName to findAndReplaceInText(reminderDescription, "Incomplete, ", "")
end if
tell application "Reminders"
set theReminder to the first reminder whose name is theReminderName
set theURL to the id of theReminder as text
set theURL to do shell script "echo \"" & theURL & "\"|sed 's/x-apple-reminder:\\/\\//x-apple-reminderkit:\\/\\/REMCDReminder\\//g'"
return "[" & theReminderName & "](" & theURL & ")"
end tell
Thanks all regarding this. We’ll add Reminders support in Hook 3.4. If all goes well, Hook 3.4 will have a short release cycle, but we don’t have an ETA yet.
This is great, but it will only work if the Reminder does not have any additional metadata: due date, notes, link from share sheet, etc.
For example, it does not work, if:
The Reminder has any value in the Notes field. There will be an additional “, $note_contents” added to your string, so the reminder will not be found by the title.
The Reminder has a system hyperlink. Ex. In the Notes app, use the share sheet to create a reminder. There will be an additional “, From Notes” added to your string
I guess you could remove everything after the comma, but then you would not be able to have any commas in the name of your reminder (which is an edge-ish case).
first, thanks again to @zsbenke for great input into using Hook with Apple Reminders.
Two corrections re my:
First, in looking at this further, the UI scripting for this may be brittle; i.e., subject to changes if Apple updates the UI. Also, there’s a line
set theReminder to the first reminder whose name is theReminderName
that is slow if there are thousands of Reminders; slow even on a MacBook Pro 2021 Pro Max in that case.
So the best approach may be to publish an adaptation of the script online once we’ve published an underlying change to Hook. After further testing we could merge it into the actual app. But till then Hook Pro (3.3.2+) users can simply copy/paste it into Hook’s integration script editor.
Secondly, the fix is likely to come in Hook 3.3.2 rather than Hook 4. We have only a bit of polishing and additional testing left to do for Hook 3.3.2. So hopefully this come fast.
Before adding any new apps to the list of apps that work with Hook, I’d much rather you find ways - brittle though they may be - to work with the standard, out-of-the-box, Apple apps, such as Reminders.
No problem! Hopefully it will be enough as a temporary solution, although I would ping Apple in Feedback Assistant to add a selected reminder option to AppleScript like Notes has.
I’ve just found this & this is heaven sent since I use it to run my personal life. I’ve read through the documentation here Using Hook with Apple Reminders – Hook
This doesn’t work at all with lists I have shared between family members. Is that a limitation?
Once I invoked it I got this error and it looks up Reminders with the rainbow pinwheel.
Even on an M1 Mac, if you have thousands of reminders it’s slow. If you allow it to Continue it should eventually finish. We should add latency to the list of caveats.
Apple Reminds has a URL scheme, so using the URLs is fast. But they don’t provide an API to quickly get the reminder of the currently selected item , so the script is a bit convoluted. I believe there are Link-friendly Mac Apps that integrate with Reminders; if so, they would have lower latency.
I’ve been using this code for a while now, thanks @zsbenke . One note is that, at least on Ventura 13.2, it fails if a reminder has a priority level assigned to it (the !!! UI shows up in the expected reminder title location).
I’ve revised the code to adapt to this (roughly, it will fail if the reminder title’s first character is !.. this can be refined further by doing a more strict string check where I look for !) and it now works with and without priorities assigned.
set sysinfo to system info
set osver to system version of sysinfo
considering numeric strings
set isMonterey to osver ≥ "12"
end considering
tell application "System Events"
tell its application process "Reminders"
tell its window "Reminders"
tell its splitter group 1
tell its UI element 3
tell its UI element 2
tell its UI element 1
if isMonterey then
set reminderOutline to first UI element whose selected of UI element 1 is true
set theReminderName2 to value of UI element 2 of UI element 1 of UI element 1 of reminderOutline
set theReminderName3 to value of UI element 3 of UI element 1 of UI element 1 of reminderOutline
else
set reminderOutline to first UI element whose selected is true
set theReminderName2 to value of UI element 2 of UI element 1 of reminderOutline
set theReminderName3 to value of UI element 3 of UI element 1 of reminderOutline
end if
end tell
end tell
end tell
end tell
end tell
end tell
end tell
tell application "Reminders"
try
if character 1 of theReminderName2 = "!" then
set theReminderName to theReminderName3
else
set theReminderName to theReminderName2
end if
set theReminder to the first reminder whose name is theReminderName
set theURL to the id of theReminder as text
set theURL to do shell script "echo \"" & theURL & "\"|sed 's/x-apple-reminder:\\/\\//x-apple-reminderkit:\\/\\/REMCDReminder\\//g'"
return "[" & theReminderName & "](" & theURL & ")"
on error errMsg
display dialog "ERROR: " & errMsg
end try
end tell
Yeah I’ve been trying to use shortcuts to pull the selected reminder title as that would speed things up, but no joy so far. regardless, appreciate the script!
That’s pretty much why we don’t include it with Hookmark. If the Manifesto for Ubiquitous Linking gains in popularity, Apple might take notice. Would be so easy for them to provide an API for this. Internally they have the IDs. Same goes for Notes and Messages. They use Message URLs between their apps (Calendar), but don’t give consumers and competitors the same benefits, as I discussed here:
Sorry about this issue.
What’s your system language?
Does the reminder have priority?
Is it a nested reminder? Nested reminder is not accessible via AppleScript.
set sysinfo to system info
set osver to system version of sysinfo
considering numeric strings
set isMonterey to osver ≥ "12"
end considering
tell application "System Events" to tell process "Reminders"
set wn to name of menu bar item 2 of menu bar 1
end tell
set sysinfo to system info
set osver to system version of sysinfo
considering numeric strings
set isMonterey to osver ≥ "12"
end considering
tell application "System Events"
tell its application process "Reminders"
tell its window wn
tell its splitter group 1
tell its UI element 3
tell its UI element 2
tell its UI element 1
if isMonterey then
set reminderOutline to first UI element whose selected of UI element 1 is true
set ele to UI element 2 of UI element 1 of UI element 1 of reminderOutline
set uiName to class of ele as string
if uiName is "text field" then
set theReminderName to value of ele
else
set theReminderName to value of UI element 3 of UI element 1 of UI element 1 of reminderOutline
end if
else
set reminderOutline to first UI element whose selected is true
set theReminderName to value of UI element 2 of UI element 1 of reminderOutline
end if
end tell
end tell
end tell
end tell
end tell
end tell
end tell
tell application "Reminders"
try
set theReminder to the first reminder whose name is theReminderName
set theURL to the id of theReminder as text
set theURL to do shell script "echo \"" & theURL & "\"|sed 's/x-apple-reminder:\\/\\//x-apple-reminderkit:\\/\\/REMCDReminder\\//g'"
return "[" & theReminderName & "](" & theURL & ")"
on error errMsg
display dialog "ERROR: " & errMsg
end try
end tell
set sysinfo to system info
set osver to system version of sysinfo
considering numeric strings
set isMonterey to osver ≥ "12"
end considering
tell application "System Events" to tell process "Reminders"
set wn to name of menu bar item 2 of menu bar 1
end tell
set sysinfo to system info
set osver to system version of sysinfo
considering numeric strings
set isMonterey to osver ≥ "12"
end considering
tell application "System Events"
tell its application process "Reminders"
tell its window wn
tell its splitter group 1
tell its UI element 3
tell its UI element 2
tell its UI element 1
if isMonterey then
set reminderOutline to first UI element whose selected of UI element 1 is true
set ele to UI element 2 of UI element 1 of UI element 1 of reminderOutline
set uiName to class of ele as string
if uiName is "text field" then
set theReminderName to value of ele
else
set theReminderName to value of UI element 3 of UI element 1 of UI element 1 of reminderOutline
end if
else
set reminderOutline to first UI element whose selected is true
set theReminderName to value of UI element 2 of UI element 1 of reminderOutline
end if
end tell
end tell
end tell
end tell
end tell
end tell
end tell
tell application "Reminders"
try
set theReminder to the first reminder whose name is theReminderName
set theURL to the id of theReminder as text
set theURL to do shell script "echo \"" & theURL & "\"|sed 's/x-apple-reminder:\\/\\//x-apple-reminderkit:\\/\\/REMCDReminder\\//g'"
return "[" & theReminderName & "](" & theURL & ")"
on error errMsg
display dialog "ERROR: " & errMsg
end try
end tell
I updated my Reminders integration script recently to make it faster on Sonoma. I also made sure that I have a “New Item” part too, so I can create reminders directly from Hookmark.
The “Get Address” script uses the backing SQLite database to find the ID of the selected reminder by title.
There are some caveats to keep in mind:
We have to replace the remindersDatabasePath property with the proper database path which is different for everyone.
Reminders are matched by title, so if we have multiple reminders with the same title, the script may fail to link the proper one.
Here are the scripts updated for Sonoma:
Get Address:
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
-- Replace this with your Reminders database path.
property remindersDatabasePath : "/Users/yourusername/Library/Group Containers/group.com.apple.reminders/Container_v1/Stores/Data-some-UUID.sqlite"
tell application "System Events"
tell its application process "Reminders"
tell its window "Reminders"
tell its splitter group 1
tell its UI element 3
tell its UI element 2
tell its UI element 1
set reminderOutline to first UI element whose selected of UI element 1 is true
set theReminderName to value of UI element 2 of UI element 1 of UI element 1 of reminderOutline
end tell
end tell
end tell
end tell
end tell
end tell
end tell
set theSQLCommand to "/usr/bin/sqlite3 \"" & remindersDatabasePath & "\" \"SELECT ZCKIDENTIFIER from ZREMCDREMINDER WHERE ZTITLE = '" & theReminderName & "'\""
set theReminderIdentifier to do shell script theSQLCommand
set theURL to "x-apple-reminderkit://REMCDReminder/" & theReminderIdentifier
return "[" & theReminderName & "](" & theURL & ")"
New Item (this one can be a bit slow unfortunately)
tell application "Reminders"
set theName to "$title"
set theBody to "$user_link"
set theReminder to make new reminder with properties {name:theName, body:theBody}
set theReminderURL to the id of theReminder
set theReminderURL to do shell script "echo \"" & theReminderURL & "\"|sed 's/x-apple-reminder:\\/\\//x-apple-reminderkit:\\/\\/REMCDReminder\\//g'"
activate
end tell
theReminderURL