Stream Deck Script Widget - Run only when pushed

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/'  // this path is relative from the `shellScriptAbsPath`
  let shellScriptAbsPath = `/abolute/path/to/ ${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);

JS calls a bash script, this script is a generic 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 


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__":

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

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: