Skip to main content

Google Login

This API logs in with a Google account.

URL Confirmation

This API uses the service-account.playnanoo.com domain.

API Information

  • URL: https://service-account.playnanoo.com/api/v20240401/google/signin
  • Method: PUT
  • Authentication Required: No

Request Parameters

ParameterTypeRequiredDescription
linked_idstringRequiredGoogle ID token
platformstringRequiredPlatform (e.g., "aos", "ios") - Auto-included
device_idstringRequiredDevice unique ID - Auto-included
device_modelstringRequiredDevice model name - Auto-included
device_osstringRequiredDevice OS - Auto-included
device_languagestringRequiredDevice language (e.g., "KO", "EN") - Auto-included
Auto-included Device Information

Using FPlayNANOOHelper::CreateRequestBody() automatically includes platform, device_id, device_model, device_os, and device_language.

Response Data

Token Information

  • AccessToken: Access token
  • RefreshToken: Refresh token

Player Information

  • UserUniqueID: User unique ID
  • OpenID: Open ID
  • Nickname: Nickname
  • LinkedID: Linked ID (Google ID)
  • LinkedType: Linked type (google)
  • PurchaseCount: Purchase count
  • PurchaseCurrencyCode: Purchase currency code
  • PurchaseTotalPrice: Total purchase amount
  • Country: Country
  • Timezone: Timezone
  • Offset: Time offset
  • JoinPeriod: Join period

Unreal C++ Implementation

Header File (GoogleSignin.h)

// GoogleSignin.h
#pragma once

#include "CoreMinimal.h"
#include "Json.h"
#include "JsonUtilities.h"

// Response callback delegates
DECLARE_DELEGATE_OneParam(FOnGoogleSigninSuccess, const FString&);
DECLARE_DELEGATE_OneParam(FOnGoogleSigninError, const FString&);

class YOURPROJECT_API FGoogleSignin
{
public:

// Token response struct
struct FTokenData
{
FString AccessToken;
FString RefreshToken;

void FromJson(TSharedPtr<FJsonObject> JsonObject)
{
JsonObject->TryGetStringField(TEXT("AccessToken"), AccessToken);
JsonObject->TryGetStringField(TEXT("RefreshToken"), RefreshToken);
}
};

// Player response struct
struct FPlayerData
{
FString UserUniqueID;
FString OpenID;
FString Nickname;
FString LinkedID;
FString LinkedType;
int32 PurchaseCount;
FString PurchaseCurrencyCode;
double PurchaseTotalPrice;
FString PurchaseVoidedCount;
FString PurchaseVoidedCurrencyCode;
FString PurchaseVoidedTotalPrice;
FString Country;
FString Timezone;
int32 Offset;
int32 JoinPeriod;

void FromJson(TSharedPtr<FJsonObject> JsonObject)
{
JsonObject->TryGetStringField(TEXT("UserUniqueID"), UserUniqueID);
JsonObject->TryGetStringField(TEXT("OpenID"), OpenID);
JsonObject->TryGetStringField(TEXT("Nickname"), Nickname);
JsonObject->TryGetStringField(TEXT("LinkedID"), LinkedID);
JsonObject->TryGetStringField(TEXT("LinkedType"), LinkedType);
JsonObject->TryGetNumberField(TEXT("PurchaseCount"), PurchaseCount);
JsonObject->TryGetStringField(TEXT("PurchaseCurrencyCode"), PurchaseCurrencyCode);
JsonObject->TryGetNumberField(TEXT("PurchaseTotalPrice"), PurchaseTotalPrice);
JsonObject->TryGetStringField(TEXT("PurchaseVoidedCount"), PurchaseVoidedCount);
JsonObject->TryGetStringField(TEXT("PurchaseVoidedCurrencyCode"), PurchaseVoidedCurrencyCode);
JsonObject->TryGetStringField(TEXT("PurchaseVoidedTotalPrice"), PurchaseVoidedTotalPrice);
JsonObject->TryGetStringField(TEXT("Country"), Country);
JsonObject->TryGetStringField(TEXT("Timezone"), Timezone);
JsonObject->TryGetNumberField(TEXT("Offset"), Offset);
JsonObject->TryGetNumberField(TEXT("JoinPeriod"), JoinPeriod);
}
};

// Response struct
struct FRes
{
FString ErrorCode;
FString Message;
FTokenData Token;
FPlayerData Player;

bool FromJson(const FString& JsonString)
{
TSharedPtr<FJsonObject> JsonObject;
TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(JsonString);

if (FJsonSerializer::Deserialize(Reader, JsonObject) && JsonObject.IsValid())
{
JsonObject->TryGetStringField(TEXT("ErrorCode"), ErrorCode);
JsonObject->TryGetStringField(TEXT("Message"), Message);

const TSharedPtr<FJsonObject>* TokenObject;
if (JsonObject->TryGetObjectField(TEXT("Token"), TokenObject))
{
Token.FromJson(*TokenObject);
}

const TSharedPtr<FJsonObject>* PlayerObject;
if (JsonObject->TryGetObjectField(TEXT("Player"), PlayerObject))
{
Player.FromJson(*PlayerObject);
}

return true;
}
return false;
}
};

/**
* Send Google login request
*/
static void Send(
const FString& GoogleIdToken,
FOnGoogleSigninSuccess OnSuccess,
FOnGoogleSigninError OnError
);
};

Implementation File (GoogleSignin.cpp)

// GoogleSignin.cpp
#include "GoogleSignin.h"
#include "PlayNANOOHelper.h"
#include "HttpModule.h"
#include "Interfaces/IHttpRequest.h"
#include "Interfaces/IHttpResponse.h"

void FGoogleSignin::Send(
const FString& GoogleIdToken,
FOnGoogleSigninSuccess OnSuccess,
FOnGoogleSigninError OnError)
{
// Create request data (device info is automatically included)
TSharedPtr<FJsonObject> Body = FPlayNANOOHelper::CreateRequestBody();
Body->SetStringField(TEXT("linked_id"), GoogleIdToken);

// Convert to JSON
FString JsonBody;
TSharedRef<TJsonWriter<>> Writer = TJsonWriterFactory<>::Create(&JsonBody);
FJsonSerializer::Serialize(Body.ToSharedRef(), Writer);

// Create HTTP request
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> Request = FHttpModule::Get().CreateRequest();
Request->SetURL(TEXT("https://service-account.playnanoo.com/api/v20240401/google/signin"));
Request->SetVerb(TEXT("PUT"));
Request->SetContentAsString(JsonBody);

// Set common headers (no authentication token needed for login API)
FPlayNANOOHelper::SetCommonHeaders(Request, false);

// Handle response
Request->OnProcessRequestComplete().BindLambda(
[OnSuccess, OnError](FHttpRequestPtr Req, FHttpResponsePtr Res, bool bSuccess)
{
if (bSuccess && Res.IsValid())
{
FString Response = Res->GetContentAsString();
FRes Result;
if (Result.FromJson(Response))
{
if (Result.ErrorCode.IsEmpty())
{
// Success
OnSuccess.ExecuteIfBound(Response);
}
else
{
// Error response
OnError.ExecuteIfBound(Response);
}
}
else
{
// JSON parsing failed
OnError.ExecuteIfBound(TEXT("Failed to parse response"));
}
}
else
{
// HTTP request failed
OnError.ExecuteIfBound(TEXT("HTTP request failed"));
}
}
);

// Send request
Request->ProcessRequest();
}

Usage Example

void UYourClass::GoogleLogin()
{
// After receiving ID token via Google login SDK
FString GoogleIdToken = TEXT("Google_ID_Token");

// Google login request (device info is automatically handled by FPlayNANOOHelper)
FGoogleSignin::Send(
GoogleIdToken,
FOnGoogleSigninSuccess::CreateLambda([](const FString& Response)
{
FGoogleSignin::FRes Result;
if (Result.FromJson(Response))
{
// Store token
FPlayNANOOHttpClient::AccessToken = Result.Token.AccessToken;

// Output token information
UE_LOG(LogTemp, Log, TEXT("AccessToken: %s"), *Result.Token.AccessToken);
UE_LOG(LogTemp, Log, TEXT("RefreshToken: %s"), *Result.Token.RefreshToken);

// Output player information
UE_LOG(LogTemp, Log, TEXT("UserUniqueID: %s"), *Result.Player.UserUniqueID);
UE_LOG(LogTemp, Log, TEXT("OpenID: %s"), *Result.Player.OpenID);
UE_LOG(LogTemp, Log, TEXT("Nickname: %s"), *Result.Player.Nickname);
UE_LOG(LogTemp, Log, TEXT("LinkedID: %s"), *Result.Player.LinkedID);
UE_LOG(LogTemp, Log, TEXT("LinkedType: %s"), *Result.Player.LinkedType);
UE_LOG(LogTemp, Log, TEXT("Country: %s"), *Result.Player.Country);

// Output purchase-related information
UE_LOG(LogTemp, Log, TEXT("PurchaseCount: %d"), Result.Player.PurchaseCount);
UE_LOG(LogTemp, Log, TEXT("PurchaseTotalPrice: %.2f"), Result.Player.PurchaseTotalPrice);
UE_LOG(LogTemp, Log, TEXT("PurchaseCurrencyCode: %s"), *Result.Player.PurchaseCurrencyCode);
UE_LOG(LogTemp, Log, TEXT("Timezone: %s"), *Result.Player.Timezone);
UE_LOG(LogTemp, Log, TEXT("Offset: %d"), Result.Player.Offset);
UE_LOG(LogTemp, Log, TEXT("JoinPeriod: %d"), Result.Player.JoinPeriod);
}
}),
FOnGoogleSigninError::CreateLambda([](const FString& Error)
{
UE_LOG(LogTemp, Error, TEXT("Google login failed: %s"), *Error);
})
);
}
Google Login Plugin

To use Google login in Unreal Engine, you need to install a Google Sign-In plugin or integrate native SDK.

  • Android: Google Play Games Services
  • iOS: Google Sign-In SDK
ID Token Issuance

You must obtain an ID token through Google OAuth login. Pass this token as the linked_id parameter.