• Drac346 EpikFail

[PowerShell] Accessing the Twitch API - Basic Version

I received a question in discord about my PowerShell scripts for accessing the twitch API.


Q. Drac, "I was wondering if you post any of your code anywhere for others to use?"


A. I do not have my code posted. I'm not a PowerShell developer by any means and my code often works for me, but rarely for others since I have never taken the time to learn how to write actual PowerShell modules. However, I'm happy to write about what I'm doing that works for me and I hope they help you on your PowerShell journey. Perhaps once day I'll learn how to develop actual PowerShell modules.


Steps Overview

  1. Create Developer Application and record your ClientID and Secret

  2. Create PowerShell Class

  3. Create Function to collect the OAuth Token

  4. Create Function to format our API Headers

  5. Create Function to make our API requests

Requirements

This script will work with PowerShell 5.1 on Windows 10. However, it was written on Windows 10 in Visual Studio Code against PowerShell 7.1 using .NET CORE as the framework.


Need Help?

I am active in my discord. http://discord.pas.team Hit me up in the #drac channel. You can also visit me and ask questions on nights that I'm streaming to twitch (I have no set schedule). https://twitch.tv/drac346


Create Developer Application and record your ClientID and Secret


  • Provide the default values for a script. Localhost will allow you to run this locally on your PC.


  • Record (copy/paste) the ClientID and Secret. We will need this in our PowerShell script. Note: click the 'new secret' button to generate the initial secret key.


  • ClientID = 33litknkhjctyjj252bu09cfcnli7m

  • Secret = vbipdw7dypwhw2k9kiwk5ujdvez8yl

  • That's all we need from the website. Create your bookmark and you can close the page. Keep your ClientID and Secret handy for the next step. DO NOT SHARE your ClientID or Secret with anyone! I'm do it here for the blog but the application will be deleted prior to this blog being posted.


Create a PowerShell Class

I am a fan of creating a PowerShell class so we can build custom PowerShell objects exactly the way we want them. In my class definition, I set the default values and the expected types for each variable I plan to store and use in various scripts.

class TwitchAuthToken {
 [string]$tokenName = "Drac's Blog Application"
 [string]$redirectURL = "http://localhost"
 [string]$clientID = "33litknkhjctyjj252bu09cfcnli7m"
 [string]$clientSecret = "vbipdw7dypwhw2k9kiwk5ujdvez8yl"
 [string]$accessToken
 [datetime]$tokenCollected
 [datetime]$tokenExpiration
 [string]$tokenType = "bearer"
 [string]$authenticationHeader
}

The first 4 values are identical from the Twitch Developers website and we are storing them as static values. The 5 remaining are created so we can make future calls to various parts of the OAuth token as we make multiple calls to twitch.


Most of these variables will not be used in the 'basic' version of this blog post, but I recommend you store the results in your scripts. Twitch provides you a token that is good for xxx amount of time and yyy number of requests per minute. You can uses these in a more advanced script to build logic into your functions to know when you do, and do not, need a new OAuth token.


Create a Function to collect the OAuth Token

I created a function for what I consider the absolute basics of what you need to successfully talk to the twitch API in your PowerShell scripts.


There are several ways to do this, better ways, but I'm going to show you the simplest example I can think of so you understand all of the elements and what we are doing every step of the way.


Steps overview

  1. Create the URI that we need to send to Twitch

  2. Send the API request for our OAuth Token

  3. Store the results of the web response

Create the URI that we need to send to Twitch

Our first step is to create the OAuth web request. Twitch defines this as a Client Credential for the type of request I'm using. Details of what we are trying to achieve can be found here: https://dev.twitch.tv/docs/authentication/getting-tokens-oauth#oauth-client-credentials-flow


The code for our URI creation looks like the below snippet. You can format this as a single line in your code, but I found better success building it over a few lines. The [uri]::EscapedataString will convert any special characters to the RFC format for a HTTP string (as requried).

 $twitchUri = "https://id.twitch.tv/oauth2/token"
 $twitchUri += '?client_id='+[uri]::EscapeDataString("33litknkhjctyjj252bu09cfcnli7m")
 $twitchUri += '&client_secret='+[uri]::EscapeDataString("vbipdw7dypwhw2k9kiwk5ujdvez8yl")
 $twitchUri += '&grant_type=client_credentials'

The result of our variable will now look like this if you created it successfully



Send the API request for our OAuth Token

The next step is to send our request to twitch and store the result


If we make only the request for testing purposes then we just need the code that happens after the variable. The first line in the result is the status code. 200 is a success which means we are successfully talking to twitch.

The information we really want is in the 'content' block. We can look at this by wrapping the query in () and adding .content to the end. Like this:


Since we have a success, lets save the entire response from twitch as a variable so we can play with the content instead of making multiple, redundant requests to the service.

$response = Invoke-WebRequest -Method Post -Uri $twitchUri -UseBasicParsing


Store the results of the web response

We noted above that we only care about the 'content' of that web request. Looking at the structure, it's in JSON format as a [key:value] pair. We will create a new variable that extracts just the information we want; leaving everything else in the old variable just in case we want it for testing.

$accessTokenImport = ConvertFrom-Json -InputObject $response.Content

This will give us the following results in our new variable



The last step is to store our response as a PowerShell object. This is where the custom class comes into play that we create at the beginning of this blog.

We begin by creating a new variable and specifying it's type as our custom class. This will set the default values that we defined above and set us up for importing the new data elements.


The script continues by populating each element and providing some default structure for our next function within the .authenticationHeader variable.


If things are correct so far, you should be able to view your variable and see all of the fields populated.





Create a Function to format our API Headers

We now have everything we need to make API calls to Twitch using PowerShell. Now we need to create a quick function that will convert our values into the correct object type necessary to make a web request.


This is the code I'm using for this example. There are more efficient ways to make this request but this example makes is very easy to see what is going where.


The first line makes a call to the function we created in the pervious step of this blog and stores our result as a variable.


Next we need to create another custom PowerShell object, but this time we need to define it as a generic dictionary which will be required for the header portion of our twitch API calls. We will set it as a hash table and populate it with Authorization and Client-ID Fields. When complete; we should end up with the following result stored in our $authHeadTwitch variable:




Create a Function to make our API requests

We've made it! Time to actually request some information from the Twitch API.

Steps Overview:

  1. Make sure we've loaded all of the code within the functions and we have 'run' them (or copied/pasted the entire function into the shell) to get them loaded into our session.

  2. Make the API call and store the result

  3. Display the result

I'm going to skip Step 1 in the overview. Step 1 is a summary of everything we have done so far and all of the functions should be loaded into the shell. If you are unsure of anything, now is your chance to look at the full code down below and make sure you've done your implementation correctly.


Step 2 and 3 are making the call, storing the result, and displaying the JSON content in a readable fashion. Like the previous examples, you can make the call without storing it into a variable for testing purposes. Ensure you receive your StatusCode of 200 and don't forget that the information we want is in the Content block. However, when you convertfrom-json, it will be reformatted into the DATA block.

I want to point out that in this example I have a hardcoded URI pointing to my twitch page. You can build this URI just like we did in the above example when I was building the OAuth URI. You start by creating the base variable and adding the sections to the line one at a time until you have your URI of choice. The twitch developers portal has a LOT of examples of what your URI needs to look like.


The code above uses the Get-Users API of twitch and I hardcoded the login=drac346 portion of that API endpoint. You can get more details on this API and all others here: https://dev.twitch.tv/docs/api/reference#get-users


What's Next?

Here are some improvements I have in my version of the script specific to the Authentication portion of the Twitch API

  1. Store the token: check expiration and renew as necessary

  2. Create loop for checking the number of requests remaining on that token for the cooldown period provided by the API calls. This is in the RAWCONTENT block of the result prior to the json conversion. See ratelimit-limit, ratelimit-remaining, and reatelimit-reset values that is provided with every twitch API call result. Create function that check's those after each API call and determine if you should continue or pause until the cooldown time (reset) has expired.

  3. Store your clientID and Secret in an encrypted file. Then update your code to decrypt the values as they are needed instead of storing them in your code.

  4. Remove all static instances of the ClientID and Secret, replace them with your functions to decrypt on the fly (see #3 above)

Full Code

I don't have this in GIT since it is just an example, but here's a copy of the full script I used in this blog post.



Contact Drac

You can find Drac active on Discord at: http://discord.pas.team

©2020 by KrookedSkull