Configurations¶
Profile¶
An entity corresponds to a uniquely identifiable attribute in the data model. E.g. Mobile Number for a Telecom Subscriber, Cell ID for a Cell Tower, customer Id for a banking customer etc. A collection of features related to the entity. Such collection may include Static features (e.g. DOB) + Historic Features (e.g. Revenue last month) + Semi Historic Features (e.g. Dropped calls let hour) + Last-Known Features (e.g. last known location, last topup amount, etc.). The Real-time Features come in the form of Real-time events.
Profiles are technically a collection of tables in Redis, each table has a key and value is a hash map. This hash map further has key value pair, representing the profile attribute name (like gender) as key and attribute value (like Female) as value.
Profile Configuration¶
Profile configurations are defined in etc/model/profiles
directory.
below is the example of a solution containing two profiles definition:
$ tree etc/model/profiles/
etc/model/profiles/
├── customer
│ └── profile.json
└── tower
└── profile.json
The name of profiles are Customer and Tower, the profile Customer represents telcom sunscribers and profile Tower represents cell tower installed by telecom providers.
The profile.json
file is structures as below:
{
keyAttribute": "MSISDN",
"masterTable": "CUSTOMER_PROFILE",
"name": "Customer",
"tables": [
{
"name": "CUSTOMER_PROFILE",
"type": "Dynamic"
},
{
"name": "CUSTOMER_SEGMENT",
"type": "QuasiStatic"
}
]
}
The above definition of Customer
profile is configured that the keyAttribute
is MSISDN (Mobile number),
This profile contains two tables i.e., CUSTOMER_PROFILE and CUSTOMER_SEGMENT. Among them the master profile is CUSTOMER_PROFILE.
The profile is of two types. Dynamic types is table that can be changed any time in realtime and attribute values are very dynamic in
nature like lastTransactionAmount. whereas a QuasiStatic table could changes slowly like customerSegment. The clients which accesses the
profile will invalidate the cache based on type of the profile table. a Dynamic table will be accessed each time by discarding cache, whereas a QuasiStatic
tables will keep the cache for 10 minutes.
Once the profile are defined in etc/model/profiles directory, we need to change the product’s configuration to point to these profiles.
The profiles are configured in drive.profiles
section of product configuration etc/drive.json
:
..
..
"drive": {
"profiles": [
"Customer",
"Tower"
],
}
..
..
"masterProfile": "Customer",
..
..
Note
Directory structure and nameing of profile directory is very important as Qbo Decisions will use this to navigate and access a particular profile configuration. The profile
Customer
is kept under profiles/customer/profile.json , if the profile name wasEvent Catelog
then the directory stucture will be profiles/event_catelog/profile.json.We can have as many profiles as required by a solution but there will one profile which is called master profile. This master profile is used as a central entity profile and used as default profile for audience and trigger evaluation.
Reference Datasets¶
Reference datasets are configured to to populate the profile tables. This defines the data model and format of reference data along with the destination profile and profile table. The reference data generally comes from dataware houses, operational systems or given as a static files.
below is the example of a solution containing one reference datasets definition:
$ tree etc/model/reference_datasets/
etc/model/reference_datasets/
├── towers.json
└── towers.schema.json
The name of reference dataset is Towers, this reference dataset is used to periodically update profile Tower.
The towers.schema.json
file is structures as below:
{
"attributes": [
{
"name": "cellId",
"type": "String"
},
{
"name": "city",
"skipped": true,
"type": "String"
},
{
"name": "cityCode",
"type": "String"
},
{
"name": "date",
"type": "String",
"allowedToBeNull": true
},
{
"name": "district",
"type": "String"
},
{
"name": "equipment",
"type": "List(String)"
},
{
"name": "lat",
"type": "Double"
},
{
"name": "lon",
"type": "Double"
},
{
"name": "siteType",
"type": "String"
},
{
"name": "towerType",
"type": "String"
}
],
"dataFileFormat": "JSON",
"dropTableBeforeInsertion": true,
"keyAttribute": "cellId",
"name": "Towers",
"profile": "Tower",
"refreshIntervalInMillis": 6000000,
"refreshable": true,
"table": "TOWER"
}
attributes
section defines the name, type, null constrains, skipped flag. by default all attributes are non-nullable. If an attribute is marked as “skipped”: true then that attribute will be skipped while loading the profile table. The order of attributes in theattribute
section defines the order of the attribute in the reference dataset’s data file.dataFileFormat
are of two types i.e., JSON or CSV.dropTableBeforeInsertion
is flag to drop the table before loading a new file.keyAttribute
is one of the attribute from the file to be used as key while loading data into profile table.name
is the name of reference data set.profile
is the name of profile to be loaded.refreshIntervalInMillis
is the frequency of checking if the file is modified.refreshable
is a flag to enable the refreshability of the reference dataset.table
is the name of table among the tables list from the configured profile.
The structure of CSV file will have some additional parameters as below:
{ ..
..
"dataFileFormat": "CSV",
"dropTableBeforeInsertion": false,
"keyAttribute": "cardType",
"name": "Card Logo",
"parameters": [
{
"name": "delimiter",
"type": "String",
"value": "|"
},
{
"name": "hasHeader",
"type": "Bool",
"value": true
}
],
..
..
}
delimiter
is the delimiter in the CSV file.hasHeader
is flag to know if the file has header or not.
Once the reference datasets are defined in etc/model/reference_datasets directory, we need to change the product’s configuration to point to these
reference datasets.
The reference datasets are configured in drive.referenceDatasets
section of product configuration etc/drive.json
:
..
..
"drive": {
"profiles": [
"Customer",
"Tower"
],
"referenceDatasets": [
"Towers"
]
}
..
..
"masterProfile": "Customer",
..
..
Note
File nameing of reference datasets directory is very important as Qbo Decisions will use this to navigate and access a particular reference dataset configuration. The reference dataset
Towers
is kept under reference_datasets/towers.schema.json and since it is a JSON type, the Qbo Decisions will expecttowers.json
in the same directory. If the type was CSV, then Qbo Decisions will expecttowers.dat
file.Qbo Decisions maintains a hash of file in the database in order to track changes in the data file and will only refresh if the file is modified.
Feed Data Model¶
Feed data models represents common classes of feed data sources in the system. E.g., Card Transaction feed data model will have common attributes from both Debit Card Transactions and Credit Card Transactions realtime data feed. A feed application can follow one or more of these feed data models. like Credit Card Transactions data feed could follow Card Transaction and Location feed data model.
feed data models are configured in etc/models/feed_data_models/<model-name>/data_model.json
.
below is the example of a solution containing four feed data model definition:
$tree etc/model/feed_data_models/
etc/model/feed_data_models/
├── identity
│ └── data_model.json
├── top_channels_prediction
│ └── data_model.json
├── topup
│ └── data_model.json
└── usage
├── data_model.json
├── enrichment_functions.json
└── enrichment_scorers.json
The name of feedDataModels are Identity, Top Channel Prediction, Topup and Usage.
Example Feed data model:
{
"attributes": [
{
"name": "MSISDN",
"required": true,
"type": "String"
},
{
"name": "calledNumber",
"required": false,
"type": "String"
},
{
"name": "callingNumber",
"required": false,
"type": "String"
},
{
"name": "lastMSISDN",
"required": false,
"type": "String"
},
{
"name": "ts",
"required": true,
"type": "Int64"
}
],
"name": "Identity",
"profiles": [
{
"keys": [
"MSISDN",
"calledNumber",
"callingNumber",
"lastMSISDN"
],
"name": "Customer"
}
]
}
attributes
is a list of attributes of the model.name
is the name of feed data model.profiles
is a list of profile that can be realted to this feed model.profiles.name
is the name of profile which can be related to this feed model for lookup or update purpose.profiles.keys
is the list of attribute which can be used as keys to perform operation for the given profile. one of these keys should be not nullable.
Once feed data models are configured in feed_data_models directory, we need to point to it in product configuration (etc/drive.json
)
The feed data models are configured in drive.feedDataModels
section of product configuration etc/drive.json
:
..
..
"drive": {
"feedDataModels": [
"Identity",
"Top Channels Prediction",
"Topup",
"Usage"
],
}
..
..
"masterProfile": "Customer",
..
..
Note
Directory structure and nameing of feed data model directory is very important as Qbo Decisions will use this to navigate and access a particular feed data model’s configuration. The feed data model
Identity
is kept under feed_data_models/identity/data_model.json , if the feedDataModel name wasTop Channels Prediction
then the directory stucture will be feed_data_models/top_channels_prediction/data_model.json.
Feed Applications Models¶
Each feed application have to configure application model and can optionally configure some other feed application model file as described below.
feed application models are configured in etc/models/applications/<feed-name>/
.
below is the example of a solution containing a feed application definition:
$ tree etc/model/applications/ericsson_usage/
etc/model/applications/ericsson_usage/
├── aggregations.json
├── application.json
├── enrichment_functions.json
└── enrichments.json
The name of feed application is Ericsson Usage .
Below sub-sections will explain each of the above files.
Application Model¶
Application model defines the key attribute and feed data model that this feed implements.
application model is defined in application.json file.
Example application Model:
{
"feedApplication": {
"dataModels": [
"Identity",
"Usage"
],
"keyAttribute": "MSISDN",
"name": "Ericsson Usage"
}
}
dataModels
a list of feed data model that are implemented by this feed.keyAttribute
an attribute from the feed that is a key attribute.name
is name of feed application.
Aggregations¶
This model describes the aggregations that are computed on a feed and stored in FastPast.
Aggregates are configured in etc/model/applications/<application_name>/aggregation.json
file.
Example Aggregation definition is as below:
{
"aggregations": [
{
"name": "avgCallDuration",
"operation": {
"aggregationKind": "Average",
"groupByAttributes": [
"callingNumber"
],
"valueAttribute": "duration"
}
},
{
"name": "numCallsByCell",
"operation": {
"aggregationKind": "Sum",
"groupByAttributes": [
"cellId"
],
"value": 1.0
}
},
..
..
]
}
aggregations
List of aggregations.name
A name (aggregations defined on different feeds can have the same name) that is in the form of an identifier (aNameLikeThis).groupByAttributes
A potentially empty list of group by attributes.aggregationKind
An aggregation kind (Average, Maximum, Minimum, Sum, Variance).valueAttribute
orvalue
A value (such as “1” for counting) or value attribute (such as “callDuration”).tupleFilter
An optional tupleFilter, which is a Boolean UEL expression
Loaded once during Qbo Decisions initialization, managed from the UI there on.
Enirchment Functions¶
Enrichment Function model file defines the meta data of an enrichment function. It defines the signature of a python function to be used in an enricher.
Enrichment Function definition is configured in etc/model/applications/<application_name>/enrichment_functions.json
file.
Example Enrichment Function:
{
"functions": [
{
"module": "acme.application_helpers.ericsson_usage.enrichment_helpers",
"name": "device_change",
"parameters": [
{
"name": "deviceName",
"required": false,
"type": "String"
},
{
"name": "isSmartphone",
"required": false,
"type": "Bool"
}
],
"type": "Bool",
"usedAttributes": [
{
"name": "IMEI",
"required": true,
"type": "String"
},
{
"name": "lastIMEI",
"required": true,
"type": "String"
}
]
},
..
..
]
}
signature of python funciton is as below:
def device_change_(tuple_, deviceName=None, isSmartphone=None):
"""Returns the last time the subscriber has changed their device"""
imei = tuple_.IMEI
lastIMEI = tuple_.lastIMEI
..
..
return xyz
functions
list of functions defined.module
a python module path.name
name of enrichment function.type
return type of the function.parameters
list of additional parameters to enrichment function, tuple is a default and first parameter to function. we need to only mention any additional parameters/usedAttributes
the list of attributes used from tuple. This is required for Qbo Decisions to know if a particular function can be applied on a feed or not.
Enrichments¶
This model describes the enrichments that are performed on a feed, whose results may be stored in PinPoint.
Enrichments are configured in etc/model/applications/<application_name>/enrichments.json
.
It has list of enrichments, where each enrichment has:
* A name (enrichments defined on different feeds can have the same name)
A list of transformed attributes
A list of lookup attributes
A list of aggregated attributes
A list of derived attributes
There are two kinds of enrichments: Pre-aggregation are list of enrichments that are applied before aggregation takes place. Post-aggregation are list of enrichments that are applied after aggregation takes place.
This file is loaded once during Drive initialization, managed from the UI there on.
Enrichment structure is as below:
{
"preAggregationEnrichments": [
{
"name": "IMEIChangeEnrichmentPre",
"operation": {
"derivedAttributes": [
..
..
],
"aggregatedAttribute": [
..
..
],
"lookupAttribute": [
..
..
],
"transformedAttributes": [
..
..
]
}
},
{
..
}
],
"postAggregationEnrichments": [
{
"name": "IMEIChangeEnrichmentPost",
"operation": {
"derivedAttributes": [
..
..
],
"aggregatedAttribute": [
..
..
],
"lookupAttribute": [
..
..
],
"transformedAttributes": [
..
..
]
}
},
{
..
}
]
}
Transformed Attributes¶
Its an UEL expression to derive a value for a new attribute.
Example:
{
"expression": "\"FOO\"",
"name": "identity",
"retained": false,
"type": "String"
}
expression
UEL expression for to derive value.name
name of enriched attribute.retained
flag to retain this new attribute in the tuple for next operator in the flow.type
is the data type of this attribute.
Lookup Attributes¶
This is used to lookup from a profile.
Example:
{
"name": "licenseId",
"retained": false,
"tableAttribute": {
"keyAttribute": "identity",
"name": "licenseId",
"table": "CUSTOMER"
},
"type": "String"
}
tableAttribute
is to define the table and attribute to lookup.tableAttribute.keyAttribute
is key attribute in the tuple which will be used to perform lookup from table.tableAttribute.name
is the name attribute from table to be looked up.tableAttribute.table
is the table name form pinpoint to be looked up.type
is the data type of the enrichmented attribute.
Aggregated Attributes¶
This enrichment attribute gets value by fetching a aggregate from FastPast.
Example:
{
"aggregate": "sumOfTransactionAmountByCustomerAndTransactionType",
"groupByAttributes": [
"customerId",
"transactionType"
],
"name": "transactionAmountInLast7Days",
"period": "Last",
"retained": true,
"type": "Double",
"windowLength": 7,
"windowLengthUnit": "Day"
}
aggregate
is the name of aggregate in the FastPast.groupByAttributes
is a list of attributes to be used for passing for groupby attributes.name
is the name of enriched attribute.period
is the period for FastPast query. e.g. Current, Last or AllTime.windowLength
is length of window for a given unit.windowLengthUnit
is the unit for which query to be made. e.g., Day, Month, Year, Minute, Hour
Derived Attributes¶
The derived attributes enrichment enables the execution of an external Python function. One such a function takes in a tuple (as well as any other required additional parameters, if any), performs a user-defined computation, and produces a result. This function invocation’s return value can then be retained and forwarded as part of an outgoing tuple.
Example:
{
"function": {
"module": "acme.application_helpers.ericsson_usage.enrichment_helpers",
"name": "device_change"
},
"name": "deviceChanged",
"retained": true,
"type": "Bool"
},
{
"function": {
"module": "acme.application_helpers.ericsson_usage.enrichment_helpers",
"name": "device_change_time"
},
"name": "deviceChangeTime",
"retained": true,
"storeBackAttribute": {
"keyAttribute": "callingNumber",
"name": "lastIMEIModificationTime",
"table": "CUSTOMER_PROFILE"
},
"type": "Int64"
},
function
This refers to enrichment function model discussed in previous sub section.storeBackAttribute
the derived attribute can optionally stored back to profile in pinpoint.
Campaigns¶
Campaigns or Events are rules and associated actions configured on data streams to detect in realtime. This consist of selecting an audience of an event, configurating the certain transaction or activity to be performed by users and configurating the actions to be performed upon event detection. This section will explain how to preconfigure different templates for audience, triggers, offer actions and e2e campaign templates so that campaign creation by marketing user will be performed easily from UI.
below are the concepts used in the campaign or event configuration process.
Enums Type Definitions¶
Enums are custom types, used for enabling dropdowns in audience, triggers and action offers templates.
Enum types are of two types i.e., Enum and TreeEnums.
Enums are configured in file etc/model/campaigns/enum_type_definitions.json
.
Enum¶
This Enum Types are simple one item selection type Enums.
Lets take example of an enum and how its configuration looks like:
"enums": [
...
...
{
"enumName": "SubscriberCategoryType",
"placeholder": "Select subscriber category",
"possibleValues": [
{
"displayOrder": 0,
"displayValue": "Regular",
"intEnumValue": 0
},
{
"displayOrder": 1,
"displayValue": "Silver",
"intEnumValue": 1
},
{
"displayOrder": 2,
"displayValue": "Gold",
"intEnumValue": 2
}
],
"uelType": "Int32"
},
...
...
]
}
Above Enum is a configuration of Subscriber Category, there are 4 possible values for this Enum i.e., Regular, Silver and Gold. In the streaming data/Real data these different values are represented as ID field and value 0 denotes Regular, 1 denotes Silver and 2 denotes Gold. But on UI users will descriptive values like Gold, Regular.
enums
is the type of enum being configured.enumName
is not name of enum to be used in various condition templates.placeholder
is the text to be show inplace where selection is required on UI.possibleValues
are list of possible values for this enum.displayOrder
is order of this value in the dropdown.displayValue
is value to be show in the drop-down item.intEnumValue
orstringEnumValue
orbooleanEnumValue
are the actual data value being selected.uelType
is the type of values.
When we use this enum type in a template condition then UI will look like below:
TreeEnums¶
TreeEnums are hierarchical enums and allows multi select in the drop-down. Once we select from a TreeEnum a list of values are selected. If you select a leaf node of the tree then only single value will be selected, but if you select any other node except leaf node, then all leaf node under that will be selected.
lets take example of DeviceType Enum as configured below:
..
..
{
"enumName": "Devices",
"placeholder": "Select device",
"possibleValues": [
{
"children": [
{
"children": [
{
"displayOrder": 0,
"displayValue": "Samsung Galaxy S5",
"enumValue": "GALAXY_S5"
},
{
"displayOrder": 1,
"displayValue": "Samsung Galaxy S6",
"enumValue": "GALAXY_S6"
},
{
"displayOrder": 2,
"displayValue": "Samsung Galaxy S7",
"enumValue": "GALAXY_S7"
}
],
"displayOrder": 0,
"displayValue": "Samsung Galaxy",
"enumValue": "ALL_GALAXY_S"
}
],
"displayOrder": 0,
"displayValue": "Samsung",
"enumValue": "ALL_SAMSUNG"
},
{
"children": [
{
"children": [
{
"displayOrder": 0,
"displayValue": "iPhone 4",
"enumValue": "IPHONE4"
},
{
"displayOrder": 1,
"displayValue": "iPhone 5",
"enumValue": "IPHONE5"
},
{
"displayOrder": 2,
"displayValue": "iPhone 6",
"enumValue": "IPHONE6"
}
],
"displayOrder": 0,
"displayValue": "iPhone",
"enumValue": "ALL_APPLE_IPHONE"
}
],
"displayOrder": 1,
"displayValue": "Apple",
"enumValue": "ALL_APPLE"
},
{
"displayOrder": 2,
"displayValue": "Google",
"enumValue": "ALL_GOOGLE"
}
]
}
..
..
When we use this enum type in a template condition then UI will look like below:
Note
Enum type definitions are loaded in-memory every-time we restart the tomcat backend.
Audience Condition Templates¶
Audience Condition Templates are template condition for filtering the master profile of Qbo Decisions. This selects a list of users which satisfies an audience condition.
audience conditions are configured in etc/model/campaigns/audience_condition_categories.json
file.
Audience templates are grouped into named categories based on their business logics as shown below:
{
"categories": [
{
"icon": "fa-sliders",
"name": "Demographic",
"templates": [
{
...
},
{
...
}
]
},
{
"icon": "fa-user",
"name": "Transaction Based",
"templates": [
{
...
},
{
...
}
]
}
}
categories are shown below:
Once we select an audience category, all audience templetes under that audience category will shown as below:
Elements inside the templates
are differnt audience template condition, we will try learn how to configure audience
condition templates by examples.
Simple Audience Templates¶
Below is an example audience template, which filters users who have not changes device since some configurable datetime:
{
"analyticsBased": false,
"caption": "Subscribers who have not changed their device since ${deviceChangeDateTime}",
"conditionTemplateId": "deviceChangeDateTime",
"domainMapping": {
"expressionTemplate": "profile.deviceChangeTime < ${deviceChangeDateTime}"
},
"name": "Device change time",
"profile": "Customer",
"segments": [
{
"segmentId": "deviceChangeDateTime",
"segmentKind": "Complex",
"segmentType": "DateTime",
"segmentValue": {
"dateTimeValue": "2000-11-11T12:00:00"
}
}
]
},
Lets look how it looks in the UI if we select this audience template in the use case:
caption
is the caption text which will appear in the UI. It can optionally cantain one or more segmentIds inorder to make caption customizable. In this example deviceChangeDateTime is a segmentId and definition of this segmentId is done in thesegments
section. Segments are used to get inputs from users while they are configuring an audience condition.conditionTemplateId
is an unique id given to used by Qbo Decisions.domainMapping.expressionTemplate
is the UEL expression that always evalues to either true or false. A Subscriber will be part of this audience only if this UEL expression evaluates to true based on their profile attributes. In order to access a profile attribute,profile.
is suffixed in the name of attribute. In this exampleprofile.deviceChangeTime
will access deviceChangeTime attribute of master profile of any given subscriber.name
is the name of the audience condition under a given audience category.profile
should alway be master profile name.segments
the list of segment definitions used in the caption.segmentId
is id of segment used in the caption.segmentKind
is the data type of segment. This can bePrimitive
type like String, Integer, Double or Boolean. orComplex
type like Time, POIs, Geofences, Duration, DateTime, AggregationDuration, MonetaryValue. or Enum or TreeEnum.segmentValue
is the value which will be shown as default value in the UI which user can update while configuring the audience.
Audience Template With Modifiers¶
An audience template can have one or more optional additional condition along with primary domainMapping condition expression.
These are called modifiers
.
Let look at below example:
{
"analyticsBased": false,
"caption": "Subscribers whose monthly average amount in the last ${recentObservationWindowLength} months has ${increasedDecreasedIndicator} by ${changePercentage}% compared to the average recharge value in the last ${historicalObservationWindowLength} months",
"conditionTemplateId": "averageRechargeAmount",
"domainMapping": {
...
...
}
},
"modifiers": [
{
"caption": "${hasRoaming} roaming enabled",
"domainMapping": {
"expressionTemplate": "profile.roamingEnabled == ${hasRoaming}"
},
"modifierId": "roamingEnabled",
"name": "Roaming...",
"segments": [
{
"captions": [
"Does not have",
"Has"
],
"segmentId": "hasRoaming",
"segmentKind": "Enum",
"segmentType": "Boolean",
"segmentValue": {
"booleanValue": false
}
}
]
},
{
"caption": "Main balance is greater than ${mainBalanceAmount}",
"domainMapping": {
"expressionTemplate": "profile.mainBalanceAmount >= ${mainBalanceAmount}"
},
...
...
}
],
"name": "Average recharge amount",
"profile": "Customer",
"segments": [
..
]
}
In above example we have 2 additional modifiers condition along with primary domainMapping condition. If selected a modifier in the UI, modifier’s domainMapping is added as an and condition logic to primary domainMapping condition.
Lets look how the list of modifiers looks in the UI :
If we select a modifer the UI refect it by expanding the caption and allowing users to exit default segment values.
Modifier follows the same structure as explained in simple audience template, expect it has unique modifierId
insead offer
conditionTemplateId
hasRoaming is a segment of type Enum. Its Enum type is Boolean and selected segment value is false
below is an example of a condition using TreeEnum
:
{
"analyticsBased": false,
"caption": "Subscribers who have installed appllications from categories ${appCategories}",
"conditionTemplateId": "treeSelectAppCategories",
"domainMapping": {
"expressionTemplate": "profile.installedAppCategories in ${appCategories}"
},
"name": "App categories",
"profile": "Customer",
"segments": [
{
"segmentId": "appCategories",
"segmentKind": "TreeEnum",
"segmentType": "AppCategories",
"segmentValue": {
"stringListValue": {
"values": [
"BOOKS_AND_REFERENCE",
"GAME_ACTION"
]
}
}
}
]
}
TreeEnum
selection retruns are list, that is why the segmentValue is stringListValue type.
Audience template With Segment Switch¶
If we want to have different expressions to be used in a domainMapping based on the value of user selected segmentId,
then we could use segmentSwitch
in the domainMapping
example as below:
{
"analyticsBased": false,
"caption": "Subscribers who ${belong} to the ${staticSegment} static segment",
"conditionTemplateId": "staticSegment",
"domainMapping": {
"segmentSwitch": {
"cases": [
{
"expressionTemplate": "${staticSegment} not in profile.segments",
"segmentValue": "false"
},
{
"expressionTemplate": "${staticSegment} in profile.segments",
"segmentValue": "true"
}
],
"segmentId": "belong"
}
},
"name": "Static Segment",
"profile": "Customer",
"segments": [
{
"captions": [
"do not belong",
"belong"
],
"segmentId": "belong",
"segmentKind": "Enum",
"segmentType": "Boolean",
"segmentValue": {
"booleanValue": true
}
},
{
"segmentId": "staticSegment",
"segmentKind": "DynamicEnum",
"segmentType": "StaticSegment"
}
]
}
In above example we can see that we have a segmentId belong whose value will decide which expressionTemplate will be used in the domain mapping.
We can also override the display value of a Enum by addition captions in the segment definition.
DynamicEnum is a builtin enum for StaticSegment selection.
Audience template with Aggregate condition¶
Audience condition can make use of aggregates being maintain by Qbo Decisions. The condition can combine any combination of profile attribute based condition and aggregate based condition.
details of aggregates based UEL expression can be found in Miscellaneous - UEL section.
An example of aggregate based profile condition is as below:
{
"analyticsBased": false,
"caption": "Subscribers who calls back after ${callBackDuration}",
"conditionTemplateId": "callBack",
"domainMapping": {
"expressionTemplate": "aggregate(numOutgoingCallsBySubscriber[profile.MSISDN], Last, ${callBackDuration.amount}, #{callBackDuration.windowLengthUnit}) == 5"
},
"name": "Call back duration",
"profile": "Customer",
"segments": [
{
"segmentId": "callBackDuration",
"segmentKind": "Complex",
"segmentOption": {
"aggregationDurationOption": {
"durationStepSizeInMinutes": 10
}
},
"segmentType": "AggregationDuration",
"segmentValue": {
"aggregationDurationValue": {
"amount": 1,
"unit": "Months"
}
}
}
]
},
Below is the UI for the same:
The segment callBackDuration is of kind Complex, of type AggregationDuration.
callBackDuration.amount will give Window Unit Length for the aggregate query.
callBackDuration.windowLengthUnit will give aggregate window unit i.e., Month, Year, Hour, Minute, or Day.
aggregate(numOutgoingCallsBySubscriber[profile.MSISDN], Last, ${callBackDuration.amount}, #{callBackDuration.windowLengthUnit}), here numOutgoingCallsBySubscriber is name of aggregate, profile.MSISDN is group by attribute, Last is the period.
Metrics¶
To better breakdown and understand the audience of an event, charts based on different metrics can be added. These chart show histograms on various metrics and these metrices are configured in the metric_categories.json file.
Trigger templates are grouped into named categories based on their business logics as shown below:
{
"categories": [
{
"icon": "fa-phone",
"name": "Voice call metrics",
"metrics": [
{
...
},
{
...
}
]
},
{
"icon": "fa-money",
"name": "Recharge metrics",
"metrics": [
{
...
},
{
...
}
]
}
}
Elements inside the metrics
are differnt metric , we will try learn how to configure metrices by examples.
metrices categories are configured in etc/model/campaigns/metric_categories.json
file.
Profile Attributes Sourced Metric¶
The Metric charts prepared from Profile Attributes Sourced metrics gets data from profiles and histograms are produced from profile values of each subscriber.
Example Configuration:
{
"dataType": "String",
"metricId": "gender",
"minimumBucketSize": 50,
"name": "Gender",
"profileAttributeSource": {
"name": "gender"
}
}
profileAttributeSource
selects a profile attribute on which histograms needs to be produced.name
is name of metric.dataType
is data type of X-Axis.metricId
is unique name of metric.minimumBucketSize
is the minimumBucketSize of histograms.
Aggregate Sourced Metrics¶
The Metric charts prepared from Aggregate Sourced metrics gets data from aggregate and histograms are produced from aggregate values buckets of each subscriber.
Example Configuration:
{
"icon": "fa-money",
"metrics": [
{
"aggregateSource": {
"groupByAttributes": [
{
"name": "MSISDN"
}
],
"name": "topupAmountBySubscriber"
},
"dataType": "Currency",
"metricId": "topupAmount",
"minimumBucketSize": 300,
"name": "Topup Amount"
}
],
"name": "Recharge metrics"
},
aggregateSource
as this metric get data from an aggregate.aggregateSource.groupByAttributes
the group by attribute to be passed.aggregateSource.name
is the name of aggregate.
Trigger Event Categories¶
Campaign trigger profile categories is a list of categories used for defining the templates used to create trigger conditions. Each category has a name and list of templates, each template has defines a list of segments. A segment is a customizable part of the audience condition like segments in audience templates which can be used when forming the template’s caption. Each trigger template also defines a domain mapping, the domain mapping may contains a switch/case statement on the segment values, and translates the condition into a UEL expression using profile attributes and aggregates, very similar to audience selection profile categories discussed earlier The former can reference profile attributes, where the latter can reference both the profile attributes and the feed attributes aka tuple’s attributes.
Trigger templates are grouped into named categories based on their business logics as shown below:
{
"categories": [
{
"icon": "fa-user",
"name": "Usage-Based Trigger Conditions",
"templates": [
{
...
},
{
...
}
]
},
{
"icon": "fa-crosshairs",
"name": "Usage threshold Based",
"templates": [
{
...
},
{
...
}
]
}
}
categories are shown below:
Once we select an trigger category, all trigger templetes under that trigger category will shown as below:
Elements inside the templates
are differnt trigger template condition, we will try learn how to configure trigger
condition templates by examples.
trigger conditions are configured in etc/model/campaigns/trigger_event_categories.json
file.
As trigger templates are very similar to audience template, below section will only discuss about the difference between them.
Simple Trigger Templates¶
Example:
{
"analyticsBased": false,
"caption": "When the subscriber's current call duration is greater than ${callDuration}",
"conditionTemplateId": "callDuration",
"domainMapping": {
"expressionTemplate": "duration > ${callDuration}"
},
"feedsSelector": {
"byNames": [
"Ericsson Usage"
]
},
"name": "Call duration",
"segments": [
{
"segmentId": "callDuration",
"segmentKind": "Primitive",
"segmentType": "Double",
"segmentValue": {
"doubleValue": 1.0
}
}
]
},
Here
domainMapping.expressionTemplate
uses attribute duration, this is an attribute in the realtime feed Ericsson Usage.feedsSelector
select a feed on which domainMapping expression will be evaluated. Feeds can be selected bybyNames
i.e., a list of feed application names or by byModelNames i.e. a list of feed data models.
Trigger Templates With Aggregate¶
Example:
{
"analyticsBased": false,
"caption": "When the subscriber's current call duration is greater than ${averageCallDurationPercent}% to his average call duration in the last ${windowLength} hours",
"conditionTemplateId": "averageCallDuration",
"domainMapping": {
"expressionTemplate": "((duration / aggregate(avgCallDuration[MSISDN], Last, ${windowLength}, Day)) * 100 ) > ${averageCallDurationPercent}"
},
"feedsSelector": {
"byNames": [
"Ericsson Usage"
]
},
"name": "Average call duration",
"segments": [
{
"segmentId": "averageCallDurationPercent",
"segmentKind": "Primitive",
"segmentType": "Double",
"segmentValue": {
"doubleValue": 2.0
}
},
{
"segmentId": "windowLength",
"segmentKind": "Primitive",
"segmentType": "Integer",
"segmentValue": {
"integerValue": 1
}
}
]
},
Trigger Templates With Modifiers¶
Example:
{
"analyticsBased": false,
"caption": "When a voice transaction using the ${walletName} wallet takes place for a subscriber",
"conditionTemplateId": "transactionUsingAWallet",
"domainMapping": {
"expressionTemplate": "currentWalletName == ${walletName}"
},
"feedsSelector": {
"byNames": [
"Voice"
]
},
"modifiers": [
{
"caption": "and wallet is expiring within ${daysToExpire} day(s)",
"domainMapping": {
"expressionTemplate": "currentWalletDaysToExpire == ${daysToExpire}"
},
"modifierId": "daysUntilExpirationForWallet",
"name": "Days until expiration for wallet",
"segments": [
{
"segmentId": "daysToExpire",
"segmentKind": "Primitive",
"segmentType": "Integer",
"segmentValue": {
"integerValue": 2
}
}
]
}
],
"name": "Transaction using the wallet",
"segments": [
{
"segmentId": "walletName",
"segmentKind": "Primitive",
"segmentType": "String",
"segmentValue": {
"stringValue": "Data200"
}
}
]
}
Offer Action Categories¶
Offer action categories are configured to enable action based offers. These actions are of two types.
offer action categories are configured in etc/model/campaigns/offer_action_categories.json
file.
Offer Action templates are grouped into named categories based on their business logics as shown below:
{
"categories": [
{
"icon": "fa-sliders",
"name": "Recharge-Based Actions",
"templates": [
{
...
},
{
...
}
]
},
}
Action offers are shown below:
Non-Cummulative Actions¶
Non-Cummulative Actions are a single action to be performed by subscriber on a real time feed. Qbo Decisions will track this event in realtime.
Example:
{
"analyticsBased": false,
"caption": "Perform a one-time recharge greater than the target recharge amount",
"conditionTemplateId": "subscriberRechargeAmount",
"feedsSelector": {
"byNames": [
"Topup Demo"
]
},
"name": "One-time recharge",
"targetMetricSegment": {
"actionType": "NonCumulative",
"domainMapping": {
"expressionTemplate": "sellAmount"
},
"name": "Recharge Amount",
"type": "Double",
"unit": "#{currencySymbol}",
"value": {
"doubleValue": 100
}
}
},
caption
is description text to be appreared in the dowpdown list.conditionTemplateId
is a unique name for a offer action template.feedsSelector
select feeds where this action is expected.name
is the name of offer action as it will appear in the dropdown list.targetMetricSegment
contains the action definition.targetMetricSegment.actionType
is type of action, this is an example forNonCumulative
action hence only single action needed.targetMetricSegment.domainMapping
is expression for the attribute or a formula, this will be compared with configured threshold value.targetMetricSegment.name
is the of the attribute for UI.targetMetricSegment.type
is the data type of attribute value.targetMetricSegment.value
is the threshold value.
Cummulative Actions¶
This allows actions to be tracked over multiple transactions done by users, the values are accumulated and thresholds are compared with this cummulative value.
Example:
{
"analyticsBased": false,
"caption": "Perform a cumulative recharge greater than the target recharge amount",
"conditionTemplateId": "cumulativeSubscriberRechargeAmount",
"feedsSelector": {
"byNames": [
"Topup Demo"
]
},
"modifiers": [
{
"caption": "${hasRoaming} roaming enabled",
"domainMapping": {
"expressionTemplate": "profile.roamingEnabled == ${hasRoaming}"
},
"modifierId": "roamingEnabled",
"name": "Roaming...",
"segments": [
{
"captions": [
"Does not have",
"Has"
],
"segmentId": "hasRoaming",
"segmentKind": "Enum",
"segmentType": "Boolean",
"segmentValue": {
"booleanValue": false
}
}
]
}
],
"name": "Cumulative recharge",
"targetMetricSegment": {
"actionType": "Cumulative",
"domainMapping": {
"expressionTemplate": "sellAmount"
},
"name": "Recharge Amount",
"type": "Double",
"unit": "#{currencySymbol}",
"value": {
"doubleValue": 100
}
}
}
targetMetricSegment.actionType
is Cumulative.We can optionally have modifier to filter transaction that should be be accumulated.