Dimelo Mobile Messaging Android SDK
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
JavaDoc
com
.DS_Store
CHANGELOG.md
Customization.md
LICENSE
README.md

README.md

Dimelo-Android

Dimelo provides a mobile messaging component that allows users of your app to easily communicate with your customer support agents. You can send text messages and receive push notifications and automatic server-provided replies.

The component integrates nicely in any Android phone or tablet, allows presenting the Mobile Messaging through Fragment or Activity and has rich customization options to fit perfectly in your application.

For more information about Dimelo Mobile, please see Dimelo Mobile Messaging reference

API Reference

Please refer to Dimelo Mobile SDK Android API Reference for advanced use.

Getting Started

Follow these three mandatory steps to integrate the Dimelo Mobile Messaging in your application:

  1. Install the Dimelo library using Gradle.
  2. Choose your authentication method and initialize the SDK.
  3. Display the Mobile Messaging in your application.


These are minimal steps to make the Mobile Messaging work in your app.
Read on how to customize the appearance and the behavior of the Mobile Messaging to perfectly fit in your app:

You can see an example of Dimelo Mobile Messaging implementation by downloading the Sample App.

How To Install With Gradle build system (Using Android Studio)

Add these to your Grade file:

repositories

  repositories {
      maven {
                url "https://raw.github.com/dimelo/Dimelo-Android/master"
    }
  }

dependencies

  dependencies {
        compile 'com.dimelo.dimelosdk:dimelosdk:1.7.+'
  }

Migration to Dimelo 1.7.0

Dimelo 1.7.0 uses a new mandatory domain name setting (first part of your Dimelo Digital URL: domain-name.engagement.dimelo.com), so these changes must be taken into consideration:

  • setApiSecret(String apiSecret) is now deprecated in favor of initWithApiSecret(String secret, String domainName, DimeloListener dimeloListener).
  • setApiKey(String apiKey) is now deprecated in favor of initWithApiKey(String apiKey, String domainName, DimeloListener dimeloListener).
  • setHostname(String hostname) is not available anymore.

Authentication and SDK initialization

With each HTTP request, Dimelo sends a JWT (JSON Web Token). This token contains user-specific info that you specify (userIdentifier, userName etc.) and a HMAC signature. User identifier allows Dimelo to identify author of messages from different in the agent's backend. If user identifier is missing (null), then an autogenerated unique installation identifier is used to identify the user (created automatically).

If your app rely on a uniq imutable technical identifier to identify user use userIdentifier to also identify them at the Agent interface level.

Use userName to provide to agent a human name for the user.

We support two kinds of authentication modes: with built-in secret and with a server-side secret.

1. Setup with a built-in secret

This is a convenient mode for testing and secure enough when user identifiers are unpredictable.

Here's how to create the Dimelo instance and initialize it using a built-in secret:

Dimelo dimelo = Dimelo.setup(Context);
dimelo.initWithApiSecret(SOURCE_API_SECRET, DIMELO_DOMAIN_NAME, DIMELO_LISTENER);
/*
  SOURCE_API_SECRET can be found in your source configuration
  DIMELO_DOMAIN_NAME is your domain name (e.g. DIMELO_DOMAIN_NAME.engagement.dimelo.com)
  DIMELO_LISTENER is an optionnal parameter that we will cover later in this document
*/

Then it will create and sign JWT automatically when needed (as if it was provided by the server).

You simply set necessary user-identifying information and JWT will be computed on the fly. You do not need any cooperation with your server in this setup.

The security issue here is that built-in secret is rather easy to extract from the app's binary build. Anyone could then sign JWTs with arbitrary user identifying info to access other users' chats and impersonate them. To mitigate that risk make sure to use this mode only during development, or ensure that user identifiers are not predictable (e.g. random UUIDs).

2. Setup with a server-side secret (better security but more complicated)

This is a more secure mode. Dimelo will provide you with two keys: a public API key and a secret key. The public one will be used to configure Dimelo instance and identify your app. The secret key will be stored on your server and used to sign JWT token on your server.

Here's how create the Dimelo instance and initialize it using a server-side secret:

Dimelo dimelo = Dimelo.setup(Context);
dimelo.initWithApiKey(SOURCE_API_KEY, DIMELO_DOMAIN_NAME, DIMELO_LISTENER);
/*
  SOURCE_API_KEY can be found in your source configuration
  DIMELO_DOMAIN_NAME is your domain name (e.g. DIMELO_DOMAIN_NAME.engagement.dimelo.com)
  DIMELO_LISTENER is an optionnal parameter that we will cover later in this document
*/

Once this is done you will have to set jwt property manually with a value received from your server. This way your server will prevent one user from impersonating another.

  1. Set authentication-related properties (userIdentifier, userName, authenticationInfo).
  2. Get a dictionary for JWT using Dimelo.getJwtDictionary(). This will also contain public API key, installationIdentifier etc.
  3. Send this dictionary to your server.
  4. Check the authenticity of the JWT dictionary on the server and compute a valid signed JWT token. Use a corresponding secret API key to make a HMAC-SHA256 signature. Note: use raw binary value of the secret key (decoded from hex) to make a signature. Using hex string as-is will yield incorrect signature.
  5. Send the signed JWT string back to your app.
  6. In the app, set the Dimelo.jwt property with a received string.

/!\ Dimelo.setUserIdentifier();, Dimelo.setAuthenticationInfo(); and Dimelo.setUserName(); must only be called BEFORE Dimelo.setJwt(); otherwise your JWT will be emptied and your request will end up in a 404 error.

You have to do this authentication only once per user identifier, but before you try to use Dimelo Mobile Messaging. Your application should prevent user from opening a Mobile Messaging until you receive a JWT token.

Displaying the Mobile Messaging

Dimelo provides different ways to display the Mobile Messaging.

As an Activity:

Achieved by calling Dimelo.openChatActivity() (wich will internally call Context.startActivity). This method will display a full screen Mobile Messaging with a Toolbar containing a title. The title and the background (drawable or color) of the Toolbar are customizable. The Navigation Icon can be displayed and customized. The user can close the Mobile Messaging (the Activity) by pressing the Navigation Icon or the back button of his device.

By default, the app name is used for the title and the primaryColor (appCompat) is used as the background color of the toolbar.

To make it work, you must declare the Activity in your AndroidManifest.xml with a name equals to com.dimelo.dimelosdk.main.ChatActivity This is the easiest way to display the Mobile Messaging.

If your application doesn't inherit from AppCompat, the toolbar and status bar of Dimelo will be black. In order to fix this, your application needs to set the ChatActivity theme to @style/DimeloTheme (AndroidManifest.xml). By default, DimeloTheme will set the Toolbar and status bar to blue.

You can change those by overriding dimelo_color_primary and dimelo_color_primary_dark in color file resources (dimelo_color_primary for toolbar and dimelo_color_primary_dark for status bar).

As a Fragment:

Your app must use an AppCompat theme to be able to use Dimelo as a Fragment. Achieved by calling Dimelo.newChatFragment() and using the Android FragmentManager and FragmentTransaction. This is the most flexible way to display the Mobile Messaging as you can manually place, open and close it like any Fragment. No Toolbar is displayed.

Note: forwarding onBackPressed() events using "Chat.onBackPressed()" is necessary to display the best user experience; "true" will be returned if the event has been consumed

As a Nested Fragment:

Dimelo support fragment nesting (i.e: Dimelo Chat fragment can be displayed inside a fragment parent). However, in this specific case, the host application needs to care about the following steps.

  1. Using Fragment.setUserVisibleHint in order to notify the Mobile Messaging about its visibility state. This will prevent the Mobile Messaging to do background work when unnecessary

  2. The Mobile Messaging uses intents for displaying attachments. Forwarding "onActivityResult" will allow the Mobile Messaging to correctly receive the results.

  3. The Mobile Messaging is compiled against Android sdk 23 and handle dynamic permissions. To allow optimal behaviors, forwarding "onRequestPermissionsResult" is necessary.

Note: forwarding onBackPressed() events using "Chat.onBackPressed()" is necessary to display the best user experience; "true" will be returned if the event has been consumed

Examples are provided within the SampleApp

Customizing Mobile Messaging Appearance

See how to customize Dimelo using the Android Resource folders.

You can also customize it programmatically:

As an Activity:

  1. Implementing Dimelo.OnActivitySetupAppearanceListener(Chat.Customization chatActivityCustomization) and modifying chatActivityCustomization attributes.
  2. Calling Dimelo.setChatCustomizationListener()

The ChatActivity will call the listener back when creating its layout.

You do not need to call customization.apply() as it will be called for you.

As a Fragment:

  1. Calling Chat.getCustomization() and receiving an istance of Chat.Customization
  2. Modifiying its attributes.
  3. Calling customization.apply() to register the changes and update the Mobile Messaging.

We provide a lot of properties for you to make the Mobile Messaging look native to your application.

For your convenience, properties are organized in two groups: Basic and Advanced. In many cases it would be enough to adjust the Basic properties only.

You can customize the inputbar color, the font and the color of any text in the Mobile Messaging view. If you are displaying the Mobile Messaging as an activity you can also cutomize the ActionBar colors and title

Advanced options include background and padding for text bubbles. We use 3 kinds of messages. Each kind can be customized independently.

  1. User's text message.
  2. Agent's text message.
  3. System text notification (automatic reply from the server).

All bubble images must be 9-part sliced resizable images or a (Drawable xml) to fit arbitrary content.

Text bubbles can be colored using properties userMessageBackgroundColor, agentMessageBackgroundColor etc.

If you provide a custom bubble image for text, you should also update message bubble padding properties to arrange your text correctly within a bubble.

Check the Dimelo Mobile SDK Android API Reference to learn about all customization options.

Push Notifications

Dimelo Mobile Messaging can receive push notifications from Dimelo server. To make them work, a couple of steps must be done on your part:

Using Google Cloud Messaging (GCM):

  1. Register to Google GCM service by using for example GoogleCloudMessaging.register(senderId)
  2. Set Dimelo.deviceToken property with the value returned by the GoogleCloudMessaging.register(senderId)
  3. Your app must register for remote notifications for example by declaring and implementing a Receiver and a Service (Android APIs).
  4. Optionally implement Dimelo.BasicNotificationDisplayer abstract class. It allows you to specify a title, an icone and how to display the Mobile Messaging when the user click the notification. If you want to handle the entire process of displaying notifications you can directly implement Dimelo.NotificationDisplayer interface.
  5. Let Dimelo consume the notification using Dimelo.consumeReceivedRemoteNotification(). If this method returns true, it means that Dimelo recognized the notification as its own and you should not process the notification yourself. The Mobile Messaging will be updated automatically with a new message.
  6. If your Android version is at least Android N, you'll receive an interactive push notification with direct reply. To disable this, use Dimelo.interactiveNotification = false;.

If the notification is received while the app is running, the sdk will display the notification only if the Mobile Messaging is not visible by the user You can override the behavior by implementing dimeloShouldDisplayNotificationWithText from the listener DimeloListener

Prior to Android 5, the notification will be displayed as a Ticker (one line scrolling notification) and is not clickable.

Starting from Android 5, the notification will be displayed as a (Heads-up). Clicking of the Heads-up will, by default, open the application. If you specify the (parent activity using the support meta-data tag), clicking the Heads-up will open the Mobile Messaging and provide the up-navigation.

If the Mobile Messaging is opened directly upon clicking the notification, then the IntentService managing the notification must ensure to properly configure the Dimelo instance (at the minimum, calling Dimelo.setup and dimelo.setApiSecret).

If you'd like to have the full control on the notification (appearance and behavior on click) you can implement the Dimelo.NotificationDisplayer interface.


Using Firebase Cloud Messaging (FCM):

Note: This is an example on how to initialize the Dimelo instance:

public class MainActivity extends AppCompatActivity {

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.your_layout);
    // Setup Dimelo
    Dimelo dimelo = setupDimelo(this);
  }

  public static Dimelo setupDimelo(Context context) {
        Dimelo.setup(context);
        Dimelo dimelo = Dimelo.getInstance();
        dimelo.initWithApiSecret(SOURCE_API_SECRET, DIMELO_DOMAIN_NAME, DIMELO_LISTENER);
        dimelo.setUserName("USER_NAME");
        dimelo.setUserIdentifier("USER_IDENTIFIER");
        JSONObject authInfo = new JSONObject();
        try {
            authInfo.put("CustomerId", "0123456789");
            authInfo.put("Dimelo", "Rocks!");
        } catch (JSONException e) {
        }
        dimelo.setAuthenticationInfo(authInfo);
        return dimelo;
  }

  // ...
}
  1. Download the google-services.json file from your firebase console and copy it in your project's /app folder
  2. Declare a FirebaseMessagingService service in your project's AndroidManifest.xml:
<service
    android:name=".MyFirebaseMessagingService">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT"/>
    </intent-filter>
</service>
  1. Create a class that extends FirebaseMessagingService:
public class MyFirebaseMessagingService extends FirebaseMessagingService
  1. Retrieve the device token and pass it to your Dimelo instance by overriding the onNewToken method:
@Override
public void onNewToken(String token) {
  if (Dimelo.isInstantiated())
    Dimelo.getInstance().setDeviceToken(token);
}
  1. Finally intercept the notification and pass it to your Dimelo instance by overring the onMessageReceived method:
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
  // You have to configure the Dimelo instance before calling the Dimelo.consumeReceivedRemoteNotification() method.
  MainActivity.setupDimelo(MyFirebaseMessagingService.this);
  if (Dimelo.consumeReceivedRemoteNotification(MyFirebaseMessagingService.this, remoteMessage.getData(), null)){
    // The notification will be handled by the Dimelo instance
  }
  else {
    // It is not a Dimelo notification.
  }
}

Activate location messages

Activating location messages allow users to send a map containing their location.

Note: This feature uses Google Places API which is by default limited to 1000 requests per day. you can increase this limitation to 150 000 requests per day (Enable billing to get 150 000 requests per 24 hour period)

  1. Connect to Google API console
  2. Access to API Manager pannel
  3. Search for Google Maps Android API and Google Places API for Android
  4. Enable both APIs
  5. Access to Credentials pannel and create an API key for Android
  6. Add your API key to your application manifest
<application
  <meta-data
  android:name="com.google.android.geo.API_KEY"
  android:value="YOUR_API_KEY">
</application>

Reacting To Mobile Messaging Events

You can react to various events in the Mobile Messaging by implementing a DimeloListener.

Two particular events that might be interesting to you are dimeloDidBeginNetworkActivity() and dimeloDidEndNetworkActivity().

Use -onOpen: and -onClose: events to get informations using dimelo parameter when the Mobile Messaging view is just opened or closed.

Please refer to Dimelo Mobile SDK Android API Reference documentation for more information.