×

Volume Mount Trigger for Shortcuts

One of the most useful features of Shortcuts is its ability to respond to specific events or “triggers” that occur: such as achieving a time of day, or reaching a location. The following trigger example enables the execution of a chosen shortcut when a volume or disk image, is mounted on your computer.

On macOS, a volume mount trigger can be provided by a “stay-open” AppleScript applet that “watches” your system and runs a pre-chosen shortcut when a volume is mounted, passing the path to mounted volume to the shortcut when it is executed..

Trigger • Volume Mount Trigger for Shortcuts

Here is an example workflow that uses the “Run AppleScript” action to set the display of the contents of the mounted volume in its corresponding Finder window. (DOWNLOAD SHORTCUT)

 1  Shortcut Input • The shortcut is set to receive text.

 2  No Text Alert • If for some reason no text is passed into the shortcut, it will post an alert.

 3  “Run AppleScript” action • This action is passed the shortcut input as its input.

 4  AppleScript script • This AppleScript script converts the input into a file reference that is used to have the Finder application open the mounted volume and set the display of its contents in the frontmost Finder window.

volume-mount-workflow

NOTE: Install the shortcut and then choose it from the list of shortcuts displayed when the AppleScript applet is launched the first time.

The “Volume Watcher” Applet

The following is the AppleScript code of the “stay-open” applet that registers itself with macOS to receive a notification when a volume is mounted on the desktop.

This applet is written in AppleScriptObj-C which provides access the macOS frameworks through a “Cocoa Bridge” that exposes most of the functionality of the operating system to scripts.

Many thanks to the Script Debugger application for providing the tools for designing, editing, and notarizing AppleScript applications.

NOTE: Should you choose to edit or alter this script yourself, be sure to save it as a “Stay Open” applet that remains active until it is told to quit.

DOWNLOAD APPLET

AppleScript Applet


use AppleScript version "2.4" -- Yosemite (10.10) or later use framework "Foundation" use framework "AppKit" use scripting additions -- classes, constants, and enums used property NSCharacterSet : a reference to current application's NSCharacterSet property NSString : a reference to current application's NSString property NSWorkspace : a reference to current application's NSWorkspace property NSUserDefaults : a reference to current application's NSUserDefaults property NSArray : a reference to current application's NSArray property ignoredVolumes : {"home", "net", "Recovery HD"} global workflowName on run -- SET VALUE OF PROPERTY TO STORED WORKFLOW PATH my initializeDefaults() -- CHECK STATUS OF STORED WORKFLOW PATH if (workflowName as text) is "" then my promptForWorkflow() else -- DISPLAY OPENING DIALOG tell me to activate display dialog "Shortcut: " & return & return & (workflowName as text) buttons {"Quit", "Change", "Start"} default button 3 with title (name of me) set buttonPressed to the button returned of the result if the buttonPressed is "Change" then -- prompt for a new workflow my promptForWorkflow() else if buttonPressed is "Quit" then tell me to quit else -- check to see if workflow file exists if my workflowCheck() is false then tell me to activate display alert "MISSING RESOURCE" message "There is no shortcut with the indicated name:" & ¬ return & return & workflowName buttons {"Select", "Quit"} default button 2 if button returned of the result is "Quit" then tell me to quit end if -- prompt for a new workflow my promptForWorkflow() end if end if end if -- REGISTER FOR NOTIFICATION my registerToReceiveNotification() end run on initializeDefaults() -- Initialize default if needed, retrieve current value tell NSUserDefaults to set defaults to standardUserDefaults() tell defaults to registerDefaults:{workflowName:""} -- set the value of the applet property to the stored value tell defaults to set workflowName to (objectForKey_("workflowName")) as text end initializeDefaults on workflowCheck() set workflowTitles to (do shell script "shortcuts list|sort") set AppleScript's text item delimiters to return set workflowTitles to every text item of workflowTitles set AppleScript's text item delimiters to "" if workflowTitles contains workflowName then return true else return false end if end workflowCheck on promptForWorkflow() -- prompt user to choose a workflow try set workflowTitles to (do shell script "shortcuts list|sort") set AppleScript's text item delimiters to return set workflowTitles to every text item of workflowTitles set AppleScript's text item delimiters to "" if workflowTitles is {} then beep display alert "Missing Resources" message "There are no saved shortcuts." error number -128 end if set the dialogResult to (choose from list workflowTitles with prompt "Choose shortcut to run when volume is mounted:") if dialogResult is false then error number -128 set workflowName to dialogResult as string tell NSUserDefaults to set defaults to standardUserDefaults() tell defaults to setObject:workflowName forKey:"workflowName" on error tell me to quit end try end promptForWorkflow on registerToReceiveNotification() -- create an instance of the Shared Workspace set workspace to NSWorkspace's sharedWorkspace() -- identify the Shared Workspace's notification center set noteCenter to workspace's notificationCenter() -- register notification handlers for dealing with volume mounting noteCenter's addObserver:me selector:"volumeWasMounted:" |name|:"NSWorkspaceDidMountNotification" object:(missing value) end registerToReceiveNotification on volumeWasMounted:notif -- CHECK FOR WORKFLOW FILE if my workflowCheck() is false then my promptForWorkflow() end if -- get the path to the mounted volume set mountedVolumePath to (notif's userInfo()'s NSWorkspaceVolumeURLKey's |path|()) -- get last path item set thisVolumeName to (mountedVolumePath's lastPathComponent()) as text if thisVolumeName is not in ignoredVolumes then -- display alert set currentApp to application (POSIX path of (path to frontmost application)) tell me to activate delay 1 tell me to activate display dialog "The volume “" & thisVolumeName & "” has been mounted on this system." & ¬ return & return & "Do you want to run the associated shortcut?" buttons {"No", "Yes"} default button 2 if the button returned of the result is "No" then error number -128 -- RUN WORKFLOW try set encodedWorkflowTitle to my encodeUsingPercentEncoding(workflowName) set encodedVolumePath to my encodeUsingPercentEncoding(mountedVolumePath as string) open location "shortcuts://run-shortcut?name=" & encodedWorkflowTitle & "&input=text&text=" & encodedVolumePath tell currentApp to activate on error errorMessage activate display alert "WORKFLOW EXECUTION ERROR" message errorMessage tell me to quit end try end if end volumeWasMounted: on encodeUsingPercentEncoding(sourceText) -- create a Cocoa string from the passed AppleScript string set the sourceString to NSString's stringWithString:sourceText -- indicate the allowed characters that do not get encoded set allowedCharacterSet to NSCharacterSet's alphanumericCharacterSet -- apply the indicated transformation to the Cooca string set the adjustedString to sourceString's stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet -- convert from Cocoa string to AppleScript string return (adjustedString as string) end encodeUsingPercentEncoding

(⬇ see below ) When the applet is launched it displays a dialog for selecting or confirming the shortcut to be executed when a volume is mounted.

Startup Dialog

(⬇ see below ) A security confirmation dialog presented the first time the shortcut is executed. Approve this dialog to allow the applet to do its job. Once approved, you will not be prompted again.

Screenshot

(⬇ see below ) A confirmation alert that is displayed by the applet when a volume is mounted.

Volume trigger alert