Build the rule in an editor. No SQL, nothing to release.
Every mission, streak and shop item asks the same question: does this customer qualify? You build that question yourself by picking from dropdowns, so a marketing manager can write it and no developer has to be involved.
Every line is a thing, a comparison, and a value you choose.
Every line reads the same way, such as money spent, is at least, 50. Only the first part varies: it can be a fact you hold about the customer, a running total, what they did in a period, or a detail attached to one thing they did.
Something you know about them
Country, tier, signup source. You send them, and none of it has to be personal.
A number you track, since the beginning
Lifetime spend, orders placed, lessons finished. Leave the window off and it reads since the beginning, answered from a running total instead of a scan.
What they did in a period
Count, sum, average, lowest or highest, over a window you choose.
A detail on one thing they did
It narrows the question above: how much did they spend on card.
The same editor writes mission goals, streak days and eligibility.
A rule you can write for a mission goal, you write the same way for a streak day or for who may buy an item. Write it directly on one campaign and it stays its own copy, or name it once as a segment and point several campaigns at it, so editing the segment changes every one of them.
// readable names, and your own keys exactly as you named them: // this is the tree the visual builder saves, written to be read. // The API takes the same tree under its own field names { "logicalOperator": "and", "conditions": [ { "operand": { "type": "eventAggregate", "eventKey": "purchase_amount", "function": "sum", "window": { "type": "currentCalendarPeriod", "unit": "month" }, // per-event filter, same AND/OR builder "filter": { "logicalOperator": "and", "conditions": [ { "operand": { "type": "eventProperty", "propertyKey": "payment_method" }, "operator": "equalTo", "value": { "type": "text", "text": "card" } } ] } }, "operator": "greaterThanOrEqualTo", "value": { "type": "number", "number": 500 } }, { "operand": { "type": "playerAttribute", "attributeKey": "tier" }, "operator": "in", "value": { "type": "list", "list": ["gold", "platinum"] } }, // this group could also be { "type": "segment", "segmentKey": "big-spender" }, // a reference to a segment edited on its own screen. Written inline, it nests // as deep as the mechanic needs; a segment reference nests one level only. { "logicalOperator": "or", "conditions": [ { "operand": { "type": "eventAggregate", "eventKey": "purchase_amount", "function": "sum", // no window: an unwindowed sum is the lifetime total "window": { "type": "allTime" } }, "operator": "greaterThan", "value": { "type": "number", "number": 1000 } }, { "operand": { "type": "eventAggregate", "eventKey": "visits", "function": "count", "window": { "type": "rolling", "unit": "day", "amount": 7 } }, "operator": "greaterThanOrEqualTo", "value": { "type": "number", "number": 20 } } ] } ] }
Tell us the rule you have never been able to write.
Describe it in your own words. We will build it in the editor during the call.