Hi @sazun, thanks for sharing the preset.
That's interesting. When I first shared with you the original script, I remember that I was only able to get the script to work using BTTEnabled2
and not BTTEnabled
. Surprisingly, when I try to use the script now, it indeed only works with BTTEnabled
and not BTTEnabled2
. Why is this the case? I do not know. What is the difference between them? I also do not know. The only reference I can find is from a comment from @Andreas_Hegenberg from 2018 where he states that BTTEnabled
and BTTEnabled2
are there for "legacy" reasons. Provide a list of valid properties for JSON representation of BTT actions - #6 by Andreas_Hegenberg
I also experience the unexpected behavior of the folders from the "TextEdit" app group being created/duplicated into the "For All Apps" group when triggering when "TextEdit" is active.
At first, I thought the cause of this might be due to your current implementation which has a lot of duplicate code which may be interfering with with itself, causing the observed unexpected behavior. Specifically, your current implementation involves four separate Run Real JavaScript Actions and two separate cmd + T Triggers.. Two of the four Run Real JavaScript Actions are defined to run sequentially, one after another, and are assigned to the cmd + T Trigger in the "For All Apps" group. The other two Run Real JavaScript actions also are defined to run sequentially, one after another, and are assigned to a different cmd + T Trigger defined in the "TextEdit" app group.
I decided to consolidate all four of these "Run Real JavaScript" Actions into a single script to see if this would resolve the unexpected behavior. Additionally, this updated and consolidated script also displays a notification to help understand if the "folder All" folders enabled state got toggled or if the "TextEdit Folders" folders enabled state got toggled. It also communicates if they got toggled ENABLED (
) or DISABLED (
).
@sazun Migration notes:
- Delete your "cmd T" Trigger in the "TextEdit" app group (this includes the two Run Real JavaScript" Actions assigned to it).
- For the "cmd T" Trigger in the "For All Apps" group, replace the two "Run Real JavaScript" Actions with a single "Run Real JavaScript" Action. The script for this Action is below:
/*
* Toggle Script for BetterTouchTool Folders
*
* Purpose:
* - Reads the current "BTTEnabled" state from each folder's configuration.
* - Toggles the state: if enabled (1) it becomes disabled (0), and vice versa.
* - Displays a notification summarizing the state transition for each folder,
* using emojis (❌ for OFF and ✅ for ON).
*
* Instructions:
* - Update the folderUUIDs object below with your folder names and UUIDs.
* - Map this script to a keyboard shortcut in BetterTouchTool.
*/
(async () => {
// Define an object with arrays of folder objects.
// Update the folder names and UUIDs below to match your configuration.
let folderUUIDs = {
folder_All: [
{ name: "folder 1 All", uuid: "6547CAE3-9405-450E-A31C-71498E9AE6EC" }, // folder 1 All
{ name: "folder 2 All", uuid: "E2330D40-A4EB-4968-AB0E-1690588CE146" } // folder 2 All
],
folder_TextEdit: [
{ name: "folder 1 TextEdit", uuid: "1543AB41-97D1-4F4C-95EC-B473EA4491FA" }, // folder 1 TextEdit
{ name: "folder 2 TextEdit", uuid: "0F67E44C-EB89-4B1D-8958-EBFC5B087B16" } // folder 2 TextEdit
]
};
// Retrieve the active app name from BetterTouchTool variables.
let active_app_name = await get_string_variable({
variable_name: "active_app_name",
});
// Choose the folder set based on the active app.
let folderKey = active_app_name === "TextEdit" ? "folder_TextEdit" : "folder_All";
// Get the array of folder objects for iteration.
let folderArray = folderUUIDs[folderKey];
let updateResponses = [];
let toggleMessages = []; // Collect messages to display in the notification.
// Iterate over each folder object.
for (let folder of folderArray) {
try {
let folderUUID = folder.uuid;
let folderName = folder.name;
// Retrieve the folder configuration using its UUID.
let folder_config = await get_trigger({ uuid: folderUUID });
// Parse the JSON configuration into an object.
let folder_config_obj = JSON.parse(folder_config);
// Get 'BTTEnabled' to determine the current state (enabled = 1, disabled = 0).
let BTTEnabled = folder_config_obj.BTTEnabled;
// Toggle the state: if enabled then disable; if disabled then enable.
let newState = BTTEnabled === 1 ? 0 : 1;
// Determine the previous and new states using emojis.
let previousEmoji = BTTEnabled === 1 ? "✅" : "❌";
let newEmoji = newState === 1 ? "✅" : "❌";
// Add a message for this folder showing the state transition.
toggleMessages.push(`${folderName}: ${previousEmoji} → ${newEmoji}`);
// Update the folder configuration with the new state.
folder_config_obj.BTTEnabled = newState;
// Convert the updated configuration object back into a JSON string.
let updateDefinition = JSON.stringify(folder_config_obj);
// Update the trigger with the new configuration.
let updateResponse = await update_trigger({
uuid: folderUUID,
json: updateDefinition,
});
// Store the update response for debugging purposes.
updateResponses.push({ uuid: folderUUID, response: updateResponse });
} catch (error) {
// In case of error, add an error message for this folder.
updateResponses.push({ uuid: folder.uuid, error: error.message });
}
}
// Create and display a notification summarizing the toggle actions.
let notificationMessage = toggleMessages.join("; ");
await display_notification({
title: folderKey, // The title shows the folder set being updated.
subTitle: notificationMessage
});
// Return the array of update responses to BetterTouchTool.
returnToBTT(updateResponses);
})();
Unfortunately, even with this updated script, I still observe the unexpected behavior of the folders in the "TextEdit" group being duplicated into the "For All Apps" group when triggering when TextEdit is the active app.
Lastly, I also created another script to help debug this situation. This script simply displays a notification of the current BTTEnabled
state for the "folder All" folders or the "folder TextEdit" folders.
/*
* State Display Script for BetterTouchTool Folders
*
* Purpose:
* - Reads the current "BTTEnabled" state from each folder's configuration.
* - Displays a notification showing each folder's name along with an emoji representing its state:
* ✅ means the folder is enabled.
* ❌ means the folder is disabled.
*
* Instructions:
* - Update the folderUUIDs object below with your folder names and UUIDs if needed.
* - Use this script for debugging to verify the current state without toggling.
* - Map this script to a different keyboard shortcut in BetterTouchTool.
*/
(async () => {
// Define an object with arrays of folder objects.
// Update the folder names and UUIDs below as necessary.
let folderUUIDs = {
folder_All: [
{ name: "folder 1 All", uuid: "6547CAE3-9405-450E-A31C-71498E9AE6EC" }, // folder 1 All
{ name: "folder 2 All", uuid: "E2330D40-A4EB-4968-AB0E-1690588CE146" } // folder 2 All
],
folder_TextEdit: [
{ name: "folder 1 TextEdit", uuid: "1543AB41-97D1-4F4C-95EC-B473EA4491FA" }, // folder 1 TextEdit
{ name: "folder 2 TextEdit", uuid: "0F67E44C-EB89-4B1D-8958-EBFC5B087B16" } // folder 2 TextEdit
]
};
// Retrieve the active app name from BetterTouchTool variables.
let active_app_name = await get_string_variable({
variable_name: "active_app_name",
});
// Choose the folder set based on the active app.
let folderKey = active_app_name === "TextEdit" ? "folder_TextEdit" : "folder_All";
// Get the array of folder objects for iteration.
let folderArray = folderUUIDs[folderKey];
let stateMessages = [];
// Iterate over each folder object.
for (let folder of folderArray) {
try {
let folderUUID = folder.uuid;
let folderName = folder.name;
// Retrieve the folder configuration using its UUID.
let folder_config = await get_trigger({ uuid: folderUUID });
// Parse the JSON configuration into an object.
let folder_config_obj = JSON.parse(folder_config);
// Get 'BTTEnabled' to determine if the folder is enabled (1) or disabled (0).
let BTTEnabled = folder_config_obj.BTTEnabled;
// Determine the emoji representing the current state.
let stateEmoji = BTTEnabled === 1 ? "✅" : "❌";
// Add a message for this folder.
stateMessages.push(`${folderName}: ${stateEmoji}`);
} catch (error) {
// In case of error, record an error message for this folder.
stateMessages.push(`${folder.name}: Error - ${error.message}`);
}
}
// Create and display a notification summarizing the current states.
let notificationMessage = stateMessages.join("; ");
await display_notification({
title: folderKey, // The title reflects the folder set being checked.
subTitle: notificationMessage
});
// Return the notification message to BetterTouchTool.
returnToBTT(notificationMessage);
})();
@sazun Please try out these updated scripts and tell me if you observe the same behavior as me.
Also, @Andreas_Hegenberg your expertise and help would be really helpful here! 
EDIT #1:
I forgot to mention that apart from the unexpected behavior of the "Folder TextEdit" folders being duplicated into the "For All Apps" group, the updated script I provided actually works as intended.
EDIT #2:
Also, please note that the enabled/disabled UI in the BTT GUI doesn't automatically update when the script is triggered. To see the updated UI, you have to force a refresh by navigating to another Trigger category tab or closing and reopening the BTT configuration GUI.