New UUID in JavaScript for Automation Action

I am working on a macro that uses a JavaScript script to generate a UUID. I am using this code:

When I run the UUID node.JS module in Terminal, it works fine. However, when I run this script in Keyboard Maestro, it doesn't appear to be importing the node.js module properly.

Here is the macro:

Here is the error message:

I would appreciate any guidance on getting the uuid module to work or where to look further.

Thanks in advance.

Alternatively, I realized I can run the UUID as a shell script. See screenshot. This macro works well. However, what is the best way to generate multiple UUIDs based on a user input. For example, a user requests 150 UUIDs and the shell script generates 150 and puts them in the clipboard.

I believe KM's own randomly-generated UUIDs are v4. So:

Generate UUIDs.kmmacros (3.6 KB)

Image

1 Like

For a JavaScript for Automation context (rather than Node JS context):

// newUUID :: () -> IO UUID String
const newUUID = () =>
    ObjC.unwrap($.NSUUID.UUID.UUIDString);

For example:

Generate UUIDs in JXA.kmmacros (2.5 KB)

1 Like

Preformatted textThank you! This works well, but I am having a hard time passing in the KM variable for the count of UUIDs that I want to insert.

I used the following:

(() => {
"use strict";

const main = () =>
    enumFromTo(1)(kmvar.local_uuidAmount)
    .map(newUUID)
    .join("\n");


// --------------------- GENERIC ---------------------

// enumFromTo :: Int -> Int -> [Int]
const enumFromTo = m =>
    n => Array.from({
        length: 1 + n - m
    }, (_, i) => m + i);


// newUUID :: () -> IO UUID String
const newUUID = () =>
    ObjC.unwrap($.NSUUID.UUID.UUIDString);


// MAIN ---
return main();

})();

It doesn't pick up the KM variable. Any suggestions?

Generate UUID v4 Multiple JXA Macro (v10.2)

Generate UUID v4 Multiple JXA.kmmacros (7.0 KB)

You're trying to use the syntax for a browser JavaScript action in a JXA action...

2 Likes

For example:

Generate give number of UUIDs in JavaScript for Automation context.kmmacros (2.6 KB)


Expand disclosure triangle to view JS source
(() => {
    "use strict";

    const main = () =>
        enumFromTo(1)(
            Number(
                Application("Keyboard Maestro Engine")
                .getvariable("uuidCount")
            )
        )
        .map(newUUID)
        .join("\n");


    // --------------------- GENERIC ---------------------

    // enumFromTo :: Int -> Int -> [Int]
    const enumFromTo = m =>
        n => Array.from({
            length: 1 + n - m
        }, (_, i) => m + i);


    // newUUID :: () -> IO UUID String
    const newUUID = () =>
        ObjC.unwrap($.NSUUID.UUID.UUIDString);

    // MAIN ---
    return main();
})();


JavaScript is an embedded scripting language, and the libraries available to a JS interpreter vary with the context is in which it is embedded.

For example:

  • A JS interpreter embedded in a browser has access, in the global context, to a library exposing an instance of the Document Object Model
  • The JXA embedding provides no DOM library – there is no web-page in sight – but does expose, in the global context, an Application library object with various methods and properties that are useful for synchronous scripting and access to ObjC libraries.
  • Neither of these has any connection to the Node JS embedding (of a V8 JS interpreter) in a non-browser local run-time context, for which the uuidv4 module is written.
3 Likes

This is fantastic. Thank you - it's clear now how to bring a KM variable into JavaScript.

Not into all "JavaScript" :slight_smile:

Just into the particular JS context of JavaScript for Automation.

(There's a different syntax for resolving KM variable names into values in browser-embedded JS)


The most concrete way to get a sense of the difference between each distinct JS context is to run the single-word program:

this

which will list, inter alia, the libraries defined in the global context – different for each embedding context.


The JXA context is the WebKit JS interpreter equipped, in the global context, with definitions for these objects and methods:

Automation
    Application
        currentApplication
    Library
    ObjC
        $
        Ref
            equals
        bindFunction
        block
        castObjectToRef
        castRefToObject
        deepUnwrap
        dict
        import
        interactWithUser
        registerSubclass
        super
        unwrap
        wrap
    ObjectSpecifier
    Path
    Progress
    delay
    getDisplayString
    initializeGlobalObject
    log
2 Likes