Beacon for Android

For issues or questions, contact Help Scout support at help@helpscout.com

Requirements

The minimum supported SDK is 21 (Android 5.0), and your app must be compiled with at least API version 27 (Android 8.1). If you need to support below SDK 21 it’s possible to create multiple APKs for different API levels. Beacon could be used as normal in the .apk which supports SDK 21+ and in the .apk that supports SDK <21 you could add fall back open of opening a new email.

The Beacon SDK only needs Internet permission which is defined in the Core module.

Sample Application

We’ve created an open source sample repository with several sample apps that you can reference during your implementation. We hope it’s helpful!

Installation

JCenter

The Beacon Android SDK is distributed as AAR and available from JCenter, so simply add the following lines to your app’s build.gradle file.

dependencies {
  implementation "com.helpscout:beacon-core:$beaconVersion"
  implementation "com.helpscout:beacon-ui:$beaconVersion"
}

Once you sync the Gradle project you’ll be ready to initialize Beacon.

Alternate install

Alternatively you can download the .aar files from our repository on bintray.com

  • Beacon Core Beacon Core download
  • Beacon UI Beacon UI download

Usage

Initialize Beacon

You can find basic setup code and your Beacon ID in the web Beacon builder by clicking “Installation” on the left sidebar, then navigating to “Android” in the options displayed at the top.

Once you’ve located the Beacon ID, you are ready to initialise the library. If you will only display one Beacon, the Application.onCreate() method of your Application class class is a great place to initialize the SDK. If you won’t know the Beacon ID at Application start, or will be running multiple Beacons, you’ll need to make sure of adding the following call to the Beacon.Builder() before you launch BeaconActivity.

Beacon beacon = new Beacon.Builder()
  .withBeaconId("76d18b11-41f4-4d34-9a8c-08679d4759e3")       
  .build();

Beacon ID field is mandatory. Failing to provide it will throw an SDKInitException when an interaction with the Beacon object is done.

We use a Provider to to handle the initialisation of the SDK with Application Context. Auto Init can be disabled by adding the following meta-data tag to your manifest:

<meta-data android:name="com.helpscout.beacon.SDKAutoInitialise" android:value="false" />

However if Auto Init is disabled you need to pass a context to Beacon.Builder.withContext() to manually init the Beacon.

Open Beacon

Once you’ve initialized Beacon, you’re ready to interact with it. Whenever you want to invoke Beacon, use the code below to display the Beacon user interface.

BeaconActivity.open(context);

There isn’t an explicit method for closing the Beacon as it is meant to be closed when the user taps the close button or navigates back using the back button.

Developer options

It’s possible to launch the Beacon SDK in developer mode. By doing so, you’ll be able to read the HTTP requests and other actions that happen with the SDK.

In order to activate this mode, you have to tell the Beacon Builder like so:

 Beacon beacon = Beacon.Builder()
   .withBeaconId("cf2102b5-0f3c-4214-972e-2a1d33c7fadb")       
   .withLogsEnabled(true)       
   .build();

Once this is done, head over to LogCat.

Authenticating users

You can provide the name and email address to pre-populate and hide the fields on the ‘Create a message’ screen.

Normal Mode

Normal mode authentication requires an user’s email address as the user identifier.

  Beacon.login("user@domain.com");

Alternatively, you can also identify the user’s name.

  Beacon.login("user@domain.com", "John Doe");

Secure Mode

If a valid signature is provided, it can be used to authenticate a user in Secure Mode and retrieve their previous conversations. Secure Mode ensures that the visitor is who they say they are. For security reasons, you’ll need to pass in the signature every time you want to open the Beacon UI.

Note: the secret key should not be stored in the app; instead your server should provide the computed signature value.

  BeaconActivity.openInSecureMode(context, "8235545a15c6f41b64e3c47e5c94d3...");

Logout

If your Beacon is in Normal Mode (you aren’t using Secure Mode), there may be a case for calling this method, which deletes the user data from the Beacon, including, email, name, user attributes, push token and reset the Beacon Device ID. It won’t remove the Beacon ID or local config overrides.

  Beacon.logout();

Clear

Will wipe all data from the Beacon including the Beacon ID. This may be useful if you are using different Beacons in different parts of your app.

  Beacon.clear();

User Attributes

Beacon supports the addition of up to 30 attributes. These are arbitrary key-value pairs used to track custom data attributes that are then synced with the customer’s Help Scout profile and displayed in the Beacon sidebar app. The attributes can only take values of type String (E.g: phone: "1-999-999-9999"" or "Subscription": "Free Plan").

You may add an attribute like so:

  Beacon.addAttributeWithKey("Subscription", "Free Plan");

You may also remove specific attributes, or clear the entire set.

  Beacon.removeAttribute("a key"); //remove one attribute
  Beacon.clearAttributes(); //clear all attributes

Prefilling the contact form

The PreFilledForm object can be used to pre-populate the “Create a message” contact form data. You can fill any of the fields: name, email, subject, the body of the message, custom fields, and attachment URIs. Note a maximum of three attachments is permitted. Unlike when using secure mode, the name and email fields will remain visible and editable.

For how to determine the ids for custom field population, see this documentation for the Beacon web component.

 Beacon.addPreFilledForm(new PreFilledForm(
                 "Steve Aoki", //name
                 "Need help with invoice", //subject
                 "Hello, I need some help with my invoice. See attached PDF...", //message
                 Collections.singletonMap(5678, "Question"), //custom field values
                 Collections.singletonList("content://media/path/to/invoice")); // list of string URIs )

Resetting the contact form

Resets the contact form by clearing all of its fields, custom fields and attachments. If your Beacon is in Normal Mode, calling reset will clear all contact form fields, including name and email address.

If your Beacon is in Secure Mode, calling reset will not clear the customer’s name or email address. Those inputs will remain hidden.

Please note that if a customer has been identified using the login method, then their name and email address won’t be cleared with this method, you’ll have to use logout for this purpose.

 Beacon.contactFormReset()

The default behaviour for Beacon will be to open the Help & Support screen. If you want to open another screen, you can do it by calling one of the ‘BeaconActivity.open()’ methods.

Opening with search results

Open the search screen and with the search results for the string “search term”

BeaconActivity.open(this, BeaconScreens.SEARCH_SCREEN, arrayListOf("search term"));

Opening to an article

You can use this method to open a specific Docs article within Beacon, using the articles ID.

Article IDs can be found in Help Scout by navigating to the article and copying the article ID from the URL. The URL is structured like this: https://secure.helpscout.net/docs/[COLLECTION ID]/article/[ARTICLE ID]/.

 BeaconActivity.open(this, BeaconScreens.ARTICLE_SCREEN, arrayListOf("12345abcd"));

Opening to Contact form

Open to the contact form screen. Note: requires the Beacon to have messaging enabled.

BeaconActivity.open(this, BeaconScreens.CONTACT_FORM_SCREEN, arrayListOf());

Custom suggestions

You can programmatically override and change the suggestions based on any criteria that you specify. You can suggest articles by specificying their ids or by passing an article title and an URL.

Article IDs can be found in Help Scout by navigating to the article and copying the article ID from the URL. The URL is structured like this: https://secure.helpscout.net/docs/[COLLECTION ID]/article/[ARTICLE ID]/.

// There is a limit of 5 article ids. If the list is larger than 5 the additional articles will be ignored.
List<SuggestedArticles> suggestedArticles = new ArrayList();
suggestedArticles.add(new SuggestedArticle.SuggestedArticleWithId("ARTICLE_ID"));
suggestedArticles.add(new SuggestedArticle.SuggestedArticleWithUrl("ARTICLE_TITLE", "ARTICLE_URL"))
Beacon.setOverrideSuggestedArticlesOrLinks(suggestedArticles);

Custom suggestions will only get loaded when the Beacon is next shown. If you’d like to revert to the default suggestion list from the Beacon Builder, you can call Beacon.setOverrideSuggestedArticlesOrLinks with an empty list

Open and close events

These methods allow you to listen to specific events in the lifecycle of the Beacon to perform custom actions. Right now we support ‘open’ and ‘close’ events. They’ll be executed when the Beacon is opened or closed.

To use it, please register the BeaconEventLifecycleHandler listener in your Application class. Example:

private void initBeaconListener() {
        BeaconEventLifecycleHandler eventLifecycleHandler = new BeaconEventLifecycleHandler(
                new BeaconOnOpenedListener() {
                    @Override
                    public void onOpened() {
                        Timber.i("Open Beacon event called")
                    }
                },
                new BeaconOnClosedListener() {
                    @Override
                    public void onClosed() {
                        Timber.i("Close Beacon event called")
                    }
                }
        );

        registerActivityLifecycleCallbacks(eventLifecycleHandler)
    }

To unregister from events, use the following example:

private void unregisterFromBeaconEvents() {
     unregisterActivityLifecycleCallbacks(eventLifecycleHandler)
}

Settings Customization

You can override various settings from the Beacon Builder configuration using the Beacon.setConfigOverrides(configOverrides) method.

General Options

Name Type Description
messagingEnabled
Boolean Enable or disable the contact options.
docsEnabled
Boolean Enable or disable the article/docs options.
color
String Beacon primary color in hex format #FFFFFF

Contact form options

These are set by setting the BeaconContactForm object on the BeaconConfigOverrides

Name Type Description
customFieldsEnabled
Boolean Enable or disable Custom Fields
showName
Boolean Display an editable Name field.
showSubject
Boolean Display an editable Subject field
showGetInTouch
Boolean Show a contact link on the Beacon home screen
allowAttachments
Boolean Display the add Attachments button

Strings

We lean on the Android resources system to provide overrides for Strings defined in the Beacon Builder. A list of the overridable strings keys is defined in the public.txt of the beacon-ui aar file. Just define a string resource with the same key and we’ll use that in preference over the Beacon Builder string value.

This allows for full localisation support for example within your res/values-es folder you could create a beacon-strings.xml file and include the following to offer Spanish localisation.

<string name="hs_beacon_send_a_message_title">Contáctenos</string>
<string name="hs_beacon_related_articles">También podría gustarte</string>
...

Note some strings are Android/Mobile specific and there isn’t a Beacon Builder equivalent but these can also be overridden in the same way. For example:

<string name="hs_beacon_home_title">Help Desk</string>
<string name="hs_beacon_error_open_activity_not_found">Cannot find an app that supports opening files of this type</string>

The customization sample project shows this in practise.

Push notifications

NOTE: There is no admin UI in Help Scout currently where you can manage your Firebase Cloud Messaging (FCM) details. If you would like to try out this feature, you can email your FCM server key and your app id to support@helpscout.com and we’ll set it up manually for you.

The push notification support allows your users to receive system notifications when a support agent replies to one of their messages sent from the Beacon SDK. Clicking the notification will open Beacon and take the user to the conversation. If running on Android 7.0 (API level 24) it’s possible for users to use Direct reply and enter text directly into the notification.

Setup

Follow Set Up a Firebase Cloud Messaging Client App on Android making sure to add the required FCM dependencies. In either case, you’ll need to send us the device’s push token which will tell the Beacon SDK to register for push notifications on future messages and/or replies sent from the SDK.

 Beacon.setFirebaseCloudMessagingToken(newToken)

For receiving the push messages there are two paths to take here, depending on whether your application uses FCM already or not.

Your application already enabled for FCM

In your custom extension of the FirebaseMessagingService class you’ll already be overriding the onNewToken() method. Just add a call to Beacon.setFirebaseCloudMessagingToken() to send us the token.

@Override
public void onNewToken(String deviceToken) {
    super.onNewToken(deviceToken);
    if(deviceToken!=null){
      //Send Beacon the token
      Beacon.setFirebaseCloudMessagingToken(deviceToken);
    }
}

Once this is done, Beacon will be able to send push notifications to your application. In order to differentiate between Beacon push notifications and any other push notifications your app might receive, we’ve added a utility method.

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        if (remoteMessage.getData().size() > 0) {
            if (BeaconPushNotificationsProcessor.isBeaconNotification(remoteMessage.getData())) {
                BeaconPushNotificationsProcessor.process(this, remoteMessage.getData());
            } else {
                // here can process your own push messages                
            }
        }
    }

Your application isn’t currently using FCM

We’ll automatically receive the push message and display a system notification. We just need the device push token.

FirebaseInstanceId.getInstance().getInstanceId()
               .addOnSuccessListener(new OnSuccessListener<InstanceIdResult>() {
           @Override
           public void onSuccess(InstanceIdResult instanceIdResult) {
               String deviceToken = instanceIdResult.getToken();

               //Send Beacon the token
               Beacon.setFirebaseCloudMessagingToken(deviceToken);
           }
       });

If in the future you want to enable your own push messaging with FCM please follow the instructions above.

Customizing Beacon notifications

Apps targeting Android Oreo (SDK 26) or higher will have push notifications delivered to a notification channel. If you wish to override the channel settings for Beacon notifications, set the following resources to the values of your choice:

   <string name="hs_beacon_notification_channel_id">your_channel_id</string>
   <string name="hs_beacon_notification_channel_name">Your channel name</string>

If you wish, you can also change the icon that will be shown in the status bar when receiving a notification. Just provide your own drawable called hs_beacon_ic_notification and it’ll override the default icon.

Advanced Implementing your own User Interface

The easiest and recommended way to interact with Beacon is to use it’s UI Mode with the ui artifact. If all you are looking to do is to expose the knowledge database of articles, the Public API mode is your best bet. There are three main components that construct the Beacon SDK that are split over two modules.

  • beacon-core
    • Beacon Builder - Beacon.Builder()
    • Public Data Layer - BeaconRepository
  • beacon-ui
    • Easiest way to integrate Beacon features into your app

We have provided you with a Repository (you can read more about this pattern here. You’ll only need to include the core dependency. The only requirement is to have created a Beacon with the Beacon.Builder as described above.

BeaconRepository repository = Beacon.getRepositoryInstance()

This Repository allows you to fetch a few collections:

Exposed methods

  • Fetch all articles article by id: List<BeaconArticle> articles = repository.getArticles()
  • Fetch an article by id: BeaconArticle article = repository.getArticleById(articleId)
  • Search for an article: List<BeaconArticle> articles = repository.searchArticles(query)

Threading

All the calls made to the BeaconRepository are synchronous. Meaning that you’ll have to provide a threading mechanism. Instead of being opinionated about it, we prefer to give you the option to use whatever mechanism works best for you.

There’s also a demo project that shows how to build your own User Interface.