Rules Engine technical details
Key definitions
-
A condition is a boolean equation that evaluates to
trueorfalse. -
A consequence is the action to be performed when the trigger is met and the condition(s) evaluates to
true. -
A rule is a set of conditions and the associated consequence(s).
-
A triggering event is the event that started the rule evaluation.
The Adobe Experience Platform Mobile SDK evaluates each tag rule for the current event that is processed by the Event Hub.
-
Rules Engine is the system that processes the mobile tag rules and initiates the associated actions when the conditions are met.
-
An asset is an opaque data blob that is needed by a specific consequence.
Rules delivery
Rules delivery occurs by using a network request from the Experience Platform SDKs to a static endpoint that is defined as part of the SDK configuration. The rules file for each mobile property is hosted on https://assets.adobedtm.com.
This request is a conditional GET and occurs by default at the start of each new application session. When the set of tag rules that were configured for a mobile property change, these changes will be picked up by the Experience Platform SDK in the next session or after the application is restarted.
File format
Rules are delivered as a standard ZIP archive, which contains a rules.json file. This file consists of a root-level JSON object that contains the following elements:
versionrules.json file format. Should be an integer that increments by 1 for each format change, and the initial version is 1.rulesRule object definition
conditionconsequencestrue. For more information, please read the consequence object definition.metaCondition object definition
Each Condition has a condition type and a definition, and the contents of a condition's definition depends on its condition type.
A Group condition contains an array of conditions, which makes the conditions infinitely nestable.
Condition object
type"type":"group"definition"definition": { "logic" : "and", "conditions" : [...] }Condition types
groupmatcherhistoricalDefinition object
Group condition type
logic"logic":"and"conditions"conditions":[...]Matcher condition type
data-variant=info
data-slots=text
keystring"key":"key1"matcherstring"matcher":"eq"valuesarray"values":["value0", "value1"]"key" key.Historical condition type
eventsfromtosearchTypeevents array are interpreted. The result produced by this search becomes the left-hand operand for the matcher. Accepted values are described in the table below. If omitted, the engine uses any.matchervalueSearch Types
anyordered0 or 1events array, with the timestamp of the first matched occurrence of the event at the previous index used as the from bound when searching for the current event. Returns 1 if all appear in order,0 if they do not appear in the specified order, and -1 if an error occurred during the lookup of any event. For a single event object, the result is 1 if at least one matching event is found and 0 otherwise.mostRecentevents array, or -1 if none of the events are found or an error occured during the lookup of any event. Example: for [A, B, C], if B is most recent the result is 1.Logic types
andtrue, all of its conditions must be true.ortrue, only one of its conditions must be true.Matcher types
eqneexnxgtgeltleconcswewMatching and retrieving values by keys
By default, keys and the associated values are sourced from the current event that is being processed by the Rules Engine. There are also some special key prefixes that can cause the values to be sourced from other locations that are known to the Experience Platform SDKs.
To avoid collisions, special key prefixes always start with a ~ (tilde) to differentiate them from the standard event key names.
~state.~state.sharedStateName/keyNamekeyName from the shared state of the module that is stored in sharedStateName.~type~typeeventType from the triggering event.~source~sourceeventSource from the triggering event.~timestampu~timestampu~timestampz~timestampz~sdkver~sdkver~cachebust~cachebust~all_url~all_urlurl format.~all_json~all_jsonjson format.Simple conditions
Conditions example 1 represents the following logical condition:
(key1 == value1)
Here is the example:
"conditions": [
{
"type": "matcher",
"definition": {
"key": "key1",
"matcher": "eq",
"values": ["value1"]
}
}
]
Conditions example 2 is slightly more complex and represents the following logical condition:
(key1 == value1 || key1 == value2) || (key2 != value3 && key2 != value4)
Here is the example:
{
"type": "group",
"definition": {
"logic": "or",
"conditions": [
{
"type": "matcher",
"definition": {
"key": "key1",
"matcher": "eq",
"values": ["value1", "value2"]
}
},
{
"type": "group",
"definition": {
"logic": "and",
"conditions": [
{
"type" : "matcher",
"definition" : {
"key" : "key2",
"matcher" : "ne",
"values" : ["value3"]
}
},
{
"type" : "matcher",
"definition" : {
"key" : "key2",
"matcher" : "ne",
"values" : ["value4"]
}
}
]
}
}
]
}
}
Event data processing
When an event is evaluated against rules, its data is normalized into a single level key-value map so that conditions can reference values using predictable key paths. This normalization is called flattening.
Nested objects and arrays are flattened, and the key path format uses dot-separated segments that form the path from the root to each leaf value. Leaf values are kept as-is.
Key collisions and special characters
If two different inputs produce the same flattened key, the last value written wins. The resolution order for collisions is undefined and may change; do not rely on it.
Keys are not escaped during flattening. If original object keys contain dots, those dots become part of the flattened key path. Create rule keys with this in mind and prefer unambiguous event data structures to avoid collisions.
With this model, conditions can reference any value in the event using a single, dot separated key.
Event data key flattening
- Object key-value pairs use their key name as the path segment.
Original event data:
{ "user": { "address": { "city": "San José" } } }
Flattened event data:
{ "user.address.city": "San José" }
Special case: dots in keys are not escaped
Original event data:
{ "user.address": { "city": "San José" } }
Flattened event data:
{ "user.address.city": "San José" }
Special case: different inputs produce the same flattened key (last write wins, order undefined)
Original event data:
{ "user": { "address": { "city": "nested" } }, "user.address.city": "flat" }
Flattened event data:
{ "user.address.city": "flat" }
or
{ "user.address.city": "nested" }
Array flattening
- Array items use their zero-based numeric index as the path segment.
Original event data:
{ "items": [1, 2] }
Flattened event data:
{ "items.0": 1, "items.1": 2 }
Original event data:
{ "list": [ { "name": "a" }, { "name": "b" } ] }
Flattened event data:
{ "list.0.name": "a", "list.1.name": "b" }
Original event data:
{ "matrix": [[10, 20], [30]] }
Flattened event data:
{ "matrix.0.0": 10, "matrix.0.1": 20, "matrix.1.0": 30 }
Consequence object definition
The consequences section of a rule lists the file names of each consequence object that should be performed when all of the conditions for that rule evaluate to true.
idsha1, or another guaranteed random value with a near-impossible chance of collisions, is recommended.detailConsequence types
urlcspaddschemarules.json examples
Example 1 is a set of rules that will only run when the event was as a result of an Analytics hit or a GPS location event.
The conditions array is set up with the following logic:
((key1 == value1 || key1 == value2) || (key2 != value3 && key2 != value4)) && (key3 == value5 || key3 == value6)
If the conditions pass, an in-app message triggered:
{
"version" : 1,
"rules" : [
{
"condition" : {
"type" : "group",
"definition" : {
"logic" : "and",
"conditions" : [
{
"type" : "group",
"definition" : {
"logic" : "or",
"conditions" : [
{
"type" : "matcher",
"definition" : {
"key" : "key1",
"matcher" : "eq",
"values" : ["value1", "value2"]
}
},
{
"type" : "group",
"definition" : {
"logic" : "and",
"conditions" : [
{
"type" : "matcher",
"definition" : {
"key" : "key2",
"matcher" : "ne",
"values" : ["value3"]
}
},
{
"type" : "matcher",
"definition" : {
"key" : "key2",
"matcher" : "ne",
"values" : ["value4"]
}
}
]
}
}
]
}
},
{
"type" : "matcher",
"definition" : {
"key" : "key3",
"matcher" : "eq",
"values" : ["value5", "value6"]
}
},
{
"type" : "matcher",
"definition" : {
"key" : "~type",
"matcher" : "eq",
"values" : ["com.adobe.eventType.location", "com.adobe.eventType.analytics"]
}
}
]
}
},
"consequences" : [
{
"id" : "48181acd22b3edaebc8a447868a7df7ce629920a",
"type" : "iam",
"detail" : {
"template" : "fullscreen",
"html" : "48181acd22b3edaebc8a447868a7df7ce629920a.html"
}
}
]
}
]
}
Example 2 uses the client-side profile to implement a show once style of in-app message. The conditions array is set up with the following logic:
((key3 == value5 || key3 == value6) && (~state.com.adobe.module.userProfile/userprofiledata.48181acd22b3edaebc8a447868a7df7ce629920a-seen does not exist))
If the conditions pass, the in-app message is displayed (first consequence), and future displays of the message are prevented by writing/incrementing value to the client-side profile:(~state.com.adobe.module.userProfile/userprofiledata.48181acd22b3edaebc8a447868a7df7ce629920a-seen) (Second consequence) prevents the conditions from evaluating to true for future evaluations.
data-variant=info
data-slots=text
{
"version": 1,
"rules": [
{
"condition": {
"type": "group",
"definition": {
"logic": "and",
"conditions": [
{
"type": "matcher",
"definition": {
"key": "key3",
"matcher": "eq",
"values": ["value5", "value6"]
}
},
{
"type": "matcher",
"definition": {
"key" : "~state.com.adobe.module.userProfile/userprofiledata.48181acd22b3edaebc8a447868a7df7ce629920a-seen",
"matcher" : "nx"
}
}
]
}
},
"consequences": [
{
"id" : "48181acd22b3edaebc8a447868a7df7ce629920a",
"type" : "iam",
"detail" : {
"template" : "fullscreen",
"html" : "48181acd22b3edaebc8a447868a7df7ce629920a.html"
}
},
{
"id" : "9d40f5665d5bdbe96dcb3a24f4e4fe98d686a602",
"type" : "csp",
"detail" : {
"operation": "write",
"key" : "48181acd22b3edaebc8a447868a7df7ce629920a-seen",
"value" : "yes"
}
}
]
}
]
}
Rules URL
The Rules Engine requires an endpoint URL to be configured in the configuration, which specifies the location from where rules should be fetched:
{
"rules.url": "https://assets.adobedtm.com/example.zip"
}
The Adobe Experience Platform SDKs process the URL that points to a zipped rules collection, and this collection contains a rules.json file. After the rules are downloaded and extracted, the contents of this compressed file are stored in the cache.
Configuration keys
rules.url