We have recently refreshed our branding across our offerings and changed the names of our pricing plans. If you have signed up before Aug 9, 2021, please click Previous plans to view your applicable plans.
We assure you that this change will not impact your product experience, and no action is required on your part.


TABLE OF CONTENTS

1. Add Freshchat SDK to your project

2. Initialization of SDK

2.1 Initialization Config Options

3. User Information

3.1 Updating User Information

3.2 Updating User Properties (Meta Data)

3.3 Log User Events in Timeline (Available from version 3.1.0)

3.4 Reset User Data

3.5 Restore user

4. Launching the Support Solution

4.1 Conversations

4.1.1 Filtering Conversation Topicss

4.1.2 Unread Count

4.1.3 Unread message count across conversations filtered by tags

4.2. FAQ

4.2.1 FAQs Options

4.2.2 Filtering FAQ categories by tags

4.2.3 Filtering FAQ articles by tags

4.2.4 Filter Topics displayed on clicking "Contact Us" in FAQs by tags

5. Send message API

6. Push Notifications

6.1 Connecting Freshchat with FCM 

6.1.1 Saving FCM server key in Freshchat web portal

6.2 Customising Notifications

7. Language localization

7.1 Changing Default SDK texts

7.2 Localization

7.3 Right-to-Left Language Support

7.4 Runtime app locale change

8. Customizations

8.1 UI Customization options

8.2 Custom Image Loader

8.3 Intercept and handle Non-Freshchat links in app

9. Other Notes

9.1 Checklist for Launch

9.2 Permissions

9.3 Proguard Configuration (If Proguard is enabled in your app)

9.4 Sample Apps


Prerequisites

  • Freshchat SDK clients require devices running Android 4.1 or higher
  • Freshchat SDK supports apps targeting Android version 7.0 with appcompat-v7 r24.2 or later.


Get your App ID, App Key, and Domain

Login to your Freshchat account as Account Owner/Admin. Go to Admin > Mobile SDK.



1. Add Freshchat SDK to your project


i) Add the maven URL to the root build.gradle (project/build.gradle)

allprojects {
    repositories {
        jcenter()
        maven { url "https://jitpack.io" }
    }
}


ii) Add the following dependency to your app module's build.gradle file (project/app/build.gradle):               

apply plugin: 'com.android.application'

android {
// ...
}

dependencies {
// ...
    implementation 'com.github.freshworks:freshchat-android:{{latest-version}}'
}

Replace {{latest-version}} with the latest version of the SDK from here. 

For e.g. implementation 'com.github.freshworks:freshchat-android:4.2.0'


iii) When app targets Android 7.0+ and Image attachment is enabled, FileProvider needs to be configured.

Include the provider in the AndroidManifest.xml as below.

AndroidManifest.xml

<provider
   android:name="androidx.core.content.FileProvider"
    android:authorities="com.example.demoapp.provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/freshchat_file_provider_paths" />
</provider>

Strings.xml

<string name="freshchat_file_provider_authority">com.example.demoapp.provider</string>


Please refer to this video for more information.


2. Initialization of SDK

Invoke Freshchat.init() with your app id, app key, and domain before invoking/ attempting to use any other features of Freshchat SDK.  


We highly recommend invoking init() from your app's launcher/support activity's onCreate() function. Freshchat SDK checks for the presence of its components during init() and will warn about missing components when it detects the components are missing or their manifest entries are missing. 


Replace the YOUR-APP-ID, YOUR-APP-KEY, and YOUR-DOMAIN in the following code snippet with the actual app ID, app key, and Domain.


FreshchatConfig config = new FreshchatConfig("YOUR-APP-ID","YOUR-APP-KEY");
freshchatConfig.setDomain("YOUR-DOMAIN");
Freshchat.getInstance(getApplicationContext()).init(config);


2.1 Initialization Config Options

Enable or disable features like camera capture by specifying it in the config before initialization. 

FreshchatConfig config = new FreshchatConfig("YOUR-APP-ID","YOUR-APP-KEY");
config.setDomain("YOUR-DOMAIN");
config.setCameraCaptureEnabled(true);
config.setGallerySelectionEnabled(true);
config.setResponseExpectationEnabled(true);
Freshchat.getInstance(getApplicationContext()).init(config);

3. User Information


3.1 Updating User Information

You can send basic user information at any point to give you more context on the user when your support agents are messaging back and forth with them. 

// Get the user object for the current installation
FreshchatUser freshchatUser = Freshchat.getInstance(getApplicationContext()).getUser();
freshchatUser.setFirstName("John");
freshchatUser.setLastName("Doe");
freshchatUser.setEmail("[email protected]");
freshchatUser.setPhone("+91", "9790987495");

// Call setUser so that the user information is synced with Freshchat's servers
Freshchat.getInstance(getApplicationContext()).setUser(freshchatUser);

3.2 Updating User Properties (Meta Data)

You can capture and send additional metadata about the user and the events in the app, all of which also becomes a way to segment your users to later push messages to them.  

/* Set any custom metadata to give agents more context, and for segmentation for marketing or pro-active messaging */
Map<String, String> userMeta = new HashMap<String, String>();
userMeta.put("userLoginType", "Facebook");
userMeta.put("city", "SpringField");
userMeta.put("age", "22");
userMeta.put("userType", "premium");
userMeta.put("numTransactions", "5");
userMeta.put("usedWishlistFeature", "yes");
                                
//Call setUserProperties to sync the user properties with Freshchat's servers
Freshchat.getInstance(getApplicationContext()).setUserProperties(userMeta);


3.3 Log User Events in Timeline (Available from version 3.1.0)


Tracking user events provides more insight and context about the user(s) in your application. Events like user actions, failure/error cases can be tracked using this API. Tracked events are listed under Events Timeline on the agent side.


String eventName = "Visited Order Details page";

// Create a map and set required properties like below  
HashMap<String, Object> properties = new HashMap<>();
properties.put("Order Id", 3223232332);
properties.put("Order Date", "24 Jan 2020");
properties.put("Order Status ", "In-Transit");

// Call trackEvent by passing eventName and a map of properties
Freshchat.trackEvent(getContext(), eventName, properties);



Note:
1. Freshchat allows only 121 unique events per account

2. Event name accepts string value (max 32 chars)

3. Property key name should be of string type (max 32 chars)

4. Property value can be of any primitive object type (max 256 chars)

4. Freshchat allows sending a maximum of 20 properties per event


3.4 Reset User Data

Reset user data at logout or when deemed appropriate based on user action in the app by invoking the resetUser API. 

Freshchat.resetUser(getApplicationContext());


3.5 Restore user

For retaining the chat messages across devices/sessions/platforms, the mobile app needs to pass the same external id and restore id combination for the user. This will allow users to seamlessly pick up the conversation from any of the supported platforms - Android, iOS, and Web.


  • External Id - This should (ideally) be a unique identifier for the user from your system like a user id or email id and is set using Freshchat.identifyUser() API. This cannot be changed once set for the user.

  • Restore Id - This is generated by Freshchat for the current user, given an external id was set and can be retrieved anytime using the Freshchat.getUser().getRestoreId() API. The app is responsible for storing and later present the combination of external id and restore id to the Freshchat SDK to continue the chat conversations across sessions on the same device or across devices and platforms.


Note: 
Restore Id for a user is typically generated only when user has sent a message.
Notifications are supported in only one mobile device at any point in time and is currently the last restored device or device with the last updated push token.



To set the external id

Freshchat.getInstance(getApplicationContext()).identifyUser(externalId, null);


To retrieve the restore id

String restoreId = Freshchat.getInstance(getApplicationContext()).getUser().getRestoreId();
saveRestoreIdForUser(restoreId);


To lookup and restore user by external id and restore id

Freshchat.getInstance(getApplicationContext()).identifyUser(externalId, restoreId);


To listen to restore id generated event

Restore Id generation is an asynchronous process. So you need to register a broadcast receiver to get notified when restore id is generated. This receiver can be registered at onCreate and unregistered at onTerminate of your application class.


Register for broadcast receiver

IntentFilter intentFilter = new IntentFilter(Freshchat.FRESHCHAT_USER_RESTORE_ID_GENERATED);
LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(broadcastReceiver, intentFilter);

Listen to broadcast receiver

BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
  @Override
  public void onReceive(Context context, Intent intent) {
     String restoreId = Freshchat.getInstance(getApplicationContext()).getUser().getRestoreId();
  }
};

Unregister broadcast receiver

LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(broadcastReceiver);


4. Launching the Support Solution

Use the snippets below to launch into the FAQ or Conversation based support experience from a call to action in your app. Your call to action or entry point can be an on-screen button or a menu item.


4.1 Conversations

In response to specific UI events like a menu selection or button on click event, invoke the showConversations() API to launch the Conversation Flow. If the app has multiple Topics configured, the user will see the Topic list. The Topics list is ordered as specified in the Dashboard (link to the Topics list in the dashboard) when there are no messages. When messages are present, the order is based on the most recently interacted Topics

Note: Only Topics with visibility set to "Visible to all users" will be displayed when using showConversations() API


Launching a conversation list from a tap of a button on your app's screen

myConversationsButton.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {
        Freshchat.showConversations(getApplicationContext());
    }
}); 


4.1.1 Filtering Conversation Topics

To filter and display only Topics tagged with a specific term, use the filterByTags API in ConversationOptions instance passed to showConversations() API as below.


Eg: To link and display only specific Topics from say orders page in your app, those specific Topics can be tagged with the term "order_queries".

List<String> tags = new ArrayList<>();
tags.add("order_queries");
ConversationOptions options = new ConversationOptions()
    .filterByTags(tags, "Order Queries");
Freshchat.showConversations(MainActivity.this, options);


Note: 
If no matching Topics are found, the user will be redirected to the default Topic.

Topics which are normally not visible when using showConversations() API, will also be displayed when tagged and the specific tag is passed to filterByTags API of ConversationOptions instance passed to showConversations() API.




Please refer to this video for more information

4.1.2 Unread Count

If you would like to obtain the number of unread messages for the user at app launch or any other specific event, use the getUnreadCountAsync API and display the count.


Freshchat.getInstance(getApplicationContext()).getUnreadCountAsync(new UnreadCountCallback() {
        @Override
        public void onResult(FreshchatCallbackStatus freshchatCallbackStatus, int unreadCount) {
            //Assuming "badgeTextView" is a text view to show the count on
            badgeTextView.setText(Integer.toString(unreadCount));
        }
    });


The app can also choose to listen to changes to unread count when the app is open. The way to listen to the broadcast is described below.


Register for the broadcast receiver

IntentFilter intentFilter = new IntentFilter(Freshchat.FRESHCHAT_UNREAD_MESSAGE_COUNT_CHANGED);
    getLocalBroadcastManager(getApplicationContext()).registerReceiver(unreadCountChangeReceiver, intentFilter);


Listen for unread count

BroadcastReceiver unreadCountChangeReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        Freshchat.getInstance(getApplicationContext()).getUnreadCountAsync(new UnreadCountCallback() {
            @Override
            public void onResult(FreshchatCallbackStatus freshchatCallbackStatus, int unreadCount) {
                //Assuming "badgeTextView" is a text view to show the count on
                badgeTextView.setText(Integer.toString(unreadCount));
            }
        });
    }
}


Unregister for the broadcast receiver

getLocalBroadcastManager(getApplicationContext()).unregisterReceiver(unreadCountChangeReceiver);

4.1.3 Unread message count across conversations filtered by tags

If you would like to obtain the number of unread messages for the user across specific conversations filtered by tags, use the getUnreadCountAsync API.


List<String> tags = new ArrayList<>();
    tags.add("premium"); // Tags to filter conversations by
    Freshchat.getInstance(getApplicationContext()).getUnreadCountAsync(new UnreadCountCallback() {
        @Override
        public void onResult(FreshchatCallbackStatus FreshchatCallbackStatus, int unreadCount) {
            badgeTextView.setText(Integer.toString(unreadCount));
        }
    }, tags);


4.2. FAQ

In response to specific UI events like a menu selection or button click event, invoke the showFAQs() API to launch the FAQ screen. By default, the FAQ Categories are displayed as a grid with a “Contact Us” button at the bottom. For customizing this, check the FAQ Options.

myFAQButton.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {
        Freshchat.showFAQs(getApplicationContext());
    }
});

4.2.1 FAQs Options

Customizations to the FAQ flow can be achieved by specifying the relevant options in the FaqOptions instance passed to the showFAQs() API.

// Launching FAQ from click of a button in your app's screen
myFAQButton.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {

        FaqOptions faqOptions = new FaqOptions()
            .showFaqCategoriesAsGrid(true)
            .showContactUsOnAppBar(true)
            .showContactUsOnFaqScreens(false)
            .showContactUsOnFaqNotHelpful(false);

        Freshchat.showFAQs(MainActivity.this, faqOptions);
    }
});


4.2.2 Filtering FAQ categories by tags

To filter and display only FAQ Categories tagged with a specific term, use the filterByTags API with Filter Type as Category in FAQOptions instance passed to showFAQs() API.


Eg: To display FAQ Categories related to specific user type, those specific FAQ Categories can be tagged with the term "premium".

List<String> tags = new ArrayList<>();
tags.add("premium");

FaqOptions faqOptions = new FaqOptions()
    .filterByTags(tags, "FAQs", FaqOptions.FilterType.CATEGORY);//tags, filtered screen title, type

Freshchat.showFAQs(MainActivity.this, faqOptions);


4.2.3 Filtering FAQ articles by tags

To filter and display only FAQs tagged with a specific term, use the filterByTags API with Filter Type as Article in FAQOptions instance passed to showFAQs() API as below. 


Note: FAQs also inherit the tags from the parent FAQ Category


Eg: To link to FAQs related to payment failure, those specific FAQs can be tagged with the term "payment_failure" and can be linked to from Payments page in the app.

List<String> tags = new ArrayList<>();
tags.add("payment_failure");

FaqOptions faqOptions = new FaqOptions()
    .filterByTags(tags, "payment_failure", FaqOptions.FilterType.ARTICLE);//tags, filtered screen title, type

Freshchat.showFAQs(MainActivity.this, faqOptions);


4.2.4 Filter Topics displayed on clicking "Contact Us" in FAQs by tags

To filter and display only Topics tagged with a specific term when user clicks "Contact Us"in FAQ screens, use the filterContactUsByTags API in FAQOptions instance passed to showFAQs() API as below.


Note: The default behavior for "Contact Us" from within FAQ flow is the same as invoking showConversations() i.e it will display all Topics that are marked "Visible to all users", except when filtering of Topics is enabled by passing tags to filterContactUsByTags API.


Eg: To display Topics related to a specific section of FAQ show, those specific Message Topics can be tagged with the term "payment_failure" 

List<String> tags = new ArrayList<>();
tags.add("payment_failure");

FaqOptions faqOptions = new FaqOptions()
    .filterContactUsByTags(tags, "Payments"); //tags, filtered screen title

Freshchat.showFAQs(MainActivity.this, faqOptions);


5. Send message API

The app can send a message on behalf of the user using the sendMessage() API. 


Note: This API would silently send a message and not launch the Freshchat SDK UI


Eg: To send a message on a Topic tagged "premium", the API can be invoked as below.

String tag = "premium";
String msgText = "User has trouble with order #1234";
FreshchatMessage FreshchatMessage = new FreshchatMessage().setTag(tag).setMessage(msgText);
Freshchat.sendMessage(getContext(), FreshchatMessage);


6. Push Notifications

Integrating Freshchat push notification in your application will help users receive your support messages quicker.

6.1 Connecting Freshchat with FCM 


Prerequisites

  1. FCM Implemented in you app
  2. Device running Play Services
  3. FCM Server Key saved in Freshchat web portal

Steps

  1. Saving FCM server key in Freshchat web portal
  2. Sending the device registration token to Freshchat

  3. Handling messages

Please refer to this video for more information.

6.1.1 Saving FCM server key in Freshchat web portal

Get your Application’s Firebase FCM server key and save it in the Freshchat web app under Admin > Mobile SDK > FCM Server key section.


6.1.2 Sending the device registration token to Freshchat

Send user push registration token to Freshchat SDK. 

String token = FirebaseInstanceId.getInstance().getToken();
Freshchat.getInstance(this).setPushRegistrationToken(token);


6.1.3 Handling messages

In the app’s implementation of  FirebaseMessagingService, pass the RemoteMessage object to Freshchat if it is a Freshchat notification.

public void onMessageReceived(RemoteMessage remoteMessage) {
    if (Freshchat.isFreshchatNotification(remoteMessage)) {
        Freshchat.handleFcmMessage(context, remoteMessage);
    } else {
        // Handle notifications with data payload for your app
    }
}


6.2 Customizing Notifications

Freshchat SDK supports customizing the following for notifications.


1. Notification Icon (Small Icon and Large Icon) - App icon is used as the default for the small icon if not set explicitly.

2. Notification Sound - Enable or disable notification tone. By default it is disabled.

3. Notification Priority - Priority for notifications in below Android 8.0 devices. Default is NotificationCompat.PRIORITY_DEFAULT.

4. Notification Importance - Importance for notifications in Android 8.0+ devices. Default is NotificationManagerCompat.IMPORTANCE_DEFAULT. This can be modified to show Heads up Notifications.

5. Activity to launch on up navigation from the messages screen launched from notification. The messages screen will have no activity to navigate up to in the backstack when it is launched from notification. Specify the activity class name to be launched.   

6. For specifying the accent color of the circle behind the small icon in a notification,

<color name="freshchat_notification_accent_color">@color/red</color>


7. On Oreo and later versions of Android, the notification channel name used to deliver notifications can be customized by overriding the string as below.

<string name="freshchat_campaign_notification_channel_name">Campaign messages</string>

    8. Specifying the notification config,

FreshchatNotificationConfig notificationConfig = new FreshchatNotificationConfig()
.setNotificationSoundEnabled(true)
.setSmallIcon(R.drawable.ic_notif_small_icon)
.setLargeIcon(R.drawable.ic_notif_large_icon)
.launchActivityOnFinish(MainActivity.class.getName())
.setPriority(NotificationCompat.PRIORITY_HIGH);

Freshchat.getInstance(getApplicationContext()).setNotificationConfig(notificationConfig);


Android Oreo Support

Freshchat supports Notification channels out of the box in Oreo or later. It automatically creates a notification channel for conversation messages.

Note:

If you haven’t already integrated FCM, do so by following the instructions here and then follow the above 3 steps.


7. Language localization


7.1 Changing Default SDK texts

All strings in SDK can be modified by overriding them in strings.xml.


All Freshchat texts can be found here.


7.2 Localization


7.2.1 Language localization of default Freshchat texts

All strings in SDK can be modified by overriding them in the respective locale strings.xml file.


All Freshchat texts can be found here.


For more details, refer to the Android developer's documentation here.

Please refer to this video for more information.

7.2.2 Language localization of FAQs and Topics

Once FAQs and Topics are localized in the Freshchat web app, SDK will automatically update content based on the user’s app/device locale.


7.3 Right-to-Left Language Support

Freshchat SDK supports RTL languages. 


7.4 Runtime app locale change


If your app can support different locale (languages) apart from the default locale of the device, follow the steps below to update the locale in your Freshchat SDK.


1. Once app changes locale, notify the sdk about the app locale change using below method,


Freshchat.notifyAppLocaleChange(activityContext);


2. Freshchat internally uses webview as part of SDK, from Android OS version 7.0, webview changes locale during the webview load.


To fix this, we have provided a callback method onLocaleChangedByWebView(), where you need to reset the locale again inside this function.


Implement FreshchatWebViewListener


private FreshchatWebViewListener webviewListener = new FreshchatWebViewListener() {
    @Override
    public void onLocaleChangedByWebView(@NonNull WeakReference<Context> activityContext) {
      if (activityContext.get() == null) {
        return;
      }
      
      // Reset the run time locale here
      changeLocale(activityContext, appLocale);
    }
  };

Set webview listener to Freshchat Instance .We recommend you to do this in onCreate() of Application class.


Freshchat.getInstance(this).setWebviewListener(webviewListener);



8. Customizations


8.1 UI Customization options

Refer theme documentation here.


8.2 Custom Image Loader

SDK defaults to including Picasso 2.5.2 library to download images. If you want to use any other version of Picasso or any other image download library, you can set your custom image downloader with Freshchat SDK using setImageLoader() API.


Examples

Implement your custom image loader

public class CustomImageLoader implements FreshchatImageLoader {
  
  @Override
 public void load(@NonNull FreshchatImageLoaderRequest request, @NonNull ImageView imageView) {
    // your code to download image and set to imageView
  }

  @Nullable
  @Override
  public Bitmap get(@NonNull FreshchatImageLoaderRequest request) {
    // code to download and return bitmap image
  }

  @Override
  public void fetch(@NonNull FreshchatImageLoaderRequest request) {
    // code to download image
  }
}


Call Freshchat.setImageLoader() in onCreate() of your Application class

public class MyApp extends Application {

  @Override
  public void onCreate() {
    super.onCreate();
    Freshchat.setImageLoader(new CustomImageLoader());
  }
}



Freshchat provides a way to handle all non Freshchat hyperlinks clicks by apps. 

Register a LinkHandler with Freshchat which would provide a callback when a user clicks a link.


We recommend setting the link handler in the Application class.


private LinkHandler linkHandler = new LinkHandler() {

    @Override

    public boolean handleLink(@NonNull String url, @Nullable Bundle bundle) {

        if (urlHandledByApp) {

            return true; // true, if handled by app

        } else {

            return false; // false, to let Freshchat SDK handle the link

        }

    }

};


// Set link handler to override links

Freshchat.getInstance(context).setCustomLinkHandler(linkHandler);




9. Other Notes


9.1 Checklist for Launch

  1. Ensure you are initializing the SDK in the onCreate of the application or support activity.
  2. Ensure you are on the latest version of SDK.
  3. Check that you have push notifications working right from your first launch and have the right notification icons configured.
  4. Ensure the App name is set right for your notifications.
  5. Configure your default Topic name and welcome message right even if you aren't using other Topics.
  6. Capture the unique user identifier, email, phone number, or any other unique customer identifiers with the SDK to ensure smooth use of APIs, as well as for the best use of our "Smart Plugs" feature on the dashboard.
  7. Ensure the push notifications are working for new installs as well as upgrades from your previous versions.

9.2 Permissions

Freshchat SDK is built with support for the Run Time/Dynamic Permissions Model introduced in Marshmallow as long as the app is built with targetSdk as Marshmallow or later.


9.3 Proguard Configuration (If Proguard is enabled in your app)

Freshchat Android SDK is configured out of the box to support proguard. Proguard will automatically pickup the config for the SDK, no manual configuration is necessary.


9.4 Sample Apps


Here is a list of sample apps that you can refer to while figuring out how to integrate the Freshchat SDK into your app. You can use the following FCM server key to test push notifications:


AAAAWQmY32o:APA91bGLTV57JJH-1vJcjNJzhz5Z72BL4Ll5SHjtSmmQKp_3SqcGUFZ9Qhm0XivQLpukN7r6CHY1oRYzsVALt9-O_uhC8YU-m1b1GmwMDfp377ckjFg81_C68b807BEPw1axYCSu32lQ