SDK ⇌ DES - Aggregated Views and Clicks

Problem

Mobile SDK currently sends raw viewedMessages and clicks to Device Event Service with each events requests, and only clicks with each inline messages request.

The structure of these lists is the following:

{
    "viewedMessages": [
        {
            "campaignId": 123456789,
            "timestamp": "2020-11-26T12:27:29.713+01:00"
        }
    ],
    "clicks": [
        {
            "campaignId": 123456789,
            "buttonId": "some-button",
            "timestamp": "2020-11-26T12:27:29.713+01:00"
        }
    ]
}

Since these lists contain raw views and clicks, they can grow huge if there are:

  • many active campaigns, or

  • long-running campaigns, or

  • open-ended campaigns, or

  • unlimited impressions or clicks.

Device Event Service is not making any special use of this raw data - it is simply grouping views/clicks by campaign ID, counting them up, and taking the timestamp of the most recent view/click.

Proposal

Device Event Service only needs the following data:

{
    "campaignStats": {
        "123456789": {
            "views": 10,
            "lastViewAt": "2020-11-26T12:39:15.507+01:00",
            "clicks": 4,
            "lastClickAt": "2020-11-26T12:39:21.706+01:00"
        }
    }
}

Instead of sending all the views and clicks since the beginning of time, SDK will send only new views/clicks since the last successful request to DES. DES will aggregate those views/clicks, calculate the stats, use them to process the request, and return them back to SDK for storage on the device. SDK will then include these stats in the next request to DES, along with new views/clicks that happened since the last request.

By delegating aggregation of the views/clicks to the server, we can more easily add additional data to the stats in the future, without the need of changing the SDK code.

We can also stop sending oldCampaigns to SDK, cause it won’t be managing the local cache on its own anymore. DES will now be taking care of that - removing canceled/deleted campaigns from the stats JSON object.

Since the SDK does not care about stats JSON structure - it simply stores them and sends them back - we will introduce a more generic JSON object for this purpose. For now it will only contain these stats, but in the future we can add additional data in DES which we want SDK to store for us on the device.

API changes

Device Event Service will introduce v4 version of the API to accomodate these changes. New SDK versions will have to use v4 prefix for all calls to DES.

SDK Request

If there is any deviceEventState JSON stored on the device, SDK includes it in the root of each events request and each inline messages request. In addition to that SDK includes only those viewedMessages and clicks which occured since the last successful request.

{
    ...,
    // only NEW viewedMessages & clicks, since the last successful request
    "viewedMessages": [
        {
            "campaignId": 123456789,
            "timestamp": "2020-11-26T12:27:29.713+01:00"
        }
    ],
    "clicks": [
        {
            "campaignId": 123456789,
            "buttonId": "some-button",
            "timestamp": "2020-11-26T12:27:29.713+01:00"
        }
    ],
    "deviceEventState": {
        // SDK does not care what is inside
    }
}

DES response

In addition to the current data, DES will include deviceEventState JSON object in the root of the response data. SDK will use this JSON as-is and simply ovewrite whatever it already had in its local data with this JSON.

DES will stop sending oldCampaigns list - SDK wil not be taking care of it’s local cache anymore, so it won’t be necessary.

{
    ...,
    "deviceEventState": {
        "campaignStats": {
            "123456789": {
                "views": 10,
                "lastViewAt": "2020-11-26T12:39:15.507+01:00",
                "clicks": 4,
                "lastClickAt": "2020-11-26T12:39:21.706+01:00"
            }
        }
    }
}