Migrating from Kraken to Helix Twitch API

15 October 2020 — Written by Almin
#personal#project#API#twitch

Few months back I've seen that my website Splitstream does not work. The issue seems to be that twitch changed their API policy. They switched from the Kraken to Helix API.

The official documentation of Twitch suggests this way of handling authentication with the Helix API

The old way with using Kraken is doing a API request with just the Client-ID .

Example:

curl -H 'Accept: application/vnd.twitchtv.v5+json' \
-H 'Client-ID: XXXXXXXX' \
-X GET 'https://api.twitch.tv/kraken/games/top'

However, with the new Helix API, the request looks liek this:

curl -X GET 'https://api.twitch.tv/helix/games/top' \
-H 'Authorization: Bearer XXXXXXXX' \
-H 'Client-Id: XXXXXXX'

As we can see there is now a Authorization header which requires us to send a Bearer token, there are 3 ways of getting a token. (Reference)

  • First way Implicite code flow

    • Send the user you want to authenticate to your registered redirect URI, which in human language means that the user should Authorize the app in a seperate window / popup which will be open, kinda like the google login things we see.
  • Second way is OAuth authorization code flow

    • To be honest it looks the same as the first one, with the only change is that there is an extra step with an Authrozation code.. I really have not dug deeper into it.
  • The third way, OAuth client credentials flow, which in the end I used and I think is the "easiest" for my use case. I Prefere it because My users do not have to be redirected somewhere or have to do a login for the app. Its essentially a server to server communication.

In the end I've created a small node server with express, and just added one endpoint which fetches the token. It looks like this:

app.get('/getToken', async function (req, res, next){
    const dataToReturn = await getCredentials()
    var dataReturner = dataToReturn.data
    // Redis to save the token
    client.set("token", dataReturner.access_token)
})


async function getCredentials() {
    var secret = SECRET_ID
    var clientid  = CLIENT_ID
    const url = 'https://id.twitch.tv/oauth2/token?client_id=' + clientid + '&client_secret=' + secret + '&grant_type=client_credentials'
    const responseToken = await axios.post(url)
    return responseToken
}

app.get('/getTopgames', async function(req, res, next) {
    
    let topGames = await axios.get('https://api.twitch.tv/helix/games/top?first=5', {
      headers: {
        'Client-ID': CLIENT_ID,
        'Authorization':'Bearer ' + client.get("token")
      }
    })

    res.json({topGames})
    
)}
 

I've also migrated all my endpoints to this nodejs Server where my frontend calls my node server which then calls the Twitch API. Think of it like a small wrapper around the twitch API. So now we have a small nodeJs server with the Twitch API calls and it is totally isolated from the frontend which only gets returned the data.

After you set the token it should be fairly easy to use it in a endpoint.

Note: Securet the endpoint if you are using it on a external server. My go to would be just using CORS for this.