Using Keyboard Maestro to Bridge URL Calls to Alfred Workflows31 Aug 2021
Recently I was working on an update to an Alfred workflow, and at triggering the workflow from another application. Alfred supports AppleScript, but I was curious to note that it didn’t seem to support triggering workflows with its URL scheme (
alfred://); or at least I couldn’t find any documentation to say that a workflow could be triggered this way. Not everything can work with AppleScript directly, but hyperlinks are far more commonplace. To that end, I came up with the idea of using Keyboard Maestro to bridge the gap.
What are Alfred and Keyboard Maestro?
Alfred is a powerful, extensible launcher application on macOS. It allows you to launch applications, find files, manage your clipboard, even control music playback. With the Alfred Powerpack upgrade, it also allows you to create workflows, and use workflows created by others, to automate what you do.
Another tool that is firmly in the automation camp is the mighty toolbox utility that is Keyboard Maestro. Capable of all sorts of automation shenanigans, there just isn’t enough space in a single blog post to describe everything it can do. Sufficed to say, if you want to save time on the Mac, Keyboard Maestro is a must.
While Keyboard Maestro has more automation breadth than Alfred, there isn’t a 100% overlap, and in some cases, Alfred is just a better tool for a particular automation. I have a great many automation tools that I use, and I always try to choose the best tool for the job rather than always just using one.
The Bridge Concept
While Alfred does not have a URL scheme that would let me call an Alfred workflow, Keyboard Maestro does have a URL scheme that lets me run a Keyboard Maestro macro. Keyboard Maestro macros can also run AppleScript. Therefore I reasoned that I could create a Keyboard Maestro macro that I could call via a URL, that would run some AppleScript to call an Alfred workflow.
The good news is that it is relatively straight forward to do, and I have created a working example for you to follow.
Building a Test Workflow
To test my macro, and to illustrate the principle, I began by creating a test workflow.
This workflow uses an external trigger to allow applications outside of Alfred to initiate the workflow. The result is it displays a system notification based on the input it receives. That’s right. We are not just going to trigger the workflow, we are also going to pass it some information to use.
You can download the example workflow, but I am also going to step through the construction so you can see how it works.
First of all the external trigger provides the unique name within the workflow which we can trigger using the example AppleScript provided. Take a look at the script, and compare it to the script we utilise later on.
Note that I have given this workflow a bundle ID of
com.thoughtasylum.testkm, which appears in the AppleScript to ensure uniqueness of certain details between workflows.
Next, we use a Split Args to Vars step to convert the incoming text into a set of variables based on splitting the incoming text apart at every occurrence of the pipe (
|) character. This is a character I would not normally expect to be passing through, but you can make it whatever you like.
Subsequent to this step, a number of variables called
split2, etc. will be created. For my purposes here, I am only interested in passing in two pieces of information separated in this way.
In the final step, we display a notification to the user. The two variables are used for the title, and for the text of the notification. Hence the two variables.
Building the Keyboard Maestro Macro
As per the initial concept, the macro is based around the AppleScript provided by the external trigger in the Alfred workflow. But how do we get from a URL to the variables?
We start with a special Keyboard Maestro variable,
%TriggerValue%. This is the content of a value parameter for a URL when a URL is used to trigger a Keyboard Maestro macro. Similar to the Split Args to Vars step in the Alfred workflow, this variable also has a nifty index split trick. We can specify an index and a split string by inserting the index in square brackets, and the split string just at the end of the variable name, before the percent delimiter character.
Here I decided to use a double exclamation mark as my separator and again split the inbound string into two with
The first question you may be asking is why are you using a different separator string? Well this is because I want to use this string to split the URL information into only two parts, with the second part containing all of the information to pass to Alfred. That, of course, naturally leads to the question, “what’s in the first part?”
The answer to that is the name of the Alfred workflow to run. By including the name of the workflow to run, this means I have just one Keyboard Maestro macro to maintain, that is capable of triggering any Alfred workflow with an external trigger.
As a special variable, I don’t think Trigger value separations get passed through nicely to AppleScript in Keyboard Maestro, and so my approach in the macro is to store the results of the split in two different variables. I can then use some AppleScript for the Keyboard Maestro engine to grab the content of those variables, and then utilise them in what is still pretty close to the original Alfred external trigger AppleScript.
The AppleScript I have used is as follows, but you can also download the macro if you wish.
tell application "Keyboard Maestro Engine" set macroName to getvariable "AlfredMacroName" set macroPayload to getvariable "AlfredPayload" end tell tell application id "com.runningwithcrayons.Alfred" to run trigger macroName in workflow "com.thoughtasylum.testkm" with argument macroPayload
Here is how the complete macro looks.
Crossing the Bridge
Now all we need to do is to test the system. If you look back at the image of the Keyboard Maestro macro above, you may notice that I have expanded the information to show the URL examples for calling the macro. This is the basis of the test.
I am going to use the name of the macro for this example, which gives us the first part of the URL:
Next, we want to build the payload of data to pass to the macro. This is going to consist of the name of the Alfred workflow to run, followed by two exclamation marks, and then the text to pass to the Alfred workflow. In all cases, we need to ensure that we are URL encoding any characters that require it, such as the space characters in the macro name as
The test macro name is “kmdisplay”, so the macro payload is going to be something like:
The Alfred workflow payload is to consist of two text strings separated by a pipe character, so let’s use “The Title”, and “The detail of the notification”.
That then gives us a macro payload string of:
Finally let’s add that in as the value parameter in the Keyboard Maestro macro trigger URL.
With the macro and workflow in place, we can then trigger this by putting the URL in the browser, or opening it at the terminal:
The resulting notification then looks like this:
The chances are, when you run this for the first time, you will be prompted by macOS to allow Keyboard Maestro to control Alfred. If you have run Alfred AppleScript from Keyboard Maestro before , you will not get this, but otherwise, it is an expected prompt, and you are okay to allow it. If you do not, Keyboard Maestro will be unable to trigger the workflow.
That’s our bridge built. It probably is not something most people would use all that often, but I find that being able to trigger automations via a hyperlink is really useful when writing process documentation for myself and others. I can put a link right alongside an explanation or in a check list and just trigger something to run as part of the walk through. I find it very convenient.
As noted at the start. There are simply times when triggering some AppleScript is not the most accessible thing to do, but hyperlinks are often another story.
Here, I was able to use Keyboard Maestro to build a bridge for Alfred workflows, further cementing its place a a key hub for my personal automation. I hope that you will be able to find some use for it too.