How To: Build Your First Twitch Bot in 10 Minutes
How To: Build Your First Twitch Bot in 10 Minutes
What is a Twitch Bot?
Twitch Bots can be used by a streamer on the Twitch platform for a variety of reasons. One of the more common use cases for a bot is to moderate the chat in real-time; a bot is not always as accurate as a moderator, but, they are excellent at identifying specific keywords and taking swift action. In addition, bots can be used to react with a streamer’s chat in order to engage the viewers – often through timed reminders and minigames.
Other types of bots:
- Moderation
- Games
- Playing Music
- Posting timed messages to chat
What will our Bot Do?
Despite what you may have heard, implementing your first chatbot for Twitch can be very simple! The goal of this guide is to show you how to make a very simple Twitch bot in only a few minutes.
Starting off as just a little baby-bot our joyous bot will gleefully greet users that we instruct it to or when a user says “Hi” in our stream chat. To test it, we’ll use the StreamLabs chat simulator.!greet CodeTober
in the Twitch chat will cause a message to appear for CodeTober.
CodeTober: Hi – in the chat will cause a message to appear in the chat aimed at CodeTober
The Twitch platform treats a bot just like a normal user. That means the very first step is to simply create a new Twitch account, which can be done using a new or an existing email address. I chose to use the same email address as my normal account when setting up the bot.
When our bot is completed, it will do three main things:
- Authenticate & Join a Stream
- Consume the Stream Chat
- Take some action based on the chat messages
Development Prerequisites
In this guide, we’ll be using NodeJS v14.16.1 and NPM. If you need help getting started with those, check out the NodeJS installation guide, NPM can be automatically installed while configuring NodeJS.
Make sure that your PATH is updated when installing NodeJS so that you can use the node
command in your terminal.
Note: The bot we’re going to make should not be used for commercial purposes as it’s not optimized for production architecture and security.
Building your NodeJS Twitch Bot
Step #1: Create a blank NodeJS App
Navigate to a new directory, and open your command line / terminal to the same directory. I like to Shift+Right-Click and select “Open Powershell window here”. Then initialize a new NPM project with the command npm init,
it will walk you through the necessary steps to set up the Node application.

Now you should notice that a file named “package.json” is located in the directory. This file is how NPM keeps track of any external packages we end up adding to the project.
Open the package.json file and add the highlighted line in the code below to your “scripts” object. This just makes it so that you can type “npm start” in the CMD/Termnial to run your app.
Once completed, your package.json file should look something like this:
{ "name": "twitch-bot", "version": "1.0.0", "description": "My First Twitch Bot", "main": "index.js", "scripts": { "start": "node index.js", "test": "echo \"Error: no test specified\" && exit 1" }, "author": "CodeTober", "license": "MIT" }
In the same folder as your package.json file, create a file called index.js
. This file is where our Node app will be created. Next, just copy the following code into your index file to get your node app bootstrapped.
function sayHello(){ console.log("Hello World"); } sayHello();
RUN IT! By going to your CMD/Termnial inside your project directory (same spot as your index.js and package.json) just enter npm start
and you will see the output message Hello World
printed to the terminal where you ran the project. Similar to the image below.

Quick review
This code is simply creating a function that can be called, which, when called will cause a String to be printed to the console. Pretty easy, yea? As you’ll soon see, the bot is not much more complicated.
Step #2: Adding the TMI.js Twitch Library
The TMI.js library is a wrapper around the logic that allows our bot to authenticate with the Twitch servers, enter a stream, and access the chat contents. We’ll walk through the setup of the TMI code and then register our new Twitch Bot account with TMI to receive an auth token.
Install TMI.js
npm install tmi.js
Configuring our Bot
There are a ton of ways to configure the bot, but, we’re going to stick to the bare minimum so we can get up and running lickity-split.
The two required pieces of the TMI configuration are identity
and channels
. Between those two pieces of configuration, we can get our bot authenticated and join the chat for a Twitch channel.
// add reference to the TMI library const TMI = require('tmi.js'); // Bot Name and Password const BOT_NAME = "HelloBot"; const TMI_OAUTH = "paste your TMI token here"; const TMI_OPTIONS = { identity: { username: BOT_NAME, password: TMI_OAUTH }, channels: [ "codetober" ] } // Connect bot to channels and get client instance const client = new TMI.client(TMI_OPTIONS); client.on('connected', onConnectedHandler); client.connect(); // Called every time the bot connects to Twitch chat function onConnectedHandler (addr, port) { console.log(`Successfully Connected to ${addr}:${port}`); }
If you run this code you’ll see a message Successfully Connected to irc-ws.chat.twitch.tv:443
if the configuration is correct. Make sure to use the username and password from your newly created twitch account (for the bot) when getting your OAuth token from TMI.
After setting up our TMI_OPTIONS
we just created a new instance of the TMI client and then we set up a callback function that is triggered whenever our client
becomes connected. This console.log will run each time our bot is connected to Twitch successfully. If you’re not seeing this message, make sure your username and oauth token are correct.
Reading the Stream Chat
Now that our bot can connect, it’s time to read the chat. Just like we did for the connected
event, this time we’ll register a function to handle the message
event. When a message comes through, we have access to the following parameters:
- target – the channel name that the message came from. This is important because your bot can monitor multiple channels at once
- tags – a set of key value pairs related to the user that sent the message
- message – the String sent in chat
- self – boolean that is
true
when the message is from our bot andfalse
when the message is from another user
Using these parameters, we can handle the incoming messages and decide how/when to reply back into the chat (next step). For now, let’s create the function to listen to the chat and handle messages.
client.on('message', onMessageHandler); function onMessageHandler(target, tags, message, self){ // Just leave this function if the message is from self if(self){ return;} let trimmedMessage = message.trim(); let splitMessage = trimmedMessage.split(" "); // log every message, remove this eventually, for debugging only console.log(target, tags.username, trimmedMessage); if(splitMessage[0] === "Hi"){ // log when a user says "Hi" in chat console.log(tags.username + " said: " + splitMessage[0]); } // TODO: Add command to greet specific users by name }
The point of this function is to do a little bit of cleaning up on messages in a Twitch chat and then log all of the chats to the terminal/CMD. This is one place where we will eventually be responding to the user. But, we don’t only want to respond to viewers in chat that are kind enough to drop a “Hi” in the chat. A good bot will always allow you to tell it what to do – if we want it to greet someone who is being rude by not saying “Hi”, we want to send a command to our bot like !greet <username>
and have our bot send a message to them in the chat.
Responding to a message and contributing to the chat
function onMessageHandler(target, tags, message, self){ // Just leave this function if the message is from self if(self){ return;} let trimmedMessage = message.trim(); let splitMessage = trimmedMessage.split(" "); let targetUser = ""; if(splitMessage.length > 1){ targetUser = splitMessage[1]; } let greetingMessage = `Hey there @${targetUser}! I'm super excited you are here today! Tell the class how you're doin'`; let hiResponse = `What's up @${tags.username}?! Thanks for joining, it's always a good time :D`; // log every message, remove this eventually, for debugging only console.log(target, tags.username, trimmedMessage); if(splitMessage[0] === "Hi"){ client.say(target, hiResponse); } else if(splitMessage[0] === "!greet"){ client.say(target, greetMessage); } }
On the highlighted lines, you notice that we added two different types of greetings for our bot and we also replaced our logging with client.say(target, string)
. The target
is the channel that we want to put the message into and the string
is the message we’d like to send.
Notice that in the greetingMessage we are using splitMessage[1]
which would be a specific username mentioned by someone else in the chat. Whereas the hiResponse uses tags.username
because our bot is responding directly to the viewer that sent the message.
Note: It’s a good idea to add a second condition before saying the greetMessage that will check if the person that issued the command is one of the moderators or the channel owner. That will stop the viewers from spamming the bot and causing an issue in chat.
Full Code for the Bot
// add reference to the TMI library const TMI = require('tmi.js'); // Bot Name and Password const BOT_NAME = "HelloBot"; const TMI_OAUTH = "<tmi oauth token here>"; const TMI_OPTIONS = { identity: { username: BOT_NAME, password: TMI_OAUTH }, channels: [ "<some channel name>" ] } // Connect bot to channels and get client instance const client = new TMI.client(TMI_OPTIONS); client.on('connected', onConnectedHandler); client.on('message', onMessageHandler); client.connect(); // Called every time the bot connects to Twitch chat function onConnectedHandler (addr, port) { console.log(`* Connected to ${addr}:${port}`); } // Called every time a message is typed in a chat that the bot is connected to function onMessageHandler(target, tags, message, self){ // Just leave this function if the message is from self if(self){ return;} let trimmedMessage = message.trim(); let splitMessage = trimmedMessage.split(" "); let targetUser = ""; if(splitMessage.length > 1){ targetUser = splitMessage[1]; } let greetingMessage = `Hey there @${targetUser}! I'm super excited you are here today! Tell the class how you're doin'`; let hiResponse = `What's up @${tags.username}?! Thanks for joining, it's always a good time :D`; // log every message, remove this eventually, for debugging only console.log(target, tags.username, trimmedMessage); if(splitMessage[0] === "Hi"){ client.say(target, hiResponse); } else if(splitMessage[0] === "!greet"){ client.say(target, greetMessage); } }