Youtube Chat Bot for FCCLA
I have prided myself over the past few weeks developing a new feature for the FCCLA livestream: a chat bot that will post to the service chat based in time with the events of the service. This project was started when I was asked to cover the chat as admin. This involved welcoming everyone, posting relevant links, and saying goodbye when necessary. I had no idea what to type in chat as there was no set script. The chat was not well monitored on on that particular day, to say the least. This gave me the idea to automate the chat process, at least to an extend. My idea involved having a couple of messages that would post at key moments during the service: a welcome, a message advertising our events and music program, a donation link, and a farewell.
My first looked on npm to see if there were any packages that would streamline the process. I have experience posting and reading to twitch chat using node, which there is a node package, so I thought the same for youtube. Oh how wrong I was.
The twitch client (tmi.js) is fairly simple to work with. You just have to provide your twitch username, client ID, client secret, and the twitch chat you wish to join. It also provides a number of easy to use functions to post to chat, read from chat, and also read subscriptions. The ease of use of that package gave me the confidence that I can work with youtube live chat. Naivety is strength and a weakness, my friend.
First issue: there is no youtube node package. This meant I had to interact directly with google apis, drastically increasing the complexity of this project. I had to activate a google develop console and wade through the very unclear documentation, of which, had very little documentation on working with node.
The bulk of my struggle with google APIs comes down to the authentication. Google requires developers to use oAuth, there is no option for only using API keys, even if you want limited access to the API. Working with oAuth in a browser is not much of an issue. However, using Node presents a host of problems hat is normally handled by the browser. When authenticating with Node, the developer has to initiate a local server that handles the authentication process and passes the tokens to the script. Those functions will be handled automatically in a browser-based application but I had to build those functionalities myself. At the end of it all, at least 60% of the code only handled the authentication, with the other 40% dealing with posting to chat.
Another annoyance when dealing with the YouTube, at least compared to working with Twitch, is how the platform handles streams itself. Because twitch is streaming focused: just providing the twitch chat you wish to connect to is enough to post and read chat. Since YouTube treats current and upcoming livestreams as videos, you have to build your bot to find a currently live broadcast and connect. This just adds an extra layer of complexity I had to build through in order to make the process as easy as possible for the end user.
Ah! I didn’t even mention. This system is operated by multiple different users. Meaning I had to hide the complexity as much as possible. The first iteration of the patch had users finding the live chat with a button once the stream goes live. I wanted to make the system as automatic as possible. Not only will users have to remember to open the patch but they will also have to remember to press an additional button once they press “Go Live” on YouTube. Since the user will not be looking at the stream chat for most of the service, it will be unlikely that they will even notice the chat bot is not connected. Or if they do, the could miss multiple messages. In the next iteration of the patch I fixed this issue by looping the scan for live broadcasts every five seconds from when the patch launches.
A continuing issue I have been having is with the authentication. When the patch launches, it immediately tries to authenticate using the previous sessions tokens. This immediately forces the script to crash. In order to circumvent this issue, the user must authenticate before the server disconnects when script crashes. However, once authenticated, the script will work without issue. I have two theories why this happens. First, it might be the script is not saving the refresh tokens properly, and they are not being dispensed when requested on launch. My second theory is that it is a version control issue. Originally, I was having Github save the tokens.json. When pulling a new version, GitHub was also pulling stale tokens. I thought I had addressed this issue by adding the tokens.json file to the .gitignore, but the device that was having the issue did not yet pull the .gitignore. I have not seen if the patch works with this update. If am still having problems that means that my first theory is correct.
I am in a constant in my development of dynamic systems. With just the couple of weeks this system has been implemented, I already noticed the staleness of the chatbot’s robotic responses. The incongruences became especially noticeable upon the messaged the chat to the stream on this “beautiful day in LA.” Ironic considering the fact that it was raining.
To amend that, I implemented a weather API that will read the current weather in Los Angeles and update the welcome message to reflect that. Right now the message only updates on launch, which could lead to some inaccuracies by the time the stream starts. I will look into adding an updated every 30 minutes or so.
Down the line, I want to add a more advanced chat system with dynamic messages and that can respond to those who say hi in chat. But where it is right now is something I am happy with.