Creating a Twitch Chatbot with Python3

There are countless chatbots you can use for your Twitch channel. Each of these performs specific tasks very well, but all of them tend to fail at giving the ability to create complex, custom functionality. In my quest to find a chatbot that can integrate with Spotify’s API, I found that creating my own bot was likely the best option, and much easier than expected.

Today we are going to create a chatbot that can be ever vigilant in your channel so your viewers can maximize their experience while watching you play.

Twitch’s entire chat system is a UI layered on top of IRC. Which makes this a much easier project, as there are many tools already to hook into IRC. Before moving forward, I highly recommend making yourself familiar with Twitch’s documentation for IRC and chatbots, we will touch on some of it, but will not cover it in its entirety. As you expand the functionality of your chatbot, you will want to have the documentation handy.

You will need to create a secondary twitch.tv account to function as your bot. This isn’t mandatory but is highly recommended, as to not confuse your viewers to who is speaking in chat. You should name this something that will quickly and clearly tell your views that it is a bot account, and it is your bot account!

Now on to the programming. The first step is to set up the class that will handle connections to Twitch’s IRC network and will aid us in the heavy lifting. We will be using the irc package, specifically the SingleServerIRCBot class.

Let’s create a class to function as our IRC management layer. The channel corresponds to your username, prepended with a #.

from irc.bot import SingleServerIRCBot

server = "irc.chat.twitch.tv"
port = 6667


class Tmi(SingleServerIRCBot):
    def __init__(self, username, password, channel, message_handler):
        self.channel = "#" + channel
        self.message_handler = message_handler

        super().__init__([(server, port, password)], username, username)

We will overwrite many of the methods within the base class to be tailored more towards Twitch’s IRC implementation.

def on_welcome(self, client, _):
    client.cap("REQ", ":twitch.tv/membership")
    client.cap("REQ", ":twitch.tv/tags")
    client.cap("REQ", ":twitch.tv/commands")
    client.join(self.channel)

Twitch requires that we request a number of permissions before attempting to join a channel and fully connect. Once requested, we can join our channel.

Now we need to handle messages as they come in, and respond as needed.

def on_pubmsg(self, client, message):
    response = self.message_handler(message)

    if response:
        c.privmsg(self.channel, response)

If you noticed in the constructor, we passed message_handler this function will parse and react to the messages and allow us to write code agnostic to the IRC client. This will provide us the ability to scale our application to much more complex functions.

Now that we have a class that allow us to connect to Twitch’s IRC, we need to start our bot and connect to Twitch. You will need to generate a specific OAuth password to connect to the IRC server. The password can be created here. Make sure you are logge`d in as your bot account, not your primary account when generating the password.

def start_bot(parse_message):
    channel = "<twitch_username>"
    username = "<twitch_bot_account>"
    password = <oauth_password>

    bot = Tmi(username, password, channel, message_handler)
    bot.start()

Next, let’s create a stub for our message_handler.

def message_handler(msg):
    pass

We will come back and fill that out with more functionality, but now we can run our script and connect to our twitch channel.

start_bot(message_handler)

Your bot should start and connect to Twitch. It is now reading any messages from chat and can act upon them if someone triggers your commands.

The msg variable in your message_handler is an Event Object. It provides information about the user who sent the message as well as, metadata about the message itself. We can use this to power more advanced functionality, but for now, let’s tackle a !dice bot.

import random

def message_handler(msg):
    chat_message = msg.arguments[0]

    if chat_message == "!dice":
        return f"You rolled a {random.randint(1, 6)}"

That’s it! Our on_pubmsg calls our handler, and sends a message to chat with our method response. Additional commands will be very easy to create, as a result, this will allow us to create much more complex commands with relative ease.

From here you can really do anything with the messages you get from your viewers, as well as set up timers to send your own messages to chat. As for my case of the Spotify API, I will keep you updated as the project progresses! Now that you have the tools to create commands, what are some interesting commands you foresee creating? Let me know on my Mastodon account