Executing JavaScript Object versions of actions and macros – some simple tools

Some simple tools for directly executing legible and easily-updated JavaScript objects as Keyboard Maestro Action/Macro sequences.

( Allowing, for example, for run-time changes to the popup menu and checkbox options of KM Actions )

KM macro JSON tools.kmmacros (98.1 KB)

Keyboard Maestro can be used as a script library – an earlier post showed an example of customising some KM XML on the fly, to click on any application menu item. (See under Controlling Keyboard Maestro by Scripting) in the KM documentation.

this works well, but XML strings:

  • are a little illegible,
  • invite slips of quoting/escaping and concatenation,
  • and are not guaranteed to be what KM uses under the hood for all eternity.

Here are some tools for using JavaScript objects (and JSON notation) instead. Why ?

  • more legible
  • simpler to change at run-time
  • more likely to remain usable if the underlying XML level is ever replaced by something like an SQLite level.

The XML-based function above (from the earlier post) could be simplified to:

function menuItemClickKMjso(strAppName, lstMenuPath) {
  "use strict";

  var appSE = Application("System Events"),
    lstApps = appSE.processes.where({
      name: strAppName
    }),
    procApp = lstApps.length ? lstApps[0] : null,
    
    dctJSO = {
    
      MacroActionType: "SelectMenuItem",
      TargetingType: "Specific",
      Menu: lstMenuPath,
      
      TargetApplication: {
        BundleIdentifier: procApp.bundleIdentifier(),
        Name: strAppName,
        NewFile: procApp.file.posixPath()
      }
      
    };

  // Executes a KM action
  // (and also returns the corresponding .kmMacros XML)
  return jsoDoScript(dctJSO);
}

Executing JSON objects as KM Actions or Macros requires the script file to include a custom jsoDoScript() function (pasted by one of the these tools) which differs from the built-in .doScript() in two respects:

  • It executes JavaScript objects, rather than XML strings, and
  • these objects can represent sequences of actions or macros.

(on its own, the built-in .doScript(strXML) only executes XML for individual actions).

The tools:

Copy selected KM macro(s) as JSON

Select one or more macros, and trigger, then paste into Script Editor.

For example, from a selected macro like:

we get a JSON string, :

which can immediately be executed as a JavaScript object by jsoDoScript().

In fact we don't need all of it, so lets pare it down to the essentials (a single action object, an array of actions, or an array of macros, for example), and use the next tool:

Paste the jsoDoScript() function

jsoDoScript() pastes in with an example action, which we can delete, giving us:

( We can execute this kind of thing directly, but more usefully, we can also generalise it a bit, creating (as in the earlier example) a function which can take an arbitrary application name and menu path as arguments )

All that remains is two tools which may be useful for testing or conversion:

Test run selected JSON as KM action(s) or macros()

Select code for one or more actions/macros, from an opening bracket to the matching closing bracket, and trigger.

Toggle clipboard between XML and JSON

If the clipboard contains KM actions or macros in either format, this tool detects the format and translates, allowing you to paste a KM XML version of the JSON, or vice versa.

(May be useful, for example, if you are copying something out of an exported .kmActions or .kmMacros file )

4 Likes

Rob, looks like you’ve done quite a bit of nice work here. It all looks very impressive. :astonished:
Sorry if I’m a bit slow, but I’m not sure I see the advantage of using this vs just putting a JS in a KM Execute Script Action. What am I missing?

Not sure that those are alternatives to each other – scripts using this approach could be launched from anywhere, Script Editor, Execute Actions, command lines etc

This is simply an alternative to direct execution of XML.

The main advantage of running XML/JSON versions of actions is that you can change the popup and checkbox options at run-time. With other scripted approaches only the textbox elements are acessible to run-time variation (through KM variables, tokens, calculations).

This is how Peter spells it out in the Controlling Keyboard Maestro via Scripting section of the documentation:

An even more powerful way to script Keyboard Maestro is to execute specific actions based on their XML code. This allows you to construct any action, including changing the action on the fly, without having to create a macro first. A simple example would be:

tell application "Keyboard Maestro Engine"
do script "MacroActionTypeSwitchToLastApplication"
end tell

> The easiest way to determine the appropriate XML is to create an example action in an example macro and then export the macro.
1 Like

Thanks for the clarification, Rob. That makes perfect sense now. :smile:

Updated above to allow for copying / toggling KM Groups as JSON (in addition to macros).

You should, for example, now be able to get a JSON copy of your whole KM Macros database, by first copying an XML version, in JXA:

(function () {
  var a = Application.currentApplication(),
    sa = (a.includeStandardAdditions = true && a);

  sa.setTheClipboardTo(
    Application("Keyboard Maestro Engine").getmacros({
      asstring: true
    })
  )
})();

and then using the toggle XML <–> JSON tool.

(Note, may take a few seconds if your database is large – it gives a notification when it is done)

1 Like