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.

Features

Coming Soon

  • Beacon chat

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.

Launching the Beacon User Interface

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.

Permissions

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

Authenticating users

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

Basic Mode

Basic 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 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 to allow you to add extra identifying information to a user. 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

Pre-filling contact form

The PreFilledForm object can be used to pre-populate the “Create a message” contact form. This should reduce the amount of typing for your customers as you may already know the customer’s name or perhaps you want to prompt for certain information in the message. You can also prefill a maximum of three attachments by providing a list of string uris.

 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.<Integer, String>emptyMap()), //custom field values.
                 uris // list of string URIs ); 

Pre-filling Custom Fields

Pre-filling custom fields requires some manual mapping for field labels and values so that if they ever change in the future, your Beacon won’t break. It’s more tedious upfront, but will stand the test of time. Note the Id must match one of your configured custom fields

All custom field types require you to include the field ID. To find the field ID, click on a Custom Field in Help Scout, and you’ll see the ID in the URL: https://secure.helpscout.net/settings/custom-fields/[Mailbox ID/[Field ID]. For dropdown field types, you’ll also have to fetch the option ID so that you can pre-fill the value properly.

Finally for date field types, the value will need to be in a specific format: YYYY-MM-DD.

Resetting contact form

To reset the contact form and clearing all of its fields, custom fields and attachments, use:

 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.

We support opening the following screens: Article, Search and Contact Form (send message).

Examples:

 // This will open the search screen and it will search for the string "search term"
 BeaconActivity.open(this, BeaconScreens.SEARCH_SCREEN, arrayListOf("search term"));

 // This will open the article screen and it will open the article with id "12345abcd"
 BeaconActivity.open(this, BeaconScreens.ARTICLE_SCREEN, arrayListOf("12345abcd"));

 // This will open the contact form screen
 BeaconActivity.open(this, BeaconScreens.CONTACT_FORM_SCREEN, arrayListOf());

Listeners

These methods allow you to listen to specific events in the lifecycle of the Beacon to perform custom actions. Right now the only two supported events are ‘open’ and ‘close’, and 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.

Articles suggestion overrides

You can programmatically override and change the suggestions based on any criteria that you specify.

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.
Beacon.setOverrideSuggestedArticles(listOf("DOCS_ARTICLE_ID_1", "DOCS_ARTICLE_ID_1"))

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.

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.

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.

Configuring 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.