Event Tracking

.

Quick Start

Javascript

In order for primedjs to make authorized calls, it expects two server-side generated values: nonce and signature. The signature is generated by concatenating the publicKey, the secretKey and the nonce. The publicKey and secretKey are provided via your PrimedIO contact. The nonce is the Unix timestamp in seconds from midnight 1970 UTC of the moment at which you are generating your signature. The concatenation of these three values is then sha512 hashed and the resulting value is the signature.

Include primedJS

<script src='cdn.primed.io/primedio.js'></script>

Generate server-side signature

# SERVER-SIDE PYTHON EXAMPLE CODE
nonce = int(datetime.datetime.now(datetime.timezone.utc).timestamp())
local = hashlib.sha512()
signature = "{}{}{}".format(pubkey, secretkey, nonce)
local.update(signature.encode('utf-8'))
signature = local.hexdigest()

The resulting signature can then be sent along with the page back to the user where it is consumed by primedjs as it runs client-side.

Instantiate primedjs

const pio = PRIMED({
	connectionString: "https://gw.<accountname>.primed.io",
	nonce: <nonce>,
	publicKey: "<publicKey>",
	signature: "<signature>",
	tracking: {
    	connectionString: 'https://collector.<accountname>.primed.io/track'
    }
});

Behavioral events

The behavioral events feed tracks end-user behavior in target applications such as viewing a page, mouse movements, clicks or scroll motions. Applications are broadly defined and include mobile apps as well as simple websites and web apps. Each event consists of a set of properties. A property has a key which is always a string, and a value which can be a primitive, such as an int, string, float, or a dictionary. We distinguish four elementary groups of properties:

  1. The type property which indicates the type of this event, such as for instance CLICK, VIEW or MOUSEMOVE
  2. The basic event properties which are always present regardless of event type
  3. The eventObject which contains the event type specific payload data
  4. The customProperties object which is a user data payload sent with each event regardless of event type.

N.B. the event type specific eventObject object can in fact also contain a separate customProperties object, which may contain user data to be sent along with the event type.

Various default events exist that need no further specification and can be easily integrated with existing applications, see for a full list . Additionally, custom events can be defined to track events such as media start/pause events, see section for more information on how to specify and implement custom events.

Event tracking can be integrated with existing applications using the client libraries (Javacript, iOS, Android).

Properties
Basic event properties

Basic event properties are always present, regardless of event type.

name type default example description
apikey string "xxxxxxxxxxxxxxxxxxxxxxxx" public api key
ts long 12345678000 (client-side) timestamp at which event took place
sid string (uuidv4) xjf1231ffm234mmmsf session id
did string (uuidv4) ufmfm12dun123d991m device id
source string WEB whether the event originates from web or app
sdkId int 0 from which client library the event originates (0: Javascript, 1: Android, 2: iOS)
sdkVersion string 0.0.1 version of the client library where the event originates
type string VIEW event type
customProperties object {} { 'category': 'tools' } user defined properties to be sent along with every event, regardless of type
eventObject object {} { 'uri': 'http://example.com/article/1' } contains the event type specific payload data

N.B. there is also a ‘special’ property being added to every event upon receipt by the system: received_at, this indicates the timestamp in milliseconds at which the event was received by the collector.

Custom event properties

TODO: describe custom event properties

Features

Features are a special type of property in that they can be used to derive signals. Example features include geolocation, time and user agent. Typically, but not always, features correspond to ‘raw’ (and potentially continuous, as opposed to discrete) data whereas signals represent discretized, binned or otherwise prepared ‘triggers’ that match feature engineering as part of model crafting efforts.

pio.features.bind({
	userId: function() {
		return 'Alice';
	} 
});

Features are logged at the start of each session using the START event.

Signals

Signals are discretized, or binned, properties used to trigger predictions. In order for Primed to become aware of signals, you attach one or more detectors. Detectors can be literals, or functions. When defined as functions, you can include features by providing the features names as arguments.

Below toddow signal detector uses the now feature, which is the local time as a DateTime object, to derive a dynamic time of day, day of the week bin used to trigger time dependent personalisation.

pio.detectors.bind({
    userId: function(userId) {
    	return userId;
    },
    device: 'iPhone',
    toddow: function(now) {
        const days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
        const timebins = ["00-03", "03-06", "06-09", "09-12", "12-15", "15-18", "18-21", "21-24"];

        return days[now.getDay()] + "_" + timebins[Math.floor(now.getHours() / 3)];
    }
});

The above configuration will ensure that for each personalise call, the following signals will be used to trigger predictions:

  • userId (always set to Alice, as it takes the value from the hardcoded userId feature as defined in the features section above)
  • device (always set to iPhone)
  • toddow (a time of day, day of week bin like Sun_00-03, depending on the time and day at which the user triggers the personalise call)

It’s important to note that all bound signals are always sent along with each personalise call, this is by design.

// TODO:add reference here For more information on signals and how they relate to prediction, consult section …

Default events

Default events are already defined in the client libraries and require little implementation effort to be exposed. They only cover basic behavior, but the data they yield is generally sufficient to get started on recommendations, churn predictions or content optimization.

MOUSEMOVE

User mouse move events sample the position as x,y coordinates of the mouse cursor at a configurable sample rate.

On WEB, MOUSEMOVE events are disabled by default. When enabled the library attaches global eventhandlers to the onmousemove DOM event, requiring no further action. On APP, however, global eventhandlers are not available so the developer will need to implement the event-handling and sampling and emit the message manually using the library, see for details: iOS, Android.

eventObject: {
    x: 568,
    y: 1044
}
CLICK

User click events register when the user issues a mouse click, logging the x, y position of the mouse cursor at the moment of the click and which mouse button was clicked: LEFT, RIGHT.

On WEB, CLICK events are disabled by default. When enabled the library attaches global eventhandlers to the onclick DOM event, requiring no further action. On APP, however, global eventhandlers are not available so the developer will need to implement the event-handling and emit the message manually using the library, see for details: iOS, Android.

eventObject: {
    x: 568,
    y: 1044,
    interactionType: 'LEFT'
}
VIEW

View events register page views, logging the uri of the viewed page.

On WEB, VIEW events are enabled by default and the library attaches global eventhandlers to the onhashchange DOM event, requiring no further action. On APP, however, global eventhandlers are not available so the developer will need to implement the event-handling and emit the message manually using the library, see for details: iOS, Android.

eventObject: {
    uri: 'https://example.com/article/1'
}
SCROLL

Registers a page scroll event logging both direction as either UP or DOWN and distance scrolled in pixels.

On WEB, SCROLL events are disabled by default. When enabled the library attaches global eventhandlers to the onscroll DOM event, requiring no further action. On APP, however, global eventhandlers are not available so the developer will need to implement the event-handling and emit the message manually using the library, see for details: iOS, Android.

eventObject: {
    direction: 'UP',
    distance: 245
}
ENTERVIEWPORT

Registers when a page element enters the viewport. This event exposes no default properties, but expects there always be a customProperties field.

TODO: describe how to assign class to WEB elements, and refer to APP docs

eventObject: {
	customProperties: { /* User defined */ }
}
EXITVIEWPORT

Registers when a page element exits the viewport. This event exposes no default properties, but expects there always be a customProperties field.

TODO: describe how to assign class to WEB elements, and refer to APP docs

eventObject: {
	customProperties: { /* User defined */ }
}
HEARTBEAT

Heartbeats are sent out at a configurable interval and can be used to determine session length. The library also provides an END event but it relies on the device actively signalling a session end (such as closing the browser). This, however, is known to not be incredibly reliable as many factors may prevent the device from sending the signal, including crashes or long running javascript code. For this reason, the HEARTBEAT event allows for determining session ends implicitly (when HEARTBEATS stop coming for a given sid)

The HEARTBEAT event only logs a single feature i, which is an incrementing integer that resets every session start.

eventObject: {
	i: 4
}
START

At every session start a START event is emitted. This event contains session features, such as the user agent string (ua, screen dimensions (screenWidth, screenHeight, viewPortWidth, viewPortHeight), local time (now) and location (location).

Additionally, the start event will contain any features as defined by the pio.features.bind() calls.

TODO: reference to the features section here

eventObject: {
	ua: '',
	screenWidth: 1024,
	screenHeight: 768,
	viewPortWidth: 700,
	viewPortHeight: 768,
	screenX: 500,
	screenY: 500,
	now: ''
}
END

A best effort is made at every session end to emit an END event. The odds of this succeeding among other depend on system state (crashed or not) and whether there are run time limitations (browsers tend to limit the amount of javascript runtime). Due to the unreliable nature of the event, it accepts no properties by design.

If high reliability for registering session end events is needed, one can use the HEARTBEAT event to implicitly detect session ends (as the heartbeats stop coming).

eventObject: {

}
PERSONALISE

Each call to the personalise endpoint will generate a PERSONALISE event upon returning. Attached to the event will be a guuid property which allows connecting sid, did and other properties across to personalise results, impressions and conversions.

eventObject: {
	guuid: '46n91msnh38ddmm10sdf' /* uuidv4 */
}
CONVERT

Each call to the convert endpoint will generate a CONVERT event. It contains an ruuid property which uniquely identifies the personalise result that led to the conversion, as well as a hasData boolean property to indicate whether data was sent along with the conversion call.

eventObject: { 
	ruuid: '37m004uenn18djdjdjfu', /* uuidv4 */ 
	hasData: true
}
POSITIONCHANGE

When a user changes position, and the POSITIONCHANGE event is enabled, this event will register it. It provides latitude, longitude and horizontal accuracy in meters.

On WEB, POSITIONCHANGE events are disabled by default. When enabled the library issues a request for location sharing to the user upon loading of the library and uses the browser navigator.geolocation.watchPosition API to listen for position changes. On APP, however, the developer will need to implement the position monitoring for changes and emit the message manually using the library, see for details: iOS, Android.

eventObject: {
    latitude: 37.89,
    longitude: 5.17,
    accuracy: 50
}

Custom Behavioral Events

When default events don’t fully satisfy requirements, custom events can be defined. Any event that can be be triggered in the target application can be captured by Primed.

Add custom event
  • determine properties
  • update schema-registry entry behavior
  • update primed-streams module/processor

Personalise Events

Retrieving predictions is done using the personalise endpoint. It uses signals (derived from features), to trigger the predictions that match a given context.

js pio.personalise({ campaign: "frontpage.recommendations", signals: { userId: 'Alice'} }).then( value => { console.log(value); }).catch( reason => { console.error( 'something went wrong: ', reason ); }); `

// TODO: add reference here See section … for more details on how to perform personalise calls.

Personalise events

Each personalise call will yield a detailed response, or PERSONALISE event, which will include a resultset. Please note, the resultset can be empty, which is by design - it is not guaranteed that for every combination of signals a result can be returned. If not empty (and so, signals were in fact matched and predictions returned), each result will contain a JSON payload that can be designed to include any type of content. Typical use cases such as recommendations populate the payload with url, img and title values that can be used to render the page accordingly.

Apart from the resultset, the personalise call also returns information about the A/B membership, the underlying experiment and which models contributed to the end result ranking to what extent. This information is returned to the client, but it is also logged and made available as event data.

Each personalise response is uniquely identified using the guuid property.

// TODO: describe the full personalise schema here

Impression events

Each of the results in the personalise responses’ resultset is considered an IMPRESSION event. This implies the assumption that results are eventually rendered to the page, perhaps as a recommended item, a personalised message or maybe a background color.

Impressions are uniquely identified using the ruuid property.

// TODO: describe the full personalise schema here

Conversion events

Once an impression lead to conversion, usually a click but other conversion actions can be registered as well, they yield a CONVERSION event. Each CONVERSION event has an ruuid property that allows tracing back to the IMPRESSION that lead to the conversion.

Catalog Events

Adding a catalog schema
Editing a catalog schema

Storage

Google Cloud Storage

Parquet
Partitioning

Clickhouse