Read me before the brand meeting
Prepare in advance
- Study this document before the call.
- Familiarize yourself with the Questionnaire and Outline.
- Fill out parts of the Questionnaire ahead of time if you know the answers.
- If time permits, research the brand beforehand to provide use cases on the spot.
During the meeting
- Maintain a high level profile (do not get caught up in minutiae on the call).
- Focus on getting the answers you need for implementing the solution.
- Stay focused on the topic without letting people go out of scope.
Pro-Tip: Work together with the Project Manager to collect, in the best way, all useful key requirements, and to outline the subject of subsequent meetings.
1 - Introduction
The goal of this document is to give a guide on the LivePerson Mobile SDKs implementation, both explaining all the technical aspects needed and to show all the deployment aspects. The document highlights implementation recommendations and best practices for making the most of the SDK's capabilities.
Scope
Any Mobile App Messaging SDK related topics.
Out of scope
Problems unrelated to the SDK integration and any aspects of the LivePerson implementation that do not directly relate to the LivePerson InApp SDK.
2 - Terminology
Term | Meaning |
---|
In-App SDK | Mobile SDK synonymous |
Campaign | Point of contact between LivePerson Conversational Cloud and brand website/mobile app.
While web messaging allows automatic capturing of events using the Web Tag, when using campaigns for In-App Messaging, it is up to the app to report the various events by using the In-App Monitoring APIs.
|
Monitoring API | Allows brands to report events related to consumers' actions in the brand’s mobile app. These reporting events will feed into the campaigns to allow controlling messaging behaviors in the app directly from the Conversational Cloud. Can be used for: - Report on the customer's journey inside the app
- Retrieve engagements based on the reported SDEs
- Report on engagement attributes
- Route conversations to a specific skill (based on engagements)
|
Engagement | A banner or button that launches a conversation. It consists of the creative, the window, all the settings, and its rules.
An engagement also refers to the actual conversation or interaction between a brand and a consumer.
|
BrandID | The LivePerson Conversational Cloud Account Number. |
AppInstallationID | Used by the Monitoring API to identify the channel. Taken from the LivePerson account and is the same for both Android and iOS. |
AppID | Used when registering for Push Notification. For iOS is the Bundle ID, for Android is the Application ID. |
3 - Project High-Level Timeline
This is an expectation of what a Mobile SDK project will cover in terms of contents and timings. Mostly for having a raw timeline, to be refined based on the brand needs.
Week 1 | Week 2 | Week 3 | Week 4 | Week 5 |
---|
Requirements Review Information gathering and requirement review | SDK Implement Mobile SDK + Monitoring API into the Brand App. | Authentication Configure authentication server settings.
What data will the brand pass in the JWT? | Configuration Configure skills, campaigns, entry points, users, etc. in LiveEngage
Configure and define Entry Points and Engagement Attributes in the Brand App. | Customization Tweak UI/UX per Brand requirements. Go through each attribute in our SDK to modify colors, enter message text, sent message text, etc. |
Week 6 | Week 7 | Week 8 | Week 9 | Week 10 |
---|
Notifications Configure push notifications or push proxy | Survey Configure Post-Convo Survey | Reporting Reporting is met via Analytics Builder reports | Testing End-to-end testing of Mobile SDK flow |
|
4 - Authentication
LivePerson authentication allows brands to use their customers' information within conversations, creating continuity in messaging interactions. The authentication process propagates brand’s client identification through the Conversational Cloud, to retrieve any additional brand related background information with in addition also messaging related data such as active conversations, history with the brand, unread messages.
Both version of brand mobile app must supports authentication in order to use it within the LivePerson Mobile App Messaging SDK:
- App users should be able to log into brand’s back-end securely;
- Brand’s back-end must be able to supply, upon request during the session, an OAuth 2.0 code (for OAuth Code Flow authentication) or a JSON Web Token (JWT) (for OAuth Implicit Flow authentication).
- The customer data encoded in the access token provided to LivePerson (the JWT) can contain authenticated information, formatted following LivePerson SDEs structure (Customer Info and Personal Info).
As the first requirement, to let the LivePerson mobile SDK integration work with authenticated users, the brand's target Conversational Cloud account must be configured with the authentication method chosen.
In addition, the following diagrams show how the two different authentication ways work:
Authentication Flows Operative Differences
Code Flow | Implicit Flow |
---|
Complex and takes more time to set up. | Quick and simple Authentication implementation. |
More secure, as the brand IDP provides an additional token, outside the client. | Less secure, as the JWT resides with the client. |
About the unauthenticated sessions:
- Without authenticating against the brand's back-end, the mobile app takes responsibility for providing the consumer name. Depending on how the app obtains this information, it might allow app users to spoof names to the brand’s agents.
- Without using authentication, conversations on different channels or different devices cannot be tied together, so consumers will lose continuity across devices.
- As unauth uses anonymous identifiers, consumer message history and ongoing conversations will be lost after the consumer is logged out from the SDK.
Authentication Customer Questionnaire
What will be the consumer unique ID (consumer ID)? |
---|
What will be the JWT exp time? |
What unique customer data do you want to pass to the agent (SDEs)? |
Is encryption of the JWT required (JWE)? |
LivePerson Authentication Recommendations
Choose the flow which best fit the brand authentication architecture
(for example, if they already have an IDP configured, it’s preferred the code flow) |
---|
Use a JWT expiration time between 5 to 30 minutes |
Advice brand to pass all the customer data in the JWT |
Android - Authentication
Prerequisites
- Your mobile app users should be able to log into your back-end securely.
- Your back-end must be able to supply, upon request during the session, an OAuth 2.0 (for Code Flow) or a JWT token (for Implicit Flow).
Authentication methods
If your system implementation involves an authentication step, you can use one of the following methods in order to get the conversation view:
Activity mode
LivePerson.showConversation(Activity activity, LPAuthenticationParams lpAuthenticationParams, ConversationViewParams params);
Fragment mode (Attach the returned fragment to a container in your activity)
LivePerson.getConversationFragment(LPAuthenticationParams lpAuthenticationParams, ConversationViewParams params);
Authenticated connection methods
AuthenticationKey
The LivePerson back-end verifies the authentication token sent by the SDK with your system servers. If the key cannot be verified on your company’s backend servers, this call fails.
LPAuthenticationParams().setAuthKey("yourAuthCode").
Tip: Alternatively, when using this method, you can also set a special redirect URL when authenticating by calling:
lpAuthenticationParams.setHostAppRedirectUri("yourRedirectUrl")
JWT
LPAuthenticationParams().setHostAppJWT("yourJwt")
Once the Authentication key expires, you get notified with a callback / local intent "void onTokenExpired()".
To re-connect with a new Authentication key, use reconnect(LPAuthenticationParams lpAuthenticationParams)
Errors while trying to connect uses callback: void onError(TaskType type, String message);
Unauthenticated in-app messaging
Unauthenticated In-App Messaging allows brands to communicate with consumers in an unauthenticated manner. This allows:
- Easier and quicker on-boarding to Conversational Cloud
- Having pre authentication messaging use cases, for example, assistance with password recovery
- The ability to use Campaigns
Related Classes, Parameters and APIs
The LPAuthenticationParams
object contains an authentication type which should be passed in the constructor. An empty constructor is also available and the default authentication type will be SIGN_UP (is deprecated as of July 2019).
Note: If you call any methods in LPAuthenticationParams that support authentication (for ex. - setHostAppJWT()
) - it will automatically set the authentication type to LPAuthenticationType.AUTH.
LPAuthenticationParams lpAuthenticationParams = new LPAuthenticationParams(LPAuthenticationType.UN_AUTH);
Server side configurations (In case needed, should be modified by LivePerson)
- Identity idle time — setting the time frame for identifying a consumer while being idle (not communicating with the brand). When a consumer opens the conversation window after being idle for the configured time, the LivePerson data will be removed from the device. If there's an open conversation — it will be closed and a dialog explaining what happened will be presented to the consumer.
- Unauthenticated token expiration — sets the time for the app to validate the token. When the token is expired, it will be refreshed.
SDK configurations
When an unauthenticated user session expire — the SDK will notify by presenting a dialog to the consumer. The dialog content can be modified by overriding the following string params
<string name="lp_new_unauth_user_dialog_title">New Conversation</string> <string name="lp_new_unauth_user_dialog_message">"Hi there! As we haven't seen you for a while, we're opening a new conversation for you."</string>
Code Samples
// 1. Init SDK with MonitoringMonitoringInitParams monitoringInitParams = new MonitoringInitParams(monitoringAppInstallId);LivePerson.initialize(getApplicationContext(), new InitLivePersonProperties(accountId,APP_ID, monitoringInitParams, new InitLivePersonCallBack() {…}));// 2. create and pass LPAuthenticationParamsLPAuthenticationParams lpAuthenticationParams = new LPAuthenticationParams(LPAuthenticationType.UN_AUTH);LivePerson.showConversation(activity,lpAuthenticationParams, conversationViewParams);
Notes and Best Practices
- Brands who wish to use Unauthenticated In-App Messaging must activate Campaigns for Messaging and create a default engagement. In addition, the SDK should be initialized with the
LPMonitoringInitParams
object. - In order to change SDK modes, Logout must be called first.
- LPAuthenticationType signup will be deprecated at the end June 2019.
To be noticed: the latest Android SDK version (5.12.0) is more strict on checking the correct use of authentication in the getConversationFragment
method: based on the authentication flow used by the brand app (implicit or code flow), it must be used the right LPAuthenticationParams
method, that is .setAuthKey()
for code flow and .setHostAppJWT()
for implicit flow. If erroneously used both, it will be returned a 401 error stating the consumer JWT is not correct (9007 IDP error).
iOS - Authentication
For users of OAuth 2.0 for customer authentication, the following functions apply:
Methods
Reconnects the conversation’s connection for conversation query:
public func reconnect(conversationQuery: ConversationParamProtocol, authenticationParams: LPAuthenticationParams)
Delegates
<LPMessagingSDKdelegate> func LPMessagingSDKAuthenticationFailed(error: NSError)
<LPMessagingSDKdelegate> func LPMessagingSDKTokenExpired(brandID: String)
5 - Push Notification
To make the best experience for the customers, they should receive a notification every time a reply or notice is available.
LivePerson strongly recommends it as a good practice, using our push notification service, or brand’s implementation. The best implementation should show to customers not only the availability of new messages, but also how many unread messages there are.
The following configuration have to be done if the brand want to use the Android-Firebase or the iOS-APNS push notification service:
Android Configuration:
- Register the client app instance
- Configure push notifications in Conversational Cloud
- Configure the services and classes
- Implement a push handle
iOS Configuration:
- Set up push notifications in your project
- Create a Certificate Signing Request
- Create the SSL certificate
- Create the certificate and key .pem files
- Configure push notifications in Conversational Cloud
The native LivePerson Push notification implementation will call automatically the Android/iOS standard push notifications service. Instead, for brands which cannot use the Google/Apple default way, it’s possible to adopt the LivePerson Push Proxy solution, which will send any agent message notifications events to the brand’s custom push endpoint, which will take care of notify the end consumer.
Here below the LivePerson Push Proxy service flow:
Push Notification Source Differences
LivePerson native Push Notification service | Brand’s custom Push Proxy |
---|
Simple and Easy to implement when the brand is using Firebase or APNS | Brands have to implement their own Service which would be invoked by LivePerson Proxy service. Brands can control the message and modify it. |
No customization of the message is available outside of LivePerson replacing the whole message with a default message such as “You have a new message”. | Good for Brands who already have customer Pusher service implemented.
|
Push Notification Customer Questionnaire
Do you have your own Pusher service or do you use APNS and Firebase for iOS and Android respectively? |
---|
Do you wish to modify or control the message before it reaches the consumer? |
Do you want to use native Android / iOS push service? |
Android - Push Notifications
Push and local notifications are a key factor that makes the experience better for consumers — they never have to stay in your app or keep the window open as they will get a proactive notification as soon as a reply or notice is available.
Prerequisites
Step 1. Register the client app instance
The proprietary SDK notification is only for display purposes, interacting with it won't launch the Application or navigate to the Conversation Fragment/Activity. For a fully interactive notification, the host app needs to provide the implementation.
- Use the registration token for the client app instance and register it using the registerLPPusher() API call so it knows which device should get each push message.
- Upon receiving a push message to your app, handle it so it is displayed to the customer.
public class MyFirebase extends FirebaseMessagingService {
/**
* Called when a message is received.
* @param remoteMessage Object representing the message received from Firebase Cloud Messaging.
*/
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// Sends the message into the SDK
LivePerson.handlePushMessage(this, remoteMessage.getData(), lpAccount, true);
}
}
Step 2. Configure push notifications in Conversational Cloud
1.Log into your Conversational Cloud account.
2.In Conversational Cloud, click the Engage tab, then Campaign Builder, and then Data Sources.
3.On the Integrations tab, under Mobile app management, click Manage.
4.Click Add new to add your app to the mobile campaign.
5.Enter your mobile package name and the Service account JSON, then click Create app.
Step 3. Configure the services and classes
1. Under the application tab, add the following services + receiver:
<service
android:name=".push.fcm.MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<service
android:name=".push.fcm.FirebaseRegistrationIntentService"
android:exported="false">
</service>
<receiver android:name=".push.NotificationUI$BadgeBroadcastReceiver">
<intent-filter>
<action android:name="ACTION_LP_UPDATE_NUM_UNREAD_MESSAGES_ACTION"/>
</intent-filter>
</receiver>
2. Now, create the classes to fit those services and change the path according to the classes you created.
The following services are an extension of Google’s Firebase cloud messaging services. For more details, see Firebase Cloud Messaging.
- MyFirebaseMessagingService: runs in the background and handles incoming messages.
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
// Send the data into the SDK
String account = "82055668";
PushMessage message = LivePerson.handlePushMessage(this, remoteMessage.getData(), account, false);
//Code snippet to add push UI notification
if (message != null){
NotificationUI.showNotification(this, message);
}
}
}
}
FirebaseRegistrationIntentService: registers for the pusher everytime the SDK gets initialized.
Enter your account number as account, and your package name as appID in order to register to the pusher, as shown in the example. Notice the token we are getting from the FirebaseInstanceId
. This is sent to the LivePerson pusher and integrated into your LivePerson account.
public class FirebaseRegistrationIntentService extends IntentService {
public static final String TAG = FirebaseRegistrationIntentService.class.getSimpleName();
public FirebaseRegistrationIntentService() {
super(TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
String token = FirebaseInstanceId.getInstance().getToken();
// Register to LivePerson Pusher
String account = "82055668";
String appID = "com.shaym.sdk28";
LivePerson.registerLPPusher(String brandId, String appId, String deviceToken, PushType pushType, LPAuthenticationParams authenticationParams, ICallback<Void, Exception> registrationCompletedCallback);
}
}
NotificationUI (or choose your own names for these classes): presents and handles the push to the UI.
public class NotificationUI {
private static final String TAG = NotificationUI.class.getSimpleName();
public static final int NOTIFICATION_ID = 143434567;
public static final String PUSH_NOTIFICATION = "push_notification";
public static void showNotification(Context ctx, PushMessage pushMessage) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(ctx).
setContentIntent(getPendingIntent(ctx)).
setContentTitle(pushMessage.getMessage()).
setAutoCancel(true).
setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_LIGHTS).
setSmallIcon(R.mipmap.ic_launcher).
setStyle(new NotificationCompat.InboxStyle()
.addLine(pushMessage.getFrom())
.addLine(pushMessage.getBrandId())
.addLine(pushMessage.getConversationId())
.addLine(pushMessage.getBackendService())
.addLine(pushMessage.getCollapseKey())
.addLine("Unread messages : " + LivePerson.getNumUnreadMessages(pushMessage.getBrandId()))
);
if (Build.VERSION.SDK_INT >= 21) {
builder = builder.
setCategory(Notification.CATEGORY_MESSAGE).
setPriority(Notification.PRIORITY_HIGH);
}
getNotificationManager(ctx).notify(NOTIFICATION_ID, builder.build());
}
public static void hideNotification(Context ctx){
getNotificationManager(ctx).cancel(NOTIFICATION_ID);
}
private static NotificationManager getNotificationManager(Context ctx) {
return (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
}
private static PendingIntent getPendingIntent(Context ctx) {
Intent showIntent = new Intent(ctx, MainActivity.class);
showIntent.putExtra(PUSH_NOTIFICATION, true);
return PendingIntent.getActivity(ctx, 0, showIntent, PendingIntent.FLAG_UPDATE_CURRENT);
}
/************************ Example of Icon Badge - For Samsung *******************************/
public static void setBadge(Context context, int count) {
SharedPreferences.Editor editor = context.getSharedPreferences("liveperson", MODE_PRIVATE).edit();
SharedPreferences prefs = context.getSharedPreferences("liveperson", MODE_PRIVATE);
int current = prefs.getInt("count", 0);
if (current == 0 || count == 1)
current += count;
else
current = count;
editor.putInt("count", current);
editor.apply();
String launcherClassName = getLauncherClassName(context);
if (launcherClassName == null) {
return;
}
Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
intent.putExtra("badge_count", current);
intent.putExtra("badge_count_package_name", context.getPackageName());
intent.putExtra("badge_count_class_name", launcherClassName);
context.sendBroadcast(intent);
}
public static String getLauncherClassName(Context context) {
PackageManager pm = context.getPackageManager();
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
for (ResolveInfo resolveInfo : resolveInfos) {
String pkgName = resolveInfo.activityInfo.applicationInfo.packageName;
if (pkgName.equalsIgnoreCase(context.getPackageName())) {
return resolveInfo.activityInfo.name;
}
}
return null;
}
/* Listen to changes in unread messages counter and update icon badge*/
public static class BadgeBroadcastReceiver extends BroadcastReceiver{
public BadgeBroadcastReceiver(){}
@Override
public void onReceive(Context context, Intent intent) {
int unreadCounter = intent.getIntExtra(LivePerson.ACTION_LP_UPDATE_NUM_UNREAD_MESSAGES_EXTRA, 0);
NotificationUI.setBadge(context, unreadCounter);
}
}
}
3. After thehandlePusherRegistration(MainActivity.this);
call added at theinit
stage, add the function to your messaging activity call to register to the pusher:
private void handlePusherRegistration(Context ctx) {
Intent intent = new Intent(ctx, FirebaseRegistrationIntentService.class);
ctx.startService(intent);
}
4. After theremoveNotification();
call added at theShowconversation
stage, add the following function to hide the push message when entering the conversation view:
private void removeNotification() {
NotificationUI.hideNotification(this);
}
Step 4. Implement a push handler
To handle a scenario when a push message is clicked, you need to implement a push handler on our messaging activity’s onCreate
function.
1. At the bottom of youronCreate
function, add:
handlePush(getIntent());
2. Add the following function into the messaging activity, which checks if the intent that opened the app came from a push notification. If it does, the function automatically directs the user to the conversation screen.
private void handlePush(Intent intent) {
boolean isFromPush = intent.getBooleanExtra(NotificationUI.PUSH_NOTIFICATION, false);
//Check if we came from Push Notification
if (isFromPush) {
clearPushNotifications();
if (LivePerson.isValidState()){
openActivity();
} else {
initActivityConversation();
}
}
}
3. Add a messaging activity to clear all pushes once the conversation screen has been clicked:
private void clearPushNotifications() {
((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).cancel(NotificationUI.NOTIFICATION_ID);
}
ℹ️ Please note that if user must see the notifications right away by waking devices up from Doze mode, a high priority notification must be sent to user device. To allow sending high priority notifications, please contact your account team to activate the feature on the LivePerson server side.
iOS - Push Notifications
Currently, our default flow for the process of loading the Conversation View Controller (such as registering with several of our internal domains) also registers the consumer to our Push Notification service.
If the adoption of the standard LivePerson Push notification service is not desired, the following flag has to be setted to “false”. in order for the changes to take effect, the consumer must log out of the LPMessagingSDK:
configuration.enableLpPusherService: Bool
Alternatively, for adopting the LivePerson Push notification service, is needed a physical device and an API key (or alternatively two .pem
files) for Conversational Cloud. Adoption of API key is preferred as is the easiest way to handle the renewal / revocation of credentials.
In section 7 it is explained the subsequent Push notification service configuration on the Conversational Cloud.
6 - SDK Callbacks
The SDK provides a callback mechanism to keep the host app updated on events related to the conversation.
LivePerson strongly recommends adopting it in order to proactively monitor for possible problems. Through callback the brand can monitor any errors thrown by the SDK, particularly with the authentication token expiration one.
These are the minimum set of use cases suggested for adopting the SDK callbacks:
- Any IDP errors event should trigger a reconnect call, e.g. expired or duplicate OAuth2.0 code. These reconnections have to be limited to few attempts and step back out of the conversation if errors continue to occur.
- Token expiration event should trigger a JWT update.
- User action on prevented permission events should be logged to see what permissions are missing. This is relevant if the brand plans to use file sharing or if it wants to control the permission request dialog.
Android - Callback Behavior
There are two ways to register to LivePerson events:
- Using Local Intents, with which it is possible to register for all Actions or to a specific Action. The SDK contains all the Actions and Extras useful, and provides a class with several methods that help get the data out of the intents.
- Using standard Callbacks.
LivePerson recommends using Local Intents. Here further details:
- Callbacks Interface
- Index of all callbacks (with both implementation versions)
iOS - Callback Behavior
The iOS version of SDK provides two type of Delegates to correctly manage every type of conversation event:
LPMessagingSDKDelegate
- for lifecycle and connectivity events;LPMessagingSDKNotificationDelegate
- for handling Push and In-App notifications.
The second delegate is mandatory to support Push notifications.
Here a complete list of the callbacks available.
7 - Conversational Cloud Settings
Mobile App Source Channel
Before proceeding with the SDK implementation it is necessary to configure the new mobile source channel. These steps allows brands to create the specific engagement for mobile apps, in the Campaign tab on Conversational Cloud:
- Activate the Mobile App channel from the Data Source section in the Campaigns tab, in the footnotes.
- Edit the Mobile App source details:
- Enter the App name (the default is Mobile App) and enter an optionally description.
- Add an application icon by entering the URL of the hosted image. The icon should be in .PNG, .JPG or .GIF format, the recommended size is 50x50 pixels (up to 50KB) and the image should be hosted on a https site.
Click Create. The Mobile App will now be installed on the Conversational Cloud account. On the same page, a new “App Key” will be created, showing the App Installation ID.
- Go to Campaigns section and under your preferred campaign add a new engagement selecting your new Mobile App channel.
After these steps it is possible to configure the SDK in the brand's app to work with the Conversational Cloud correctly.
Engagement configuration
Once the App source is configured, you can use it during engagement creation, selecting it as a Entry point source, like in the following screenshot:
The entry point configured can be easily used in the app code, as shown by the following iOS implementation example (relating on the above image):
@IBAction func getEngagementClicked(_ sender: Any) {
let entryPoints = ["retail_mobile_recent_orders"]
let engagementAttributes = [
["type": "purchase", "total": 20.0],
["type": "lead",
"lead": ["topic": "luxury car test drive 2015",
"value": 22.22,
"leadId": "xyz123" ]]
]
getEngagement(entryPoints: entryPoints, engagementAttributes: engagementAttributes)
}
This code shows how to use the entry point configured and how to pass some engagement attributes. It is also possible to use the behavioral targeting of the engagement, as shown in the following image:
Push Notifications configuration
Once the push notification service has been configured in the app, it must also be configured on the Conversational Cloud:
- In Conversational Cloud, go to the Campaigns tab, in the Data Sources footnote section.
- On the Integrations tab, under Mobile app management, click Manage.
- Click Add new to add your app to the mobile campaign.
- For Android, enter your mobile package name and the Google Firebase Legacy API key, then click Create app.
- For iOS, only enter your app’s name, and then click Create app. About this step check instructions on the iOS Push Notification section below.
8 - SDK OS-Version Support
The LivePerson InApp SDK supports:
- iOS - the latest major version and the previous two major versions.
- Android - always targets the latest Android version but maintains support for older versions with significant market share.
Brands should be aware they must upgrade the SDK in order to gain support for newer OS versions. Specifically on iOS, gaining support for a new major version means losing support for an older major version, so it is crucial to be prepared for any customer impact this may have.
As a best practice, LivePerson strongly recommends to integrate an SDK logout and login mechanism to reconnect customers after an SDK version upgrade. This ensures that any LivePerson persistent data structures are reliably upgraded.
Android - Login / Logout
To correctly log in authenticated customer and get the conversation app window, use this method:
- getConversationFragment()
To log out the customer use:
To recover connection after token expiration, use:
iOS - Login / Logout
To correctly log in authenticated customer and show the conversation app screen, use this:
To log out the customer use:
To recover connection after token expiration, use:
9 - Data Masking
Should be required for potentially customers’ sensitive data. There are two masking capabilities available to be configured:
- Client-side masking: The data is masked in the conversation transcript, appearing as asterisks, but the Agent can read it.
- Real-time masking: Both client and agent data get masked. Is possible to use pattern matching to block messages from being sent in error, or to hide a pattern of characters from the consumer side.
Here below a schematic summary of the two types of Data Masking.
| Real time masking | Client side masking |
---|
Masking on the app conversation screen
| ✓ | ✓ |
Masked when saved on the device’s local database
| ✓ | ✓ |
Masked when sending over the network
| ✓ | x |
Masked when shown to agents during the conversation
| ✓ | x |
Masked when retrieved from the engagement history (previous old conversations)
| ✓ | x |
Android - Data Masking
For enabling it, you need to set true the related attributes shown here.
iOS - Data Masking
Enablement instructions here.
10 - Quick Replies
Are a group of actionable items (chips) that appear as part of the conversation, making it easier to have an automated conversation with consumers.
Conversational Cloud enables sending 1-24 quick reply chips per message. Each chip can have:
- Title: up to 25 characters (use ellipsis)
- Click operation: with actions and metadata
- Styling elements: for full branding and styling needs
When a quick reply chip is tapped, the items are dismissed. Agents can see the quick replies group at all times, even if it is no longer visible to the consumer.
As a best practice, LivePerson recommends to offer Quick Replies also to returning customers when starting a new conversation.
Android - Quick Replies
Ensure that the following toggle is enabled within the SDK
enable_structured_content
iOS - Quick Replies
Ensure that the following toggle is enabled within the SDK
11 - Photo and File Sharing
The SDK provides the capability to share files from both agents and customers. List of supported formats:
- PNG
- JPG/JPEG
- GIF (non-animated) - previewed as a static image only
- PDF
- DOCX
- PPTX
- XLSX
Size details:
- Thumbnail - 30 KB (base64-encoded)
- Max upload size allowed - 5 MB uncompressed
To be noticed that:
- In an authenticated session, backgrounding the app while loading photos is not interrupting the action;
- For unauthenticated sessions, consumers must tap the photo again with each visit because the history gets cleared when a session expires or logs the consumer out.
Android - File Sharing
The Android SDK allows opening any supported file types other than images through the picker application. The customer can either long click on the thumbnail or open the file through the picker application to share and save the file.
To be noticed: To support SDK Photo and File sharing feature on Android 13 and above, a new permission has been introduced (to be added to the main manifest file):
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
iOS - File Sharing
The iOS SDK supports previewing all the supported file types on the device as per the iOS operating system by double-tapping on the thumbnail image.
12 - Control over the conversation window
Android - Conversation window
- Using the Activity mode brand can only customize the window provided by LivePerson. Here below an example:
- Using the Fragment mode brand can create a more integrated user experience, with richer customisation of the conversation window menus. Here below an example:
LivePerson recommend to use the Fragment mode, here further details:
About the window customization:
- Branding configuration
- All design attributes
iOS - Conversation window
Using the Window mode brand can only customize the window provided by LivePerson. Here below an example:
Using the ViewController mode brand can create a more integrated user experience, with richer customisation of the conversation window menus. Here below is an example:
LivePerson strongly recommends using the ViewController mode.
About the window customization:
- Branding and message screen
- All design attributes
Conversation windows differences
Android Activity Mode / Apple Window Mode | Android Fragment Mode / Apple View Controller Mode |
---|
Enable brands to customize only the standard window. | Enable brands full control of the window. |
Easy and quick to implement. | More complex and long, but related to the app design requirements. |
Conversation windows Questionnaire
What design requirements do you have? |
---|
How flexible are you with these design attributes? |
Are you willing to be flexible with some of your design requirements for the sake of speed of implementation (Android Activity Mode / Apple Window Mode)? |
LivePerson Conversation windows Recommendations
Implement Fragment Mode / View Controller Mode to have full control of the window. |
---|
Go through each of the Design Attributes in our documentation BEFORE implementation to understand how flexible we are. |
If you are pressed for time, then implement Activity Mode, then pivot to Fragment Mode in a later release. |
13 - Monitoring API
The Monitoring API is meant to enable consumer monitoring and engagement flows. By combining monitoring capabilities with our Campaigns feature, you can display tailored engagements to the right consumer at the right time.
Monitoring API allows brands to report events related to consumers' actions in the brand’s mobile app. These reporting events will feed into the campaigns to allow controlling messaging behaviors in the app directly from the Conversational Cloud.
Can be used for:
- Report on the customer's journey inside the app
- Retrieve engagements based on the reported SDEs
- Report on engagement attributes
- Route conversations to a specific skill (based on engagements)
Monitoring API sample flow
Here below an example of Monitoring API adoption in the conversation flow, with a graphic diagram:
- Brand’s app sends a request with the Engagement method. It’s possible to add in the request information regarding the consumer's activity within the brand's environment -
consumerId
or identities, entry points, engagement attributes, client properties, and other method’s required data. - The monitoring system creates a session for the requesting device and replies with an eligible engagement, including the
visitorId
and a sessionId
in the response.
The requesting device sends a request with the Report method, specifying the visitorId
and the sessionId
created in Step 2, in order to report about the status of the engagement usage - i.e. displayed, clicked.
Using Monitoring API VS Not Using It
Monitoring API | No Monitoring API |
---|
Display specific Campaigns / Messaging buttons to a customer based on data points. For example, display and route to the Sales team if the consumer goes to the Sales view of the app. Understand whether a given consumer has an open conversation at any time. | Always show the same Campaign / Messaging button for all entry points. |
Add more information before the start of or during the conversation. For example: - To see from which part of the App customer started Messaging
- To attach the reason why the customer has started it.
- To add some values from the product cart.
| Use authentication for passing customer Information, if user information is not changing, during conversation. |
Offer specific skill routing | All routing points to the same engagement. May require automation for advanced routing. |
Additional development work. | Quickier due to less development work. |
Monitoring API Questionnaire
Do you have routing use-cases? |
---|
Do you intend to tailor Messaging buttons with specific conditions? For example, at a certain time of day, certain type of customer, etc. |
Do you need to know whether the consumer has an open conversation at any time? |
LivePerson Monitoring API Recommendations
Implement the Monitoring API approach upfront due to routing flexibility and scalability. |
---|
Pass your Entry Points in your app views to LivePerson even if you aren’t using it at first, because it will allow you to scale easier once you do want to add routing logic. |
Remember to pass “identities” object within the Monitoring APIgetEngagement()call when you are using Authentication. This allows the brand to understand whether the consumer has an open conversation. |
14 - Get Unread Message Count
Here below the best practices to maximize the accuracy of the unread message count in the UI for the app user
- Call
getUnreadMessagesCount
(Android / iOS)with authentication credentials, in order to know who to return the count for; - The method caches values for 10 seconds. That means if the consumer quickly navigates about and the method is called twice, it will return the same value;
- The best time to call the method is after registering for push notifications, right after the SDK initialization;
- The best time to update the unread message count in the UI is right after a push notification (from LivePerson) has been received. The notification payload contains the latest unread messages count;
- The best time to reset the count to 0 in the UI is when the messaging window opens and has finished downloading the unread messages. You can tell when the messages have been downloaded when the:
Connection State has Changed
(Android) orLPMessagingSDKConnectionStateChanged
(iOS)
event triggers and returns true.
15 - General Tutorials
Android - Tutorial
For a more detailed implementation overview, refer to:
- Android quick start technical guide
- Messaging API - all messaging related methods.
iOS - Tutorial
For a more detailed implementation overview, refer to these:
- iOS quick start technical guide (XCFramework v5.2.1 and down)
- iOS quick start technical guide (XCFramework v6.0 and up)
16 - Deprecated Methods
Over time, the best practice way to implement methods has changed as new features have been introduced into the Mobile SDK. This section covers which commonly used methods have changed to assist with SDK upgrades.
Android methods
1. initialize
The initialize method now expects a initProperties
argument instead of a brandId
and initCallBack
. The initProperties
is the new way of passing those parameters, in addition to the new appId
and mMonitoringInitParams
parameters.
public static void initialize (
Context context,
InitLivePersonProperties initProperties
)
|
---|
|
2. logout
Logout now accepts a PushUnregisterType
argument that allows you to control what push notifications are unregistered on logout. By default, all notifications will cease but you can now choose whether to keep the user fully registered or only allow messages from Proactive Messaging.
You can also specify the forceLogOut
boolean that lets logOut complete successfully, even if the unregistering from push notifications fails.
public static void logOut(
Context context,
String brandId,
String appId,
boolean forceLogOut,
PushUnregisterType type,
LogoutLivePersonCallback logoutCallback
)
|
---|
|
3. showConversation
LPAuthenticationParams
and ConversationViewParams
are now required as part of showConversation.
See the documentation for more details on conversationViewParams
and authenticationParams
.
public static boolean showConversation(
Activity activity,
LPAuthenticationParams lpAuthenticationParams,
ConversationViewParams params
)
|
---|
|
4. getConversationFragment
Similar to showConversation, the getConversationFragment also requires LPAuthenticationParams
and ConversationViewParams
.
public static Fragment getConversationFragment(
LPAuthenticationParams lpAuthenticationParams,
ConversationViewParams params
)
|
---|
|
5. LPAuthenticationParams
A new enum property is needed to be set as part of LPAuthenticationParams
. The default is SIGN_UP
, however, this is being deprecated and UN_AUTH
/AUTH
should be used instead.
public class LPAuthenticationParams{
private LPAuthenticationType mType;
private String mAuthKey;
private String mHostAppJWT;
private String mHostAppRedirectUri;
private List<String> mCertificatePinningKeys;
public enum LPAuthenticationType {SIGN_UP, UN_AUTH, AUTH }
}
|
---|
|
You can set the LPAuthenticationType
when you create an instance of the LPAuthenticationParams
class as follows:
new LPAuthenticationParams(LPAuthenticationType.AUTH)
|
---|
|
6. registerLPPusher
When registering for push notifications, authenticationParams
should be provided to ensure the user gets notifications as soon as the user is registered. Otherwise, notifications will only be received once the user has opened the messaging window.
The method also accepts a ICallback
to allow for the handling of successful/failed registration attempts.
Support for FCM and HUAWEI notification services has also been implemented. The required service can now be specified via the PushType
property.
public static void registerLPPusher(
String brandId,
String appId,
String deviceToken,
PushType pushType,
LPAuthenticationParams authenticationParams,
ICallback<Void, Exception> registrationCompletedCallback
)
|
---|
|
7. getUnreadMessagesCount
A version of this method was called getNumUnreadMessages and has been deprecated in favor of this new method.
This new implementation requires an instance of LPAuthenticationParams
to be able to check the unread message count before the user opens up the messaging window.
public static void getUnreadMessagesCount(
String appId,
LPAuthenticationParams authenticationParams,
final ICallback<Integer, Exception> callback
)
|
---|
|
iOS Methods
1. initialize
Older versions of initialize only required the brandId
. Now, LPMonitoringInitParams
should always be provided. See the documentation for details on the LPMonitoringInitParams
class.
func initialize(
_ brandID: String? = nil,
monitoringInitParams: LPMonitoringInitParams? = nil
)
|
---|
|
2. logout
Logout now accepts an unregisterType
argument that allows you to control what push notifications are unregistered on logout. By default, all notifications will cease but you can now choose whether to keep the user fully registered or only allow messages from Proactive Messaging.
Older SDK versions didn’t include completion and failure callbacks. It is highly recommended to implement these for handling failure flows.
func logout(
unregisterType: LPPusherUnregisterType,
completion: @escaping ()->(),
failure: @escaping (_ error: Error)->()
)
|
---|
|
3. showConversation
showConversation is not available on iOS 12 and below. Wrap the method in availability annotations and display an error message to the consumer suggesting that they update to a newer iOS version.
See the documentation for more details on conversationViewParams
and authenticationParams
.
func showConversation(
_ conversationViewParams: LPConversationViewParams,
authenticationParams: LPAuthenticationParams? = nil
)
|
---|
|
4. LPAuthenticationParams
LPAuthenticationType
must now be defined. It should take the value of .unauthenticated
or .authenticated
since .signup
has been deprecated.
class LPAuthenticationParams: NSObject {
var authenticationCode: String?
var jwt: String?
var redirectURI: String?
var certPinningPublicKeys: [String]?
var type: LPAuthenticationType = .signup
}
|
---|
|
5. registerPushNotifications
registerPushNotifications
now accepts an authenticationParams
argument. This allows LP to know who the user is before they open the messaging window and allow the user to receive notifications much earlier.
func registerPushNotifications(
token: Data,
notificationDelegate: LPMessagingSDKNotificationDelegate? = nil,
alternateBundleID: String? = nil,
authenticationParams: LPAuthenticationParams? = nil
)
|
---|
|
6. getUnreadMessagesCount
You can now pass authentication details via authenticationParams
to check the unread message count before the user opens up the messaging window.
func getUnreadMessagesCount(
_ conversationQuery: ConversationParamProtocol,
authenticationParams: LPAuthenticationParams?,
completion: @escaping (_ badgeCounter: Int)->(),
failure: @escaping (_ error:NSError)->()
)
|
---|
|
16 - F.A.Q.
Q: How is Conversational Cloud messaging deployed on the brand’s app?
A: The app owner integrates the SDK and uses its APIs to interface with the app. The SDK communicates with the Conversational Cloud in the background and facilitates a continuous conversation, in which agents are using the Conversational Cloud web interface to interact with consumers.
Q: Is there a test environment to explore the setup before implementing the program?
A: LivePerson can provide sample apps (iOS + Android) that can be used for code samples and to explore our features.
Q: Will the SDK affect the brand’s app’s performance?
A: The SDK footprint is very low in terms of memory and CPU usage. While the messaging feature is in the foreground, the SDK consumes and processes data (depending on usage) to sync with the servers. After leaving the conversation screen, the SDK actively disconnects any redundant networking activity.
Q: How does the integration of messaging impact brand’s app size?
A: For Android, the size of the SDK once installed utilizes approximately 4MB with external required dependencies. For iOS, the size of the SDK once installed utilizes approximately 3.5MB.
Q: How much usage of data does mobile messaging expend?
A: A typical conversation with a length of 12 back-and-forth messages will expend 40KB of download and 5KB of upload data (not including shared photos or files).
Q: How does the SDK ensure that sensitive information is transmitted to consumers securely?
A: Security is an integral part of the software development processes at LivePerson. To protect the privacy of both consumers and the brand, the Conversational Cloud messaging SDK was designed with the strictest security measures.
Q: What is the maximum supported message length a consumer or an agent can send through InApp SDK? Can these limits be configured?
A: Limits for message length cannot be configured. The maximum supported length of messages on InApp SDK is 2000 characters for an agent or consumer messages.
Ready to move on to the capabilities for this stage? Click here to proceed.