I need help parsing JSON into KM variables

Guys, if anyone could help me I would very much appreciate. I need help parsing this:

{"id":"bitcoin","symbol_in_db0":"btc","symbol_in_db1":"btc","name":"Bitcoin","homepage":null,"twitter_screen_name":null,"facebook_username":null,"image":null,"genesis_date":null,"synchronized_with_db1":true,"synchronized_with_db0":false,"created_at":"2018-11-15T18:22:39.833Z","updated_at":"2018-11-15T18:22:50.999Z"}

I needed to get "id", "name", "homepage", "twitter", etc into KM variables.

What would be the best approach? Could you provide a sample so I could see how extrapolate to other data?

Thank you all in advance.
G.

IMO, for dealing with JSON, you really want to install jq and save yourself a lot of headaches trying to parse it yourself.

If you use brew, you can use brew install jq.

If you don’t, grab one of the precompiled binaries for OS X from the download page.

From there it should be a relatively simple matter of using jq in a shell script in Keyboard Maestro and having it save variables from there.

In an Execute Javascript for Automation action, you can use JSON.parse to read a json-structured KM variable value, and create other KM variables from the parse result.

Untitled%202

JS source:

(() => {
    'use strict';

    const main = () => {

        const
            ks = ['id', 'name', 'homepage', 'twitter_screen_name'],
            pfx = 'json_',
            kme = Application('Keyboard Maestro Engine'),

            result = bindLR(
                (() => {
                    try {
                        return Right(JSON.parse(
                            kme.getvariable('rawJSON')
                        ))
                    } catch (e) {
                        return Left(e.message)
                    }
                })(),
                dct => Right(ks.map(
                    k => {
                        const
                            v = dct[k],
                            strValue = Boolean(v) ? v.toString() : 'null',
                            kmName = pfx + k;
                        return (
                            // Effect
                            kme.setvariable(kmName, {
                                to: strValue
                            }),

                            // Value
                            kmName + ' -> ' + strValue
                        );
                    }
                ).join('\n'))
            );

        return result.Left || result.Right;
    };

    // GENERIC FUNCTIONS ----------------------------

    // Left :: a -> Either a b
    const Left = x => ({
        type: 'Either',
        Left: x
    });

    // Right :: b -> Either a b
    const Right = x => ({
        type: 'Either',
        Right: x
    });

    // bindLR (>>=) :: Either a -> (a -> Either b) -> Either b
    const bindLR = (m, mf) =>
        undefined !== m.Left ? (
            m
        ) : mf(m.Right);

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

I uploaded a plug-in action a while back that deals with this exact thing:

Although the name of the post cites "Plist", it actually handles both Plist and JSON. In your particular case, here's how it would work:


and here's the list of dictionary values that were created in KM by reading your JSON data:

3 Likes

thank you. I'll take a look into that. I'm not very knowledgeable though. Need to add these things to my skill-set.

Thank you very much ComplexPoint. Getting an answer from a legend like you is amazing. I should invest some time learning JS. The automation possibilities look almost infinite.

Hmm this looks very promising and straightforward. Thank you for taking your time to reply.

Direct support for this is done for the next version.

9 Likes

Such a good idea ...

You are such a great dev Peter, seriously. The amount of benefits we get out of KM is so much, it feels like cheating.

5 Likes

This is super helpful, thank you! How does this work for nested keys though?

1 Like

Actually, I decided to save the first key's values to a Keyboard Maestro variable and then parsed it further down. Would still be a nice-to-know if I can do this without an intermediate variable.

This example might help: Multi-level JSON

1 Like