Automation Documentation: Hooking Apple Shortcuts

Earlier this week I wrote about how I was using Hook and Obsidian to support my documentation of automations. In this post I will aim to explain how I am using this set up to help me access documentation for my Apple Shortcuts automations.

Shortcuts

Apple’s Shortcuts application came to the Mac in 2021 and provided Mac users with the latest functionality in native Apple automation. Shortcuts is a natural successor to Automator - or in effect, what Automator could easily have become if the investment had been there at the time. While statistically most shortcuts are probably less than a half-dozen actions, there are inevitably more complex ones. Some people build shortcuts with hundreds of actions. Personally I break my shortcuts down into smaller more reusable shortcuts - a typical developer approach; but this does mean that these multi-shortcut solutions are not as easily shared with others.

Regardless, the complexity of such Shortcuts solutions inevitably leads to a need to document in order to fully support its use and maintenance. As a result, like my other automations, I document some of my Apple Shortcuts automations in Obsidian, and my preference is to use the Hook application to support that.

Apple Shortcuts Integration Script

Hook allows me to create bidirectional links between resources to associate them. To do this it relies on access to unique identifiers, URL schemes and a way to programmatically reference these through Hook’s integration scripts.

Pro subscribers of Hook can create their own integration scripts that allow Hook to work with any app capable of supporting hyperlinking to a specific resource. While I have a pro subscription, and Shortcuts does support using URLs for open a shortcut for editing, Shortcuts is somewhat ironically not particularly scriptable.

After applying a little thought to the situation, I was able to put together an AppleScript that interacts with the Shortcuts application’s user interface, which then enabled me to allow an address to be generated by Hook for a particular shortcut. It utilises the system clipboard to grab the name of the shortcut and build the edit URL from that - so it is doubly important to ensure that your shortcuts are uniquely named. The script also makes use of some helpful scripted solutions from others, which have been included verbatim and include references back to their creators and websites.

The script is added via the script editor in Hook’s preferences. It should be added in the Get Address section as the script returns a Markdown link.

-- `menu_click`, by Jacob Rus, September 2006
-- Accepts a list of form: `{"Finder", "View", "Arrange By", "Date"}`
-- Execute the specified menu item.  In this case, assuming the Finder 
-- is the active application, arranging the frontmost folder by date.

on menu_click(mList)
    local appName, topMenu, r
    
    -- Validate our input
    if mList's length < 3 then error "Menu list is not long enough"
    
    -- Set these variables for clarity and brevity later on
    set {appName, topMenu} to (items 1 through 2 of mList)
    set r to (items 3 through (mList's length) of mList)
    
    -- This overly-long line calls the menu_recurse function with
    -- two arguments: r, and a reference to the top-level menu
    tell application "System Events" to my menu_click_recurse(r, ((process appName)'s ¬
        (menu bar 1)'s (menu bar item topMenu)'s (menu topMenu)))
end menu_click

on menu_click_recurse(mList, parentObject)
    local f, r
    
    -- `f` = first item, `r` = rest of items
    set f to item 1 of mList
    if mList's length > 1 then set r to (items 2 through (mList's length) of mList)
    
    -- either actually click the menu item, or recurse again
    tell application "System Events"
        if mList's length is 1 then
            click parentObject's menu item f
        else
            my menu_click_recurse(r, (parentObject's (menu item f)'s (menu f)))
        end if
    end tell
end menu_click_recurse

-- Encoding functions from macosxautomation.com
-- https://www.macosxautomation.com/applescript/sbrt/sbrt-08.html
on encode_char(this_char)
    set the ASCII_num to (the ASCII number this_char)
    set the hex_list to {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"}
    set x to item ((ASCII_num div 16) + 1) of the hex_list
    set y to item ((ASCII_num mod 16) + 1) of the hex_list
    return ("%" & x & y) as string
end encode_char


on encode_text(this_text, encode_URL_A, encode_URL_B)
    set the standard_characters to "abcdefghijklmnopqrstuvwxyz0123456789"
    set the URL_A_chars to "$+!'/?;&@=#%><{}[]\"~`^\\|*"
    set the URL_B_chars to ".-_:"
    set the acceptable_characters to the standard_characters
    if encode_URL_A is false then set the acceptable_characters to the acceptable_characters & the URL_A_chars
    if encode_URL_B is false then set the acceptable_characters to the acceptable_characters & the URL_B_chars
    set the encoded_text to ""
    repeat with this_char in this_text
        if this_char is in the acceptable_characters then
            set the encoded_text to (the encoded_text & this_char)
        else
            set the encoded_text to (the encoded_text & encode_char(this_char)) as string
        end if
    end repeat
    return the encoded_text
end encode_text

-- Now the scripting that uses those functions to return a Markdown link to Hook
tell application "Shortcuts" to activate
menu_click({"Shortcuts", "File", "Rename…"})
delay 0.2
tell application "System Events"
    keystroke "c" using command down
    delay 0.2
    keystroke return
    delay 0.2
end tell

return "[Shortcuts Action - " & (the clipboard as text) & "](" & ¬
    "shortcuts://open-shortcut?name=" & encode_text((the clipboard as text), true, true) & ")"

Once in place, this will allow you to generate an edit shortcut link when you are editing a shortcut in Apple Shortcuts. This then allows Hook to do its association “magic”.

Summary

Being able to bidirectionally link to a note in Obsidian to create documentation for my shortcuts is very useful to me. As you might have guessed from the details above, I do not feel the need to document every single Shortcut, but through use, I have found I am documenting some of the simpler shortcuts as well as the more complex ones. This is because it then gives me a more capable way of identifying shortcuts than just by the name of the shortcut.

Much like being able to cross-reference subroutines in Keyboard Maestro, for multi-part solutions where one shortcut calls another, it makes it really easy for me to link up to the documentation of those other shortcuts. I can even put together a quick Mermaid diagram in Obsidian to show me those more complex flows.

Author: Stephen Millard
Tags: | shortcuts | hook | applescript |

Buy me a coffeeBuy me a coffee



Related posts that you may also like to read