Creating a Twitch Command Script With Streamlabs Chatbot
By: Nintendo Engineer
Tags: Programming, Twitch, Commands, Python, Streaming

Appendix B: Nice to Have

Here is some neat stuff you could add to your command to make it just a little bit cooler, but they’re by no means necessary to create your commands.

Adding a cooldown period

You might not want your commands to be available to everyone all the time, even though they’re awesome. You could have a busy chat or someone could be a troll and spam the command all the time.

That’s where cooldowns come in. SC has a few handles to add and check for cooldowns on a user or a command. I’m going to show the user-specific cooldown here.

It involves two small additions:

Add the user cooldown at the end of the Execute(data) method, using data.User to get the user ID of the viewer and specify 30 seconds as the cooldown time:

That should put a dent in the number of triggers.

Now, at the beginning of the Execute(data) method, in the command check, include an extra check for the user cooldown.

If a user calls this command again while still on cooldown, we don’t want to execute our logic. Adding that bit of logic:

Now the trolls have been thwarted!

Checking whether I can trigger the command shortly after each other yields a promising result. The command does not execute, because I triggered it in the last 30 seconds:

I guess he must be speechless after his faulty conclusion last time.

Now you know how to add a user cooldown.

Adding a cooldown for the command itself has a similar flow, simply exchange the user cooldown methods with the command cooldown methods.

Adding UI

You may or may not have seen an interface in SC for some commands where the controller can change values used in the script. It looks something like this:

The huge added benefit is that things like cooldown time and other values can be changed from outside of the script, without having to touch the script at all.

This saves quite a bit of work and makes the script easier to handle for people who aren’t used to scripting.

I want this for our script, so let’s dive into it:

First off, let’s create the UI_Config.json file in the same folder as our Python file. Get the naming right, create it and open it in your IDE:

It’s kinda empty in here…

SC has the format and options of the file documented on their GitHub Wiki page. First, we have to choose the name and type of file our values will be dumped in to use in our script.

Add the following to the file:

Mind the brackets and the quotes.

We need two values for our script: the probability in percentages and the cooldown in seconds. Both are numbers, so we’ll need a numberbox for both.

Let’s add those and fill in the fields:

value: the initial value, label: what appears above the box, tooltip: when you hover over it with your mouse.

Save the file, go back to the Scripts section in SC and reload the scripts.

When you now click on the Mulder command, it shows our fresh new UI:

What’s this!? Your Mulder is evolving!

We’re not there yet, friend. Remember the output file we defined? Hit Save Settings in the UI and head back to your IDE.

You should see two new files created:

So far, so good.

We’re interested in the settings.json file, which is the file we defined. If you open it up, you’ll see our defined values and their data:

This is automatically generated by SC. Nice, huh?

We now want to use these dynamically updated values instead of the hardcoded ones in our file. To this end, we’ll need to import some libraries to help with reading out this settings file.

Add the following above the global script information variables:

We’ll get to using these next.

Before we load the file, we need to have something to store these variables in. Let’s create a global settings object to that end:

Empty at first, we’ll load the values next.

We only want to read these values in once, when the script is (re)loaded. There is no need to read those every time the script executes.

Which method runs only once per (re)load? You remembered! It’s the Init() method. Let’s start adding logic to it step-by-step.

First, we need to let Python know we are going to change our global settings object:

Now Python knows that we mean our global settings object when we use it in the method.

We’re going to need to access the settings.json file.

As it’s in the same place as the current script we’re in, we can ask Python to get the path to the directory we’re in right now for later use:

Just a little longer, you can do it!

Alright then! Now, let’s get to the juicy bit: reading the file and storing the contents in our settings object.

We’re going to construct the full path to the file with the working directory we defined before and join that with the actual filename. Make sure the filename is exactly the same as the filename defined in UI_Config.json :

We have loaded the settings!

Great! Now that we have loaded the settings, we can use that object to access the values defined in the UI.

Let’s replace the hardcoded values with the dynamic reference to their counterpart (Make sure the spelling matches the spelling in the UI_Config.json file):

Test time! Head towards SC, go to the Scripts section and reload the scripts.

Calling the command in the console yields the result we had before, but now we can dynamically change our values from outside of our script:

Same, but not the same?

Bonus point: We can catch a possible error when trying to read our settings file. In our current scenario, a read error would result in the script breaking, but if we catch and handle this error, we’re able to build a fallback.

This is the cleaner way to handle this. The following code catches any error, or exception in Python lingo, logs the error for research, and provides fallback values so the script can continue while you calmly investigate what’s happening:

Make sure the spelling is correct!

And that’s how you incorporate UI!