You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
8.2 KiB
150 lines
8.2 KiB
# Twitch IRC Bot
|
|
|
|
A simple answer bot written in Go that uses Twitch's IRC service to do most of the work. This project is meant to explain to anyone else trying to make a similar client all the weird setup crap Twitch makes you do with OAUTH2.
|
|
|
|
## How to Actually Write a Twitch Bot
|
|
|
|
Twitch's documentation on this is _extremely_ confusing. It's the classic, "We've explained every
|
|
single thing exactly but didn't explain how they all work together." In this document I'm going to
|
|
explain how you _actually_ get a Twitch bot setup. I'm using IRC but this initial setup should apply
|
|
to the WebAPI...I think.
|
|
|
|
## Overview of the Problem
|
|
|
|
Twitch uses [Oauth2](https://oauth.net/2/) to confirm that a user wants to give your bot access to
|
|
their account. This is a good thing. Imagine you have a bot that pays people channel points or
|
|
some similar thing and any user that wants to play with your bot must give them access. Then the
|
|
flow is something like this:
|
|
|
|
1. User says, "Hey, this bot is cool I want to use it."
|
|
2. User goes to a web page explaining the bot.
|
|
3. Use clicks the, "Give Access" button which is _your button on your site, not twitch.tv_.
|
|
4. This then sends the user to twitch.tv's Oauth2 receiver and Twitch confirms they actually do want
|
|
to give the bot access. This will also list the things your bot wants access to in their
|
|
account.
|
|
5. Once they click the confirmation on _twitch's Oauth2_ end point, twitch bounces them back to your
|
|
site's "oauth2 is done" URL.
|
|
6. Your bot now has access to the information you requested in their account.
|
|
|
|
That's all reasonable, and should be the same process for other features like extensions.
|
|
|
|
## Anyone Using Oauth2 for Servers Deserves to Rot in Hell
|
|
|
|
Twitch, in their infinite wisdom decided that _you_--the bot author--would use this same workflow to
|
|
__give a bot you created in their own UI access to your own bot you created in your own account__.
|
|
If that sounds dumb it is, and I have a theory about why they're doing this at the end.
|
|
|
|
To make things worse, Twitch does not explain this weird "use oauth2 to get a key for my bot" flow
|
|
and they have errors in their UI. Here's the flow:
|
|
|
|
1. You would like to create a simple bot using Twitch's IRC.
|
|
2. You register your bot at https://dev.twitch.tv/console/apps/
|
|
3. Your bot has a __Client ID__ and __Client Secret__.
|
|
4. You also...register an Oauth2 end point. Why does a bot that you run on a server need Oauth2?
|
|
This also has to be `https` in the UI.
|
|
5. Because, to get the _actual_ key you use you have to get an Oauth2 URL at twitch.
|
|
6. When you go to this URL--that's exactly like the one for a user using your bot--it will ask you
|
|
to...give yourself access to your own bot...that you just __fucking created in their fucking UI
|
|
and got a two fucking keys for__. You have KEYS ALREADY!
|
|
7. You click the "Give Myself Access to Myself" button on the Oauth2 page, and it bounces you back
|
|
to your...Oauth2 receiver that you definitely don't have because the _fucking bot is running on
|
|
your computer at localhost and their stupid UI only allows `https` endpoints!_
|
|
8. That means _you_ have to run an _entire Oauth2 stack on a computer on the internet_ just to get
|
|
_yet another key_ from their Oauth2 system that's using the key they already gave you from their
|
|
application registration.
|
|
9. Finally, when you get this key, it's not permanent. No, you have to refresh it using a _refresh
|
|
key_ so we're now up to 4 different keys just to create a bot.
|
|
|
|
Yes, it is as absolutely stupid as it sounds, but I'm going to tell you how to get this to work.
|
|
|
|
## Just Use the `twitch-cli`
|
|
|
|
Thankfully, someone at Twitch rebelled against the middle manager in charge of this raging pile of
|
|
bullshit and created the lovely [twitch-cli](https://dev.twitch.tv/docs/cli/). The `twich-cli`
|
|
command will handle the Oauth2 bullshit for you, even setting up a local server and also handling
|
|
the token management. It's also written in Go so you can study how they do it and you can even
|
|
install it on Windows with `winget install Twitch.TwitchCLI`.
|
|
|
|
2. Log into your account and go to https://dev.twitch.tv/console/apps/
|
|
3. Click "Register Application"
|
|
4. Give it a unique name, _but you will not use this name in the IRC login later_. Yes, you heard
|
|
me right.
|
|
5. On the __OAuth Redirect URLs__ you'll see this error `Redirect URIs must use HTTPS protocol`. The
|
|
problem is `twich-cli` creates a Oauth2 receiver at `http://localhost:3000` so it can't be https.
|
|
__Just add http://localhost:3000/ anyway.__ The error message seems to be wrong, but I ran into a
|
|
situation where I couldn't add so I had to do this:
|
|
|
|
a. Add a fake url `https://localhost:3000`. Yes, `https`, make sure that's there.
|
|
b. Then add a second one with `http://localhost:3000`.
|
|
c. Remove the first `https` one and you're done.
|
|
|
|
6. For the category you must select `Chat Bot` as the category.
|
|
7. You also select `Confidential` as the type of bot. This is because you aren't in a web page but
|
|
instead running as a server.
|
|
|
|
## The Oauth2 Dance
|
|
|
|
After you create your application it's time to dance with Twitch's entirely useless Oauth2 key
|
|
provisioning thing:
|
|
|
|
1. Install [twitch-cli](https://dev.twitch.tv/docs/cli/).
|
|
2. Run `twitch configure` and give it your Client ID and Client Secret. This will configure the
|
|
`twitch` command for later operations.
|
|
3. Run `twitch token --user-token --scopes "chat:read chat:edit"` to get your keys. It's important
|
|
you do `--user-token` here since you need the Oauth2 authentication even though you said in [the
|
|
console](https://dev.twitch.tv/docs/cli/) that your application is Confidential.
|
|
4. The `twitch` command will then open a browser for you to approve your bot using Oauth2.
|
|
5. After you approve it your browser will redirect back to http://localhost:3000/ and the `twitch`
|
|
command will handle the Oauth2 result.
|
|
6. It will then output your `ClientSecret` and `RefreshToken` for the `secret.json` file used in
|
|
this bot's configuration. __DO NOT COMMIT THIS TO GIT__.
|
|
|
|
## Refreshing Your Keys
|
|
|
|
Currently my bot doesn't auto-refresh the keys, but you should only need to send a POST to
|
|
`/oauth2/token` with your `RefreshToken` to renew it. Until then I do this manually:
|
|
|
|
1. Copy `secret_example.json` to `secret.json`.
|
|
1. Run `twitch token --refresh RefreshToken` where I replace "RefreshToken" with my `secret.json`'s
|
|
`RefreshToken` setting.
|
|
2. This outputs a __totally new key that you have to record again__. So update your `secret.json`
|
|
file and it should keep working.
|
|
|
|
Once again, this is incredibly stupid and does not add security to their system. Companies like
|
|
Paypal and Stripe only use secret keys given out by their UI and those companies deal with trillions
|
|
of real dollars. Adding this bullshit key rotation layer on top of Oauth2 does nothing but make
|
|
things complicated and inject a [notoriously](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/05-Authorization_Testing/05-Testing_for_OAuth_Weaknesses) [insecure](https://nvd.nist.gov/vuln/detail/CVE-2026-34457) [system](https://portswigger.net/web-security/oauth) into the mix.
|
|
|
|
|
|
## Running This Bot
|
|
|
|
Once you have your `secret.json` configured you can then edit the `config.json` to configure your
|
|
bot. Run `cp config_example.json config.json` to get your version of the file. Here's they key configurations:
|
|
|
|
`ClientNick`
|
|
: This is _your username_, not the bot's, although the bot's will work too.
|
|
|
|
`Channel`
|
|
: Your channel to join. Not sure if it will work with any channel, but you might be able to use the
|
|
`chat:read` scope.
|
|
|
|
`Commands`
|
|
: This is a list of `{"command": "Message"}` combinations. The "command" is used by the user with
|
|
!command in the chat.
|
|
|
|
`Periodic`
|
|
: This is a list of messages the bot will post into chat periodically. Just say how many seconds to
|
|
wait and it will wait then say that.
|
|
|
|
## TODO
|
|
|
|
1. Hot reloading would be nice.
|
|
2. Controlling the bot from the chat, which would require
|
|
3. Authenticating the owner? Or just knowing it's you.
|
|
4. Productionizing how it's run, as in making it run as a server.
|
|
|
|
## Conspiracy Theory
|
|
|
|
There's a middle manager at Amazon in charge of the Oauth2 system and they will receive a bonus for
|
|
the number of users that utilize Oauth2. To get their bonus this idiot required everyone across the
|
|
company to use Oauth2 in everything even if it didn't make sense like in a server.
|
|
|