BetterTouchTool Simple JSON Format

BetterTouchTool 4.690 introduced a new "Simple JSON Format", which can currently be used with the predefined actions "Show Custom Context Menu (New)" and "Choose From List". It allows to create those menus dynamically using Java Script & JSON.

Soon this will also be supported for Floating Menus.

4.690 now contains a first version of this that works with the predefined actions "Custom Context Menu New" and "Choose From List". Unfortunately I will need a few more hours to document this properly as it became quite powerful.

Here is what I started typing - it's probably not very useful yet - but I'm now on a day trip with the kids. Will finish the docs this evening.

You need to click the "Retrieve Content Dynamically Via Java Script" checkbox. image|690x496

Then you can have a function like this that returns a JSON:

Simple example

async function retrieveJSON() {
  let items = [
    {
        "title": "trigger some shortcut",
        "icon": "sfsymbol::globe",
        "action": "shortcut::TheShortcutFromTheShortcutsApp"
    },
    {
        "title": "trigger some named trigger",
        "icon": "sfsymbol::house",
        "action": "named::TheNameOfTheBTTNamedTrigger"
    },
    {
        "title": "trigger some BTT trigger via UUID",
        "icon": "sfsymbol::star",
        "action": "uuid::4ff033d2-8f67-490d-b281-3124d452ef07"
    }
  ];

  return JSON.stringify(items);
}

Complex example

async function retrieveJSON() {
  let items = [
    {
        "title": "hello world",
        "icon": "sfsymbol::globe"
    },
    {
      title: "some title",
      subtitle: "some subtitle",
      subitems: [
        {
          title: "some sub-item",
          action: "named::NameOfNamedTriggerInBTT",
          icon: "sfsymbol::house::weight@@light::size@@30"
        },
        {
          title: "some sub-item2",
          icon: "base64::iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAFUlEQVR42mNkYPhfz0AEYBxVSF+FAP5FDvcfRYWgAAAAAElFTkSuQmCC",
          action: "shortcut::NameOfShortcutInShortcutsApp@@OptionalInput"
        },
      ],
      icon: "sfsymbol::star::color@@B53E93",
      // this shows various forms of actions. In case you are just triggering
      // a single action, it does not need to be an array.
      action: [
        `btt::paste_text@@{"text": "hello world"}`,
        "keyboard::0", //type a
        "keyboard::11", //type b
        "keyboard::8", //type c
        "js::runShellScript({script: `say hello`})",
        {
          btt: "paste_text",
          args: {
            text: "hello world 2",
            insert_by_pasting: true,
          },
        },

        {
          shortcut: "theNameOfTheShortcut",
          input: "some optional input",
        },
      ],
    },
  ];

  return JSON.stringify(items);
}

simple format config resulting context menu

alt text

You'll find more examples on https://community.folivora.ai for example here is an example that will list all apps / files in a specified folder: Example to list all files in a folder


Allowed keys:

title

supported properties color & size

Examples:

{
"title": "hello::size@@30::color@@#000000"
}

Alternative syntax:

{
   "title": {
      "text": "some title",
      "size": 30,
      "color": "#000000"
   }
}

subtitle

supported properties color & size. Only works in the "choose from list action".

Examples:

{
"subtitle": "some subtitle::size@@30::color@@#000000"
}

Alternative syntax:

{
   "subtitle": {
      "text": "some subtitle",
      "size": 30,
      "color": "#000000"
   }
}

subitems

Examples:

{
    "title": "submenu",
    "subitems": [
        {
           "title": "hello"
        },
        {
           "title": "world"
        }
    ]
}

setvariable

this allows to set a variable value before the action is executed

Examples:

{
"setvariable": "variablename@@variablevalue"
}

Alternative syntax:

{
   "setvariable": {
      "name": "variablename",
      "variablevalue": "test"
   }
}

icon

this allows to define an icon

Supported properties: type (sfsymbol, size, path, base64, background, width, height)

Examples:

{
"icon": "sfsymbol::star"
}

Or with more options:

{
"icon": "sfsymbol::star::weight@@light::color@@#fefefe::color@@#000000::background@@#B53E93"
}

From file:

{
"icon": "path::~/Downloads/test.png::width@@40::height@@40"
}

From base64:

{
"icon": "base64::base64code"
}

Alternative syntax:

{
   "icon": {
      "type": "sfymbol",
      "sfymbol": "star",
      "weight": "light",
       "colors" : ["#000000", "#fefefe"],
      "background": "#B53E93",
      "size" : 30
   }
}

action

supported properties named, shortcut, js, keyboard, uuid, btt. Can also be an array of actions.


named

This will trigger a named trigger configured in BTT (see http://docs.folivora.ai/docs/1002_named_triggers.html )

{"title": "trigger named trigger", "action": "named::theNameOfTheNamedTrigger"},

Alternative syntax:

{
    "title": "trigger named trigger alternative", 
    "action": {
        "named": "helloworld"
    },
    "icon": "sfsymbol::star.leadinghalf.filled"
}

uuid

This will trigger any trigger configured in BTT using its UUID

{"title": "trigger via uuid", "action": "uuid::4ff033d2-8f67-490d-b281-3124d452ef07"},

Alternative syntax:

{
    "title": "trigger via UUID alternative", 
    "action": {
        "uuid": "4ff033d2-8f67-490d-b281-3124d452ef07"
    }
}

shortcut

This will trigger a shortcut configured in Apple's shortcuts app

{"title": "trigger shortcut form shortcuts app", "action": "shortcut::theNameOfTheShortcut@@someOptionalInput"},

Alternative syntax:

{
    "title": "trigger shortcut form shortcuts app alternative", 
    "action": {
        "shortcut": "theNameOfTheShortcut",
        "input": "some optional input"
    }
}

js

This will run BTT Java Script which also allows to run shell scripts or apple scripts and trigger ny of BTT's scripting functions (http://docs.folivora.ai/docs/1106_java_script.html)

E.g. run some shell script:

{"title": "say hello", "action": "js::runShellScript({script: `say hello`})"},

Or run some arbitrary apple script:

 {
      title: "show some apple script dialog",
      action: {
        js: `(async () => {

                // put the Apple Script into a string (back ticks are great for multi-line strings)
                let appleScript = \`
                    set theDialogText to "The curent date and time is " & (current date) & "."
                    set result to display dialog theDialogText
                    return result
                \`;

                // this will execute the Apple Script and store the result in the result variable.
                let result = await runAppleScript(appleScript);

                // do whatever you want with the result

                // at the end you always need to call returnToBTT to exit the script / return the value to BTT.
                returnToBTT(result);

                // it is important that this function self-executes ()
                })()
            `,
      },
    },

btt

This can run any of BTT's scripting functions (http://docs.folivora.ai/docs/1102_apple_script.html ). To see how to configure & trigger a specific action you can right-click the action in BTT and choose "copy java script to trigger action".

"action": `btt::paste_text@@{"text": "hello world"}`

Alternative syntax

{
"title": "paste item 1",
 "action": {
      "btt":"paste_text", 
      "args": {
          "text": "ddasdas",
          "insert_by_pasting": true
       }
  }
},
{
  "title": "application expose",
  "action": {
    "btt": "trigger_action",
    "args": {
      "json": {
        "BTTActionCategory": 0,
        "BTTPredefinedActionType": 6,
        "BTTPredefinedActionName": "Application Expose"
      }
    }
  }
}

keyboard

This can trigger a keyboard shortcut.

It needs to constist of comma separated modifier keys (cmd, shift, opt, fn, ctrl) and one key code at the end. A list of key codes can e.g. be found here: https://eastmanreference.com/complete-list-of-applescript-key-codes

"action": "keyboard::shift,opt,0"

Examples

Get result from Apple Shortcut, e.g. some weather conditions:

async function retrieveJSON() {

let weather = await runAppleShortcut({name: "weather", "input": ""});


let items = [
 {"title": weather},
{"title": "test item 2"},
{"title": "test item 3", "icon": "sfsymbol::star"}
]; 

 return JSON.stringify(items);

}

Execute multiple actions from one item (example types abc)

async function retrieveJSON() {
    let items = [
       {
        "title": "multiple actions (type abc)", 
        "action": [
            "keyboard::0", //type a
            "keyboard::11", //type b
            "keyboard::8", //type c
        ],
        "icon": "sfsymbol::keyboard"
      },
    ]; 

    return JSON.stringify(items);

}

Fetch menu from some server:

async function retrieveJSON() {
    const response = await fetch('https://folivora.ai/various/test-menu.json');

    const data = await response.json();
    const jsonString = JSON.stringify(data);
    return jsonString;

}

Works with custom menubar items as well when assigning the "Show Context Menu New" action: alt text

results matching ""

    No results matching ""