User profile and behaviour tracking

Tagging relevant information regarding your user profiles and their behaviours is crucial to send personalized and valuable messages.

Although the Accengage SDK collects by default certain useful information (such as install date, last open date, number of visits, device model ...), it also offers a number of advanced tagging and tracking features for app developers, that will allow you to target notifications, trigger messages at the right time, customize the user experience and analyze your campaign and application performance.

It is important that you check with the product or marketing team what type of actions they would like to perform, so that you can determine which information needs to be tagged. Most of the time they will provide you with a "tagging plan" which lists all of these.

However, a strategy could be to first implement a minimal version of Accengage in order to speed up the process and learn faster, then implement the tagging plan at a later stage for more relevant messages.

In the following section, we will look at the various options that you can enjoy to collect and use the right information:

  • enrich user profile, thanks to custom device information (or User Attributes), which are very useful for targeting and message personalization
  • tag user location, for geolocation targeting
  • tag user behaviours, thanks to events which offer many benefits (targeting, triggering and measurement), as well as views
  • register users to static lists, in order to manage preferences

If the information you would like to track is inside a webview, please see the Advanced section here

User profiles

In order to send well-targeted and personalized messages, Accengage lets you enrich your user profiles with additional relevant information, called custom device information.

These are very important for campaign targeting, as well as message personalization.

For instance, if you tag and update the first name of a user, you will be able to personalize a message with "Hello ${firstname}".

Traditional usage of custom device information for instance include first name, account ID (to match with external systems), total number of purchases, last purchased product, last purchase date, favorite product... They can be numeric values (set values, or incremental), strings, dates...

By implementing the library in your app, you will automatically gather certain information about your app users: their device model, OS version, language, country, time zone, app version, install date, the number of visits and more.

The Accengage library lets you also collect additional custom device information, which can be attached to the user profile through custom database fields.

If the information you would like to enrich is inside a webview, please see the Advanced section here.

Device Information

The Device Information is a profile qualifying a user device. It contains standard fields filled by the SDK and may contain custom fields that developers can add (for instance, to register whether a user is opt in or opt out for some categories of notifications). The standard fields are sent to the server in different moments: some of them at the beginning of session, other after 5 minutes timeout if a device location is changed, etc...

 

Custom fields (Deprecated, use UpdateDeviceInformation instead)

The custom fields are sent to the server after calling the method  updateDeviceInfo() if they contain new values. Old values which are already sent will be ignored to avoid spamming the server. In order to use custom fields they must be created first via Accengage dashboard (for more details, see the User Guide ). Once custom fields are created you can set/update its values. The following example shows how to set/update two custom fields First Name and Last Name:

 

Bundle bundle = new Bundle();
bundle.putString("firstname", "toto");
bundle.putString("lastname", "Robert");
A4S.get(mContext).updateDeviceInfo(bundle);

New API to Update Device Information

Starting from SDK 3.8.0, a new API is available in order to update device information in a more structured manner.

You can now use the DeviceInformation class object to encapsulate data made to be transmitted to the SDK.

Set a value

You can set a value for a custom field with the "set" method. The value can be a String, an Integer, a Long, a Float, a Double or a Date. First you must create a DeviceInformation object, and call the "set" methods with it, for each custom field that you want to set. Then you just have to call "updateDeviceInformation" with the object that you created.

DeviceInformation info = new DeviceInformation();
info.set("Firstname", "John");
info.set("Lastname", "Doe");
info.set("Age", 35);
A4S.get(mContext).updateDeviceInformation(info);
Delete a value

To delete a value, you just have to create a DeviceInformation object, and call the delete method, with the field's key that you want to delete.

DeviceInformation info = new DeviceInformation();
info.delete("Firstname");
A4S.get(mContext).updateDeviceInformation(info);
Increment or decrement a value

For numeric values, you can also increment or decrement this value. By creating first a DeviceInformation object, like always, and then call the desired method "increment" or "decrement", and pass the value to add or substract, as a double.

DeviceInformation info = new DeviceInformation();
info.increment("purchases_done", 2);
info.decrement("popularity", 92);
A4S.get(mContext).updateDeviceInformation(info);

Date Format

You can send a date using the updateDeviceInfo method.

Your date has to be in the following format: “yyyy-MM-dd HH:mm:ss zzz”

Please use the code below to format your date before sending it to Accengage servers:

SimpleDateFormat dateFormat = newSimpleDateFormat("yyyy-MM-dd HH:mm:ss zzz");
bundle.putString("myKey", dateFormat.format(myDate));

Logcat Output

A4S|DEBUG|UpdateDeviceInfoTask|Sending : "key" with value : "value"
A4S|DEBUG|UpdateDeviceInfoTask|Profile is successfully updated
Error logs
  • Profile update failed = No internet connection or server is unreachable
  • Request succeeded but parameters are invalid = some of the parameters sent are invalid, please read carefully the log to understand what is wrong
  • Some fields do not exist = You tried to update fields that do not exist inside your app's database scheme. Verify your app configuration and please note that fields are case sensitive

Static Lists

After creating Static Lists via Accengage dashboard, your application can:

  • get static lists for which the device is subscribed
  • subscribe to static lists
  • unsubscribe from static lists
  • get the status of particular static lists

Get Static Lists for which the device is subscribed

A static list contains information defining devices subscribed to the list. The device can be subscribed to a static list either by the Device ID (IDFV) or Client ID. You need to specify it in your .csv file before uploading it to the server.

One device can be subscribed to several static lists, i.e. several .csv files with the same DeviceID/ClientID must be uploaded to the server. To check for which static lists the device is subscribed you need to create a callback and pass it to the method getListsOfSubscriptions:

com.ad4screen.sdk.A4S.Callback<List<com.ad4screen.sdk.StaticList>> subscriptionCallback = new Callback<List<StaticList>>() {

    @Override
    public void onResult(List<StaticList> result) {
        if (result != null) {
            Log.i(TAG, "List detail with subscription true");
            for (StaticList staticList : result) {
                Log.i(TAG, "ID: " + staticList.getListId());
                Log.i(TAG, "Name: " + staticList.getName());
            }
        }
    }

    @Override
    public void onError(int error, String errorMessage) {
        // Process error
        // Error code 0: Network error
        // Error code 1: The list does not exist
    }
};

A4S.get(this).getListOfSubscriptions(subscriptionCallback);

Subscribe to static lists

The device can also be subscribed dynamically to static lists via the SDK without specifying it in the .csv file. In order to add the current device to a Static List, create a new StaticList object. Two constructors are available: with and without an expiration date.

StaticList staticList1 = new StaticList("listId#1");

StaticList staticList2 = new StaticList("listId#2", new Date(new Date().getTime() + 30 * 24 * 60 * 60 * 1000)); // Actual date + 30 days

Then pass your static lists for which the device must be subscribed to the method subscribeToLists:

A4S.get(this).subscribeToLists(staticList1, staticList2);

// or

List<StaticList> staticLists = new ArrayList<>(2);
staticLists.add(staticList1);
staticLists.add(staticList2);
A4S.get(this).subscribeToLists(staticLists);

Note that listId#1 and listId#2 are External ID of your static lists.

Unsubscribe from static lists

Like for subscription, the device can be unsubscribed dynamically from static lists. In order to remove the current device from a Static List(s), create a new  StaticList  object(s) from which the device must be unsubscribed and pass them to the method unsubscribeFromLists

A4S.get(this).unsubscribeFromLists(staticList1, staticList2);

// or

List<StaticList> staticLists = new ArrayList<>(2);
staticLists.add(staticList1);
staticLists.add(staticList2);
A4S.get(this).unsubscribeFromLists(staticLists);

Get the status of particular static lists

If you know ExternalIDs of Static Lists you may check if a device is subscribed or not for them.

Create a List of StaticLists:

StaticList staticList1 = new StaticList("listId#1");
StaticList staticList2 = new StaticList("listId#2");

List<StaticList> staticLists = new ArrayList<>(2);
staticLists.add(staticList1);
staticLists.add(staticList2);

Create a Callback to get the result or errors (for instance : no network, invalid id, ..) and pass it to the getSubscriptionStatusForLists:

com.ad4screen.sdk.A4S.Callback<List<com.ad4screen.sdk.StaticList>> subscriptionCallback = new Callback<List<StaticList>>() {

    @Override
    public void onResult(List<StaticList> result) {
        if (result != null) {
            Log.i(TAG, "List detail");
            for (StaticList staticList : result) {
                Log.i(TAG, "ID: " + staticList.getListId());
                Log.i(TAG, "Name: " + staticList.getName());
                Log.i(TAG, "Status: " + staticList.getStatus());
            }
        }
    }

    @Override
    public void onError(int error, String errorMessage) {
        // Process error
        // Error code 0: Network error
        // Error code 1: The list does not exist
    }
};

A4S.get(this).getSubscriptionStatusForLists(allStaticLists, subscriptionCallback);

Subscription tag

Subscription tag is a new API used to mark user interest for a particular topic.

A subscription tag is defined by a Category and an ID. The category represents a group or a repertory of tag and the ID is just the name of the tag.

The subscription tag can have up to 5 custom parameters. These parameters can be use to personalize your message and/or set an expiration for your tag.

You can set an expiration date for your tag by adding a custom parameter whose key is “exp” and the value is a timestamp. The timestamp must be sent as an Integer.

Example :

DeviceTag tag = new DeviceTag("Quinté", "123456");
tag.addCustomParameter("jockey_name", "John Doe");
tag.addCustomParameter("exp", 156538190);
A4S.get(getContext()).setDeviceTag(tag);

You can unsubscribe a user from a tag:

Example :

DeviceTag tag = new DeviceTag("Quinté", "123456");
A4S.get(this).deleteDeviceTag(tag);

Behaviour tracking

Views

Views are quite similar to States:

  • they are not transmitted to the server
  • they allow to trigger In-App messages or scheduled alarms

The main goal of views is to define on which Android activities, fragments or tabs Accengage messages can be displayed.

In order to use views they must be declared also via Accengage dashboard.

Then you can select the view for which you need to activate or deactivate triggering a message.

Set a view

There are two ways to bind your activities with views:

  • by tag
  • by method

Binding by tag

@Tag(name = "PopupPromoActivity")
public class MyPromoActivity extends A4SActivity {
    ...
}

Binding by method

If you want to tag each Fragment/Tabs and be able to target it, you can use the following code as soon as a view is displayed:

A4S.get(mContext).setView("your-view");

Log output

A4S|DEBUG|InApp|View is now set to : YourViewName
or
A4S|DEBUG|InApp|View is now set to : your.package.YourActivity

Events

There are 4 types of events:

  • Lead
  • Cart
  • Purchase
  • Custom

They differ in the fields sending to the server but they all have same roles:

  • passing analytic information to the server (tracking events)
  • triggering in-app messages or scheduled alarms (inclusion/exclusion events)

Tracking events

Lead

Lead event is an event containing two fields: label and value. To track a lead event you need to create a corresponding object and pass it to the method trackLead:

Lead lead = new Lead("MyLabel", "123");
A4S.get(mContext).trackLead(lead);

Log output:

A4S|DEBUG|Dispatcher|Dispatching lead #10 : [ '{"label":"MyLabel","value":"123"}' ]

After tracking a lead you can check it via Accengage dashboard:

Cart

Cart event is an event containing a cartID and Item. To track a cart event you need to create an Item object, then a Cart one and pass it to the method trackAddToCart:

Item item = new Item("Bas en latex S/M - 36/38", "bas_en_latex", "Lingerie", "eur", 39.30, 1);
Cart cart = new Cart("MyCart#123", item);
A4S.get(mContext).trackAddToCart(cart);

Note: Currency should be a valid 3 letters ISO4217 currency (EUR,USD,..) and the 2 last arguments are price and quantity

Log output:

A4S|DEBUG|Dispatcher|Dispatching add to cart #30 : [ '{"articleId":"bas_en_latex#69","label":"Bas en latex S\/M - 36\/38","category":"Lingerie","currency":"EUR","quantity":1,"cartId":"MyCart#123","unitPrice":39.9}' ]

After tracking a cart you can check it via Accengage dashboard:

Purchase

Purchase event is an event containing an information about the purchase (purchase id, currency and price). The event can also contain items of the purchase. To track it, create a purchase object (with or without items) and pass it to the method trackPurchase:

// without items
Purchase purchase = new Purchase("Purchase ID", "Purchase Currency", 12.30);

// or with items
Item[] items = new Item[] {
      new Item("ArticleID#1", "Label#1", "Category", "EUR", 12.30, 1),
      new Item("ArticleID#2", "Label#2", "Category", "EUR", 5.99, 1),
};
Purchase purchase = new Purchase("MyPurchase#456", "EUR", 17.29, items);

A4S.get(mContext).trackPurchase(purchase);

Log output:

A4S|DEBUG|Dispatcher|Dispatching purchase #50 : [ '{"currency":"EUR","items":[{"label":"Label#1","category":"Category","currency":"EUR","price":12.3,"quantity":1,"id":"Article#1"}],"total":17.29,"purchaseId":"MyPurchase#456"}' ]

After tracking a purchase you can check it via Accengage dashboard:

Possible reasons of errors:

  • Failed to send purchase events to server = No internet connection or server is unreachable
  • Request succeeded but parameters are invalid = some of the parameters sent are invalid, please read carefully the log to understand what is wrong
  • Error with this purchase = purchase id you tried to send already exists (already sent). Please note that each purchase event sent should have a distinct purchase id

Custom event

To track a custom event you need to call trackEvent and pass your eventId and value. You can also add additional parameters to the method.

JSONObject eventValue = new JSONObject();
eventValue.put("string-type-field", "value");
eventValue.put("bool-type-field", true);
eventValue.put("number-type-field", 7201);
eventValue.put("date-type-field", (myDate.getTime() / 1000L));
A4S.get(mContext).trackEvent(1001, eventValue.toString());

Log output:

A4S|DEBUG|Dispatcher|Dispatching event #1001 : [ '{"string-type-field":"value","bool-type-field":true,"number-type-field":7201,"date-type-field":1498233848}' ]

After tracking a custom event you can check it via Accengage dashboard:

Tracking events from a web page

If you need to track events from a web page you must open it with A4SWebView which provides JavaScript interface to handle tracking calls on JavaScript from web pages. Below there is JavaScript API for A4SWebView:

A4S.trackEvent(int eventId, String data);
A4S.trackPurchase(String data);
A4S.trackAddToCart(String data);
A4S.trackLead(String data);

States

States like events allow you to trigger In-App messages or scheduled alarms. However for states there are two differences:

  1. states are not transmitted to the server
  2. you can trigger messages by state values and not just by state ID (event ID).

As for events, states must be declared firstly via Accengage dashboard.

Then you can select a state value for which you need to activate or deactivate triggering a message.

Set a State

In order to set/update the state value you need to call putState:

A4S.get(mContext).putState("search", "how to chose a gift");

Where "search" is the state name and “how to choose a gift” is the value you want to set for this state.

Clear a State

In order to clear a state, just set it's value to null:  

A4S.get(mContext).putState("search", null);

Log output

A4S|DEBUG|InApp|State 'search' is now set to 'hot to chose a gift'

Session

The Accengage SDK sends analytic information (tracking) to the server at the beginning of each session. A new session is created:

  1. at the application startup (if the application process wasn't started before)
  2. or after 5 minutes of SDK API inactivity

Session analytic information contains a part of Device Information and other fields linked with the session:

  • current session date and time
  • sessions count
  • app installation date and time
  • connection type (wifi / cell)
  • android version
  • language
  • country code
  • timezone
  • the SDK version
  • and other technical information

Embedded web content tracking

Accengage webview A4SWebView  contains JavaScript interface to be able to handle calls on  JavaScript from web pages.  Below there are methods of JavaScript A4S object which you can use to:

A4S Javascript Methods

A4S.trackLead(data)

Tracks a lead event. The  data  is json containing the lead information. For example:

{
    "value":"leadValue",
    "label":"leadLabel"
}

A4S.trackAddToCart(data)

Tracks a cart event. The data is json containing the cart information. For example:

{
    "cartId":"cartId",
    "quantity":1,
    "category":"catItem",
    "label":"labelItem",
    "price":23,
    "articleId":"idItem",
    "currency":"EUR"
}

A4S.trackPurchase(data)

Tracks a purchase. The data is json containing the purchase information. For example:

 {
   "purchaseId":"777",
   "items":[
      {
         "id":"idItem1",
         "quantity":1,
         "category":"cat1",
         "label":"item1",
         "price":23,
         "currency":"EUR"
      },
      {
         "id":"idItem2",
         "quantity":2,
         "category":"cat2",
         "label":"item2",
         "price":50,
         "currency":"EUR"
      }
   ],
   "totalPrice":123,
   "currency":"EUR"
}

A4S.trackEvent(eventId, data)

Tracks an event (lead, cart, purchase or custom event). The eventId is an ID of the event (10 - Lead, 30 - Cart, 50 - Purchase, etc) and the data is either json for lead, cart, purchase or value for custom event.

A4S.setView(view)

Sets a view for the page you would like to target. The view is a view name value.

A4S.updateDeviceInfo(data)

Updates Device Information. The data is json containing fields and its values to update. For example:

{
    "key1":"value1",
    "key2":"value2",
    ...
}

Javascript Injection

When an A4SWebview is started, it will automatically run a javascript file added by Accengage as soon as the page is fully loaded. You can replace this script by your own. For this, set your js URL in ad4webviewscript_url parameter:

strings.xml

<resources>
    <!-- Accengage SDK parameters -->
    ...
    <string name="acc_webview_script_url">http://urlduscript.com/lescript.js</string>
</resources>

Custom WebviewClient

If you want to modify a behaviour of A4SWebview methods, you may use your own WebviewClient :

A4SWebview wv = new A4SWebview();
wv.setWebviewClient(new YourWebViewClient());

Close WebView from WebView's content

You can close the WebView with a specific URL inside the WebView. First, you need to manage the close action.

A4SWebView wv = new A4SWebView(this);
wv.setCloseUrlActionCallback(new Callback<Void>() {

    @Override
    public void onResult(Void result) {
        finish();
    }

    @Override
    public void onError(int error, String errorMessage) {
        // Nothing
    }
});
Next, in your HTML content, add the  **bma4sclose**  key in the closing URL, for example: http://www.google.com?bma4close=true

JavaScript Sample

For quick tests of A4S methods, check out our simple project on node.js rendering an html page with JavaScript code:

<script>
    function trackLead() {
        var data = "{\"value\":\"leadValue\",\"label\":\"leadLabel\"}";
        A4S.trackLead(data);
    }

    function trackCart() {
        var data = "{\"cartId\":\"cartId\",\n" +
                     "\"quantity\":1,\n" +
                     "\"category\":\"catItem\",\n" +
                     "\"label\":\"labelItem\",\n" +
                     "\"price\":23,\n" +
                     "\"articleId\":\"idItem\",\n" +
                     "\"currency\":\"EUR\"\n}";
        A4S.trackAddToCart(data);
    }

    function trackPurchase() {
        var data = " {\n" +
                   "   \"purchaseId\":\"777\",\n" +
                   "   \"items\":[\n" +
                   "      {\n" +
                   "         \"id\":\"idItem1\",\n" +
                   "         \"quantity\":1,\n" +
                   "         \"category\":\"cat1\",\n" +
                   "         \"label\":\"item1\",\n" +
                   "         \"price\":23,\n" +
                   "         \"currency\":\"EUR\"\n" +
                   "      },\n" +
                   "      {\n" +
                   "         \"id\":\"idItem2\",\n" +
                   "         \"quantity\":2,\n" +
                   "         \"category\":\"cat2\",\n" +
                   "         \"label\":\"item2\",\n" +
                   "         \"price\":50,\n" +
                   "         \"currency\":\"EUR\"\n" +
                   "      }\n" +
                   "   ],\n" +
                   "   \"totalPrice\":123,\n" +
                   "   \"currency\":\"EUR\"\n" +
                   "}";
        A4S.trackPurchase(data);
    }

    function trackEvent() {
        var data = "myCustomEvent";
        A4S.trackEvent(567, data);
    }

    function setView() {
        A4S.setView("PopupPromoActivity");
    }

    function updateDeviceInfo() {
        var data = "{\n" +
                   "    \"firstname\":\"François\",\n" +
                   "    \"lastname\":\"Hollande\"\n" +
                   "}";
        A4S.updateDeviceInfo(data);
    }

</script>

To start the webservice call:

$> node app.js
Node app is running on port 5001