Using Alfred to Trigger Keyboard Maestro Macros

In this tutorial I'll share how I use Alfred to launch Keyboard Maestro macros.

Of course there are many ways to trigger a KM macro, but Alfred Workflows work quite nicely when one wants to conditionally run a macro. In these cases, the Alfred Workflows include an AppleScript to trigger the macro and supply a parameter which the macro reads via the %TriggerValue%.

In addition, the Alfred gui includes features that can be leveraged to display information about the macro and/or the optional parameters.


Here's a macro that can be used to create the AppleScript code to trigger a selected macro.

Download: AppleScript To Run Selected Macro.kmmacros (16 KB)

Macro-Image


Macro-Notes
  • Macros are always disabled when imported into the Keyboard Maestro Editor.
    • The user must ensure the macro is enabled.
    • The user must also ensure the macro's parent macro-group is enabled.

System Information
  • macOS 13.4.1 (22F82)
  • Keyboard Maestro v10.2

4 Likes

Example 1

In this post Note Picker will be the example macro; it can run in two modes:

  1. a value is not supplied via the %TriggerValue%, or
  2. a value of f/ folder_substring or t/ title_subscring is supplied via the %TriggerValue%.

See Note Picker for more information regarding the two modes.


Using the Alfred Workflow that is detailed below, Note Picker can be triggered four different ways:

Method A

Method B

Method C

Method D


With Method A (user types: np<return>), Note Picker is run exactly as if it was triggered using the hot key configured in Keyboard Maestro.

Method B (user types: np log<return>) and D (user types: np t.log<return>) are interchangeable. In these cases Note Picker is triggered and the macro receives t/ log via the %TriggerValue%.

With Method C (user types: np f.mac<return>), Note Picker is triggered and the macro receives f/ mac via %TriggerValue%.


Here's the Alfred Workflow:


The Input>Keyword is configured as follows:

Keyword: np

Title: np: KM Note Picker +'{query}'

Subtext: ⒪ title substring; f.folder substring; t.title substring

Aside: By convention, when I configure the Subtext for Input>Keywords, I use an prefix to indicate that an argument is optional. In this case, that means that a user can launch Alfred and simply type np<return> (that is, like with Method A).


The left Actions>Run Script block is as follows:

shell script ( expand / collapse )
# Build the %TriggerValue% for the macro

query=$1

# If nothing passed, then echo null
if [ -z "$query" ]
then
	echo -n

# If f.some text is passed, then echo f/ some text
elif [[ "$query" =~ ^f\.* ]]
then
	echo -n f/ ${query:2}

# If t.some text is passed, then echo f/ some text
elif [[ "$query" =~ ^t\.* ]]
then
	echo -n t/ ${query:2}

# Otherwise, assume it a title and echo some text
else
	echo -n t/ ${query}

fi

The right Actions>Run Script block is as follows:

shell script ( expand / collapse )
query=$1

# echo -n $query

osascript <<EndOfScript

-- Note Picker 
property theP : "$query"

tell application "Keyboard Maestro Engine"
  do script "A3DF7C60-CF4B-4E64-AD35-72BAB6937E9F" with parameter theP
end tell

EndOfScript
1 Like

Example 2

In this post Engine.log Tool will be the example macro. Alfred is a great option with a macro like this because it can quickly trigger the macro in the default mode or in one of the alternate modes.


Using the Alfred Workflow that is detailed below, Engine.log Tool can be triggered by typing elt. If <return> is then pressed, the macro is triggered normally and the main dialog is displayed. Alternatively, the %TriggerValue% can be set to one of the 15 values (listed below in the three Alfred entries) if the respective abbreviation is specified.

For example, if elt cb<return> is typed, the Engine Log Tool main dialog will be bypassed and the failure/timeout from the Engine.log will be written the System Clipboard. Other examples:

  • elt r<return> will start Engine.log Tool initially displaying the failure |timeout that was last viewed when the macro previously ran.

  • elt a<return> will bypass the Engine.log Tool main dialog. The Keyboard Maestro app will open and the macro action that generated the failure/timeout will be selected.

  • elt 0kfailed:|timeout<return> will bypass the Engine.log Tool main dialog. The Engine.log will be trimmed keeping only the entries that have failed: or timeout in the text.


Here's the Alfred Workflow:

Note how the workflow includes three Keyword blocks. This is simply because Engine.log Tool includes 15 alternate methods of execution and it takes three entries to display them all. Because the Keyword blocks all flow into the left Run Script block, any of the 15 options can be entered when any of the three Alfred entries are selected.


The first Input>Keyword is configured as follows:

Keyword: elt

Title: elt: KM Engine Log Tool ({query})

Subtext: ⒪ r→recall; c→console; a→action; rd→reduce; cd→clipboard; e→editor; rv→reveal; s→select; t→tail

Aside: By convention, when I configure the Subtext for Input>Keywords, I use an prefix to indicate that an argument is optional. In this case, that means that a user can launch Alfred and simply type elt<return>.


The second Input>Keyword is configured as follows:

Keyword: elt

Title: elt: KM Engine Log Tool ({query}) 𝘭𝘦𝘢𝘥𝘪𝘯𝘨 0 𝘰𝘱𝘵𝘪𝘰𝘯𝘢𝘭

Subtext: ⒪ 0d→0:delete; 0p:𝘙𝘦𝘨𝘌𝘹→0:purge:𝘙𝘦𝘨𝘌𝘹; 0k:𝘙𝘦𝘨𝘌𝘹→0:keep:𝘙𝘦𝘨𝘌𝘹; 0t𝘯→0:tail:𝘯


The third Input>Keyword is configured as follows:

Keyword: elt

Title: elt: KM Engine Log Tool ({query}) 𝘭𝘦𝘢𝘥𝘪𝘯𝘨 0 𝘰𝘱𝘵𝘪𝘰𝘯𝘢𝘭

Subtext: ⒪ 0td→0:today; 0d𝘯→0:days:𝘯; 0tm𝘺𝘺𝘺𝘺-𝘮𝘮-𝘥𝘥 𝘩𝘮𝘮→0:time:𝘺𝘺𝘺𝘺-𝘮𝘮-𝘥𝘥 𝘩𝘮𝘮


The left Actions>Run Script block is as follows:

shell script ( expand / collapse )
query=$1

# Evaluate the query
case "${query}" in

    c) tv="console";;
    a) tv="action";;
    rd) tv="reduce";;
    cb) tv="clipboard";;
    e) tv="editor";;
    rv) tv="reveal";;
    s) tv="select";;
    r) tv="recall";;

    0p*) tv="0:purge:${query#0p}";;
    0k*) tv="0:keep:${query#0k}";;
    0td) tv="0:today";;
    0d*) tv="0:days:${query#0d}";;
    0tm*) tv="0:time:${query#0tm}";;
    0t*) tv="0:tail:${query#0t}";;

    p*) tv="purge:${query#p}";;
    k*) tv="keep:${query#k}";;
    td) tv="today";;
    d*) tv="days:${query#d}";;
    tm*) tv="time:${query#tm}";;
    t*) tv="tail:${query#t}";;

    0d) tv="0:delete";;
    d) tv="delete";;
    t) tv="tail";;

    *) tv="";;

esac

case "${tv}" in

    days:) tv="delete";;
    0:days:) tv="0:delete";;
   	tail:) tv="tail";;
    0:tail:) tv="tail";;

esac

# If a colon was entered, then the output would include two ::. Remove one.
tv=$(echo "$tv" | sed 's/::/:/g')

echo "$tv"

The right Actions>Run Script block is as follows:

shell script ( expand / collapse )
query=$1

osascript <<EndOfScript

-- Engine.log Tool

tell application "Keyboard Maestro Engine"
	do script "1AAD6C42-EE53-4044-8571-420CEF1EE6F7" with parameter "$query"
end tell

EndOfScript
1 Like

To get this to work, I had to modify the first shell script as follows:

query=$1

# echo -n $query

osascript <<EndOfScript

-- Note Picker 
property theP : "$query"

tell application "Keyboard Maestro Engine"
  do script "A3DF7C60-CF4B-4E64-AD35-72BAB6937E9F" with parameter theP
end tell

EndOfScript

Thanks, @rolian. I will fix the post. For some odd reason, it appears a newline was lost during my posting process.