Return to

Devember - From CLI to GUI



I withdrew the post because I found out about Viper which solves my exact problem regarding writing to TOML, but thanks for the info regardless.

As far as I understand, .env files are used for storing oauth tokens for web apps and such, right? I’ll want to keep that in mind. Thanks.


Yeah, usually you put stuff stuff in there that is highly specific to what ever it runs on. OAUTH, PAC’s, or DB info, or server BASE_URL, or PORT are also quite common.


Day 20

Hey all, not a super productive day (despite spending a stupid amount of time on the project today). Reason for this is because I’m trying to display all of the settings and their values from my config.toml value to the GUI. This involves making a JSON struct out of the settings, but sadly all of the unique keys, and a mix of integers, strings and arrays are really messing it up. Not sure how to continue.

I did add some changes to the home page, and did some things on the back-end I can’t even remember anymore, lol.


Day 21

Today it felt like a lot of things fell in place nicely. I worked on creating my own Table component because I was having issues with a third-party one.

Well, it didn’t work all that nicely, but I learned a lot more about states and how the pieces of React work together. I’ve gone with a simple third-party one called react-table which has worked nicely.

I’ve added a Games page to handle settings related to game. (Which is an absolute PITA to set up, so much data and design going on.)

Below is an example of the games layout.

Also I’m implementing a simple conditional check to see if the API sends out data or if it’s null. If null, it should not render the table and creation menus. Actually if I don’t do this, the whole program breaks, because it’s expecting data but borks if it gets null.

// react-table does not handle null data at all. So this is an easy way to do that.
    let render;
    let submenu;
      if (this.state.coms == undefined) {
        render = "No data from Commands."
        submenu = null
      } else {
        render = this.renderTable();
        submenu = this.renderSubMenu();

No data:

Data is returned:


Day 22

Today I implemented being able to disable games from the GUI. This involves handling state / graphical changes properly in React, while the changes are written from the back-end.

So it does work, but a huge problem is the fact that the bot can’t reassign its config values when something changes. So for example, there is a line in my toml config file that sets whether ‘gamesenabled’ is true or false. I initially had the issue with figuring out how to track when the config is changed.

Turns out Viper, which is what I’m using to read / write TOML, has the functionality to do so. It has WatchConfig() and OnConfigChange functions for this purpose. However, each time I make a change to the config and test that setting with the bot, I get this error:

panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x4d5eb7]

So I know that the new value is being picked up, but something is getting messed up in the process. I’ll be working on that tomorrow.

Below is a screenshot of the Games part of the GUI.


Day 23

Hey all, today was spent on figuring out how to load new config settings from the GUI so the bot would have said new values without having to restart. In addition I’ve continued working on the games / settings a little bit.

For the values reloading, I’ve determined that the bot will not reliably load new values by reading the config file over again after there is a change. Instead, when Golang receives new settings for the config, it writes to the config and then separately reassigns the variable that was changed to the new value.

So my bot has this struct to represent it’s various items:

type BotInfo struct {
	ChannelName                 string
	ServerName                  string
	BotOAuth                    string
	BotName                     string
	WebAppGUIEnabled            bool
	SpamProtection              bool
	SpamCount                   int
	SpamInterval                int
	LetModeratorsUseAllCommands bool
	CasterMessage               string

That only covers around a 4th of the whole struct, but gets the idea across. So for example, if the SpamProtection config value is changed from the GUI, that is written to the config file then some code like this is run.

if change.Setting == "spamprotection" {
     irc.SpamProtection = change.Value

change is the variable holding the JSON post request. It has a struct that the serializer binds values to, so we’re just accessing that here.

It’s a very manual approach, and I have to add a condition for every possible setting that can be changed, but it does allow setting changes to occur in real time which is nice.

GUI was far less interesting, so I won’t go into that today.


Day 24 - 31

Hey everyone, I’ve been MIA the past week due to family coming down for the holidays and I almost never get to see them, so I spent all the time I had with them.

I’ve gotten a few minutes in here or there in the mean time. Basically this has involved adding new input form and toggles for the various bot settings in the config.toml file.

Looking back

I may do a more in-depth post later, but in case I don’t get around to it, I want to share a few thoughts about this project and process.

If I had told my past self before this project that I’d have a functional and somewhat nice looking GUI for my twitch bot project, he would be laughing out loud. GUI’s have always been something I’ve avoided working on, so this is a huge leap for me.

This project has allowed me to better understand states, components and to a small degree the greater JavaScript ecosystem.

I wish i was able to stick to the challenge on more days, but finals and then family visits made that hard, but I am very happy with what I’ve done in the last month.

Pain points

Speaking of the JavaScript ecosystem, here’s some of my pain points. React has been a great way for me to jump in and start writing stuff with a plethora of documentation on the web. However, I can’t help but feel that the whole ecosystem feels ‘bloated’. There are so many third-party modules, many of which have vulnerability issues. The only reason I feel comfortable using them for this project is that this is all done in a localhost system, not exposed to the greater world.

But I can’t deny this is a easy way to write a decent cross-platform GUI for newbies like me.

Next Steps

It isn't quite done yet however. Most of the features I want is in place, but several bugs still exist. I probably won't update this thread, but will keep my GitHub updated.

Big thanks to @Dynamic_Gravity and @psycho_666 for working on this challenge and @anotherriddle for being a strong supportive voice throughout!


Really a great piece of work you did there and I enjoyed your blog here. :slight_smile:

Regarding the challenge all credit goes to @Dynamic_Gravity for creating the Devember thread and @psycho_666 for petitioning for the Devember challenge in the lounge.

I agree this community here is really great! :sunglasses:


I haven’t done anything special…