Using Real Java Script in BTT

NOTE: If you are using the floating webview action in BTT have a look here instead: Floating Webview JavaScript


This feature is new in BetterTouchTool version 3.333. I think it is the most powerful and easiest way to script BetterTouchtool.

It's basically just modern Java Script (so you can use async await and the like) however it has a few important additions:

  • It can call any Apple Script - and get the result
  • It can call any Shell Script - and get the result.
  • It can trigger all functions available in BetterTouchTool's scripting interface.

By combining these three you can automate almost any task on your Mac.

mcc


1.) Running Apple Scripts

To run a Apple Script from within the Java Script code, use the runAppleScript(scriptCode) function. The function takes a string that defines the Apple Script, and returns a promise which resolves to the result value.

I'm always using it with async await, but you can also use classic Promise syntax.

Example: Run Apple Script from within Java Script

// I always put my code into a self executing async function, because top level await is not allowed in JavaScript.
(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 ()
})();

2.) Running Shell Scripts

Example: Run Shell Script from within Java Script

// I always put my code into a self executing async function, because top level await is not allowed in JavaScript.
(async () => {

// put the shell script into a string (single backticks are great for multiline strings)
let shellScript = `say hello world`;


let shellScriptWrapper = {
    script: shellScript, // mandatory
    launchPath: '/bin/bash', //optional - default is /bin/bash
    parameters: '-c', // optional - default is -c. If you use multiple parameters please separate them by ;; e.g. -c;;date
    environmentVariables: '' //optional e.g. VAR1=/test/;VAR2=/test2/;
};

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

// 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 ()
})();

3.) Running Shortcuts From Apple's Shortcuts App:

You can provide the name of the shortcut and some input (optional).

(async () => {
  let shortcut = "some name";
  let input = "some input";
  let result = await runAppleShortcut({name: shortcut, input: input});
  returnToBTT(result);
})();

If you want to provide multiple files as input, please separate them with two semicolons. For example

(async () => {
  runAppleShortcut({name: 'multi-file-test', input: '~/Downloads/test1.png;;~/Downloads/test2.png'});
})();

4.) Using the JavaScript to call BTT scripting functions

All BetterTouchTool scripting functions can be accessed from Java Script.

Available BetterTouchTool Scripting Interfaces

The available scripting functions are:

  • trigger_named
  • update_touch_bar_widget
  • update_stream_deck_widget
  • trigger_action
  • execute_assigned_actions_for_trigger
  • refresh_widget
  • get_trigger
  • get_triggers
  • update_trigger (to create or if exists update a trigger)
  • add_new_trigger
  • delete_trigger
  • delete_triggers
  • trigger_named
  • trigger_named_async_without_response
  • cancel_delayed_named_trigger_execution
  • get_dock_badge_for
  • get_active_touch_bar_group
  • is_true_tone_enabled
  • get_location
  • set_persistent_string_variable
  • set_string_variable
  • set_persistent_number_variable
  • set_number_variable
  • get_number_variable
  • get_string_variable
  • export_preset
  • display_notification
  • paste_text
  • set_clipboard_content
  • get-selected-text

Floating Menus:

  • update_menu_item
  • get_menu_item_value
  • set_menu_item_value
  • webview_menu_item_load_html_url_js

Example script function calls:

trigger_named

This method will trigger the specified named trigger (which can be configured in the "Other" tab in BetterTouchTool.)

Example

(async ()=> {
let result = await trigger_named({trigger_name: 'Action5', wait_for_reply: true});
// Currently only the Apple Script and Shell Script actions return results, if you don't care about the result, setting wait_for_reply to false can make execution a bit faster (default is true)
returnToBTT(result);
})();

trigger_named_async_without_response

This method will trigger the specified named trigger (which can be configured in the "Other" tab in BetterTouchTool.).

Optional parameter: delay This lets you set a delay before the named trigger is executed (in seconds). While the trigger has not been executed you can cancel the execution by calling the cancel_delayed_named_trigger_execution function

Example

(async ()=> {
  trigger_named_async_without_response({trigger_name: 'Action5',  wait_for_reply: false});
// Currently only the Apple Script and Shell Script actions return results.
returnToBTT("done");
})();

cancel_delayed_named_trigger_execution

This method will cancel the execution of a delayed named trigger (see previous function)

Example

(async ()=> {
  cancel_delayed_named_trigger_execution({trigger_name: 'Action5'});
// Currently only the Apple Script and Shell Script actions return results.
returnToBTT("done");
})();

update_touch_bar_widget

This method will temporarily update the contents of a Touch Bar Script Widget (identified by its uuid). You can provide a new text to show, a new icon and a new background color.

For the icon you can either provide it directly using the icon_data parameter (must be base64 encoded) or you can provide a file path (via the icon_path parameter) that points to the new icon.

You can get the uuid by right-clicking any script widget in BTT.

Example:

(async ()=> {

let widgetConfig = {
    text: "hi there!",
    icon_path: "/Users/andi/Desktop/test.png",
    background_color: "200,100,100,255"    
};

  update_touch_bar_widget({uuid: '9990CE09-9820-4D67-9C52-8BABAB263056', json: widgetConfig});

returnToBTT('done');

})();

update_stream_deck_widget

This method will temporarily update the contents of a Stream Deck Script Widget (identified by its uuid). The changes will not be persisted. You can provide a new text to show on the button and you can update any other of the button's properties. To see what properties are possible right-click an existing & configured Strem Deck button in BTT and choose "copy". When pasting this copied button into some text editor you'll see the possible values in the "BTTTriggerConfig" section.

Example:

(async ()=> {

let widgetConfig = {
    text: "some new title!",
    BTTStreamDeckBackgroundColor: "200,100,100,255",
  BTTStreamDeckSFSymbolName : "bitcoinsign.circle.fill",

};

  update_stream_deck_widget({uuid: '9990CE09-9820-4D67-9C52-8BABAB263056', json: JSON.stringify(widgetConfig)});

returnToBTT('done');

})();

trigger_action

This method will trigger any of BetterTouchTool's predefined actions (or any combination of them).

You need to provide a JSON description of the action you want to trigger as a string. The easiest way to get such a JSON description is to right-click the trigger you have configured in BetterTouchTool and choose "Copy JSON". This will copy the complete JSON (including the configuration for the trigger itself), but this action will ignore anything that's not needed. (or you can delete the not needed parts)

Example:

(async ()=> {

let actionDefinition = {
  "BTTPredefinedActionType" : 153, 
  "BTTPredefinedActionName" : "Move Mouse To Position", 
  "BTTMoveMouseToPosition" : "{100, 100}", 
  "BTTMoveMouseRelative" : "6"
};


let result = await trigger_action({json: JSON.stringify(actionDefinition), wait_for_reply: false});

returnToBTT(result);

})();

execute_assigned_actions_for_trigger

This method execute all the assigned actions for a given trigger (i.e. gesture, shortcut, drawing etc.) identified by its uuid.

You can get the uuid by right-clicking any configured trigger in BetterTouchTool.

Example

(async ()=> {

    let result = await execute_assigned_actions_for_trigger({uuid: '2F34005D-4537-464D-94E9-A7F42DA39DF1'});
    // Currently only the Apple Script and Shell Script actions return results.
    returnToBTT(result);
})();

refresh_widget

This method will execute all scripts assigned to a script widget and update its contents accordingly.

The widget is identified by its uuid, which you can get by right-clicking the widget in BetterTouchTool.

Example

(async ()=> {

  refresh_widget({uuid: '2F34005D-4537-464D-94E9-A7F42DA39DF1'});

returnToBTT('done');

})();

update_trigger

This method will create or update the configuration of any specified trigger (i.e. gestures, shortcuts, touchbar items etc.).

You need to provide the uuid of the trigger you want to update (get by right-clicking it in BTT) and a JSON object defining the updates. To know how the JSON object should look like, right-click the trigger in BTT and choose "Copy JSON".

Optional Parameter: trigger_parent_uuid (if you want to add the trigger to a group)

Example:

Hint: don't forget to use JSON.stringify() before passing the updateDefinition object.

(async ()=> {

var updateDefinition = JSON.stringify(
  {
    "BTTTriggerConfig": {
      "BTTTouchBarButtonName" : "New Name",
      "BTTTouchBarItemIconHeight": 25
    }
  }
);

  update_trigger({uuid: 'ED631459-115C-4D8C-940A-D428E4EAE086', json: updateDefinition});

returnToBTT('done');

})();

get_trigger

This allows you to retrieve the json representation of any trigger (e.g. gesture, Touch Bar button, keyboard shortcut etc.) identified by the given UUID.

You can get the UUID by right-clicking any trigger in BTT.

(async ()=> {

let result = await get_trigger({uuid:'123e4567-e89b-12d3-a456-426655440000'})
returnToBTT(result);
})();

get_triggers

This allows you to retrieve the JSON description of multiple triggers in BTT (e.g. Touch Bar item, Gesture, Keyboard Shortcut etc.) based on a few properties.

You can get the properties of a specific trigger by selecting it in BTT and copy pasting it to some text editor.

The get_triggers() function supports these parameters (all optional):

  • trigger_type (e.g. BTTTriggerTypeMagicMouse)
  • trigger_id (e.g. 643 for named triggers)
  • trigger_parent_uuid (if you want to get the items of a folder)
  • trigger_uuid (to get a specific trigger)
  • trigger_app_bundle_identifier (to get triggers assigned to a specific app)
(async ()=> {

  let allNamedTriggersJSONString = await get_triggers({trigger_id: 643});
  let allTriggersJSONArray = JSON.parse(allNamedTriggersJSONString);

  let allNamedTriggerNames = [];
  for(let trigger of allTriggersJSONArray) {
    allNamedTriggerNames.push(trigger["BTTTriggerName"]);
  }

  returnToBTT(allNamedTriggerNames);
})();

add_new_trigger

This method will add a new trigger to BTT (i.e. gestures, shortcuts, touchbar items etc.).

You need to provide a JSON object defining the new trigger. To know how the JSON object should look like, right-click any existing trigger in BTT and choose "Copy JSON".

Optional Parameter: trigger_parent_uuid (if you want to add the trigger to a group)

Example


(async ()=> {
var newTriggerDefinition = {
  "BTTTriggerClass" : "BTTTriggerTypeKeyboardShortcut",
  "BTTPredefinedActionType" : 5,
  "BTTPredefinedActionName" : "Mission Control",
  "BTTAdditionalConfiguration" : "1179648",
  "BTTTriggerOnDown" : 1,
  "BTTEnabled" : 1,
  "BTTShortcutKeyCode" : 2,
  "BTTShortcutModifierKeys" : 1179648,
  "BTTOrder" : 3
}

  add_new_trigger({json: JSON.stringify(newTriggerDefinition)});

returnToBTT('done');

})();

delete_trigger

This method will delete a trigger from BetterTouchTool. You need to provide the uuid of the trigger you want to delete (get by right-clicking it in BTT).

Example

(async ()=> {
 let result = await add_new_trigger({uuid: '2F34005D-4537-464D-94E9-A7F42DA39DF1'});
returnToBTT(result);
})();

get_clipboard_content

Gives you the current text content of the clipboard.

Example

(async ()=> {

let result = get_clipboard_content({});
returnToBTT(result);

})();

set_persistent_string_variable

This allows you to set a variable to a given string that persists over BTT relaunches.

Java Script for Automation Example:

(async ()=> {

let result = await set_persistent_string_variable({variable_name: 'test', to: "this is a test value"});

returnToBTT(result);

})();

set_string_variable

This allows you to set a variable to a given string that persists over BTT relaunches.

(async ()=> {

let result = await set_string_variable({variable_name: 'test', to: "this is a test value"});

returnToBTT(result);

})();

set_persistent_number_variable

This allows you to set a variable to a given string that persists over BTT relaunches.

(async ()=> {

let result = await set_persistent_number_variable({variable_name: 'test', to: 12345});

returnToBTT(result);

})();

set_number_variable

This allows you to set a variable to a given string that persists over BTT relaunches.

(async ()=> {

let result = await set_number_variable({variable_name:'OutputVolume' to: 0.5});

returnToBTT(result);
})();

get_number_variable

This allows you to retrieve the contents of a number variable with the given name

(async ()=> {

let result = await get_number_variable({variable_name:'OutputVolume'})
returnToBTT(result);

})();

get_string_variable

This allows you to retrieve the contents of a string variable with the given name

(async ()=> {

let result = await get_string_variable({variable_name:'BTTActiveAppBundleIdentifier'})
returnToBTT(result);
})();

export_preset

This allows you to export a specific preset

(async ()=> {

let result = await export_preset({name:'the_preset_name', compress: 1, includeSettings: 0, outputPath: '~/Downloads', comment: 'this is a great preset', link: 'https://someoptionallink', minimumVersion: '4.123'})
returnToBTT(result);
})();

display_notification

This shows a notification

(async ()=> {

let result = await display_notification({title:'notification title', subTitle: 'some subttitle', soundName: 'frog', imagePath: '~/Downloads/image.png})
returnToBTT(result);
})();

paste_text

This pastes some text

Parameters:

text: The text to paste. insert_by_pasting: If set to true BTT will use cmd+v to paste the text. Otherwise it will actually try to type it (only possible for standard formats) move_cursor_left_by_x_after_pasting: If specified BTT will move the cursor by the given amount to the left. format: Optional. The format the text will be interpreted as when pasting (e.g. if you want to paste a table, you can use set the string to

...
and specify the format NSPasteboardTypeHTML)

Default formats are (more are possible):

  • NSPasteboardTypeString
  • NSPasteboardTypeTIFF
  • NSPasteboardTypePNG
  • NSPasteboardTypeRTF
  • NSPasteboardTypeRTFD
  • NSPasteboardTypeHTML
  • NSPasteboardTypeTabularText
  • NSPasteboardTypeFont
  • NSPasteboardTypeRuler
  • NSPasteboardTypeColor
  • NSPasteboardTypeSound
  • NSPasteboardTypeMultipleTextSelection
  • NSPasteboardTypeTextFinderOptions
  • NSPasteboardTypeURL
  • NSPasteboardTypeFileURL
(async ()=> {

let result = await paste_text({text:'<strong>Hello world</strong>', format: 'NSPasteboardTypeHTML'})
returnToBTT(result);
})();

set_clipboard_content

Changes the content of the clipboard

Parameters:

content: The content to put in your clipboard. format: Optional. The format the content will be interpreted as when pasting (e.g. if you want to paste a table, you can use set the string to

...
and specify the format NSPasteboardTypeHTML)

Default formats are (more are possible):

  • NSPasteboardTypeString
  • NSPasteboardTypeTIFF
  • NSPasteboardTypePNG
  • NSPasteboardTypeRTF
  • NSPasteboardTypeRTFD
  • NSPasteboardTypeHTML
  • NSPasteboardTypeTabularText
  • NSPasteboardTypeFont
  • NSPasteboardTypeRuler
  • NSPasteboardTypeColor
  • NSPasteboardTypeSound
  • NSPasteboardTypeMultipleTextSelection
  • NSPasteboardTypeTextFinderOptions
  • NSPasteboardTypeURL
  • NSPasteboardTypeFileURL
(async ()=> {

let result = await set_clipboard_content({content:'<strong>Hello world</strong>', format: 'NSPasteboardTypeHTML'})
returnToBTT(result);
})();

get-selected-text

To access the currently selected text, make use of the selected_text variable like this:

(async ()=> {
let selectedText = await get_string_variable({variable_name:'selected_text'})
returnToBTT(selectedText);
})();

results matching ""

    No results matching ""