# Usage
# Twitch Developer Acccount
To use the TwitchAuthComponent
you first need to setup a Twitch Developer Account, so that you can create a Client ID.
Create your Twitch Developer Account here.
# Registering a Twitch App
If you got your Twitch Developer Account setup, navigate to your dashboard and from there view your apps:
Next register a new application:
WARNING
It is important to enter the http://localhost address in the OAuth Redirect URI, otherwise it will not work.
After the application is registered you will be taken to the Manage Application page, here we can find the Client ID we need.
# Before You Dive In
# Plugin Content
TIP
There are two examples included in the content of the plugin. There you can get you hands wet without re-drawing the blueprints below.
To access the content you just have to enable Show Plugin Content in the Content Browser.
# Browser Cache
While testing and implementing your Twitch authentication within your game you are likely to test with different Twitch accounts, as the web browser used within Unreal Engine 4 automatically caches the previous authentications (when sucessfull) you need to clear the browser cache before you test with a different account.
You can delete the cache in your projects when you delete this project folder Saved/webache
.
WARNING
You have to shut down the editor to this.
# Blueprint
# In-Game Web Browser Setup
To use the plugin we need a web browser to display the Twitch authentication page. The plugin is designed so that you can place the web browser in a Widget Blueprint any way you want.
Create a Widget Blueprint and add a web browser to the canvas. The web browser can be found under the experimental category.
TIP
If you can not find the web browser please enable it in the plugin settings of your project. It can be found under Build-In -> Widgets menu.
# Host Actor
Now we need a new Blueprint Actor that will use the TwitchAuthComponent
that ships with this plugin.
Let's create the Actor and add the component to it.
# Component Properties
There are two properties on the component.
- Twitch application Client ID that will be needed to communicate to the Twitch API
- Flag, whether the authentication is verified every time the user start the game.
TIP
Please read the section Twitch Developer Account on how to retrieve your Client ID.
# Component Events
Before we start implementing the actual blueprint let's create the needed events that the component provides for us. As we are dealing with HTTP requests to the Twitch REST API we need callback events when we trigger an action on the component.
# On User Authenticated
This is the callback event for when the authentication process has finished.
# On User Subcribed To Channel
This is the callback event for when the check for a subscription against the Twitch API finishes.
# On Authentication Page Loaded
This event is a little different. It is meant to be used to control the flow of the UI. Common use case for this event is the enabling of the mouse cursor so that the player can interact with the authentication web page.
# On Access Token Page Loaded
This event is fired when the access token page is loaded into the web browser. As this page is only used to extract the access token from the processed authentication we can use it to hide the web browser.
Now we can start implementing the authentication logic.
# On BeginPlay
On BeginPlay we will create web browser widget and start the authentication process via the previously added component.
# On Authentication Page Loaded
On Authentication Page Loaded we will enable the mouse cursor so that the player can interact with the web browsers content.
# On Access Token Page Loaded
On Access Token Page Loaded we will again disable the mouse cursor and hide the web browser as the access token page does not contain any content.
# On User Authenticated
On User Authenticated we can check if the authentication went through successfully. If it did we can retrieve the authenticated user and check if the user is subscribed to a channel. If the authentication did not finish successfully we can retrieve the last error and print it.
# Authentication Successful
# Authentication Failed
# On User Subscribed To Channel
On User Subscribed To Channel we can now process to continue the game, in the given case we just print a message.
# C++
# Modules Setup
As we are trying to use the plugins content through C++ we have to added it as a dependency.
WARNING
We also need to add the dependency for the "WebBrowserWidget" as TwitchAuth depends on it.
# Host Actor
First we need to create a new C++ Actor that will serve as a host to our component.
Choose Actor as the Parent Class:
And give the child a name:
Once the class has been added and the compilation finished successfully Visual Studio will open automatically.
Now that we have a new Actor Class we can add the TwitchAuthComponent
to it.
# Component Events
Before we start implementing the actual code let's go over the events that the component provides for us. As we are dealing with HTTP requests to the Twitch REST API we need callback events when we trigger an action on the component.
# On User Authenticated
This is the callback event for when the authentication process has finished.
# On User Subcribed To Channel
This is the callback event for when the check for a subscription against the Twitch API finishes.
# On Authentication Page Loaded
This event is a little different. It is meant to be used to control the flow of the UI. Common use case for this event is the enabling of the mouse cursor so that the player can interact with the authentication web page.
# On Access Token Page Loaded
This event is fired when the access token page is loaded into the web browser. As this page is only used to extract the access token from the processed authentication we can use it to hide the web browser.
Now we can start implementing the authentication logic.
# Implementation (Header)
First we need to include the header file of the component:
#include "TwitchAuthComponent.h"
Then let's add the component as a public property and create our constructor:
public:
ATwitchAuthExampleActor();
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Twitch Auth")
class UTwitchAuthComponent* TwitchAuthComponent;
Finally we need callback methods that will handle our above mentioned events:
protected:
UFUNCTION()
void HandleOnAccessTokenPageLoaded();
UFUNCTION()
void HandleOnAuthenticationPageLoaded();
UFUNCTION()
void HandleOnUserAuthenticated(bool bAuthenticated);
UFUNCTION()
void HandleOnUserSubscribedToChannel(bool bSubscribed, FTwitchSubscription TwitchSubscription);
WARNING
It is important to mark all this methods as UFUNCTIONs as does will be bound to the events provided by the component.
At last we write a little helper function to print a Twitch error if we encounter one:
private:
void PrintTwitchError(FTwitchError TwitchError);
This is our complete header file:
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "TwitchAuthComponent.h"
#include "TwitchAuthExampleActor.generated.h"
UCLASS()
class FFGPLUGINS_API ATwitchAuthExampleActor : public AActor
{
GENERATED_BODY()
public:
ATwitchAuthExampleActor();
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Twitch Auth")
class UTwitchAuthComponent* TwitchAuthComponent;
protected:
UFUNCTION()
void HandleOnAccessTokenPageLoaded();
UFUNCTION()
void HandleOnAuthenticationPageLoaded();
UFUNCTION()
void HandleOnUserAuthenticated(bool bAuthenticated);
UFUNCTION()
void HandleOnUserSubscribedToChannel(bool bSubscribed, FTwitchSubscription TwitchSubscription);
private:
void PrintTwitchError(FTwitchError TwitchError);
};
# Implementation (Source)
As we are dealing with a component we have to create and add it to the actor in the constructor:
ATwitchAuthExampleActor::ATwitchAuthExampleActor()
{
PrimaryActorTick.bCanEverTick = false;
// Creating the Twitch Auth component.
TwitchAuthComponent = CreateDefaultSubobject<UTwitchAuthComponent>(TEXT("Twitch Auth"));
// Set the client ID.
TwitchAuthComponent->ClientId = "<your_client_id_here>";
// And the verification.
TwitchAuthComponent->bForceVerify = true;
// Finally, we wire up our handler methods.
TwitchAuthComponent->OnAuthenticationPageLoaded.AddDynamic(this, &ATwitchAuthExampleActor::HandleOnAuthenticationPageLoaded);
TwitchAuthComponent->OnAccessTokenPageLoaded.AddDynamic(this, &ATwitchAuthExampleActor::HandleOnAccessTokenPageLoaded);
TwitchAuthComponent->OnUserAuthenticated.AddDynamic(this, &ATwitchAuthExampleActor::HandleOnUserAuthenticated);
TwitchAuthComponent->OnUserSubscribedToChannel.AddDynamic(this, &ATwitchAuthExampleActor::HandleOnUserSubscribedToChannel);
}
To handle the visibility aspect of the web browser displaying the authentication page and receiving the access token URL page we can use the following callback methods:
void ATwitchAuthExampleActor::HandleOnAccessTokenPageLoaded()
{
// We hide the web browser when the access token URL comes in.
UWebBrowser* webBrowser = TwitchAuthComponent->GetWebBrowser();
webBrowser->SetVisibility(ESlateVisibility::Hidden);
}
void ATwitchAuthExampleActor::HandleOnAuthenticationPageLoaded()
{
// We show the web browser when the authentication web page loaded in.
UWebBrowser* webBrowser = TwitchAuthComponent->GetWebBrowser();
webBrowser->SetVisibility(ESlateVisibility::Visible);
}
When the authentication process finishes we have access to the authenticated user and can start to check for subscriptions:
void ATwitchAuthExampleActor::HandleOnUserAuthenticated(bool bAuthenticated)
{
// First we check if the authentication went through successfully.
if(bAuthenticated == true)
{
// Now we can retrieve the authenticated Twitch user.
FTwitchUser user = TwitchAuthComponent->GetUser();
// Writing out a little debug message.
const FString message = user.display_name + " just signed in!";
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, message);
// And now we can check if the authenticated Twitch user is subscribed to a Twitch channel.
TwitchAuthComponent->IsUserSubscribedToChannel("hardlydifficult");
}
else
{
// If authentication was not successful we get the last error and print it.
FTwitchError error = TwitchAuthComponent->GetLastError();
PrintTwitchError(error);
}
}
After the subscription check process finishes we have access to the subscription data and know what to do with the player:
void ATwitchAuthExampleActor::HandleOnUserSubscribedToChannel(bool bSubscribed, FTwitchSubscription TwitchSubscription)
{
// First we check if a subscription is present.
if(bSubscribed == true)
{
// We again here get the Twitch user, but only to print a debug message.
FTwitchUser user = TwitchAuthComponent->GetUser();
// Creating and printing the debug message.
const FString message = user.display_name + " is subscribed to the channel " + TwitchSubscription.channel.name;
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, message);
// Load up the game...
}
else
{
// If the request was not successful we get the last error and print it.
FTwitchError error = TwitchAuthComponent->GetLastError();
PrintTwitchError(error);
// Show message that to the player "Nope, you're not a subscriber..."
}
}
Finally the source code for our little helper method we used throughout the implementation:
void ATwitchAuthExampleActor::PrintTwitchError(FTwitchError TwitchError)
{
// Creating the print message out of the given Twitch error.
const FString message = TwitchError.error + "(" + FString::FromInt(TwitchError.status) + "): " + TwitchError.message;
// And print it.
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, message);
}
This is our complete source file:
#include "TwitchAuthExampleActor.h"
ATwitchAuthExampleActor::ATwitchAuthExampleActor()
{
PrimaryActorTick.bCanEverTick = false;
// Creating the Twitch Auth component.
TwitchAuthComponent = CreateDefaultSubobject<UTwitchAuthComponent>(TEXT("Twitch Auth"));
// Set the client ID.
TwitchAuthComponent->ClientId = "<your_client_id_here>";
// And the verification.
TwitchAuthComponent->bForceVerify = true;
// Finally, we wire up our handler methods.
TwitchAuthComponent->OnAuthenticationPageLoaded.AddDynamic(this, &ATwitchAuthExampleActor::HandleOnAuthenticationPageLoaded);
TwitchAuthComponent->OnAccessTokenPageLoaded.AddDynamic(this, &ATwitchAuthExampleActor::HandleOnAccessTokenPageLoaded);
TwitchAuthComponent->OnUserAuthenticated.AddDynamic(this, &ATwitchAuthExampleActor::HandleOnUserAuthenticated);
TwitchAuthComponent->OnUserSubscribedToChannel.AddDynamic(this, &ATwitchAuthExampleActor::HandleOnUserSubscribedToChannel);
}
void ATwitchAuthExampleActor::HandleOnAccessTokenPageLoaded()
{
// We hide the web browser when the access token URL comes in.
UWebBrowser* webBrowser = TwitchAuthComponent->GetWebBrowser();
webBrowser->SetVisibility(ESlateVisibility::Hidden);
}
void ATwitchAuthExampleActor::HandleOnAuthenticationPageLoaded()
{
// We show the web browser when the authentication web page loaded in.
UWebBrowser* webBrowser = TwitchAuthComponent->GetWebBrowser();
webBrowser->SetVisibility(ESlateVisibility::Visible);
}
void ATwitchAuthExampleActor::HandleOnUserAuthenticated(bool bAuthenticated)
{
// First we check if the authentication went through successfully.
if(bAuthenticated == true)
{
// Now we can retrieve the authenticated Twitch user.
FTwitchUser user = TwitchAuthComponent->GetUser();
// Writing out a little debug message.
const FString message = user.display_name + " just signed in!";
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, message);
// And now we can check if the authenticated Twitch user is subscribed to a Twitch channel.
TwitchAuthComponent->IsUserSubscribedToChannel("hardlydifficult");
}
else
{
// If authentication was not successful we get the last error and print it.
FTwitchError error = TwitchAuthComponent->GetLastError();
PrintTwitchError(error);
}
}
void ATwitchAuthExampleActor::HandleOnUserSubscribedToChannel(bool bSubscribed, FTwitchSubscription TwitchSubscription)
{
// First we check if a subscription is present.
if(bSubscribed == true)
{
// We again here get the Twitch user, but only to print a debug message.
FTwitchUser user = TwitchAuthComponent->GetUser();
// Creating and printing the debug message.
const FString message = user.display_name + " is subscribed to the channel " + TwitchSubscription.channel.name;
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, message);
// Load up the game...
}
else
{
// If the request was not successful we get the last error and print it.
FTwitchError error = TwitchAuthComponent->GetLastError();
PrintTwitchError(error);
// Show message that to the player "Nope, you're not a subscriber..."
}
}
void ATwitchAuthExampleActor::PrintTwitchError(FTwitchError TwitchError)
{
// Creating the print message out of the given Twitch error.
const FString message = TwitchError.error + "(" + FString::FromInt(TwitchError.status) + "): " + TwitchError.message;
// And print it.
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, message);
}
That's it, now you just have to call the Authenticate
method within a child blueprint: