List all variables and arguments in Streamer.bot and use them

Streamer.bot is a great piece of software but it comes with some caveats: scripting is tedious. I use Streamer.bot for my own streams and I have enjoyed scripting some events.

This software is missing some pretty important debugging tools and Streamer.bot is not open source. I would have thrown in some of my improvements so I might instead get to writing plugins.

Inspecting all the variables a script can use

First, what I’m calling variables in this context is not actually variables, the documentation refers to these as arguments. But since I’ll be using them as variables, that have been set by previous actions, I will be referring to them as variables.

My main issue with C# script in Streamer.bot is that you cannot inspect variables easily. The documentation sometimes is incomplete and doesn’t list the variables that are available to you or sometimes it just displays a blank page.

The great thing about scripting, when you know what you are looking for, is that you can print to the log file whatever information you need:

using System;

public class CPHInline
{
    public bool Execute()
    {
        CPH.LogInfo("LogVars::Start");
        foreach (var arg in args)
        {
            CPH.LogInfo($"LogVars::{arg.Key} = {arg.Value}");
        }
        CPH.LogInfo("LogVars::End");

        return true;
    }
}

The output will look like (some lines were truncated):

[2024-04-29 07:29:31.736 DBG] InlineCode :: Running 'Execute' entry point from instance '5ded116b-fc1e-4ecf-9627-3055d1965acd'
[2024-04-29 07:29:31.752 INF] LogVars::Start
[2024-04-29 07:29:31.752 INF] LogVars :: __source = ElgatoWaveLinkMicrophoneMuteChanged
[2024-04-29 07:29:31.752 INF] LogVars :: microphoneName = Elgato Wave XLR
[2024-04-29 07:29:31.753 INF] LogVars :: microphone.name = Elgato Wave XLR
[2024-04-29 07:29:31.753 INF] LogVars :: microphone.gain = 0.75
[2024-04-29 07:29:31.753 INF] LogVars :: microphone.muted = True
[2024-04-29 07:29:31.753 INF] LogVars::End

You will then be able to access those variables through the TryGetArg function as such:

using System;

public class CPHInline
{
    public bool Execute()
    {
        bool muted = false;
        CPH.TryGetArg<bool>("microphone.muted", out muted);
        if (muted)
        {
            // Do something for a muted mic
        }

        return muted;
    }
}

The old documentation kindly refers to this snippet of code because I sure as hell wouldn’t come up with it.

Arguments VS variables

What Streamer.bot calls arguments can also be somewhat called variables. My opinion is that it can be confusing for those not in the know and I’ve set global variables in places where I didn’t think about using the arguments.

It’s fine because it works, but is it the proper way? No and I should make the switch where appropriate to make things run as they should be.

The big difference is that the triggers will output arguments that can be surround by % to be used such as %username%, while global variables are surrounded by ~ such as ~username~ when you want to use them.

But I still think that arguments should just be called local variables.

The page about arguments and variables: https://docs.streamer.bot/guide/variables#types

Conclusion

Due to the lack of proper up to date documentation and debugging tool it’s tricky to inspect what’s happening in Streamer.bot.

This post was written months ago but I never published it because I stopped producing content. I think it’s only right for this to go out to all of you in case someone might need it.

Bash reminder

I’m currently doing so much Bash scripting that I always end up googling the stuff I should know by now so it’s time for me to write it all down once and for all.

Looping through a text file

Sometimes you build up a list that you want to process, let’s say you want to wget a few URLs.

for read line; do
  wget "${line}"
done < ./urls.txt

It’s obviously a good idea to validate inputs but for the sake of this post it’s not necessary.

Redirecting STDERR

Redirecting to a file and just redirecting to STDOUT can be done two ways. I always forget the syntax so it’s always good to be reminded of it.

# STDERR to STDOUT
curl "${URL}" 2>&1

# STDERR and STDOUT to file
curl "${URL}" &> ./out.log

EOF syntax

In case you want to forward  a multi-line string to a variable you can invoke cat with the EOF syntax:

cat <<EOF
Hello World!
Why So Serious?
EOF

The syntax can actually be a bit tricky since you define on the first line the keyword that will end the multi-line string, in this case EOF.

Mounting a RAM disk

RAM disks are quick and ideal if you need a fast scratch disk, they can be mounted to any folders just like any other kind of device:

mkdir /mnt/ram
mount -t tmpfs tmpfs /mnt/ram -o size=4096M

You can now read and write on your RAM disk through /mnt/ram.

SSH tunnel

When you want to access services that are not available outside of a network you can open an SSH tunnel, which is like a VPN but not totally.

ssh -L 13306:127.0.0.1:3306 user@example.com

Here we bind the local port 13306 to the remote port 3306 through our localhost, we can then access a remote MySQL server through the SSH folder since there’s not good reason to have a MySQL server open to access on the internet.
Let’s manage ou MySQL server now:

mysql -h 127.0.0.1 -P 13306

Keep in mind that even though you can use this SSH command to proxy your network traffic, you will most certainly not achieve better performances than a standard VPN or OpenVPN setup.