So, the big complicated part is learning about making POST requests and how the OAuth authentication tokens work. You can find the template starter code Twitch provides here: https://dev.twitch.tv/docs/chat/chatbot-guide/ that gives you a good starting place to work from in getting things working, but this guide will try to provide information on how to get (and refresh automatically) your OAuth tokens, and how to customize the authentication request for different things your Twitch bot can listen to.
TLDR
- 1. Make your Chat Bot Application in dev.twitter (get Client ID and Client Secret)
- 2. Make a POST request to https://id.twitch.tv/oauth2/authorize with the appropriate scope permissions from your bot account in the browser, authorize and get the code from the output URL
- 3. Make a POST request to https://id.twitch.tv/oauth2/token using the code from part 2 to get your OAuth code and Refresh Token
- 4. Get your Stream and Bot numeric IDs from https://www.streamweasels.com/tools/convert-twitch-username-%20to-user-id/
- 5. Get the starter code from Twitch, set up your project space, fill in the constant values with the values from steps 3 and 4, and run it!
- 6. As a bonus, do security with .env files, set up automatic OAuth token refreshing
- 7. Creatively program bot behaviors! The baseline works, now do real programming!
Assumptions
I am assuming you have a main Twitch account (the streaming account) and a secondary Twitch account (the bot account). I am assuming you have node.js installed and have done the "How to set up and run the code" steps in the link provided above from dev.twitch (basically having done npm init and npm install ws).
You will also need to go to https://dev.twitch.tv/ to get your bot's Client ID and Client Secret.
If you want to get ahead of the game on being secure about your codes/tokens, also install this https://www.npmjs.com/package/dotenv when you set up your project for a much later step.
Getting our Client ID and Client Secret
Go to https://dev.twitch.tv/, log in as your stream account, go to your Console > Applications, and register a new application. The name can be whatever is descriptive for your bot, the redirect url should be http://localhost (this doesn't really get used in our relatively simple bot here), and you need to set the Client Type to Confidential. Category should be Chat Bot as that is what we are making here.
Once created, you will see your Client ID and can generate a secret token. Make sure you copy the secret token and store it securely. Keep these handy for later.
What is OAuth?
OAuth is a way to get a secret token string that lets an arbitrary javascript program send POST/GET requests to the Twitch API under the identity of a particular twitch account. They are primarily used here to subscribe your bot to different 'events' that occur during your stream (chat messages, follows, message deletions, subscriptions, etc.), and then validate their identity when sending chat messages.
You can find the list of such subscribable events here: https://dev.twitch.tv/docs/eventsub/eventsub-subscription-types/ and the example starter code from twitch shows subscribing to channel.chat.message.
Security is complicated, and there used to exist convenient sites that would auto-generate you a token but that has become frowned upon and most guides assume a greater familiarity with how to do this sort of thing than I had when I started. You basically just have to send a few POST requests to two different URL's owned by Twitch with some ID info for your bot, and then use the code you get from doing that to verify that you're legit and pre-authorized to do stuff.
Once you've done it and it's working, it's actually quite trivial, but going from not understanding at all to being able to do it can take some work so this guide will do it's best to get you there smoothly and introduce some convenient tools to make it go faster.
OAuth Step One: Authorization code (set permissions here)
OAuth is acquired in two steps: first, by sending a POST request to this address: https://id.twitch.tv/oauth2/authorize with additional information included as parameters to specify your bot account identifier, the permissions you are requesting for it, where to send back the data you are requesting, and some metadata.
You can manually set up this address as https://id.twitch.tv/oauth2/authorize followed by parameters for:
- client_id (Client ID of your bot you get from https://dev.twitch.tv/console)
- redirect_uri (where the response is sent to; we use 'http://localhost')
- response_type (keyword, set this to "code")
- scope (which permissions we want for our bot; the list of subscribable events details which permissions each event requires)
- state (an arbitrary code you can set and ensure is sent back to you unchanged for data integrity)
- force_verify (not actually sure, but we set this to "true")
The most complicated part of this is going to be scope due to needing to specially format the ':' symbol as %3A due to HTML encoding. The basic scope requirements are user:read:chat, user:write:chat, and user:bot (maybe also channel:bot?). These need to be formatted, for example, as user%3Aread%3Achat in the URL you are constructing.
Each of the events described here https://dev.twitch.tv/docs/eventsub/eventsub-subscription-types/ detail their scope requirements.
Each of the parameters listed above need to be appended to the end of the base url https://id.twitch.tv/oauth2/authorize as first ?client_id=dfhwjenfgkjawehriawfj and then &=redirect_uri=http://localhost for each following parameter. (The first parameter is prefaced with a ?, then & for the rest).
This is messy, prone to minor errors, and hard to reproduce when you potentially need to do this a dozen times due to small errors or your OAuth token expiring. I recommend you use a free service called Postman that lets you configure URL requests in a neat format that allows easy editing and trivial recall.
Postman
Go to https://web.postman.co/ and make a free account. Make/go to a new workspace, and make a new HTTP request (top left of the screen, click "New" then select HTTP).
Change the type from "GET" to "POST" and then put the base URL in the 'Enter URL or paste text box' next to the button that let you switch "GET" to "POST". Make sure you put the base URL there first. The URL is auto-configured as you add keys/values. Add each of the parameters listed in Step One as Keys, and populate the Value for each with the appropriate value.
Once this is set up, please make sure to Save this URL you have setup in the interface (the save button is above the "Send" button) and give it a descriptive name so that, in a week, you can trivially reload this URL request and not have to figure out the formatting again. Do so for each Postman request we format in this guide.
While there is an option to "Send" this URL and get the data returned to use, we cannot do that for this step. Copy the complete URL and access it in a web browser while logged in as your bot account; you are authorizing your bot account to be used automatically by your program. You do not ask your streaming account for permission for anything (if it's your own bot account, you have likely given it moderator access already).
After you send the first POST request in a browser, it will load a page that asks you to confirm the permissions. You will then be redirected to a new site where the URL header of that blank site has your authorization code. The site you are redirected to is one of the parameters for the POST request; for simplicity, we just redirect to http://localhost and copy our authorization code from the URL header.
This is kind of awkward; ideally we would set up some html page that can interpret the URL to display the code nicely, but it's not that hard to just grab the code from the URL you are redirected to, so we are going to do that for now.
OAuth Step Two: Get your OAuth Code and Refresh Token
Step two: with our authorization code, we make another POST request. This one does not need to be done in a web browser, so we can use Postman's "Send" button after configuring this URL address. The base URL is https://id.twitch.tv/oauth2/token for this one, with the following parameters:
- client_id (the Client ID from dev.twitter)
- client_secret (the Client Secret from dev.twitter)
- code (our authorization code from Step One)
- grant_type (just set this to authorization_code)
- redirect_uri (just set this to http://localhost)
Set this up in Postman like in Step One, it should look like the following:
This time we can just press "Send" and we will see a response back containing our OAuth Token and a Refresh Token.
That is how you get your OAuth Token. These will expire periodically and, in my experience, inconsistently, so we will want to set up an automatic refresh when we are told it has expired.
Side note: For completion's sake, I also did the following step which may do some backend verification, but the code this returns is not needed for anything in the twitch starter code or that I have done so far.
Set up another Postman request with the base URL https://id.twitch.tv/oauth2/token and the following parameters:
- client_id (Client ID from dev.twitch)
- client_secret (Client Secret from dev.twitch)
- grant_type (set to "client_credentials")
This gives you an App Access Token that several guides have said is necessary but in my experience it doesn't work and the OAuth token is able to validate for everything I have done so far. But it might do something in the backend that I'm not aware of, so I'm including it for reference. If things aren't working, maybe run this POST request and see if that changes anything, or try substituting the APP Access Token for the OAuth token.
Debugging processes are random and weird, so that's just another thing to try if stuff breaks.
Back to automatically refreshing our tokens...
But first, how do I set up that starter code from Twitch to work?
The starter code from twitch at https://dev.twitch.tv/docs/chat/chatbot-guide/ has some constant values at the start that you substitute with your own values. Most obviously are OAUTH_TOKEN, which will be the OAuth Token we just generated using the second Postman request, and CLIENT_ID which you got from dev.twitch earlier.
Getting my Stream and Bot IDs (they aren't just my username?)
However, it also references BOT_USER_ID and CHAT_CHANNEL_USER_ID, which are not just the usernames of your bot account and stream account. They are the backend ID identifiers of your accounts, which are not public facing.
Go here: https://www.streamweasels.com/tools/convert-twitch-username-%20to-user-id/ and plug in your account names to get the codes.
I would encourage you to add a new constant REFRESH_TOKEN and store the Refresh Token you got back in step 2 here as well.
At this point, you should be able to run your code (node [my_bot_file].js in the terminal at the directory where you did the npm init earlier) and get the feedback saying it connected successfully. You may get some errors saying you don't have sufficient permissions, which means you should check the scope parameter from step one and make sure that you correctly formatted the permissions and included all of the permissions that the subscribables you're interested in state that you require.
I got more errors than that when I did this the first time, but it's been a while, so reach out and tell me if you get errors (include the feedback in the terminal (removing private information like authorization codes and client ID/secret)) and I'll update this.
Environment File For Security
I encourage you to set up a .env file to store your important codes/variables so that they aren't in the javascript file itself. This is done by making a file that is unnamed and of type '.env.' (on windows, open up a new Notepad file and save it as ".env" with the file type set to "All Files", otherwise it's a file called ".env" of type ".txt" annoyingly).
Include within it lines such as OAUTH_TOKEN=asdasdasdasdasd that contain your codes/tokens.
In the directory for your project, call npm install dotenv --save (https://www.npmjs.com/package/dotenv) to install a package that lets you read the environment in your file. In your Javascript file, add at the top import 'dotenv/config'.
You can now, in your code, reference the variables from .env as process.env.OAUTH_TOKEN to not include them in your files directly. If you upload your files to github, you can put .env in the .gitignore list to share your code without compromising your bot.
The Token Expires Sometimes
Periodically your OAuth token will expire and stuff will stop working. It should take two months but in my experience it's 12 hours for some reason; I'm likely doing something wrong, which means other people will too. You could reuse the Postman requests we set up earlier and manually update the OAuth token in your .env file or still embedded in the .js file itself, or we can use that Refresh Token to automatically take care of it.
In Javascript, as we can see in the starter code from twitch, we can use the 'fetch' library to send POST requests automatically within our code. The same kind of POST requests we were doing with Postman. So, we can send a POST request to refresh our OAuth token and overwrite the .env file to now use the new OAuth Token and Refresh Tokens automatically when we detect that the OAuth Token has expired (which is a 401 error from most other POST requests we send to twitch that use the OAuth token).
I just wrote a function that I could call anytime a request came back with a 401 error (response.status_code contains the status code number) that would send a POST request. The base URL is https://id.twitch.tv/oauth2/token and you're basically just changing the grant_type to "refresh_token" while including the parameter "refresh_token" in your URL.
This returns a JSON file payload (response.json() to access this, which can take some time so make sure you await it), and it will contain your new tokens in the keys "access_token" and "refresh_token". Yes, the refresh token is also changed by this, so you need to store both.
Most of the code below for this function is just rewriting my .env file to replace the old values with the new ones.
That would've been a code embed to easily copy it but the code tag in this editor wasn't working properly. I may make my github repo with my code public at some point in which case I'll just link that here.
With that, once you've set it up once and have this code integrated properly into your project, you can avoid having to think about OAuth tokens until something really major breaks (or your Refresh Token expires somehow so you have to go back to Postman manually).
Thanks for Reading
That's all from me on getting your basic bot set up! I may make another guide at some point for how to further customize this (easier way to manage subscribing to multiple events, convenient ways to have your bot respond to chat commands or dynamically add new ones, how to write your code to get those 'Drink Water!' messages every 20 minutes, and useful ways to get program information for error logging.
Also I have a neat way for having your own on-screen chat messages by dynamically writing the HTML code for it as your bot is running along with an OBS plugin to make Browser Sources refresh automatically. (You can point Browser Sources at local .html files so you can just embed your own code in there, or have your bot write novel content to those .html files that OBS is constantly reading and updating! It's neat).
Thanks for reading, I hope this helps anyone in the same position as I was over this past weekend which ate up many hours of my life.