Stream Deck Script Widget - Run only when pushed

Hello,
I want to run different python scripts from my Stream deck buttons and change the buttons appearance based the results.

I've defined a Stream Deck Script Widget using JavaScript that calls a bash script that calls my python script....that's a lot of scripts in a row :sweat_smile: but I guess there is no other way, here's why:

1 - Js Script:

(async () => {

  let pyScriptRelPath = './rel/path/to/script.py'  // this path is relative from the `shellScriptAbsPath`
  let shellScriptAbsPath = `/abolute/path/to/execute.sh ${pyScriptRelPath}`; // absolute path to my shell script

  let shellScriptWrapper = {
      script: shellScriptAbsPath,
      launchPath: '/opt/homebrew/bin/bash', //my bash version
      parameters: '-c', 
      environmentVariables: ''
  };
  
  let result = await runShellScript(shellScriptWrapper);
  returnToBTT(result);
})();

JS calls a bash script, this script is a generic execute.sh to which I pass a relative path to the python scripts I want to execute, that is pyScriptRelPath.
I do this because I'm planning to make this Js reusable and just pass this variable to it.

QUESTION 1: how to reuse this code?
I've tried to do this with named trigger but there isn't any named trigger that resemble the Stream Deck Script Widget so I guess at the moment I can't do this and I would need to replicate this script in all my StreamDeck buttons that need to execute my scripts. Unless there is another solution.

2 - Bash script

#!/usr/bin/env bash
export PATH=$PATH:/usr/local/bin/;

# I do this to be able to execute my python from a relative path from where this file is located
parent_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )
cd "$parent_path"

# path to my pyenv virtualenv python bin 
outputString=$("/my/pyenv/virtualenv/bin/python" ./$1)
echo $outputString 

exit;

This bash script:

  • takes the relative path of my python script as input
  • execute my python script using a specific virtualenv python version
  • print the result (that will be the result passed to BTT)

3 - Python Script


def main():
    print('{"text": "TEST", "BTTStreamDeckBackgroundColor": "100,100,100,255"}')

if __name__ == "__main__":
    main()

My python script print the escaped json that will be passed to bash and then to BTT to actually style the StreamDeck button.

QUESTION 2
At the moment this works but given the Widget Option "Execute script every x seconds" the script is always executed at least once even if I put very big number.
This will produce unwanted result in my workflow as I need the script to be executed EXACTLY once when and only when I push the button.
I guess at the moment this isn't possible, isn't it?

In this case the widget functionality should be slightly modified to:

  • allow for a default button appearance
  • allow the script to be executed only when the button is pushed

Any other way to achieve these results (question 1 and 2) with the current limitations ?
Also any way to simplify this workflow? That's a long line of scripts to be called :sweat_smile:

Thanks