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 was Event 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 the attribute 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 expect towers.json in the same directory. If the type was CSV, then Qbo Decisions will expect towers.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 was Top 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 or value 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 or stringEnumValue or booleanEnumValue 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:

../_images/screen_50.png

Enum used in a template.

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:

../_images/screen_51.png

TreeEnum used in a template.

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:

../_images/screen_53.png

Audience categories.

Once we select an audience category, all audience templetes under that audience category will shown as below:

../_images/screen_54.png

List of Audience templates.

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:

../_images/screen_52.png

Simple Audience condition.

  • 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 the segments 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 example profile.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 be Primitive type like String, Integer, Double or Boolean. or Complex 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 :

../_images/screen_55.png

Modifiers list in the Audience condition.

If we select a modifer the UI refect it by expanding the caption and allowing users to exit default segment values.

../_images/screen_56.png

Modifiers selected in the Audience condition.

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:

../_images/screen_57.png

Aggregate based Audience condition.

  • 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:

../_images/screen_58.png

Trigger categories.

Once we select an trigger category, all trigger templetes under that trigger category will shown as below:

../_images/screen_59.png

List of Trigger templates.

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 by byNames 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:

../_images/screen_60.png

Offer actions.

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 for NonCumulative 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.