Activity analyzers
An Activity Analyzer is a Plugin that allows you to modify an activity on the fly before storing it. It runs as a part of the processing pipeline, for each activity of the channel it is associated with.
This feature is useful for:
  • Improving the data quality, for example by fetching product information based on a product id
  • Events filtering
  • Changing events formatting
If you don't know what a plugin is, you can find complete documentation in the specific section.
An activity analyzer is called only with activities tracked in real time with de different methods explained in the real time user tracking guide. If you want to upload bulk activities, make sure that they are already formatted before starting the upload as the activity analyzer won't run.
The standard group ID for an activity analyzer is {domain}.{organisation}.activity-analyzer, for example com.mediarithmics.activity-analyzer

Endpoints to implement

Activity analyzers have only one predefined endpoint to implement
post
myworker
/v1/activity_analysis
Process an activity
See Plugin Instances to learn why you should use the activity_analyzer_id parameter to retrieve the instance properties.

Available outbound services

The code of the activity analyzer can call the following API endpoints to retrieve its instance context.
get
https://api.mediarithmics.com
/v1/activity_analyzers/:id
Retrieve the instance
get
https://api.mediarithmics.com
/v1/activity_analyzers/:id/properties
Retrieve the instance properties

Creating an activity analyzer

See the plugins documentation to see how plugins are created and deployed.
An activity analyzer has the ACTIVITY_ANALYZER plugin type. Its group id should be {domain.organisation.activity-analyzer} (for example com.mediarithmics.activity-analyzer. Its artifact id should be the name of the activity analyzer, ie update-product-infos.
Use our Plugins SDK to create your activity analyzer in nodejs : the required routes are already defined and you only have to override specific functions.
You can find a sample activity analyzer in the examples folder of the plugins SDK.
We can provide you with a hello world project using our SDK. Please contact your support in order to have access to it.
The project structure and files work as with every other plugin.

Interfaces to implement

Your should extend ActivityAnalyzerPlugin class and implement the instanceContextBuilder and onActivityAnalysisfunctions from the plugins SDK.
onActivityAnalysis function is called every time an activity runs through the activity analyzer. It is responsible for the activity transformation.
The instance context built in instanceContextBuilder is cached to improve performances. It should retrieve and store the plugin properties and configuration files used by the code.
Don't forget to catch your errors. You should log / respond with the appropriate message to facilitate debugging.
1
import { core } from "@mediarithmics/plugins-nodejs-sdk";
2
import { CustomInstanceContext } from "./interfaces/InstanceContextInterface";
3
4
export class ActivityAnalyzerPlugin extends core.ActivityAnalyzerPlugin {
5
// Called to update a user activity
6
// Uses the instance context built with instanceContextBuilder
7
// to adapt to the properties and technical files
8
protected async onActivityAnalysis(
9
request: core.ActivityAnalyzerRequest,
10
instanceContext: CustomInstanceContext)
11
: Promise<core.ActivityAnalyzerPluginResponse> {
12
13
try{
14
const updatedActivity = request.activity;
15
16
// Your code to modify the activity.
17
// Exemple adding product infos in each event
18
// If the technical configuration allows it
19
if (instanceContext.technicalConfig.updateActivities){
20
updatedActivity.$events.forEach(event => {
21
if (event.$properties && event.$properties.$items && event.$properties.$items.length > 0) {
22
event.$properties.$items.forEach((item: any) => {
23
var product = Products.find(p => p.$id == item.$id);
24
item.$name = product.$name;
25
item.categories = product.categories;
26
item.inStock = product.inStock;
27
});
28
}
29
});
30
}
31
32
33
const response: core.ActivityAnalyzerPluginResponse = {
34
status: "ok",
35
data: updatedActivity
36
};
37
38
return Promise.resolve(response);
39
}
40
catch (err) {
41
const errorResponse: core.ActivityAnalyzerPluginResponse = {
42
status: 'error',
43
data: request.activity
44
};
45
this.logger.error(`TRANSFORMATION ERROR while processing activity: ${JSON.stringify(request.activity)}`);
46
return Promise.resolve(errorResponse)
47
}
48
}
49
50
// Build the instance context
51
// by fetching properties and configuration files
52
protected async instanceContextBuilder(activityAnalyzerId: string)
53
: Promise<CustomInstanceContext> {
54
const baseInstanceContext = await super.instanceContextBuilder(activityAnalyzerId);
55
try {
56
57
// Retrieve a technical configuration file
58
const validator = new Jsonschema.Validator();
59
const technicalConfig: ITechnicalConfig = await this.validateJSONSchema(TECH_CONFIG_FILE, validator, technicalConfigurationSchema, activityAnalyzerId);
60
61
// Retrieve a property from the plugin instance
62
const eventExclusionList = baseInstanceContext.properties.findStringProperty("events_exclusion_list");
63
64
// Return the completed instance context
65
const result: CustomInstanceContext = {
66
...baseInstanceContext,
67
event_exclusion_list: eventExclusionList,
68
technicalConfig: technicalConfig
69
};
70
71
this.logger.debug(`Loaded InstanceContext with: ${JSON.stringify(result,null,4)}`);
72
return Promise.resolve(result);
73
} catch (err) {
74
this.logger.error(`Something bad happened during the build of the Instance Context ${err}`);
75
return Promise.reject(`Something bad happened during the build of the Instance Context ${err}`);
76
}
77
};
78
}
Copied!
Your instance context interface should extend ActivityAnalyzerBaseInstanceContext
1
import { core } from "@mediarithmics/plugins-nodejs-sdk";
2
3
export interface CustomInstanceContext
4
extends core.ActivityAnalyzerBaseInstanceContext
5
{
6
event_exclusion_list: string[];
7
technicalConfig: ITechnicalConfig;
8
}
Copied!

Debugging

Plugin logs and metrics

As activity analyzers are plugin, you can monitor them as you do with all plugins.

Verifying an activity

User activities that run through activity analyzers are generally aggregated into sessions. You won't see your user activity until it has been put into a session and gone through the whole activity processing pipeline. See how sessions are built to understand when you should see your activity or how you could fasten the process.
  1. 1.
    Go to the navigator > monitoring and search for the user point associated with the activity.
  2. 2.
    Click on the view json button on any activity on a timeline
  3. 3.
    You can check if all the properties are OK and if your activity analyzers processed the activity as expect
In case of problem, you can look at two properties added to the activity. processed_by will tell you if the activity has been processed by your activity analyzer, and $error_analyzer_id will give you an error ID if the activity analyzer returned an error response.
1
{
2
"processed_by": "<YOUR_ANALYZER_ID>",
3
"$error_analyzer_id": "<ERROR_ID>"
4
}
Copied!