Skip to main content

User Hub

note

This feature is in closed beta. Contact Helpshift Customer Success to enable this feature.

The new Identity System provides many advantages, with minimal efforts (as outlined below) over the legacy method, in the form of faster context collection, easier agent experience, and enhanced security and spam protection.

Prerequisites

  1. Ensure that the Identity System is enabled for your domain (reach out to Helpshift Customer Success if you wish to enable this)
  2. Ensure that you have an endpoint set up for obtaining user JWTs on-demand

Logging in your end-users

In order to use the new Identity system, you need to implement the following steps:

  1. Specify the authenticateWith parameter in helpshiftConfig prior to loading Web Chat
  2. Ensure that userId and/or userEmail are specified in helpshiftConfig
  3. Start listening for the onLoginRequest event from Helpshift
  4. Obtain a JWT for the given user from your dedicated endpoint
  5. Log your user in with the JWT + full privacy information
window.helpshiftConfig = {
// ... your other config values
// Step 1
authenticateWith: "identities",

// Step 2
userEmail: "<your-user-email>",
userId: "<your-user-id>"
}

/////////////////////////////////
// Your embed script goes here //
/////////////////////////////////

// Step 3: Add the event listener
Helpshift("addEventListener", "onLoginRequest", async ({userId, userEmail}) => {

// Step 3:
// Note: Your implementation here may vary. This is just an example.
const identityToken = await fetch("<your-jwt-endpoint>", {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify({userId, userEmail})
})

// Step 4:
// Note: The userId/userEmail specified in the identity_token
// MUST match the values specified in the helpshiftConfig object.
// If they do not match, the login will be unsuccessful.
Helpshift("login", {
identity_token: identityToken,
full_privacy_enabled: false // or true. Assumed false if not specified
});
});

Full privacy scenarios

The following rules apply depending on the value of the full_privacy_enabled flag:

  • If full privacy flag is false, one of userId or userEmail is mandatory, unless you are logging in an anonymous user.
  • If userId is present and full_privacy_enabled is also true - Web Chat will use the userId to identify the user.
  • If userId is absent and full_privacy_enabled is true - Web Chat will generate an anonymous ID and use this ID to identify the user.
  • Full privacy is assumed to be false if no value is specified, or if the passed value is invalid.

Best practices to follow for Login API

  • When you have more information to associate with current logged in user, use the addUserIdentities API.
  • The userId or userEmail should uniquely identify the user across all users of your app. It should NOT be duplicated for two or more different users.
  • If you are setting full_privacy_enabled to true, you shouldn't use email as the only identifier in the login API for that user. This will result in the creation of an anonymous user.
  • For logging in a new user, first use the logout API, update the userId and userEmail in helpshiftConfig, and call updateHelpshiftConfig, to retrigger a new login request.

Identity token format

The identity token must be a JWT signed using the shared secret from your app settings in the dashboard. When decoded, it must adhere to the following format:

interface Identity {
identifier: "uid" | "email" | "phone_number" | "facebook_id" |
"discord_id"|"whatsapp_id"|"google_playstore_id"|
"apple_gamecenter_id" | "nintendo_id" | "psn_id" |
"xbox_live_id" | "steam_id",
value: string,
metadata?: {
[key:string]: string
}
}

interface IdentityToken {
identities: Identity[],
iat: number // UNIX epoch time in seconds, generated in the last 24h or earlier
}
Important

Always generate the JWT on the server side, and store your shared secret securely.

info

Helpshift can also trigger the onLoginRequest event to reverify your user session if we detect suspicious activity or if the user's session is about to expire. In such cases, the same event handler is sufficient for reverification, as long as you provide a JWT that has been generated within the last 24h.

We wait for the onLoginRequest callback to be executed for 5 seconds before we consider the session as expired. If this happens, we replace the chat with a full screen session expired message.

With anonymous users

We recommend logging in your end-user into Helpshift as early as possible, since it helps streamline the entire support experience.

However, in the case where you have anonymous users, all you have to do is set the authenticateWith value, and Helpshift will take care of generating an anonymous UID and logging your end-user in.

The userId and userEmail values can be omitted altogether or set to an empty string, "".

window.helpshiftConfig = {
// ... your other config values
authenticateWith: "identities"
// Notice that "userId" and "userEmail" are not specified here
}

/////////////////////////////////
// Your embed script goes here //
/////////////////////////////////

Retroactively logging your end-user in

In certain cases, your end-user may be anonymous for a short while before you log them in. In such cases, you will have to update helpshiftConfig and call the Helpshift("updateHelpshiftConfig") API to trigger a new login.

window.helpshiftConfig = {
// ... your other config values
authenticateWith: "identities"
// Anonymous user since no userId/userEmail are provided
}

/////////////////////////////////
// Your embed script goes here //
/////////////////////////////////

// Register your event listener
Helpshift("addEventListener", "onLoginRequest", async ({userId, userEmail}) => {

const identityToken = await fetch("<your-jwt-endpoint>", {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify({userId, userEmail})
})

Helpshift("login", {
identity_token: identityToken,
full_privacy_enabled: false // or true. Assumed false if not specified
});
});

// At some point in the future, when your user logs in:
window.helpshiftConfig.userId = "<your-user-id>"
window.helpshiftConfig.userEmail = "<your-user-email>"

Helpshift("updateHelpshiftConfig")
// ^ This will trigger the onLoginRequest event.

Adding more user identities

Note that although the API is named identities, if you wish to send multiple identities, they must be a part of the JWT's payload itself. Essentially, the API expects a single string JWT and NOT an array of JWTs.

Example:

  // ... Some custom logic here that obtains user data
const identities = "header.payload.hash";
Helpshift("addUserIdentities", identities)

Refer to identity token format for the schema of the identity token.

Info

You can plug this API call into any place where you collect user identities. However, be careful not to call it in any useEffect-like callbacks or frequently-firing events, since rate-limiting restrictions may kick in.

For a list of errors that can occur when using this API, refer ADD_USER_IDENTITY_FAILED.

Updating global user data

You can update your user's global data using this API.

The following key/value pairs are accepted in this API call:

interface CustomUserFields {
[key: string]: string
}

interface GlobalUserData {
// Note that all primitive values must be coerced to string
first_name?: "string",
last_name?: "string",
full_name?: "string",
display_name?: "string",
last_country?: "string",
last_city?: "string",
age?: "string",
lifetime_value?: "string",
user_persona?: "string",
user_vip_segment?: "string",
user_support_status?: "string"
last_active_date?: "string" // epoch time in ms/seconds
accepted_t_and_c?: "string" // true/false converted to string
preferred_language?:"string"

// Non-primitives
new_tags?: Array<string>
tags_to_remove?: Array<string>
reset_tags?: Array<string>
custom_user_fields?: CustomUserFields
}

Example:

  // ... Some custom logic here that obtains user data
const full_name = "John Doe";

Helpshift("updateGlobalUserData", {full_name})
Info

You can plug this API call into any place where you collect user data. However, be careful not to call it in any useEffect-like callbacks or frequently-firing events, since rate-limiting restrictions may kick in.

Global user data is also referred to as core attributes.

For a list of errors that can occur when using this API, refer UPDATE_GLOBAL_USER_DATA_FAILED.

Updating app user data

You can update your user's app or website-specific data using this API.

The following key/value pairs are accepted in this API call:

interface CustomUserFields {
[key: string]: string
}

interface AppUserData {
// Note that all primitive values must be coerced to string
app_version: "string",
user_vip_segment: "string",
sdk_version: "string",
language:"string",
app_rating: "string",
user_paying_segment: "string",
country: "string"
user_support_status: "string"
user_persona: "boolean string"
accepted_t_and_c: "string"
user_level: "string",
app_status: "string",
city: "string",
lifetime_value: "string",


// Non-primitives
custom_user_fields?: CustomUserFields
}

Example:

  // ... Some custom logic here that obtains user data
const app_rating = "5";

Helpshift("updateAppUserData", {app_rating})
Info

You can plug this API call into any place where you collect user data. However, be careful not to call it in any useEffect-like callbacks or frequently-firing events, since rate-limiting restrictions may kick in.

App user data is also referred to as app attributes.

For a list of errors that can occur when using this API, refer UPDATE_APP_USER_DATA_FAILED.

Logging out your end-users

To log out your end-users, you can use the logout API.

Helpshift("logout");

Note that after calling this API, Web Chat will clear any user specific data from the helpshiftConfig object, and reset the chat to an anonymous user. Depending on the value of helpshiftConfig.clearAnonymousUserOnLogin, this can either be the previous anonymous user or a new anonymous user.

Tip

For a better user experience, consider hiding the chat widget after the user logs out.

Optimizations

Note

Web Chat will run smoothly even without these optimizations. However, if you want to see faster load times for Web Chat, and reduced load on your infrastructure, you may choose to implement these optimizations.

Send the identity_token in SSR requests

If your application uses SSR, you can send the identity_token as part of your page load, injecting it in the onLoginRequest callback directly.

Please ensure that you do not set this value in a global variable to minimize the security risks for your end-user.

Caveat

Helpshift fires the onLoginRequest event if we detect suspicious end-user activity. In such cases, your page will provide a stale ID token, which will result in an expired support session.

A refresh of the page would allow their session to be restored.

This is usually not an issue for most end-users, but in case you want instant support session recovery, a JWT endpoint would become necessary.

Caching the identity_token

We highly discourage caching the identity_token on the client-side since it increases the potential attack surface for XSS. However, you may choose to cache it on the server-side, provided that the cache is invalidated before 24 hours elapse.

Troubleshooting and tips

Login failure can be detected by listening to the onWebChatRuntimeError event. The possible reasons for login failure are cited in the LOGIN_FAILED runtime errors.

If your login is still failing, you can investigate these other potential reasons:

  1. Ensure that your JWT endpoint is generating tokens in the accepted format
  2. Ensure that your JWT endpoint is signing tokens with the shared secret
  3. Ensure that your JWT endpoint has an iat (issued_at_time) value that is NOT older than 24h
  4. In case you are caching the JWT, ensure that you do not cache it for longer than 24h.

System limits

When using the User Identity APIs, the following system-level limits are applicable. Where applicable, these limits will also be reported to you as documented in the API failure reasons.

  • Key lengths across all APIs - Max 255 chars
  • Value length for any identity (except uid) - Max 300 chars
  • Value length for uid identity - Max 750 chars
  • Value length for CUF - Max 255 chars
  • Value length for multiline CUF - Max 100000 chars
  • Value length for user tags - Max 100 chars
  • Collection size - Max 30 entries

API failure reasons

You can subscribe to the onWebChatRuntimeError event to handle these errors programmatically. The following errors are emitted for the User Identity APIs:

LOGIN_FAILED

Occurs when the user login fails. The following reason and details combinations are possible in this scenario:

ReasonDetailsNotes
AUTHENTICATE_WITH_FIELD_INCORRECT

Client-side validation. Fired when you attempt to call Login, but authenticateWith: "identities" is not set in the helpshiftConfig.

JWT_IS_INVALIDClient-side validation. Fired when the JWT format is incorrect.
IDENTITIES_KEY_ABSENT

Client-side validation. Fired when your JWT payload is missing the identities key.

USERID_AND_EMAIL_MISSINGClient-side validation.
CONFIG_JWT_EMAIL_MISMATCH
interface ConfigJwtEmailMismatchDetails {
jwtEmail: string,
configEmail: string
}
Client-side validation.
CONFIG_JWT_USER_ID_MISMATCH
interface ConfigJwtEmailMismatchDetails {
jwtUserId: string,
configUserId: string
}
Client-side validation.
IDENTITIES_FEATURE_DISABLEDServer-side validation.
IDENTITIES_INVALID_TOKEN

Server-side validation. Fired when your ID token is invalid. Check these troubleshooting steps for help with debugging this.

IDENTITIES_INVALID_PAYLOAD
interface InvalidPayloadDetails {
missingFields?: Array<string>
invalidFields?: Array<string>
invalidIdentities?: Array<string>
invalidIdentityTokens?: Array<string>
}
Server-side validation.
INTERNAL_HELPSHIFT_ERROR_DURING_USER_LOGIN Server-side issue. Try refreshing or check the Helpshift status page.

ADD_USER_IDENTITY_FAILED

This error can occur when you attempt to update the a user identity with the new Identity System. Also see IDENTITY_PROFILE_UPDATE_FAILED.

ReasonDetailsNotes
AUTHENTICATE_WITH_FIELD_INCORRECT

Client-side validation. Fired when you attempt to call this API, but authenticateWith: "identities" is not set in the helpshiftConfig.

JWT_IS_INVALID
interface JwtIsInvalidDetails {
expectedDataType: string,
receivedDataType: string
}

In case the problem is not due to invalid data type, you might not receive the details key.

Client-side validation. Fired when you attempt to call this API, but authenticateWith: "identities" is not set in the helpshiftConfig.

UPDATE_GLOBAL_USER_DATA_FAILED

This error can occur when you attempt to update global user data with the new Identity System. Also see IDENTITY_PROFILE_UPDATE_FAILED.

ReasonDetailsNotes
AUTHENTICATE_WITH_FIELD_INCORRECT

Client-side validation. Fired when you attempt to call this API, but authenticateWith: "identities" is not set in the helpshiftConfig.

MAX_KEY_VALUES_LIMIT_EXCEEDED
  interface MaxKeyValuesLimitExceededDetails {
receivedTotalKeys: number,
maxKeysAllowed: number
}
Client-side validation. Only 100 keys are allowed per update you send.
MAX_KEY_VALUES_CHAR_LIMIT_EXCEEDED
  interface MaxKeyValuesCharLimitExceededDetails {
invalidKeys: Array<string>,
invalidValues: Array<string>
}
Client-side validation. The client-side limit is 1000 characters per key or value that you send.

UPDATE_APP_USER_DATA_FAILED

This error can occur when you attempt to update the app user data with the new Identity System. Also see IDENTITY_PROFILE_UPDATE_FAILED.

ReasonDetailsNotes
AUTHENTICATE_WITH_FIELD_INCORRECT

Client-side validation. Fired when you attempt to call this API, but authenticateWith: "identities" is not set in the helpshiftConfig.

MAX_KEY_VALUES_LIMIT_EXCEEDED
  interface MaxKeyValuesLimitExceededDetails {
receivedTotalKeys: number,
maxKeysAllowed: number
}
Client-side validation. Only 100 keys are allowed per update you send.
MAX_KEY_VALUES_CHAR_LIMIT_EXCEEDED
  interface MaxKeyValuesCharLimitExceededDetails {
invalidKeys: Array<string>,
invalidValues: Array<string>
}
Client-side validation. The client-side limit is 1000 characters per key or value that you send.

IDENTITY_PROFILE_UPDATE_FAILED

Web Chat batches your user data updates and syncs them periodically. As a result of this, if a validation failure occurs on the server-side, this error will report it.

ReasonDetailsNotes
IDENTITIES_FEATURE_DISABLED
IDENTITIES_INVALID_PAYLOAD
interface IdentitiesInvalidPayloadDetails {
missingFields?: Array<string>,
invalidAppAttributes?: Array<string>,
invalidCoreAttributes?: Array<string>,
invalidIdentities?: Array<string>,
invalidIdentityTokens?: Array<string>
}