Skip to main content
Version: v3

Tap Customer Service Development Guide

This article describes how to access the customer service system provided by TDS in the game.

SDK initialization

Get TapSDK at download page and introduce TapSupport module:

The SDK can be imported either through Unity Package Manager or manually**. Please choose according to your project needs.

Method 1: Use Unity Package Manager

NPMJS Installation

As of version 3.25.0, TapSDK supports NPMJS installation, with the advantage that only the version number needs to be configured and nested dependencies are supported.

Add the following dependencies to your project's Packages/manifest.json file:

"dependencies":{
"com.taptap.tds.support":"3.29.4",
}

However, it should be noted that scopedRegistries must be declared under the same level of dependencies in Packages/manifest.json:

"scopedRegistries": [
{
"name": "NPMJS",
"url": "https://registry.npmjs.org/",
"scopes": ["com.tapsdk", "com.taptap", "com.leancloud"]
}
]
GitHub Installation

Add the following dependencies to your project's Packages/manifest.json file:

"dependencies":{
"com.taptap.tds.common":"https://github.com/TapTap/TapCommon-Unity.git#3.29.4",
"com.taptap.tds.support":"https://github.com/TapTap/TapSupport-Unity.git#3.29.4",
"com.leancloud.storage":"https://github.com/leancloud/csharp-sdk-upm.git#storage-2.3.0",
}

Select Window > Package Manager in the top menu of Unity to see the packages already installed in your project.

Method 2: Import Manually

  1. Find the download addresses of TapSDK Unity and LeanCloud C# SDK on the download page , and download TapSDK-UnityPackage.zip and LeanCloud-SDK-Realtime-Unity.zip respectively.

  2. In the Unity project, go to Assets > Import Packages > Custom Packages, and from the unzipped TapSDK-UnityPackage.zip, select the TapSDK packages that you want to use in the game, and import them:

    • TapTap_Common.unitypackage TapSDK Basic library, mandatory
    • TapTap_Support.unitypackage TapTap Customer Service Library, a must
  3. The decompresses LeanCloud-SDK-Realtime-Unity.zip is in the Plugins folder, drag and drop it to Unity.

Before initializing the SDK, there are a few preparations to complete:

  1. Ask the vendor administrator or customer service administrator to invite you to become a customer service administrator.
  2. Each vendor will be assigned a unique domain name, which you need to write down and use. You can find the available domain names in Settings > Developer Information in the Customer Service Workbench. If you want to use your own domain name, you can contact the vendor administrator to bind it in the Game Customer Service module of the Developer Center.
  3. In the Customer Service Workbench, create a product for your game (Settings > Administration > Products & Categories) and write down the ID of this product.

Then use the following code to initialize the TapSupport module:

using TapTap.Support;

TapSupport.Init("https://please-replace-with-your-customized.domain.com", "Product ID");

In the above code example, please-replace-with-your-customized.domain.com is the domain name obtained or bound in Preparation 2. The product ID is the ID of the new product created in Preparation 3.

Login

In order to ensure that the information submitted by a player, such as forms, is only accessible to that player, the customer service system requires a login in order to be used. We offer three different login options:

  • TDSUser (TDS Built-in Account) Login
  • TDSUser login
  • Anonymous Login
note

Logging in here refers to the process of authentication when a gamer uses the customer service system's features within the game. This step is the interaction between the game side and the customer service system, and is usually not perceived by the player, as opposed to logging in to the game itself (e.g., the anonymous login here has nothing to do with the game's guest login).

TDS Built-in Account Login

If your game uses the TDS built-in account service, you can log in to the customer service system directly on the client side using the logged-in TDSUser authorization.

info

The TDS Built-in Account Service is a user system provided by TDS that supports multiple login methods. If your game is already using TapTap Login, Friends, Achievements, Leaderboards and other services, you are probably already using TDS Built-in Accounts. For more information, please refer to "Introduction to Built-in Account Features".

To use TDSUser authorization to log in to the customer service system, you first request an authorization token using a logged-in TDS user account, and then use that token to call the TDS login interface of the customer service module:

try {
string token = await TDSUser.RetrieveShortToken();
await TapSupport.LoginWithTDSCredential(token);
Debug.Log("Log in to TDSUser JWT Completion");
} catch (TapException e) {
Debug.LogError($"{e.Code} : {e.Message}");
} catch (Exception e) {
Debug.Log(e);
}

Exception Handling

If the SDK throws an exception during login and subsequent processes, developers can be notified via a callback.

Among these exceptions, we need to handle the token expiration (EXPIRED_CREDENTIAL) exception in particular, and re-execute the above request authorization token, call login interface process to log in the customer service again.

For other kinds of exceptions, it is recommended to show them to players directly. Since customer service exceptions usually don't affect the player's playing experience, we can consider only prompting the player that customer service is not available at the customer service portal, and provide the interaction of manually triggering retries.


if (e is TapException ex && ex.Code == 9006) {
// Login expired
} else {
// Other exceptions
}

Associated login for game's own account system

If your game uses another user system, the customer service system also supports logging in with signed user information.

requires a server

Signing user information requires the use of a secret, so a server is required to use this method.

The developer first needs to generate an auth secret in Settings - Developer Settings - Player Authentication in the Customer Service Workbench, and then Use this secret on the server to JWT-sign the player information using the HS256 algorithm. The player information (payload) should contain the user's unique identifier and a name for display, and should be structured as follows:

{
"sub": "U1234567", // unique identification
"name": "Dash" // Displayed in the name of the work order, customer service back office
}
JWT Example of a signature
input:
  • Algorithm: HS256
  • payload: {"sub": "U1234567", "name": "Dash"}
  • secret: 44a23a3701955756301768bbb5dd1e1ea51500b556fb73201de76d5365150653

exports JWT:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJVMTIzNDU2NyIsIm5hbWUiOiJEYXNoIn0.OV2LCP-7cLVTfjJlx21q9O1Tj_LlM0LFyW3OOu7CeNk

Finally, the obtained JWT is returned to the client, and the client calls the third-party account login interface of the SDK to complete the login:

TapSupport.LoginWithCustomCredential(jwt);

For security reasons, we usually add an exp field to the JWT payload to specify its expiration time, and the customer service system will honor the JWT's expiration time setting:

{
"sub": "U1234567",
"name": "Dash",
"exp": 1676546560 // Unix epoch
}

Considering both security and performance, we recommend setting the JWT expiration time to 1-3 days from the current time.

Exception Handling

If an exception occurs in the SDK during login and subsequent processes, the developer can be notified via a callback.

Among these exceptions, we need to handle the JWT expiration (EXPIRED_CREDENTIAL) exception in particular, and re-execute the above request JWT, call login interface process to log in the customer service again.

For other kinds of exceptions, it is recommended to show them to the player directly. Since customer service exceptions usually do not affect the player's playing experience, we can consider only prompting the player that the customer service is unavailable at the customer service portal, and provide the interaction of manually triggering the retry.


if (e is TapException ex && ex.Code == 9006) {
// Login expired
} else {
// Other exceptions
}

Anonymous Login

Anonymous login means that the game uses a string that only the current player can get as an anonymous identification (ID) to log into the customer service system.

TapSupport.LoginAnonymously("uuid");

Anonymous login can be used to differentiate players by device in scenarios where the game does not have an account system or the player is not logged in, or to differentiate players by account after they have logged into their game account.

Associating with Devices

The game client generates and persists a UUID for the device, and then uses this ID to call the anonymous login interface to associate the player with the device.

At this point, the anonymous ID on the device is the only identity credentials. If the ID is lost due to deletion of the application or clearing of local data, the player will not be able to access data such as historical work orders.

associated with a game account

Similarly, to be associated with a game account, the anonymous login interface needs to be called using an ID that has a one-to-one relationship with the account.

The anonymous login mechanism is very flexible. For example, if you want a player to have a separate customer service account for each game, you can assign a separate anonymous ID to each game; if you want to track the player across games, you can use an anonymous ID at the pass level, in which case the customer service system doesn't know what the ID means, which is where the name "anonymous" comes from. This is where the name "anonymous" comes from.

The price of flexibility is security. If not used correctly, anonymous login can lead to data leakage. The customer service system doesn't care where the anonymous ID came from, and can't do any verification, which means that the historical work order data of the player who leaked the ID will also be leaked. Therefore, "only the current player can get it" needs to be guaranteed by the game side. More specifically, the anonymous ID needs to meet the following conditions:

  • Unique and unchanging to the player
  • Cannot be guessed or deduced, cannot be enumerated.
  • It is not public, and will not be disclosed by the player through sharing or screenshots.
Example of a correct anonymous ID
  • b3a59993-c659-49f9-9f51-f2c808a472a0:The game user system generates a UUID when a new player is created that serves as the player's anonymous ID for the customer service system, and the player logs in to log in to the customer service system with that ID.
  • sha1('2436234209' + secret):Append a fixed secret to the player's UID on the server side and then hash it. Only after the player logs in can he get the ID to log into the customer service system.
Example of an insecure anonymous ID

Simply put, no client-only solution is secure:

  • '2436234209' Player UID: This is usually public information, visible and potentially shared by the player in the game, and a purely numeric ID that is easy to enumerate.
  • sha1('2436234209') :Hashing alone is still easy to enumerate when the algorithm is guessed.

To reduce the risk of misuse, the anonymous login interface restricts the minimum length of the anonymous ID to 32.

Clear Login Status

TapSupport.Logout();

Open the customer service page

TapSupport.OpenSupportView();
info

If the opened page has no content, you can first configure some subcategories for that game category in the Customer Service Workbench.

Scenario-based portals

In addition to landing pages, the SDK also supports opening specific pages directly in specific scenarios.

TapSupport.OpenSupportView();

Different pages are distinguished by different path parameters. The currently supported pages are:

pathclarification
/tickets/new?category_id={id}To submit a new work order, specify the id of the category.
/ticketsPlayer work order list page to see all historical work orders of the player.
/articles/{id}Knowledge base article page.

Reporting Information

The work order module supports developers to collect additional information such as device, player, etc. through custom fields. Developers can bring in additional information when opening a support page (openSupportView), and the SDK will record this information in the work order fields when submitting a work order. This information can be viewed and analyzed in the customer service workbench.

Before reporting data, you first need to define fields in the Customer Service Workbench (Settings > Administration > Work Order Fields). These fields need to be set to "Customer Service Only" access. Once created, you need to write down the ID of the field, which we will use in the SDK.

Dictionary<string, object> fields = new Dictionary<string, object>();
fields.Add("243", "iOS 15.1"); // 243 is the ID of the "OS" field created in the background.
fields.Add("244", "Dash"); // 244 is the ID of the Role Name field created in the backend

TapSupport.OpenSupportView("/", fields);

In addition to setting it when opening the customer service page, developers can also set the global default field information through the following interface:

TapSupport.SetDefaultFieldsData(fields: fields);

Global fields can be updated after setup:

TapSupport.DefaultFields = new Dictionary<string, object> {
{ "key", "value" }
};

Globally set fields are merged with the incoming fields parameter at OpenSupportView time. Fields passed in during the OpenSupportView method have a higher priority than global fields, meaning that global fields will not take effect if they are the same.

Closing the support page

Players can click the close button within the customer service page to exit. However, in certain scenarios, the game may need to actively close the customer service page:

TapSupport.CloseSupportView();

Unread Message Notification

Unread messages are generated when there are new developments in a submitted work order (e.g. a new customer service response). Usually in-game, players are notified of unread messages in the customer service portal using red dots, etc. The SDK automatically polls for dimensional messages, and when the status of an unread message changes - from none to yes or yes to no - the SDK notifies the developer via a callback to notify the developer:

using TapTap.Support;

TapSupport.Init("https://please-replace-with-your-customized.domain.com", "categorization ID", new TapSupportCallback
{
UnReadStatusChanged = (hasUnRead, exception) =>
{
Debug.Log($"hasUnRead:{hasUnRead} exception:{exception}");
}
});
info

Developers do not need to additionally clear the local unread notification status (small red dot) when tapping the customer service portal. This is because clicking on the customer service portal does not mean that the player has viewed all unread work orders. If the player has viewed all unread work orders, the SDK will get the latest status and notify the developer via the callback mentioned above.

Pause Polling

The SDK's built-in polling mechanism intelligently adjusts the frequency of getting the status of unread messages. However, there are some scenarios where these requests are still unnecessary overhead, such as when a player wants to pause all unnecessary background requests during a game match (when there is no red dot displayed on the interface), and the SDK provides a pair of APIs for controlling polling for this purpose:

  • Pause: pauses polling
  • Resume: resumes polling.
TapSupport.Resume();
TapSupport.Pause();
SDK Polling Policy
  • Initially, a request is initiated immediately, and the next request interval is set to be 10s.
    • If there is no change in the status of an unread message compared to the current status, increase the interval by 10s until the maximum interval is 300s, and reset the interval to 10s if there is a change.
    • If the player never opens the WebView, the interval is increased to a constant 3600s.
  • Calling the Resume method resets the polling to its initial state.