SaveToFile action

Hallo @Andreas_Hegenberg

I am looking for a SaveToFile / ReadFromFile action to save&read a string variable to/from a text file ( maybe here .../Library/Application Support/BetterTouchTool/ )

I got a experimental Java Script / HTML CodeMirror-Editor running in a BTT WebView, which reads/writes currently to a BTT variable (called "FlipText").
looks like this:

if you want to try the Editor menu make sure to create a string variable "FlipText"* first) :

[
  {
    "BTTActionCategory" : 0,
    "BTTLastUpdatedAt" : 1748466251.301111,
    "BTTTriggerType" : 767,
    "BTTTriggerTypeDescriptionReadOnly" : "Floating Menu",
    "BTTTriggerClass" : "BTTTriggerTypeFloatingMenu",
    "BTTUUID" : "00960D90-33F1-4DD5-8C29-1B50FDDE8E35",
    "BTTPredefinedActionType" : 366,
    "BTTPredefinedActionName" : "Empty Placeholder",
    "BTTAdditionalConfiguration" : "Floating Menu: Text Editor",
    "BTTEnabled" : 1,
    "BTTOrder" : 1,
    "BTTTriggerName" : "Floating Menu: Text Editor",
    "BTTMenuItems" : [
      {
        "BTTActionCategory" : 0,
        "BTTLastUpdatedAt" : 1748460285.9572558,
        "BTTTriggerType" : 773,
        "BTTTriggerTypeDescription" : "Standard Item",
        "BTTTriggerParentUUID" : "00960D90-33F1-4DD5-8C29-1B50FDDE8E35",
        "BTTTriggerClass" : "BTTTriggerTypeFloatingMenu",
        "BTTUUID" : "4D933970-B244-4170-9EDD-0071ACFA29BE",
        "BTTPredefinedActionType" : 366,
        "BTTPredefinedActionName" : "Empty Placeholder",
        "BTTAdditionalConfiguration" : "Menu Item: Back",
        "BTTEnabled" : 1,
        "BTTOrder" : 2,
        "BTTTriggerName" : "Menu Item: Back",
        "BTTMenuItemActions" : [
          {
            "BTTActionCategory" : 0,
            "BTTLastUpdatedAt" : 1748435381.843569,
            "BTTTriggerParentUUID" : "4D933970-B244-4170-9EDD-0071ACFA29BE",
            "BTTTriggerClass" : "BTTTriggerTypeFloatingMenu",
            "BTTUUID" : "14DC3657-66EC-461D-A49A-89710376CA3C",
            "BTTPredefinedActionType" : 387,
            "BTTPredefinedActionName" : "Hide Floating Menu",
            "BTTAdditionalActionData" : {
              "BTTMenuActionMenuID" : "Text Editor"
            },
            "BTTEnabled" : 1,
            "BTTOrder" : 1,
            "BTTMenuConfig" : {
              "BTTMenuElementIdentifier" : "no-name-F6B038A"
            },
            "BTTMenuAvailability" : 0,
            "BTTMenuName" : "A8E4B210-4B5A-4732-BEC6-69FA4C800693"
          }
        ],
        "BTTMenuConfig" : {
          "BTTMenuCategoryZIndex" : 0,
          "BTTMenuItemScriptActive" : 1,
          "BTTMenuItemBorderColorDark" : "255.000, 255.000, 255.000, 255.000",
          "BTTMenuItemIconColor1" : "255.000, 255.000, 255.000, 255.000",
          "BTTMenuUseStyleForSubmenu" : 1,
          "BTTMenuItemBackgroundColor" : "66.431942, 66.433720, 66.432762, 255.000000",
          "BTTMenuCategoryItemVisibility" : 0,
          "BTTMenuItemBackgroundType" : 0,
          "BTTMenuItemMaxHeight" : 25,
          "BTTMenuCategoryMenuVisibility" : 0,
          "BTTMenuHoverEndAnimationDuration" : 0.14999999999999999,
          "BTTMenuItemMaxWidth" : 1395,
          "BTTMenuCategoryItemIcon" : 0,
          "BTTMenuItemBorderWidth" : 0,
          "BTTMenuCategoryShadow" : 0,
          "BTTMenuCategoryItemBehavior" : 0,
          "BTTMenuCategoryItemSpacing" : 0,
          "BTTMenuItemCornerRadius" : 5,
          "BTTMenuCategoryModifiers" : 0,
          "BTTMenuItemBorderColorHover" : "192.288, 192.292, 192.290, 255.000",
          "BTTMenuCategoryOnlyShowIf" : 0,
          "BTTLastChangeUUID" : "0134F602-CFAA-46EF-9EAC-30E4E75CACFE",
          "BTTMenuCategoryMenuOpacity" : 0,
          "BTTMenuItemBorderColor" : "94.492, 94.494, 94.493, 255.000",
          "BTTMenuCategorySize" : 0,
          "BTTMenuItemMinHeight" : 25,
          "BTTMenuItemBackgroundColorDark" : "108.442, 96.000, 190.435, 166.991",
          "BTTMenuItemVisibleWhileActive" : 1,
          "BTTMenuElementIdentifier" : "Back",
          "BTTMenuItemVisibleWhileInactive" : 1,
          "BTTMenuItemMinWidth" : 1395,
          "BTTMenuItemBackgroundTypeDark" : 4,
          "BTTMenuAttributedText" : "{\\rtf1\\ansi\\ansicpg1252\\cocoartf2761\n\\cocoatextscaling0\\cocoaplatform0{\\fonttbl}\n{\\colortbl;\\red255\\green255\\blue255;}\n{\\*\\expandedcolortbl;;}\n}",
          "BTTMenuCategorySpacing" : 0,
          "BTTMenuItemBorderColorHoverDark" : "255.000, 255.000, 255.000, 255.000",
          "BTTMenuAppearanceStyle" : 1,
          "BTTMenuItemBackgroundColorHover" : "255.000000, 255.000000, 255.000000, 255.000000",
          "BTTMenuAlwaysUseLightMode" : 1,
          "BTTMenuCategoryBackground" : 0,
          "BTTMenuCategoryItemSizing" : 0,
          "BTTMenuItemSelectedTab" : 0,
          "BTTMenuCategoryResizeOnHover" : 0,
          "BTTMenuAttributedTextDark" : "{\\rtf1\\ansi\\ansicpg1252\\cocoartf2761\n\\cocoatextscaling0\\cocoaplatform0{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n{\\colortbl;\\red255\\green255\\blue255;}\n{\\*\\expandedcolortbl;;}\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\\partightenfactor0\n\n\\f0\\fs24 \\cf0 Multi Selection Dummy Text - You can change the formatting for multiple items at the same time, but not the text.}",
          "BTTMenuCategoryPosition" : 0,
          "BTTMenuItemBackgroundColorHoverDark" : "90.000, 90.000, 180.000, 166.991",
          "BTTMenuCategoryBorder" : 0,
          "BTTMenuHoverStartAnimationDuration" : 0.14999999999999999
        },
        "BTTMenuAvailability" : 0,
        "BTTMenuName" : "Back",
        "BTTGestureNotes" : "Standard Item"
      },
      {
        "BTTActionCategory" : 0,
        "BTTLastUpdatedAt" : 1748466251.301125,
        "BTTTriggerType" : 778,
        "BTTTriggerTypeDescriptionReadOnly" : "Web View \/ HTML Item",
        "BTTTriggerTypeDescription" : "Standard Item",
        "BTTTriggerParentUUID" : "00960D90-33F1-4DD5-8C29-1B50FDDE8E35",
        "BTTTriggerClass" : "BTTTriggerTypeFloatingMenu",
        "BTTUUID" : "0FA23ED0-B3FD-4981-A030-12EAAC383E18",
        "BTTPredefinedActionType" : 366,
        "BTTPredefinedActionName" : "Empty Placeholder",
        "BTTAdditionalConfiguration" : "Webview Menu Item: Text Editor Webview",
        "BTTEnabled" : 1,
        "BTTOrder" : 1,
        "BTTTriggerName" : "Webview Menu Item: Editor Webview",
        "BTTMenuConfig" : {
          "BTTMenuItemBorderColorHoverDark" : "255.000, 255.000, 255.000, 255.000",
          "BTTMenuItemVisibleWhileActive" : 1,
          "BTTMenuAttributedTextDark" : "{\\rtf1\\ansi\\ansicpg1252\\cocoartf2761\n\\cocoatextscaling0\\cocoaplatform0{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n{\\colortbl;\\red255\\green255\\blue255;}\n{\\*\\expandedcolortbl;;}\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\\partightenfactor0\n\n\\f0\\fs24 \\cf0 Multi Selection Dummy Text - You can change the formatting for multiple items at the same time, but not the text.}",
          "BTTMenuItemBackgroundTypeDark" : 4,
          "BTTMenuItemBackgroundColor" : "33.000000, 33.000000, 33.000000, 255.000000",
          "BTTMenuCategoryItemVisibility" : 0,
          "BTTMenuSelectedTab" : 0,
          "BTTMenuCategoryResizeOnHover" : 0,
          "BTTMenuItemBorderWidth" : 1,
          "BTTMenuCategoryOnlyShowIf" : 0,
          "BTTMenuCategoryModifiers" : 0,
          "BTTMenuItemBackgroundColorDark" : "108.442, 96.000, 190.435, 166.991",
          "BTTMenuCategoryItemPositioning" : 0,
          "BTTMenuItemCornerRadius" : 5,
          "BTTMenuFrameWidth" : 500,
          "BTTMenuItemMinHeight" : 850,
          "BTTMenuFrameHeight" : 750,
          "BTTMenuCategoryShadow" : 0,
          "BTTMenuItemBorderColor" : "192.000000, 192.000000, 192.000000, 255.000000",
          "BTTMenuCategoryBackground" : 0,
          "BTTMenuCategoryZIndex" : 0,
          "BTTMenuItemPaddingTop" : 1,
          "BTTMenuCategoryItemBehavior" : 0,
          "BTTMenuItemText" : "<!DOCTYPE html>\n<html lang=\"de\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>CodeMirror Editor<\/title>\n  <!-- CodeMirror CSS -->\n  <link rel=\"stylesheet\" href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/codemirror\/5.65.13\/codemirror.min.css\">\n  <link rel=\"stylesheet\" href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/codemirror\/5.65.13\/theme\/material-darker.min.css\">\n  <link rel=\"stylesheet\" href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/codemirror\/5.65.13\/addon\/hint\/show-hint.min.css\">\n  <link rel=\"stylesheet\" href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/codemirror\/5.65.13\/addon\/scroll\/simplescrollbars.min.css\">\n\n  <style>\n    html, body {\n      margin: 0;\n      padding: 0;\n      background: #212121;\n      color: #fff;\n      font-family: monospace;\n      font-size: 16px;\n    }\n\n    #editor {\n      width: 1300px;\n      height: 730px;\n      margin: 20px auto;\n      padding: 10px;\n      border: 1px solid #444;\n    }\n\n    .CodeMirror {\n      height: 100%;\n      background: #111;\n      color: #fff;\n    }\n    \n    .CodeMirror-selected {\n      background: #3333ff !important;\n    }\n\n    #controls {\n      display: flex;\n      justify-content: center;\n      gap: 10px;\n      margin: 10px auto;\n      flex-wrap: wrap;\n    }\n\n    button, select {\n      padding: 10px 20px;\n      background: #333;\n      color: #fff;\n      border: 1px solid #666;\n      border-radius: 8px;\n      cursor: pointer;\n    }\n\n    button:hover, select:hover {\n      background: #444;\n    }\n\n    #helpModal, #statusModal {\n      display: none;\n      opacity: 0;\n      position: fixed;\n      top: 15%;\n      left: 50%;\n      transform: translateX(-50%);\n      background: #111;\n      color: #fff;\n      padding: 20px;\n      border: 1px solid #555;\n      z-index: 999;\n      width: 300px;\n      height: 240px;\n      border-radius: 12px;\n      \/* 14px rechts, 17px unten, 25px Unschärfe *\/     \n      box-shadow: 14px 17px 25px rgba(0, 0, 0, 0.7);\n      flex-direction: column;\n      justify-content: space-between;\n      text-align: center;\n    }\n\n    #helpModal.show,\n    #statusModal.show {\n      display: flex;\n      opacity: 1;\n      transition: opacity 1s ease;\n    }\n\n    #helpModal.fade-out,\n    #statusModal.fade-out {\n      opacity: 0;\n    }\n\n    .modal-button {\n      margin-top: auto;\n      align-self: center;\n      padding: 8px 16px;\n      border-radius: 6px;\n      background: #333;\n      color: #fff;\n      border: 1px solid #666;\n      cursor: pointer;\n    }\n\n    .modal-button:hover {\n      background: #444;\n    }\n  <\/style>\n<\/head>\n<body>\n\n<div id=\"editor\"><\/div>\n\n<div id=\"controls\">\n  <button onclick=\"BTTSave()\">💾 Speichern<\/button>\n  <button onclick=\"editor.undo()\">↺ Undo<\/button>\n  <button onclick=\"editor.redo()\">↻ Redo<\/button>\n\n  <select id=\"modeSelector\" onchange=\"changeMode(this.value)\">\n    <option value=\"javascript\">JavaScript<\/option>\n    <option value=\"htmlmixed\">HTML<\/option>\n    <option value=\"null\">Plain text<\/option>\n  <\/select>\n\n  <button onclick=\"showHelp()\">❔ Hilfe<\/button>\n<\/div>\n\n<div id=\"helpModal\" tabindex=\"0\">\n  <div>\n    <strong>Tastenkürzel:<\/strong><br><br>\n    ⌘+S \/ Ctrl+S – Speichern<br><br>\n    Ctrl+Space – Auto-Vervollständigung<br><br>\n    ↺ \/ ↻ – Rückgängig\/Wiederholen<br>\n  <\/div>\n  <button class=\"modal-button\" onclick=\"hideHelp()\">Schließen<\/button>\n<\/div>\n\n<div id=\"statusModal\">\n  <div id=\"statusMessage\">Status<\/div>\n  <button class=\"modal-button\" onclick=\"hideStatus()\">OK<\/button>\n<\/div>\n\n<!-- CodeMirror Scripts -->\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/codemirror\/5.65.13\/codemirror.min.js\"><\/script>\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/codemirror\/5.65.13\/mode\/javascript\/javascript.min.js\"><\/script>\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/codemirror\/5.65.13\/mode\/htmlmixed\/htmlmixed.min.js\"><\/script>\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/codemirror\/5.65.13\/mode\/xml\/xml.min.js\"><\/script>\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/codemirror\/5.65.13\/mode\/css\/css.min.js\"><\/script>\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/codemirror\/5.65.13\/addon\/edit\/matchbrackets.min.js\"><\/script>\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/codemirror\/5.65.13\/addon\/edit\/closebrackets.min.js\"><\/script>\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/codemirror\/5.65.13\/addon\/hint\/show-hint.min.js\"><\/script>\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/codemirror\/5.65.13\/addon\/hint\/javascript-hint.min.js\"><\/script>\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/codemirror\/5.65.13\/addon\/hint\/html-hint.min.js\"><\/script>\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/codemirror\/5.65.13\/addon\/hint\/css-hint.min.js\"><\/script>\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/codemirror\/5.65.13\/addon\/scroll\/simplescrollbars.min.js\"><\/script>\n\n<script>\n  let editor = null;\n\n  async function BTTInitialize() {\n    const text = await get_string_variable({ variableName: \"FlipText\" }) || \"\";\n\n    editor = CodeMirror(document.getElementById(\"editor\"), {\n      value: text,\n      mode: \"javascript\",\n      theme: \"material-darker\",\n      lineNumbers: true,\n      indentUnit: 2,\n      tabSize: 2,\n      matchBrackets: true,\n      autoCloseBrackets: true,\n      scrollbarStyle: \"overlay\",\n      extraKeys: {\n        \"Cmd-S\": () => BTTSave(),\n        \"Ctrl-S\": () => BTTSave(),\n        \"Ctrl-Space\": \"autocomplete\"\n      }\n    });\n  }\n\n  function changeMode(mode) {\n    editor.setOption(\"mode\", mode);\n  }\n\n  function showHelp() {\n    const modal = document.getElementById(\"helpModal\");\n    modal.style.display = \"flex\";\n    modal.classList.remove(\"fade-out\");\n    modal.classList.add(\"show\");\n    modal.focus();\n  }\n\n  function hideHelp() {\n    const modal = document.getElementById(\"helpModal\");\n    modal.classList.remove(\"show\");\n    modal.classList.add(\"fade-out\");\n    setTimeout(() => {\n      modal.style.display = \"none\";\n    }, 1000);\n  }\n\nfunction showStatus(message) {\n  const modal = document.getElementById(\"statusModal\");\n  const msg = document.getElementById(\"statusMessage\");\n  msg.innerHTML = \"<strong>Info:<\/strong><br><br><br><br>\" + message + \"<br><br>\";\n  modal.classList.remove(\"fade-out\");\n  modal.classList.add(\"show\");\n  modal.style.display = \"flex\";\n\n  setTimeout(() => {\n    modal.classList.add(\"fade-out\");\n    setTimeout(() => {\n      modal.classList.remove(\"show\");\n      modal.style.display = \"none\";\n    }, 1000);\n  }, 2500);\n}\n\n  function hideStatus() {\n    const modal = document.getElementById(\"statusModal\");\n    modal.classList.add(\"fade-out\");\n    setTimeout(() => {\n      modal.classList.remove(\"show\");\n      modal.style.display = \"none\";\n    }, 1000);\n  }\n\n  document.addEventListener(\"keydown\", function(event) {\n    if ((event.key === \"Enter\" || event.key === \"Return\")) {\n      if (document.getElementById(\"helpModal\").classList.contains(\"show\")) {\n        hideHelp();\n      }\n      if (document.getElementById(\"statusModal\").classList.contains(\"show\")) {\n        hideStatus();\n      }\n    }\n  });\n\n  async function BTTSave() {\n    try {\n      const rawText = editor.getValue();\n      const result = await set_string_variable({ variableName: \"FlipText\", to: rawText });\n      showStatus(\"Text gespeichert !\");\n      console.log(\"Text gespeichert:\", result);\n    } catch (error) {\n      console.error(\"Fehler beim Speichern:\", error);\n      showStatus(\"Fehler beim Speichern!\");\n    }\n  }\n\n\n  document.addEventListener(\"DOMContentLoaded\", BTTInitialize);\n<\/script>\n\n<\/body>\n<\/html>",
          "BTTMenuHoverEndAnimationDuration" : 0.14999999999999999,
          "BTTMenuItemSelectedTab" : 778,
          "BTTMenuUseStyleForSubmenu" : 1,
          "BTTMenuItemBackgroundColorHoverDark" : "90.000, 90.000, 180.000, 166.991",
          "BTTMenuCategoryItemSpacing" : 0,
          "BTTMenuCategoryMenuOpacity" : 0,
          "BTTMenuItemBackgroundType" : 4,
          "BTTMenuItemBorderColorDark" : "255.000, 255.000, 255.000, 255.000",
          "BTTMenuItemPaddingLeft" : 1,
          "BTTMenuItemBackgroundColorHover" : "33.000000, 33.000000, 33.000000, 255.000000",
          "BTTMenuCategoryMenuVisibility" : 0,
          "BTTMenuItemVisibleWhileInactive" : 1,
          "BTTMenuCategoryBorder" : 0,
          "BTTMenuItemMaxHeight" : 850,
          "BTTMenuItemPaddingRight" : 1,
          "BTTMenuHoverStartAnimationDuration" : 0.14999999999999999,
          "BTTMenuAttributedText" : "{\\rtf1\\ansi\\ansicpg1252\\cocoartf2761\n\\cocoatextscaling0\\cocoaplatform0{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n{\\colortbl;\\red255\\green255\\blue255;}\n{\\*\\expandedcolortbl;;}\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\\partightenfactor0\n\n\\f0\\fs24 \\cf0 .}",
          "BTTMenuItemMinWidth" : 1395,
          "BTTMenuItemMaxWidth" : 1395,
          "BTTMenuCategoryItemSizing" : 0,
          "BTTMenuAppearanceStyle" : 1,
          "BTTMenuItemBorderColorHover" : "192.000000, 192.000000, 192.000000, 255.000000",
          "BTTLastChangeUUID" : "0BEC507A-83DC-441E-9869-E5485268A0E7",
          "BTTMenuCategorySpacing" : 0,
          "BTTMenuElementIdentifier" : "Editor Webview",
          "BTTMenuCategoryPosition" : 0,
          "BTTMenuItemIconColor1" : "255.000, 255.000, 255.000, 255.000",
          "BTTMenuItemPaddingBottom" : 1,
          "BTTMenuAlwaysUseLightMode" : 1,
          "BTTMenuCategoryItemIcon" : 0,
          "BTTMenuCategorySize" : 0
        },
        "BTTMenuAvailability" : 0,
        "BTTMenuName" : "Editor Webview",
        "BTTGestureNotes" : "Standard Item"
      },
      {
        "BTTActionCategory" : 0,
        "BTTLastUpdatedAt" : 1748452532.3500271,
        "BTTTriggerType" : 773,
        "BTTTriggerTypeDescription" : "Standard Item",
        "BTTTriggerParentUUID" : "00960D90-33F1-4DD5-8C29-1B50FDDE8E35",
        "BTTTriggerClass" : "BTTTriggerTypeFloatingMenu",
        "BTTUUID" : "CA6B1904-B0F8-4CDD-A831-58BBE253A0CB",
        "BTTPredefinedActionType" : 366,
        "BTTPredefinedActionName" : "Empty Placeholder",
        "BTTAdditionalConfiguration" : "Menu Item: Titel",
        "BTTEnabled" : 1,
        "BTTOrder" : 0,
        "BTTTriggerName" : "Menu Item: Titel",
        "BTTMenuItemActions" : [
          {
            "BTTActionCategory" : 0,
            "BTTLastUpdatedAt" : 1748435381.8426549,
            "BTTTriggerParentUUID" : "CA6B1904-B0F8-4CDD-A831-58BBE253A0CB",
            "BTTTriggerClass" : "BTTTriggerTypeFloatingMenu",
            "BTTUUID" : "49826C3D-C95B-48EE-9638-EF9E1D64E940",
            "BTTPredefinedActionType" : 387,
            "BTTPredefinedActionName" : "Hide Floating Menu",
            "BTTAdditionalActionData" : {
              "BTTMenuActionMenuID" : "Text Editor"
            },
            "BTTEnabled" : 1,
            "BTTOrder" : 1,
            "BTTMenuConfig" : {

            },
            "BTTMenuAvailability" : 0,
            "BTTMenuName" : "1AEA4003-A5DF-430C-BCB7-57E17689A002"
          }
        ],
        "BTTMenuConfig" : {
          "BTTMenuHoverStartAnimationDuration" : 0.14999999999999999,
          "BTTMenuItemBackgroundColorHoverDark" : "90.000, 90.000, 180.000, 166.991",
          "BTTMenuItemIconColor1" : "255.000, 255.000, 255.000, 255.000",
          "BTTMenuItemBorderColorDark" : "255.000, 255.000, 255.000, 255.000",
          "BTTMenuItemBackgroundColor" : "29.999996, 29.999996, 29.999996, 255.000000",
          "BTTMenuCategoryItemVisibility" : 0,
          "BTTMenuItemBackgroundType" : 4,
          "BTTMenuItemMaxHeight" : 35,
          "BTTMenuCategoryMenuVisibility" : 0,
          "BTTMenuHoverEndAnimationDuration" : 0.14999999999999999,
          "BTTMenuItemMaxWidth" : 1395,
          "BTTMenuCategoryItemIcon" : 0,
          "BTTMenuItemBorderWidth" : 0,
          "BTTMenuCategoryShadow" : 0,
          "BTTMenuCategoryItemBehavior" : 0,
          "BTTMenuCategoryOnlyShowIf" : 0,
          "BTTMenuItemCornerRadius" : 5,
          "BTTMenuCategoryModifiers" : 0,
          "BTTMenuItemBorderColorHover" : "192.288, 192.292, 192.290, 255.000",
          "BTTMenuCategoryItemSpacing" : 0,
          "BTTLastChangeUUID" : "8FB45412-1753-4E3B-956A-67B52C704145",
          "BTTMenuCategoryMenuOpacity" : 0,
          "BTTMenuItemBorderColor" : "94.492, 94.494, 94.493, 255.000",
          "BTTMenuCategorySize" : 0,
          "BTTMenuItemMinHeight" : 35,
          "BTTMenuItemBackgroundColorDark" : "108.442, 96.000, 190.435, 166.991",
          "BTTMenuItemVisibleWhileActive" : 1,
          "BTTMenuElementIdentifier" : "Titel",
          "BTTMenuItemVisibleWhileInactive" : 1,
          "BTTMenuItemMinWidth" : 1395,
          "BTTMenuItemBackgroundTypeDark" : 4,
          "BTTMenuAttributedText" : "{\\rtf1\\ansi\\ansicpg1252\\cocoartf2761\n\\cocoatextscaling0\\cocoaplatform0{\\fonttbl\\f0\\fnil\\fcharset0 SFPro-Regular;}\n{\\colortbl;\\red255\\green255\\blue255;\\red255\\green255\\blue255;}\n{\\*\\expandedcolortbl;;\\cssrgb\\c100000\\c100000\\c100000;}\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\\qc\\partightenfactor0\n\n\\f0\\fs24 \\cf2 Java-Script \/ HTML Editor}",
          "BTTMenuCategorySpacing" : 0,
          "BTTMenuItemBorderColorHoverDark" : "255.000, 255.000, 255.000, 255.000",
          "BTTMenuAppearanceStyle" : 1,
          "BTTMenuItemBackgroundColorHover" : "29.999996, 29.999996, 29.999996, 255.000000",
          "BTTMenuAlwaysUseLightMode" : 1,
          "BTTMenuCategoryBackground" : 0,
          "BTTMenuCategoryItemSizing" : 1,
          "BTTMenuAttributedTextDark" : "{\\rtf1\\ansi\\ansicpg1252\\cocoartf2761\n\\cocoatextscaling0\\cocoaplatform0{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n{\\colortbl;\\red255\\green255\\blue255;}\n{\\*\\expandedcolortbl;;}\n\\pard\\tx560\\tx1120\\tx1680\\tx2240\\tx2800\\tx3360\\tx3920\\tx4480\\tx5040\\tx5600\\tx6160\\tx6720\\pardirnatural\\partightenfactor0\n\n\\f0\\fs24 \\cf0 Multi Selection Dummy Text - You can change the formatting for multiple items at the same time, but not the text.}",
          "BTTMenuCategoryResizeOnHover" : 0,
          "BTTMenuCategoryBorder" : 0,
          "BTTMenuUseStyleForSubmenu" : 1,
          "BTTMenuCategoryZIndex" : 0,
          "BTTMenuCategoryPosition" : 0,
          "BTTMenuItemSelectedTab" : 0
        },
        "BTTMenuAvailability" : 0,
        "BTTMenuName" : "Titel",
        "BTTGestureNotes" : "Standard Item"
      }
    ],
    "BTTFloatingMenuRenderedPreview" : "iVBORw0KGgoAAAANSUhEUgAAAMgAAACCCAYAAAADm4eUAAAAAXNSR0IArs4c6QAAAHhlWElmTU0AKgAAAAgABAEaAAUAAAABAAAAPgEbAAUAAAABAAAARgEoAAMAAAABAAIAAIdpAAQAAAABAAAATgAAAAAAAABIAAAAAQADKNoAAAtLAAOgAQADAAAAAQABAACgAgAEAAAAAQAAAMigAwAEAAAAAQAAAIIAAAAA1hcSLAAAAAlwSFlzAAALEwAACwQBBRkYjgAABtBJREFUeAHt2M9OG1cUx_E79tiAQ0RXCSjUEEUKYpEs8hhVVB6i2yy66gO0T9EXyCY7VuyqSt2ibCJl0QXKAiRIICj_LBuwe8+UQUdHSUR0sImOvyONfO7gO+P7uf7NHVMsLy__1mw2f0kpzeSdbQwCp6enF2ctiiKNRqOLdl3kOUhnZ2dVs36PvDYajYvj+r3yN7bxCJycnPyzt7f3Rz77UZkn5tdcLH1u0sZz+ek76+rqahoOh0m+1B8+fEiLi4vp48ePFURZllUA3r17l27evJnm5ubS7OzsxbH379+n27dvJwnQYDBIvV4vvX37tjqPhIftagXENO87+azNvN8qczCWrvYSnK0WkJuOfOHv379ffcGlne9MaX5+vgqJfPnv3LmT9vf3kwSl1WqlmZmZKkwrKyvp8PCwev_S0lJ1vN_vVyvK9vZ2fQler1jgfKGol+dWkR+xevnONnvF1+F05wJyR5Ivv8DLCiKPW+d3qSoIEghZGeRYXtqr98h7ZcWQTVYeqeWYPofUbOMRyI+6f+Ub2ZN89na5sLDwZ77LPckT8f+MjOeanPULAvJF73Q6X_grhyctcH6j+jcHZCjXLh8_frzx7NmzfJMiH5OeDK73_QnIKp9_I_7YbrcbsrKXN27c6Eohz79sCCCQ5B8kc7VDIy_xstdtXhFAQAnwf0KFQYmAFSAgVoQ2AkqAgCgMSgSsAAGxIrQRUAIERGFQImAFCIgVoY2AEiAgCoMSAStAQKwIbQSUAAFRGJQIWAECYkVoI6AECIjCoETAChAQK0IbASVAQBQGJQJWgIBYEdoIKAECojAoEbACBMSK0EZACRAQhUGJgBUgIFaENgJKgIAoDEoErAABsSK0EVACBERhUCJgBQiIFaGNgBIgIAqDEgErQECsCG0ElAABURiUCFgBAmJFaCOgBAiIwqBEwAoQECtCGwElQEAUBiUCVoCAWBHaCCgBAqIwKBGwAgTEitBGQAkQEIVBiYAVICBWhDYCSoCAKAxKBKwAAbEitBFQAgREYVAiYAUIiBWhjYASICAKgxIBK0BArAhtBJQAAVEYlAhYAQJiRWgjoAQIiMKgRMAKEBArQhsBJUBAFAYlAlaAgFgR2ggoAQKiMCgRsAIExIrQRkAJEBCFQYmAFSAgVoQ2AkqAgCgMSgSsAAGxIrQRUAIERGFcZzkcDtPZ2VkajUbX+TG4thEgIAZk0s06EN1uN927dy+VZZkkLGzfh0D5fXyM6fwUEo5Op5M2NjaqcDSbzfTq1au0ubmZDg8PU6PB_eu6vxnMwDXOgDxSPXz4MJ2enqajo6N0cHCQ+v1+evDgwTV+Ki6tBVhBtMaEa1kx5NFKXj99+lRdXerl5eVqZen1eqkoigl_Ki6nBQiI1phwLY9YsnLI747FxcXqB_rx8XG1ogwGA8Ix4fn43OV4xPqcyoSOSUBevnyZ1tbW0urqarp7925aX19POzs76eTkZEKfgst8TYAV5Gs6Y_6b_Ajf3d1NT58+TY8ePUqtVis9f_68OsYP9DHjX_L0BOSSUON4m_y+kFXk9evXaWtrq7pE_Zujfh3HdTnn5QV4xLq81VjeWQdBXnU9lotx0m8WYAX5ZrKr71AH4+rPzBm9AqwgXkH6hxYgIKGnl8F5BQiIV5D+oQUISOjpZXBeAQLiFaR_aAECEnp6GZxXgIB4BekfWoCAhJ5eBucVICBeQfqHFiAgoaeXwXkFCIhXkP6hBQhI6OllcF4BAuIVpH9oAQISenoZnFeAgHgF6R9agICEnl4G5xUgIF5B+ocWICChp5fBeQUIiFeQ_qEFCEjo6WVwXgEC4hWkf2gBAhJ6ehmcV4CAeAXpH1qAgISeXgbnFSAgXkH6hxYgIKGnl8F5BQiIV5D+oQUISOjpZXBeAQLiFaR_aAECEnp6GZxXgIB4BekfWoCAhJ5eBucVICBeQfqHFiAgoaeXwXkFCIhXkP6hBQhI6OllcF4BAuIVpH9oAQISenoZnFeAgHgF6R9agICEnl4G5xUgIF5B+ocWICChp5fBeQUIiFeQ_qEFCEjo6WVwXgEC4hWkf2gBAhJ6ehmcV4CAeAXpH1qAgISeXgbnFSAgXkH6hxYgIKGnl8F5BQiIV5D+oQUISOjpZXBeAQLiFaR_OIGiKMp6UOWLFy9+73a7Pw+Hw6I+yCsC0yrQbDZTu93+ezAYVAQSip_ygc60gjBuBIxAkcNxnI8d5L1aSn7IB4bmTTQRmFYBWTRm6sHLs1Yv77P1AV4RmHIBCUi9YBTS6OZ9RR3MJRsCUy3Qz6OXkOxLQGRfyvutvI_yzobAtAtIJt7kffc_kgAwypNYS4AAAAAASUVORK5CYII=",
    "BTTMenuConfig" : {
      "BTTMenuBringToFrontOnHover" : 0,
      "BTTMenuOnlyUpdatePositionOnExplicitRequest" : 1,
      "BTTMenuVerticalSpacing" : 0,
      "BTTMenuAnchorRelation" : 0,
      "BTTMenuItemBackgroundColor" : "33.000000, 33.000000, 33.000000, 255.000000",
      "BTTMenuOffsetXUnit" : 0,
      "BTTMenuCategoryItemVisibility" : 0,
      "BTTMenuSelectedTab" : 1,
      "BTTMenuPositioningType" : 1,
      "BTTMenuItemBorderWidth" : 0,
      "BTTMenuCategoryResizeOnHover" : 0,
      "BTTMenuPositionRelativeTo" : 3,
      "BTTMenuCategoryOnlyShowIf" : 0,
      "BTTMenuCategoryModifiers" : 0,
      "BTTMenuOffsetX" : 50,
      "BTTMenuOffsetY" : -50,
      "BTTMenuItemShadowEnabled" : 1,
      "BTTMenuItemCornerRadius" : 10,
      "BTTMenuFrameWidth" : 1400,
      "BTTMenuFrameHeight" : 925,
      "BTTMenuCategoryShadow" : 0,
      "BTTMenuItemBorderColor" : "33.110, 33.111, 33.110, 255.000",
      "BTTMenuCategoryBackground" : 1,
      "BTTMenuScreenUUID" : "37D8832A-2D66-02CA-B9F7-8F30A301B230",
      "BTTMenuItemPaddingTop" : 1,
      "BTTMenuCategoryItemBehavior" : 0,
      "BTTMenuItemSelectedTab" : 0,
      "BTTMenuCategoryZIndex" : 0,
      "BTTMenuUseStyleForSubmenu" : 1,
      "BTTMenuCategoryItemSpacing" : 0,
      "BTTMenuItemScriptActive" : 0,
      "BTTMenuVisibility" : 1,
      "BTTMenuItemsUseModifierModes" : false,
      "BTTMenuCategoryMenuOpacity" : 0,
      "BTTMenuItemBlurredBackground" : 0,
      "BTTMenuCloseOnOutsideClick" : 0,
      "BTTMenuLayoutDirection" : 0,
      "BTTMenuScriptSettings" : {
        "BTTScriptType" : 3,
        "BTTAppleScriptString" : "(async ()=> {\n\n   \/\/ let result = await set_string_variable({variable_name: 'FlipText', to: 'Text Editor with some test string'});\n\n   returnToBTT(\"{}\");\n\n})();",
        "BTTScriptLocation" : 0,
        "BTTAppleScriptUsePath" : false,
        "BTTJavaScriptUseIsolatedContext" : false
      },
      "BTTMenuItemBackgroundType" : 0,
      "BTTMenuItemPaddingLeft" : 0,
      "BTTMenuTitleBarStyle" : 0,
      "BTTMenuItemBackgroundColorHover" : "33.000000, 33.000000, 33.000000, 255.000000",
      "BTTMenuHorizontalSpacing" : 0,
      "BTTMenuCategoryMenuVisibility" : 0,
      "BTTMenuWindowLevel" : -2147483602,
      "BTTMenuCategoryBorder" : 0,
      "BTTMenuItemPaddingRight" : 0,
      "BTTMenuModifierMode" : 3,
      "BTTMenuSizingBehavior" : 0,
      "BTTMenuCloseAfterAction" : 0,
      "BTTMenuWindowResizable" : 0,
      "BTTMenuAnchorMenu" : 0,
      "BTTMenuShowIfWindowLevelEqualsEnabled" : 0,
      "BTTMenuCategoryItemSizing" : 0,
      "BTTMenuAppearanceStyle" : 1,
      "BTTMenuItemBorderColorHover" : "66.432, 66.434, 66.433, 255.000",
      "BTTMenuAvailability" : 1,
      "BTTLastChangeUUID" : "4451FA38-BA7C-4C39-AF18-D71A9564F4CE",
      "BTTMenuCategorySpacing" : 0,
      "BTTMenuElementIdentifier" : "Text Editor",
      "BTTMenuCategoryPosition" : 0,
      "BTTMenuItemPaddingBottom" : 1,
      "BTTMenuAlwaysUseLightMode" : 1,
      "BTTMenuCategoryItemIcon" : 0,
      "BTTMenuOffsetYUnit" : 0,
      "BTTMenuCategorySize" : 0
    },
    "BTTMenuAvailability" : 1,
    "BTTMenuName" : "Text Editor"
  }
]

Hallo @Andreas_Hegenberg

I found in the BTT doc that there is already a java script function: writeStringToFile,
somehow I can't get it working.

(--> Error writing (Test) to file (~/Library/Application Support/BetterTouchTool/FlipText.txt): Unknown error)

I have granted "Full Disk Access" to BetterTouchTool,
Checked folder permissions: my user account does have read/write permissions
tried other paths
variable does contain data ("Test"),
"Allow external BetterTouchTool Scripting" is ticked

whatelse could it be ?

Thx,
Christian

async function Save2File() {
  try {
    // Get the content of the BTT variable
    const result = await get_string_variable({ variable_name: 'FlipText' });
    if (!result) throw new Error("Variable 'FlipText' is empty or not defined");

    // Determine the HOME path via a Shell Script
    // const homeResult = await runShellScript({ script: "echo $HOME", with_env: true });
    // const home = homeResult.trim();
    // const fullPath = "${home}/Desktop/My Downloads/FlipText.txt";

    const fullPath = "~/Library/Application Support/BetterTouchTool/FlipText.txt";

    // Try to write the file
    const writeResult = await writeStringToFile(fullPath, JSON.stringify(result) );

    if (!writeResult || writeResult.success !== true) {
      throw new Error(`Error writing (${result}) to file (${fullPath}): ${writeResult?.error || 'Unknown error'}`);
    }

    return "success";
  } catch (error) {
    // console.log("Error in Save2File():", error.message);
    return error.message;
  }
}

unfortunately writeStringToFile was only available in BTT’s Java Script Runner, but not inside the webview context. In the latest alpha 5.445 I made it available there as well, but haven’t tried it yet.

Hallo @Andreas_Hegenberg

oh no,
I mixed up the parameter (in fact GPT did this !)
(writeStringToFile(fullPath,value,) is wrong.

in 5.445 it is working now in the BTT Java script action
(I was not using/tested it in the WebView)

async function Save2File() {
  try {
    // Get the content of the BTT variable
    const result = await get_string_variable({ variable_name: 'FlipText' });
    if (!result) throw new Error("Variable 'FlipText' is empty or not defined");

    // Determine the HOME path via a Shell Script
    // const homeResult = await runShellScript({ script: "echo $HOME", with_env: true });
    // const home = homeResult.trim();
    // const fullPath = "${home}/Desktop/FlipText.txt";

    const fullPath = "~/Documents/BetterTouchTool/FlipText.txt";

    // Try to write the file
	 const writeResult = await writeStringToFile(result, fullPath, false );
    // let ok = await writeStringToFile('Hello', '~/output.txt', false);
    
	 return(writeResult);
	 // - return "success";
	
  } catch (error) {
    return error.message;
  }
}