Skip to content
Andras Sarro edited this page Nov 9, 2022 · 71 revisions

Contents

1. First steps

A Sample Application using the Emarsys SDK is available here. The Sample Application provides examples of how you can use the various features of the Emarsys SDK in a real application and what steps are needed e.g. to be able to receive push messages.

1.1 Initialization

To configure the SDK, you should do the following in the onCreate method in the application class:

Note

applicationCode: is needed if you want to use Mobile Engage features

merchantId: is needed if you want to use Predict features

inAppEventHandler: is needed if you want to handle user actions on the inApp messages

notificationEventHandler: is needed if you want to handle user actions on the push messages

silentMessageEventHandler: is needed if you want to handle silent messages

onEventActionHandler: is needed if you want to handle onEventActions

Java
public class SampleApplication extends Application {

private static final String TAG = "SampleApplication";

@Override
public void onCreate() {
super.onCreate();
    EmarsysConfig config = new EmarsysConfig.Builder()
    .application(this)
    .applicationCode(<applicationCode:String?>)
    .merchantId(<merchantId:String?>)
    .build();

    Emarsys.setup(config);
    }
}
Kotlin
class SampleApplication: Application() {

    override fun onCreate() {
    super.onCreate()
    val config = EmarsysConfig(
        application = this,
        applicationCode = <applicationCode: String?>,
        merchantId = <merchantId:String?>)
    Emarsys.setup(config)
    }
}

1.2 CompletionListener

Most calls can receive a completionListener as parameter, that you can use to track our calls. The CompletionListener defines one method:

Java
@Override
public void onCompleted(@Nullable Throwable errorCause) {
    if(errorCause != null){
        Log.e(TAG, error.getMessage(), error);
    }
}

1.3 setContact

After the application setup is finished, you can use setContact method to identify the user with a contactFieldId and a contactFieldValue.

Without contact identification all tracked events will be linked to an anonymous contact in Mobile Engage and will rely on visitor cookies in case of Predict. Please note that both parameters are required, but the CompletionListener is optional.

Java
Emarsys.setContact(
    Integer contactFieldId,
    String contactFieldValue,
    CompletionListener completionListener);
Kotlin
Emarsys.setContact(
    contactFieldId: Int,
    contactFieldValue: String,
    completionListener: CompletionListener? = null)

1.4 setAuthenticatedContact

Note

At the current time Predict does not support authenticating users with Open ID Connect, identifying a contact with setAuthenticatedContact will disable the usage of Predict features!

After the application setup is finished, you can use setAuthenticatedContact method to identify the user with an contactFieldId and a openIdToken.

More information about Open ID Connect can be found here.

Without contact identification all tracked events will be linked to an anonymous contact in Mobile Engage and will rely on visitor cookies in case of Predict. Please note that both parameters are required, but the CompletionListener is optional.

Java
Emarsys.setAuthenticatedContact(
    Integer contactFieldId,
    String openIdToken,
    CompletionListener completionListener);
Kotlin
Emarsys.setAuthenticatedContact(
    contactFieldId: Int,
    openIdToken: String,
    completionListener: CompletionListener? = null)

1.5 clearContact

When the user signs out, we should use the clearContact method with the CompletionListener which is optional. The method is going to automatically log in an anonymous user instead of the one leaving.

Note

You only need to call clearContact when you explicitly want to sign out the contact from Emarsys even if the user isn’t logged in into your application.

Java
Emarsys.clearContact(CompletionListener completionListener);
Kotlin
Emarsys.clearContact(completionListener: CompletionListener? = null)

1.6 trackCustomEvent

If you want to track custom events, the trackCustomEvent method should be used, where the eventName parameter is required, but the attributes and the CompletionListener are optional.

Java
Emarsys.trackCustomEvent(String eventName, Map<String,String> attributes, CompletionListener completionListener);
Kotlin
Emarsys.trackCustomEvent(eventName: String, attributes: Map<String, String>?, completionListener: CompletionListener? = null)

1.7 enableVerboseConsoleLogging

Note

Console logging is only available in DEBUG mode!

If you want to see more logs from the Emarsys SDK, you can call enableVerboseConsoleLogging on the EmarsysConfigBuilder. After this, all the logs generated by the SDK will also be sent to your console.

Java
    new EmarsysConfig.Builder()
    .enableVerboseConsoleLogging()
    .build();

From Kotlin, this can be included as a named parameter in the EmarsysConfig:

Kotlin
EmarsysConfig(application = application,
        applicationCode = APP_CODE,
        merchantId = MERCHANT_ID,
        sharedSecret = SHARED_SECRET,
        sharedPackageNames = SHARED_PACKAGE_NAMES,
        enableVerboseConsoleLogging = true)

2. Push

Note

The SDK sends an AppEvent action on every interaction with the push notification. (buttons click or click on the push itself)

Event name is: push:click, and the payload is the whole rootParameters.

If the push also contains an AppEvent, then the callback will be called twice, where the first one will be the push:clicked.

Make sure, that if you are supporting android API levels > 26, set up your notification channels within your application.

2.1 setPushToken

The Emarsys SDK automatically handles setPushToken for the device and it is recommended to leave this to the SDK. However if you have your custom implementation of MessagingService, please use the setPushToken() method, where CompletionListener parameter is optional, to set the pushToken.

Java
Emarsys.getPush().setPushToken(String pushToken,CompletionListener completionListener);
Kotlin
Emarsys.push.setPushToken(pushToken: String, completionListener: CompletionListener? = null)

2.2 getPushToken

The pushToken value can be retreived by this method.

Java
Emarsys.getPush().getPushToken();
Kotlin
Emarsys.push.pushToken

2.3 clearPushToken

If you want to remove pushToken for the Contact, please use clearPushToken() method where CompletionListener parameter is optional.

Note

To use clearPushToken you have to disable the automatic setPushTokenHandling, using disableAutomaticPushTokenSending during the setup or the SDK is going to eventually set a new push token automatically. Please consider that in this case, you have to set the push token manually, like in the MyMessagingService example.

Java
Emarsys.getPush().removePushToken(CompletionListener completionListener);
Kotlin
Emarsys.push.removePushToken(completionListener: CompletionListener? = null)

2.4 trackMessageOpen

The Emarsys SDK automatically handles whether the push messages have been opened, however, if you want to track it manually the trackMessageOpen method should be used, where the intent parameter is required but the CompletionListener is optional.

Java
Emarsys.getPush().trackMessageOpen(Intent intent, CompletionListener completionListener);
Kotlin
Emarsys.push.trackMessageOpen(intent: Intent, completionListener: CompletionListener? = null)

2.5 setNotificationEventHandler

In order to react to an event, triggered by a push notification message, you can register for it using the setNotificationEventHandler method.

Java
Emarsys.getPush().setNotificationEventHandler(EventHandler notificationEventHandler);
Kotlin
Emarsys.push.notificationEventHandler(notificationEventHandler: EventHandler)

2.6 setSilentMessageEventHandler

In order to react to an event triggered by the silent message, you can register for it using the setSilentMessageEventHandler method. The eventHandler is a callback for a silent message event.

Java
Emarsys.getPush().setSilentMessageEventHandler(EventHandler silentMessageEventHandler);
Kotlin
Emarsys.push.silentMessageHandler(silentMessageEventHandler: EventHandler)

2.7 setNotificationInformationListener

In case you need information about the received message, you can set your NotificationInformationListener implementation as a callback to our Emarsys.push and we will call the method of the listener with a NotificationInformation object.

Java
Emarsys.getPush().setNotificationInformationListener(NotificationInformationListener notificationInformationListener);
Kotlin
Emarsys.push.notificationInformationListener(notificationInformationListener: NotificationInformationListener)

2.8 setSilentNotificationInformationListener

In case you need information about the received message, you can set your NotificationInformationListener implementation as a callback to our Emarsys.push and we will call the method of the listener with a NotificationInformation object.

Java
Emarsys.getPush().setSilentNotificationInformationListener(NotificationInformationListener silentNotificationInformationListener);
Kotlin
Emarsys.push.silentNotificationInformationListener(silentNotificationInformationListener: NotificationInformationListener)

3. InApp

3.1 Overlay In-App

3.1.1 pause

When a critical activity starts and should not be interrupted by InApp, use pause to pause InApp messages.

Java
Emarsys.getInApp().pause();
Kotlin
Emarsys.inApp.pause()

3.1.2 resume

In order to show inApp messages after being paused, use the resume method.

Java
Emarsys.getInApp().resume();
Kotlin
Emarsys.inApp.resume()

3.1.3 isPaused

Java
boolean isPaused = Emarsys.getInApp().isPaused();
Kotlin
val isPaused = Emarsys.inApp.isPaused()

3.1.4 setEventHandler

In order to react to an event, triggered by the InApp message, you can register for it using the setEventHandler method.

Java
Emarsys.getInApp().setEventHandler(EventHandler inAppEventHandler);
Kotlin
Emarsys.inApp.setEventHandler { eventName, payload -> ...}

3.2 Inline In-App

In-App message, that takes place in the application's view hierarchy. Multiple inline In-App components are allowed in one screen.

3.2.1 Implementation

There are three ways to implement the inline In-App.

  • First way is from XML, this way onAppEventListener, onCompletionListener and onCloseListener cannot be set.
  • Secondly is completely from code, this way it could be set up by its constructor.
  • The last one is the mixed setup, for this the view could be created in XML, then the listeners should be set by code.
3.2.1 loadInAppWithViewId

In order to load the inline In-App, the loadInApp must be called with the corresponding viewId. When the view is created from XML and this value has been set, this call is unnecessary.

Java
InlineInAppView inlineInAppView = new InlineInappView(Context context);
inlineInAppView.loadInApp(String viewId);
Kotlin
val inlineInAppView = InlineInAppView(context: Context)
inlineInAppView.loadInApp(viewId: String)
3.2.2 appEventListener

In order to react to an event triggered from the In-App message, register an onAppEventListener. The onAppEventListener is a callback for an In-App message event.

Java
inlineInAppView.setOnAppEventListener(EventHandler onAppEventListener);
Kotlin
inlineInApp.onAppEventListener = { property: String?, json: jsonObject ->
    ...
}
3.2.3 onCompletionListener

The onCompletionListener is triggered when the inline In-App message is loaded.

Java
inlineInAppView.setOnCompletionListener(<Throwable errorCause> -> {
            ...
        });
Kotlin
inlineInApp.onCompletionListener = CompletionListener { throwable: Throwable? ->
    ...
}
3.2.4 onCloseListener

The onCloseListener is triggered when the close button has been clicked on the inline In-App message.

Java
inlineInAppView.setOnCloseListener(() -> {
    ...
});
Kotlin
inlineInApp.onCloseListener = {
    ...
}

3.3 Dark mode

Starting from SDK version 3.3.0 the dark mode for InApp messages (both overlay and inline) is being supported.

  • The feature only works on Android API 29 or higher because WebView's dark mode is only supported from Android API 29.

  • The SDK will check the applications current theme and set the WebView's theme accordingly. For this to work you need to add the following item to your application's Theme's style settings xml:

<style name="Theme.AppTheme" parent="Theme.AppCompat.DayNight">
   <item name="android:forceDarkAllowed">true</item>
   ...

This is required for applications targeting Android API levels 29-32.

  • In applications targeting Android API 33 or above WebView always sets the content HTML's media query prefers-color-scheme according to the app's theme attribute isLightTheme, setting it light if the isLightTheme is light or not defined, and dark otherwise. This means that the inApp's dark or light style will automatically match the applications current theme, it is not necessary to set isLightTheme manually.

4 Predict

We won't go into the details to introduce how Predict works, and what its capabilities are, rather we aim to explain the mapping between the Predict commands and our interface. Please visit Predict's documentation for more information.

4.1 Initialization

To use the Predict functionality you have to set up your merchantId during the initialization of the SDK. In order to track Predict events, you can use the methods available on our Predict interface.

4.2 trackCart

When you want to track the cart items in the basket, you can call the trackCart method with a list of CartItems. CartItem is an interface that can be used in your application for your own CartItems and then simply use the same items with the SDK.

Java
Emarsys.getPredict().trackCart(List<CartItem> items);
Kotlin
Emarsys.predict.trackCart(items: List<CartItem>)

4.3 trackPurchase

To report a purchase event, you should call trackPurchase with the items purchased and with an orderId.

Java
Emarsys.getPredict().trackPurchase(String orderId, List<CartItem> items);
Kotlin
Emarsys.predict.trackPurchase(orderId: String, items: List<CartItem>)

4.4 trackItemView

If an item was viewed, use the trackItemView method with an itemId as a required parameter.

Java
Emarsys.getPredict().trackItemView(String itemId);
Kotlin
Emarsys.predict.trackItemView(itemId: String)

4.5 trackCategoryView

When the user navigates between the categories, you should call trackCategoryView in every navigation. Be aware to send categoryPath in the required format. Please visit Predict's documentation for more information .

Java
Emarsys.getPredict().trackCategoryView(String categoryPath)
Kotlin
Emarsys.predict.trackCategoryView(categoryPath: String)

4.6 trackSearchTerm

To report search terms entered by the contact, use trackSearchTerm method.

Java
Emarsys.getPredict().trackSearchTerm(String searchTerm)
Kotlin
Emarsys.predict.trackSearchTerm(searchTerm: String)

4.7 trackTag

To track custom tags, use the trackTag method, where, the eventName parameter is required, but the attributes is optional.

Java
Emarsys.getPredict().trackTag(String eventName, Map<String,String> attributes);
Kotlin
Emarsys.predict.trackTag(eventName: String, attributes: Map<String,String>?)

4.8 recommendProducts

With the Emarsys SDK you can ask for product recommendations based on different recommendation logics.

Note

recommendProducts is also going to track the value attached to the logic on the backend, so no additional tracking needed when using recommendations!

4.8.1 logic

This is a required parameter of the recommendProducts method.

The currently supported logics are:

  • SEARCH - based on searchTerm
  • CART - based on cartItems
  • RELATED - based on itemViewId
  • CATEGORY - based on categoryPath
  • ALSO_BOUGHT - based on itemViewId
  • POPULAR - based on categoryPath
  • PERSONAL - based on current browsing and activity
  • HOME - based on most recent browsing behaviour

Note

For more information on the recommender logics, please visit [the official documentation].(https://help.emarsys.com/hc/en-us/articles/115004662189-Web-Recommender-logics "The Official Documentation")

You can pass the values to the chosen recommendation logic, but if you leave it empty, the SDK handles it and uses the last tracked values.

4.8.2 filters

This is an optional parameter of the recommendProducts method.

You can filter product recommendations with the SDK by building RecommendationFilters. There are two types of filters: Exclude or Include.

In every case there are four types of comparators you can use to compare your chosen field to expectationValue:

  • isValue - checking if the field is matching the value
  • inValues - any of the values has a match with the field
  • hasValue - One of the field values is equal to expectation value (applicable only to fields containing multiple values)
  • overlapsValues - One or more of the field values are found in expectation values (applicable only to fields containing multiple values)

For further information please check the predict documentation.

4.8.3 limit

This is an optional parameter of the recommendProducts method.

You can limit the number of recommended products received by defining a limit. This is an optional parameter, by default its value is 5.

4.8.4 resultListener

This is a required parameter of the recommendProducts method.

The SDK is going to retrieve recommended products via its resultListener

Java
RecommendationFilter filter = RecommendationFilter.exclude("category").isValue("SHIRT");
List<RecommendationFilter> filters = new ArrayList();
filters.add(filter);

Emarsys.getPredict().recommendProducts(RecommendationLogic.category(), filters, new ResultListener<Try<List<Product>>>() {
    @Override
    public void onResult(@NonNull Try<List<Product>> result) {
        if (result.getResult() != null) {
            List<Product> recommendedProducts = result.getResult();
        }
        
        if (result.getErrorCause() != null) {
            Throwable cause = result.getErrorCause();
            Log.e(TAG, "Error happened: " + cause.getMessage());
        }
    }
});
Kotlin
val filter = RecommendationFilter.exclude("category").isValue("SHIRT")
Emarsys.predict.recommendProducts(RecommendationLogic.category(), listOf(filter)){
    it.result?.let { result ->
        val recommendedProducts = result.result
    }
    it.errorCause?.let { cause ->
        Log.e(TAG, "Error happened: ${cause.message}")
     }
}
4.8.5 availabilityZones

This is an optional parameter of the recommendProducts method.

You can personalize the recommendation further by setting the availabilityZones parameter of the recommendation, to only recommend the locally available products.

For more information please check the Emarsys Predict documentation

4.9 trackRecommendationClick

The Emarsys SDK doesn't track automatically recommendationClicks, so you have to call manually trackRecommendationClick when an interaction happens with any of the recommended products.

Java
Emarsys.getPredict().trackRecommendationClick(Product clickedProduct);
Kotlin
Emarsys.predict.trackRecommendationClick(clickedProduct: Product)

4.10 variants

Variants are used by the HOME and PERSONAL logic types. By adding a list of Strings used as suffixes to logic names, recommendations are grouped by the variants provided.

5. DeepLink

Note

Please check our DeepLink page for more information.

5.1 Handle DeepLink tracking

The Emarsys SDK automatically tracks email link clicks that open the application directly in most use cases, with only one exception: manual tracking is needed when your Activity has onNewIntent overridden. In that case, you can track the deep link using the trackDeepLink method like below:

Java
@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    Emarsys.trackDeepLink(this, intent, new CompletionListener(){
    
    	 @Override
         public void onCompleted(@Nullable Throwable errorCause) {
         ...               
         }
    );
    }
}
Kotlin
override fun onNewIntent(intent:Intent) {
    super.onNewIntent(intent)
    Emarsys.trackDeepLink(this, intent) {throwable -> ...}
}

6. ApplicationCode and merchantId change

Emarsys SDK provides a solution for applicationCode and merchantId change in a convenient way without restarting the SDK. Please check our Config page for more information.

7. MessageInbox

User centric inbox solution. Emarsys SDK provides a Message named model class to make MessageInbox information easily accessible.

Kotlin
data class Message(
        val id: String,
        val campaignId: String,
        val collapseId: String?,
        val title: String,
        val body: String,
        val imageUrl: String?,
        val receivedAt: Long,
        val updatedAt: Long?,
        val expiresAt: Long?,
        val tags: List<String>?,
        val properties: Map<String, String>?,
        val actions: List<ActionModel>?
)

The following action types are supported:

  • App event action
Kotlin
data class AppEventActionModel(
    val id: String,
    val title: String,
    val type: String
    val name: String,
    val payload: Map<String, Any>?
)
  • Custom event action
Kotlin
data class CustomEventActionModel(
    val id: String,
    val title: String,
    val type: String,
    val name: String,
    val payload: Map<String, Any>?
)
  • Open External URL action
Kotlin
data class OpenExternalUrlActionModel(
    val id: String,
    val title: String,
    val type: String,
    val url: URL
)

The description of the supported actions are available here.

7.1 fetchMessages

In order to receive the messageInbox content, you can use the fetchMessages method.

Java
Emarsys.getMessageInbox().fetchMessages(result -> {
    if (result.getResult() != null) {
        InboxResult inboxResult = result.getResult();
        Log.i(TAG, "Inbox result: " + inboxResult.toString());
    }
    if (result.getErrorCause() != null) {
        Throwable cause = result.getErrorCause();
        Log.e(TAG, "Error happened: " + cause.getMessage());
    }
});
Kotlin
Emarsys.messageInbox.fetchMessages {
    it.result?.let { notificationStatus ->
        notificationStatus.messages.forEach { notification ->
            Log.i(TAG, "Messages: ${notification.title}")
        }
    }
    it.errorCause?.let { cause ->
        Log.e("Error fetching messages: ${cause.message}")
    }
}

7.2 addTag

To label a message with a tag, you can use addTag method. (for example: "READ", "SEEN" etc)

Java
Emarsys.getMessageInbox().addTag(String tag, String messageId, CompletionListener completionListener);
Kotlin
Emarsys.messageInbox.addTag(tag: String, message: String, completionListener: CompletionListener? = null);

7.3 removeTag

To remove a label from a message, you can use removeTag method.

Java
Emarsys.getMessageInbox().removeTag(String tag, String messageId, CompletionListener completionListener? = null);
Kotlin
Emarsys.messageInbox.removeTag(tag: String, message: String, completionListener: CompletionListener);

8. Geofence

PILOT VERSION

Note The Geofence feature is still in pilot phase, please only use it if you have a pilot service order in place! If you would like to use the feature please contact your CSM @ Emarsys.

Important Note: Geofencing is disabled on devices, that does not have Google Play Services!

Geofence makes it available to trigger certain actions based on the users location. When the user enters a predefined region (represented by latitude, longitude and radius) EmarsysSDK fires a customEvent which can trigger an action, for example, a push notification. This requires permission for background locations from the user.

Currently supported triggers

The geofence feature has two different trigger types: ENTER and EXIT.

  • ENTER triggers when the user reaches the bounds of the geofence and enters it.
  • EXIT triggers when the user reaches the bounds of the geofence and exits it.

Note

Based on our experiences so far, the accuracy of geofencing is inconsistent and can be different based on device types and the environment of usage. We recommend adding at least 100m of radius to your geofences, to ensure that the triggers happen. Based on the Android documentation only 100 geofences/app can be used, so please be aware that our current geofencing solution only works well when there are no other geofencing solution used by the application.

Requirements

For the location permissions the applications AndroidManifest.xml must be extended with the following permissions:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Make sure that your app is requesting the required permissions from the user. From Android 12, the ACCESS_FINE_LOCATION also needs the ACCESS_COARSE_LOCATION permission, since the user can now prevent applications from accessing the precise location of the phone. In response to this, both android.permission.ACCESS_COARSE_LOCATION and android.permission.ACCESS_FINE_LOCATION permissions are mandatory for geofences to work.

Limitations

From Android 12, when the ACCESS_FINE_LOCATION permission is granted to the Application, the geofencing will work as before. If only ACCESS_COARSE_LOCATION is granted, then we can't guarantee that the geofences will trigger at the correct times.

8.1 enable

The enable method is responsible for the activation of this feature

Java
Emarsys.getGeofence().enable(CompletionListener completionListener);
Kotlin
Emarsys.geofence.enable(completionListener: CompletionListener? = null)

8.2 disable

The disable method is responsible for disabling this feature

Java
Emarsys.getGeofence().disable();
Kotlin
Emarsys.geofence.disable()

8.3 isEnabled

The isEnabled method returns if the geofencing is currently enabled or not

Java
Emarsys.getGeofence().isEnabled();
Kotlin
Emarsys.geofence.isEnabled()

8.4 registeredGeofences

You can access the registered geofences from the device using the registeredGeofences method.

Java
Emarsys.getGeofence().getRegisteredGeofences();
Kotlin
Emarsys.geofence.registeredGeofences

8.5 setEventHandler

In order to react to an event triggered by a geofence, you can register for it using the setEventHandler method. The eventHandler is a callback for a Geofence event.

Java
Emarsys.getGeofence().setGeofenceEventHandler(EventHandler geofenceEventHandler);
Kotlin
Emarsys.geofence.geofenceEventHandler(geofenceEventHandler: EventHandler)

8.6 initialEnterTriggerEnabled

When initialEnterTriggerEnabled is true, Emarsys SDK will trigger all the affected geofences with Enter type triggers at the moment when the geofence is enabled if the device is already inside that geofence. By default, this value is set to false.

Java
Emarsys.getGeofence().setInitialEnterTriggerEnabled(true);
Kotlin
Emarsys.geofence.initialEnterTriggerEnabled = true

9. Testing

The SDK supports Espresso Idling Resources.

Register the EmarsysIdlingResources class to the IdlingRegistry before running UI tests.

  IdlingRegistry.getInstance().register(EmarsysIdlingResources.countingIdlingResource)

Then use the following code sample to unregister it after running the tests

  IdlingRegistry.getInstance().unregister(EmarsysIdlingResources.countingIdlingResource)

10. On Event Action

Emarsys SDK supports a new way of creating actions in the applications by tracking a customEvent, this trigger happens in a silent way, no in-app or push is needed. All of the action types known from rich push messages are supported.

For this to work an eventHandler should be set up in the SDK.

10.1 setOnEventActionEventHandler

Java
Emarsys.getOnEventAction().setOnEventActionEventHandler(EventHandler eventHandler);
Kotlin
Emarsys.onEventAction.onEventActionEventHandler(eventHandler: EventHandler)
Clone this wiki locally