Making a Twitch bot in Golang: need a bit of advice

Hey everyone!

I am working on a Twitch bot in Golang. I’ve made one in Python, but am wanting to mess with Go a bit.

The basics are up and running, but I need some advice on dealing with commands and words that would trigger a ban/timeout.

For those who don’t know, a command is when a user in the chat types something like “!help” then, the bot responds with a response based off of what the user said. Same thing for bannable words: when a user says a ‘bad word’, the bot will timeout/ban them.

The problem I’m having is figuring out, purely on a theoretical level, is how to store these. Do I use a map? It should be dynamic and can easily be appended/removed to. It should be easily editable, and needs to be stored so that the changes are saved for the next time the bot is run.

It is a common feature that a moderator can add/remove a command from the IRC chat, without needing access to the code. My initial thought is to use maps or a json file, but some advice here would be great.

A map sounds like a good choice yes, since it can be added/removed from dynamically and it should have pretty fast lookup (relevant if you have a huge number of commands/banwords).

I don’t know so much about golang, but think about having a map between like, a word and an object or function or something. Then, if you want multiple words to have the same effect, they can just map to the same object or function. I don’t really know what go features would be best for this.

While I guess it’s not optimal for stability, loading the map from some format (is this built in in go?) on startup, and saving on shutdown (just overwriting the old one with new updates) should be fine. Although it might be good to save intermittently if you expect a lot of changes will be made in one run, and you don’t want to lose them if there is a crash. Depending on how the map saving is implemented, keys/values might be rearranged so I’d expect it to be easier to just overwrite for saving, rather than updating.

I like the idea of saving it as the program is running.

Go has a built in build process, as easy as ‘go build file.go’ in a CLI. It will build a binary for the platform you are on. For that reason, I want to get the commands/bannable words and such out of the main bot file.

In any case, thanks for the advice!

+1 for using maps. They are simple to use by both humans and computers

I wouldn’t go with JSON though, because it’s awkward to edit. There’s better formats made specifically for configuration files. Take a look at TOML for example. It’s an INI-style format, but well defined and has parsers available for all major languages.

Sample syntax for your use case:

[badwords]
"foo" = "warn"  # print a warning when somebody uses the word "foo"
"bar" = "ban"   # ban users using the word "bar"

This file will be parsed to a map like this: {"foo": "warn", "bar": "ban"}

Took me a little while to get it working properly, but now that I have, I can totally see what you mean about TOML being better. JSON was giving me some pain, but TOML has been great.

Thank you for the suggestion.

Hey everyone, hoping for some further suggestions.

I want to take this a step further.

It’s common functionality for users to type something like “!addcom !test” in the Twitch chat, then the bot adds the new command. The current problem with TOML is properly updating and saving the file… it’s certainly possible but feels sketchy to me?

Is something like TOML still the best way to go for this? I wonder if something like a db file is a smarter idea?

TOML would work, but saving the file will remove the any formatting and comments the user has added. I’d use TOML strictly for data the user is supposed to edit and store anything program-generated in another file (either JSON or TOML). A database is overkill IMO, but that could just be because I don’t like working with them :slightly_smiling_face:

A database also won’t store comment.

Toml / any kind of flat file is probably fine. What sqlite for example would buy you is a little more safety from corruption, it would make sure old version of data is not discarded until new version is there through some clever use of journaling and/or calling sync calls.

You can do the same if you want to be clever,… or you can just not care.