Set up Discord login
Configure your Discord application and wait for a ready authenticated client.
This package enables Discord on Win64 and Android.
- In your Discord application’s OAuth2 settings, enable Public Client for this client-side login flow.
- Add the redirect URL for each target:
http://127.0.0.1/callbackon Win64, anddiscord-APP_ID:/authorize/callbackon Android (replaceAPP_ID). Discord authentication setup - Copy the Application ID into Project Settings → Betide → Crossplay → Discord → Client Id. Set it before packaging Android; the plugin uses it for the app’s URL scheme.
Sign in to Discord
Loading the interactive viewer.
Game Instance variable: DiscordLoginBusy (Boolean, false).
Game module dependencies: DiscordGame, BetideCore, Engine.
// DiscordLoginGameInstance.h
#pragma once
#include "Engine/GameInstance.h"
#include "DiscordLoginGameInstance.generated.h"
UCLASS()
class UDiscordLoginGameInstance : public UGameInstance
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable)
void SignInToDiscord();
private:
bool DiscordLoginBusy = false;
};
// DiscordLoginGameInstance.cpp
#include "DiscordLoginGameInstance.h"
#include "DiscordGameSubsystem.h"
#include "Nodes/Discord_GetAuthToken_AsyncFunction.h"
DEFINE_LOG_CATEGORY_STATIC(LogGameDiscordLogin, Log, All);
void UDiscordLoginGameInstance::SignInToDiscord()
{
if (DiscordLoginBusy)
{
UE_LOG(LogGameDiscordLogin, Warning, TEXT("Discord sign-in is already running"));
return;
}
DiscordLoginBusy = true;
auto *Login = UDiscord_GetAuthToken_AsyncFunction::GetDiscordAuthToken(this);
if (!Login)
{
DiscordLoginBusy = false;
UE_LOG(LogGameDiscordLogin, Error, TEXT("Could not create Discord login action"));
return;
}
const TWeakObjectPtr<UDiscordLoginGameInstance> WeakThis(this);
Login->CompletionCallback = [WeakThis](const FString &, const FBetideError &Error) {
UDiscordLoginGameInstance *Self = WeakThis.Get();
if (!Self)
return;
Self->DiscordLoginBusy = false;
if (Error.IsError())
{
UE_LOG(LogGameDiscordLogin, Warning, TEXT("%s"), *Error.Message);
return;
}
if (const UDiscordGameSubsystem *Discord = Self->GetSubsystem<UDiscordGameSubsystem>())
{
UE_LOG(LogGameDiscordLogin, Log, TEXT("Discord ready: %s (%lld)"),
*Discord->GetDiscordDisplayName(), Discord->GetDiscordUserId());
}
};
Login->Activate();
}Login authorizes communication scopes, exchanges the code, applies the token, and connects. Success means the client reached Ready. The connection stage has a 30-second timeout; that is not a timeout for the authorization UI. The returned access token can be passed explicitly to an external-auth consumer such as EOS Connect; never log it.
Keep the connection ready
Observe On Discord Client Status Changed for disconnects and reconnection. Connect Discord Client resumes an initialized connection; Disconnect Discord Client stops it. Neither is an account login/logout operation.
In C++, use UDiscordGameSubsystem from DiscordGameSubsystem.h. ConnectDiscord() and DisconnectDiscord() control the connection. RevokeToken(Token) requests token revocation. Bind On Discord Command Completed first and check the RevokeToken result. The cached session is cleared before the request completes; an empty cache does not confirm revocation.
Refresh and stored tokens
The subsystem refreshes automatically after token expiry when it has a refresh token. Otherwise, sign in again. Fetch Discord User For Token validates a stored access token and reports On Discord Token User Fetched; bind the event before calling, then apply a valid token with Update Access Token.
Use Get Discord Runtime Snapshot when diagnosing SDK availability, application ID, authentication, and the current user. Keep tokens in secure storage if your game persists them. Multiple test users must authorize the same Discord application.
Next: friends and invites or lobbies and voice.