Integrate the PGS Recall API within your game

This page explains how to implement the Recall API within your game. It first covers setting up your game server and client to support the API, and then goes through how to store and retrieve tokens.

Game server setup

Set up your game server to make Recall API calls to Google servers.

Set up your Play Games Services project

(If not already completed) Follow the instructions in Setting Up Google Play Games Services.

Set up a service account for the game

Follow the instructions on creating a service account. At the end you should have a JSON file with service account credentials.

Download server-side Java library for Play Games Services

Download the latest google-api-services-games library and upload this to your server.

Prepare credentials for Recall API calls

See Preparing to make a delegated API call for more context.

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.services.games.Games;
import com.google.api.services.games.GamesScopes;

// ...

GoogleCredential credential =
  GoogleCredential.fromStream(new FileInputStream("<credentials>.json"))
    .createScoped(Collections.singleton(GamesScopes.ANDROIDPUBLISHER));

Games gamesApi =
    new Games.Builder(httpTransport, JSON_FACTORY, credential).build();

Game client setup

Set up your game client to retrieve the recall session IDs used by your server to communicate with Google servers.

Java SDK

Set up the Java SDK within your client, and make sure to include com.google.android.gms:play-services-games-v2:19.0.0 and com.google.android.gms:play-services-tasks:18.0.2 or higher in your Gradle file.

To communicate with Google's servers with the correct information, request a Recall session ID from the client SDK, which you send to your game's server:

Kotlin

PlayGames.getRecallClient(getActivity())
  .requestRecallAccess()
  .addOnSuccessListener { recallAccess -> val recallSessionId: String = recallAccess.getSessionId() }
  // Send the recallSessionId to your game server

Java

PlayGames.getRecallClient(getActivity())
  .requestRecallAccess()
  .addOnSuccessListener(
    recallAccess -> {
      String recallSessionId = recallAccess.getSessionId();
      // Send the recallSessionId to your game server
  });

Use the Recall API within your game server

After configuring your server and client, you can send the recallSessionID from your game client to your game server and follow the guidance below to start using the Java API to store, retrieve or delete the Recall tokens server-side.

Store tokens

Store the user's persona and game token using the LinkPersonaRequest object. Use the GoogleCredential to call Google APIs. To follow the 1:1 cardinality constraint, you can only link one persona to one PGS profile at a time, and vice-versa. Set the resolution policy in case this PGS profile already has been linked with another persona.

Optionally, you may choose to set a TTL on the token, which declares how long the token is valid using a Durations object. You may choose to set this using SetTtl() (as shown below), which sets the expiry date from the amount of time specified in the method, or setExpireTime(), which lets you set an exact time for when the tokens expire.

You must encrypt the persona and game token, and they cannot contain personally identifiable information. Persona and token strings can be at most 256 characters long, and there can be at most 20 tokens or personas stored per player per game.

Only one token can be stored per persona per player at a given time. If you try to store another token with the same persona, the system overwrites the original token.

import com.google.api.services.games.Games.Recall.LinkPersona;
import com.google.protobuf.util.Durations;

// ...

Games gamesApi =
    new Games.Builder(httpTransport, JSON_FACTORY, credential).build();

String recallSessionId = ... // recallSessionID from game client
String persona = ... // encrypted opaque string, stable for in-game account
String token = ... // encrypted opaque string encoding the progress line

LinkPersonaRequest linkPersonaRequest =
  LinkPersonaRequest.newBuilder()
    .setSessionId(recallSessionId)
    .setPersona(persona)
    .setToken(token)
    .setCardinalityConstraint(ONE_PERSONA_TO_ONE_PLAYER)
    .setConflictingLinksResolutionPolicy(CREATE_NEW_LINK)
    .setTtl(Durations.fromDays(7)) // Optionally set TTL for token
    .build();

LinkPersonaResponse linkPersonaResponse =
  gamesApi.recall().linkPersona(linkPersonaRequest).execute();

if (linkPersonaResponse.getState() == LINK_CREATED) {
  // success
}

Retrieve tokens

To retrieve the recall token, get the recallSessionId from the client, and pass it into the retrieveTokens API:

import com.google.api.services.games.Games.Recall.RetrieveTokens;

// ...

String recallSessionId = ... // recallSessionID from game client

RetrievePlayerTokensResponse retrievePlayerTokensResponse =
  gamesApi.recall().retrieveTokens(recallSessionId).execute();

for (RecallToken recallToken : retrievePlayerTokensResponse.getTokens()) {
  String token recallToken.getToken();
  // Same string as was written in LinkPersona call
  // decrypt and recover in-game account
}

Delete recall token

If needed, you can also delete the recall token with the following call:

import com.google.api.services.games.Games.Recall.UnlinkPersona;

// ...

String recallSessionId = ...
String persona = ...
String token = ...

Games gamesApi =
    new Games.Builder(httpTransport, JSON_FACTORY, credential).build();

UnlinkPersonaRequest unlinkPersonaRequest =
  UnlinkPersonaRequest.newBuilder()
    .setSessionId(recallSessionId)
    .setPersona(persona)
    // .setToken(token) - alternatively set token, but not both
    .build();

UnlinkPersonaResponse unlinkPersonaResponse =
  gamesApi.recall().unlinkPersona(unlinkPersonaRequest).execute();

// Confirm that the unlinking process completed successfully.
boolean unlinked = unlinkPersonaResponse.isUnlinked();

Enable profileless mode

You can enable limited Recall API functionality for users that don't have PGS profiles by following these steps:

  1. Enable profileless recall for your PGS game project in the Play Developer Console. Select the option labeled
  2. Review the additional terms described later in this section.
  3. Add the following metadata tag into your app manifest:
<meta-data
  android:name="com.google.android.gms.games.PROFILELESS_RECALL_ENABLED"
  android:value="true" />

Additional terms

In addition to being subject to the Play Games Services Terms of Service, you agree that if you use the Recall API for users without a PGS profile, which enables sharing end user's data with Google without them having a Play Games Services profile, you must, prior to sharing such data with Google, provide the end user with appropriate notice describing 1) your sharing of the data with Google to enable Play Games' account linking feature, 2) the availability of settings to manage such sharing such as those via Play Games settings, and 3) the processing of such data under the Google Privacy Policy, and obtain appropriate end user consent for such sharing that meets all applicable legal requirements.