Condition System
The Condition System is a powerful visual builder that creates JSON condition trees for filtering and routing messages. Conditions are stored as JSON in the database and evaluated at runtime in the V8 isolate.
How Conditions Work
Architecture
┌─────────────────────────────────────────────────────────────────┐
│ Condition Lifecycle │
├─────────────────────────────────────────────────────────────────┤
│ 1. ADMIN UI: Visual Condition Builder │
│ └─ User builds conditions with drag/drop interface │
│ │
│ 2. API SUBMISSION: POST /api/workflow-entities │
│ └─ Condition tree sent as JSON in request body │
│ │
│ 3. DATABASE: PostgreSQL JSON column │
│ └─ condition: Json? in WorkflowEntity table │
│ │
│ 4. CONSUMER: V8 Evaluation │
│ └─ evaluateCondition(conditionTree, message) │
│ │
│ 5. RESULT: Boolean (true/false) │
│ └─ Determines workflow branching │
└─────────────────────────────────────────────────────────────────┘
Database Schema
The condition is stored as a JSON column in the WorkflowEntity table:
model WorkflowEntity {
id String @id @default(uuid())
organizationId String
environmentId String
name String
condition Json? // Condition tree structure
script String? @db.Text
resultStatus String?
modelId String?
tfCondition String @default("Single Path")
logicField String?
prompt String? @db.Text
// ... other fields
}
Condition Tree Structure
TypeScript Interfaces
// Individual Rule
interface ConditionRule {
type: 'rule';
field: string; // e.g., "message.payload.event.type"
comparison: string; // e.g., "equals", "contains", "greater_than"
value: any; // The value to compare against
}
// Group of Conditions
interface ConditionGroup {
type: 'group';
operator: 'AND' | 'OR';
conditions: Condition[]; // Array of rules or nested groups
}
type Condition = ConditionRule | ConditionGroup;
JSON Examples
Simple Rule:
{
"type": "rule",
"field": "message.payload.metadata.league",
"comparison": "equals",
"value": "nfl"
}
AND Group with Two Rules:
{
"type": "group",
"operator": "AND",
"conditions": [
{
"type": "rule",
"field": "message.payload.metadata.league",
"comparison": "equals",
"value": "nfl"
},
{
"type": "rule",
"field": "message.payload.event.play_type",
"comparison": "equals",
"value": "touchdown"
}
]
}
Nested Logic (AND with nested OR):
{
"type": "group",
"operator": "AND",
"conditions": [
{
"type": "rule",
"field": "message.payload.metadata.league",
"comparison": "equals",
"value": "nfl"
},
{
"type": "group",
"operator": "OR",
"conditions": [
{
"type": "rule",
"field": "message.payload.event.play_type",
"comparison": "equals",
"value": "touchdown"
},
{
"type": "rule",
"field": "message.payload.event.play_type",
"comparison": "equals",
"value": "field_goal"
}
]
},
{
"type": "rule",
"field": "message.payload.game.quarter",
"comparison": "greater_than",
"value": 2
}
]
}
Available Comparison Operators
| Operator | Label | Applicable Types | Generated JavaScript |
|---|---|---|---|
equals | Equals (==) | string, number, boolean | field === value |
not_equals | Not Equals (!=) | string, number, boolean | field !== value |
contains | Contains | string | String(field).includes(value) |
not_contains | Does Not Contain | string | !String(field).includes(value) |
greater_than | Greater Than | number | field > value |
less_than | Less Than | number | field < value |
greater_than_or_equal | Greater or Equal | number | field >= value |
less_than_or_equal | Less or Equal | number | field <= value |
starts_with | Starts With | string | String(field).startsWith(value) |
ends_with | Ends With | string | String(field).endsWith(value) |
exists | Exists | any | field !== undefined |
not_exists | Does Not Exist | any | field === undefined |
regex | Matches Regex | string | new RegExp(value).test(String(field)) |
Default Field Paths
The condition builder provides these pre-defined fields:
| Field Path | Label | Type |
|---|---|---|
message.organizationId | Organization ID | string |
message.environmentId | Environment ID | string |
message.type | Message Type | string |
message.payload.event.type | Event Type | string |
message.payload.event.play_type | Play Type | string |
message.payload.metadata.event_type | Metadata Event Type | string |
message.payload.metadata.league | League | string |
message.payload.game.quarter | Quarter | number |
message.payload.game.status | Game Status | string |
custom | Custom Path... | custom |
Select "Custom Path..." to enter any valid JavaScript path, such as:
message.user.roles[0]message.payload.data.nested.valueenv.MY_CUSTOM_VARIABLE
V8 Evaluation
At runtime, the consumer evaluates conditions using the evaluateCondition() function:
// In the V8 isolate context
const result = evaluateCondition(conditionTree, message);
// result is true or false
The evaluator recursively processes the condition tree:
- Rule: Compare
message[field]againstvalueusingcomparison - AND Group: All conditions must be true
- OR Group: At least one condition must be true
Evaluation Flow
┌─────────────────────────────────────────────────────────────┐
│ evaluateCondition(tree, message) │
├─────────────────────────────────────────────────────────────┤
│ IF tree.type === 'rule': │
│ └─ Compare message[field] with value using comparison │
│ └─ Return boolean │
│ │
│ IF tree.type === 'group': │
│ └─ IF operator === 'AND': │
│ └─ Return ALL conditions === true │
│ └─ IF operator === 'OR': │
│ └─ Return ANY condition === true │
└─────────────────────────────────────────────────────────────┘
Visual Condition Builder
The admin UI provides a visual builder for creating conditions:
Features
- Drag & Drop — Rearrange conditions and groups
- Nested Logic — Unlimited nesting of AND/OR groups
- Type-Aware — Comparisons filtered by field type
- Live Preview — See generated JavaScript in real-time
- Color-Coded — Visual hierarchy by nesting level
UI Components
| Component | Purpose |
|---|---|
| ConditionBuilder | Main container, "Add Condition" button |
| ConditionGroup | AND/OR group with nested conditions |
| ConditionRule | Single field/comparison/value rule |
| ConditionPreview | Generated JavaScript display |
Condition CRUD Operations
Conditions are created, read, updated, and deleted as part of workflow entities via the /api/workflow-entities endpoint.
API Endpoints
| Operation | Method | Endpoint | Permission Required |
|---|---|---|---|
| Create Entity with Condition | POST | /api/workflow-entities | entities:create |
| Read Entity with Condition | GET | /api/workflow-entities/{id} | entities:read |
| Update Entity Condition | PUT | /api/workflow-entities/{id} | entities:update |
| Delete Entity | DELETE | /api/workflow-entities/{id} | entities:delete |
| List Entities | GET | /api/workflow-entities | entities:read |
Create Request
To create a workflow entity with a condition, send a POST request with the condition tree in the condition field:
POST /api/workflow-entities
Content-Type: application/json
Cookie: appSession=<session_cookie>
{
"organizationId": "550e8400-e29b-41d4-a716-446655440000",
"environmentId": "660e8400-e29b-41d4-a716-446655440001",
"name": "NFL Touchdown Filter",
"workflowEntityTypeId": "<event-type-uuid>",
"condition": {
"type": "group",
"operator": "AND",
"conditions": [
{
"type": "rule",
"field": "message.payload.metadata.league",
"comparison": "equals",
"value": "nfl"
},
{
"type": "rule",
"field": "message.payload.event.play_type",
"comparison": "equals",
"value": "touchdown"
}
]
},
"tfCondition": "Single Path"
}
Response:
{
"id": "770e8400-e29b-41d4-a716-446655440002",
"organizationId": "550e8400-e29b-41d4-a716-446655440000",
"environmentId": "660e8400-e29b-41d4-a716-446655440001",
"name": "NFL Touchdown Filter",
"workflowEntityTypeId": "<event-type-uuid>",
"condition": {
"type": "group",
"operator": "AND",
"conditions": [...]
},
"tfCondition": "Single Path",
"createdAt": "2025-12-15T10:00:00.000Z",
"updatedAt": "2025-12-15T10:00:00.000Z",
"workflowEntityType": {
"id": "<event-type-uuid>",
"name": "Event",
"showConditions": true,
"showScript": true,
"showLogic": true
},
"arguments": [],
"logic": []
}
Update Request
To update an existing entity's condition:
PUT /api/workflow-entities/{id}
Content-Type: application/json
{
"condition": {
"type": "rule",
"field": "message.payload.event.play_type",
"comparison": "equals",
"value": "touchdown"
}
}
Important:
- The entire condition tree is replaced on update (not merged)
- Set
condition: nullto remove the condition entirely - The entity will always execute if no condition is defined
Clear Condition
To remove a condition and make the entity always execute:
PUT /api/workflow-entities/{id}
Content-Type: application/json
{
"condition": null
}
Read Condition
To retrieve an entity with its condition:
GET /api/workflow-entities/{id}
Response includes:
condition: The JSON condition tree (or null if none)workflowEntityType.showConditions: Whether this entity type supports conditions
List with Search
To find entities by name (useful for finding specific conditions):
GET /api/workflow-entities?organizationId={id}&environmentId={id}&search=touchdown
Condition Service (Frontend)
The frontend uses WorkflowEntityService to manage entities with conditions:
import { workflowEntityService } from '@/app/services/workflowEntityService';
// Create entity with condition
const entity = await workflowEntityService.create({
organizationId: 'org-uuid',
environmentId: 'env-uuid',
name: 'NFL Touchdown Filter',
workflowEntityTypeId: 'event-type-uuid',
condition: {
type: 'group',
operator: 'AND',
conditions: [
{ type: 'rule', field: 'message.type', comparison: 'equals', value: 'touchdown' }
]
},
tfCondition: 'Single Path'
});
// Update condition
await workflowEntityService.update(entity.id, {
condition: {
type: 'rule',
field: 'message.type',
comparison: 'equals',
value: 'field_goal'
}
});
// Clear condition
await workflowEntityService.update(entity.id, {
condition: null
});
// Get entity with condition
const retrieved = await workflowEntityService.getById(entity.id);
console.log(retrieved.condition); // The condition tree
UI Condition Builder Integration
The ConditionBuilder React component provides the visual interface for creating conditions:
Component Usage
import { ConditionBuilder } from '@/app/components/conditions/ConditionBuilder';
import { Condition } from '@/app/types/condition';
function EventEntityForm() {
const [condition, setCondition] = useState<Condition | null>(null);
return (
<ConditionBuilder
value={condition}
onChange={setCondition}
availableFields={DEFAULT_FIELDS} // Optional: custom fields
/>
);
}
ConditionBuilder Props
| Prop | Type | Description |
|---|---|---|
value | Condition | null | Current condition tree |
onChange | (condition: Condition | null) => void | Called when condition changes |
availableFields | FieldDefinition[] | Optional custom field definitions |
ConditionBuilder Behavior
- No condition: Shows "Add Condition" button
- Root group: Always creates a group as root (required structure)
- Nested rules: Rules can only exist within groups
- Live preview: Shows generated JavaScript code
- Remove button: Clears condition back to null
Real-World Example: NFL Events
Here's an actual condition for filtering NFL scoring events:
{
"type": "group",
"operator": "AND",
"conditions": [
{
"type": "rule",
"field": "message.payload.metadata.league",
"comparison": "equals",
"value": "nfl"
},
{
"type": "group",
"operator": "OR",
"conditions": [
{
"type": "rule",
"field": "message.payload.event.play_type",
"comparison": "equals",
"value": "touchdown"
},
{
"type": "rule",
"field": "message.payload.event.play_type",
"comparison": "equals",
"value": "field_goal"
},
{
"type": "rule",
"field": "message.payload.event.play_type",
"comparison": "equals",
"value": "safety"
}
]
}
]
}
Generated JavaScript:
(message.payload.metadata.league === "nfl") &&
((message.payload.event.play_type === "touchdown") ||
(message.payload.event.play_type === "field_goal") ||
(message.payload.event.play_type === "safety"))
JavaScript Code Generation
The condition system generates JavaScript code for the live preview. This code shows exactly what will be evaluated at runtime.
Code Generation Function
The generateConditionJs function converts condition trees to JavaScript:
import { generateConditionJs } from '@/app/types/condition';
const condition = {
type: 'group',
operator: 'AND',
conditions: [
{ type: 'rule', field: 'message.type', comparison: 'equals', value: 'touchdown' },
{ type: 'rule', field: 'message.score', comparison: 'greater_than', value: 6 }
]
};
const js = generateConditionJs(condition);
// Output: "((message.type === \"touchdown\") && (message.score > 6))"
Value Type Handling
The code generator intelligently handles value types:
| Input Value | Type Detection | Output |
|---|---|---|
"hello" | string | "hello" |
42 | number | 42 |
"42" | number (string) | 42 |
"true" | boolean | true |
"false" | boolean | false |
true | boolean | true |
Comparison Code Generation
| Comparison | Generated Code |
|---|---|
equals | (field === value) |
not_equals | (field !== value) |
contains | (String(field).includes(value)) |
not_contains | (!String(field).includes(value)) |
greater_than | (field > value) |
less_than | (field < value) |
greater_than_or_equal | (field >= value) |
less_than_or_equal | (field <= value) |
starts_with | (String(field).startsWith(value)) |
ends_with | (String(field).endsWith(value)) |
exists | (field !== undefined && field !== null) |
not_exists | (field === undefined || field === null) |
regex | (new RegExp(value).test(String(field))) |
Common Condition Patterns
Pattern 1: Message Type Filter
Filter by message type (most common pattern):
{
"type": "rule",
"field": "message.type",
"comparison": "equals",
"value": "user.signup"
}
Pattern 2: Event Category with Type
Filter by event category AND specific type:
{
"type": "group",
"operator": "AND",
"conditions": [
{ "type": "rule", "field": "message.payload.metadata.league", "comparison": "equals", "value": "nfl" },
{ "type": "rule", "field": "message.payload.event.play_type", "comparison": "equals", "value": "touchdown" }
]
}
Pattern 3: Multiple Alternatives (OR)
Match any of multiple values:
{
"type": "group",
"operator": "OR",
"conditions": [
{ "type": "rule", "field": "message.type", "comparison": "equals", "value": "touchdown" },
{ "type": "rule", "field": "message.type", "comparison": "equals", "value": "field_goal" },
{ "type": "rule", "field": "message.type", "comparison": "equals", "value": "safety" }
]
}
Pattern 4: Range Check
Check if a numeric value is within a range:
{
"type": "group",
"operator": "AND",
"conditions": [
{ "type": "rule", "field": "message.payload.game.quarter", "comparison": "greater_than_or_equal", "value": 3 },
{ "type": "rule", "field": "message.payload.game.quarter", "comparison": "less_than_or_equal", "value": 4 }
]
}
Pattern 5: Existence Check
Check if a field exists before evaluating:
{
"type": "group",
"operator": "AND",
"conditions": [
{ "type": "rule", "field": "message.user.premium", "comparison": "exists", "value": null },
{ "type": "rule", "field": "message.user.premium", "comparison": "equals", "value": true }
]
}
Pattern 6: Regex Pattern Matching
Match complex string patterns:
{
"type": "rule",
"field": "message.payload.description",
"comparison": "regex",
"value": "^[A-Z]\\. [A-Z][a-z]+ (scores|throws)"
}
Pattern 7: Exclude Specific Values (NOT pattern)
Match everything except specific values:
{
"type": "group",
"operator": "AND",
"conditions": [
{ "type": "rule", "field": "message.type", "comparison": "not_equals", "value": "timeout" },
{ "type": "rule", "field": "message.type", "comparison": "not_equals", "value": "commercial_break" }
]
}
Best Practices
Condition Design
- Start Simple — Begin with single rules, add complexity as needed
- Use AND for Required — All conditions must pass
- Use OR for Alternatives — Any condition can pass
- Test with Sample Data — Verify logic before deployment
Performance
- Order Matters — Put most-likely-to-fail conditions first in AND groups
- Avoid Deep Nesting — Keep nesting to 3-4 levels max
- Use Specific Fields — More specific field paths are faster
Debugging
Use print() in scripts to debug condition evaluation:
// After condition evaluation
print('Condition result:', ___result___);
print('Message type:', message.type);
print('Event play_type:', message.payload?.event?.play_type);
Error Handling
Conditions handle missing fields gracefully:
- Accessing undefined properties returns
undefined undefined === "value"evaluates tofalseexistscheck can verify a field before comparing
Condition Validation
Root Must Be Group
The condition builder enforces that the root element must be a group:
// ✅ Valid - Root is a group
{
"type": "group",
"operator": "AND",
"conditions": [
{ "type": "rule", "field": "message.type", "comparison": "equals", "value": "x" }
]
}
// ❌ Invalid - Root is a rule (builder will wrap in group)
{
"type": "rule",
"field": "message.type",
"comparison": "equals",
"value": "x"
}
Empty Conditions
Empty condition arrays always evaluate to true:
{
"type": "group",
"operator": "AND",
"conditions": []
}
// Evaluates to: true (no conditions to fail)
Null Condition
A null condition means "always execute":
{
"condition": null
}
// Entity always executes
Complete Entity Creation Examples
These examples show complete JSON payloads for creating workflow entities with various condition types via the API.
Example: Simple Event Entity with Single Rule Condition
Create an Event that triggers only for user signup messages:
{
"organizationId": "550e8400-e29b-41d4-a716-446655440000",
"environmentId": "660e8400-e29b-41d4-a716-446655440001",
"name": "User Signup Filter",
"workflowEntityTypeId": "<event-type-uuid>",
"description": "Filters for user signup events",
"tfCondition": "Single Path",
"condition": {
"type": "group",
"operator": "AND",
"conditions": [
{
"type": "rule",
"field": "message.type",
"comparison": "equals",
"value": "user.signup"
}
]
}
}
Example: Event with True/False Branching
Create an Event that branches based on premium user status:
{
"organizationId": "550e8400-e29b-41d4-a716-446655440000",
"environmentId": "660e8400-e29b-41d4-a716-446655440001",
"name": "Check Premium Status",
"workflowEntityTypeId": "<event-type-uuid>",
"description": "Routes premium and basic users differently",
"tfCondition": "True/False",
"condition": {
"type": "group",
"operator": "AND",
"conditions": [
{
"type": "rule",
"field": "message.user.subscription",
"comparison": "equals",
"value": "premium"
}
]
}
}
Example: Event with Multi-Branch Routing
Create an Event that routes based on message category:
{
"organizationId": "550e8400-e29b-41d4-a716-446655440000",
"environmentId": "660e8400-e29b-41d4-a716-446655440001",
"name": "Route by Category",
"workflowEntityTypeId": "<event-type-uuid>",
"description": "Routes messages to different handlers based on category",
"tfCondition": "Multi",
"logicField": "category",
"condition": {
"type": "group",
"operator": "AND",
"conditions": [
{
"type": "rule",
"field": "message.type",
"comparison": "equals",
"value": "content.published"
}
]
},
"script": "var category = message.payload.category || 'general';",
"logic": [
{ "name": "Sports", "value": "sports" },
{ "name": "News", "value": "news" },
{ "name": "Entertainment", "value": "entertainment" },
{ "name": "Other", "value": "*" }
]
}
Example: Event with Iterable Array Processing
Create an Event that processes each item in an array:
{
"organizationId": "550e8400-e29b-41d4-a716-446655440000",
"environmentId": "660e8400-e29b-41d4-a716-446655440001",
"name": "Process Order Items",
"workflowEntityTypeId": "<event-type-uuid>",
"description": "Processes each item in an order separately",
"tfCondition": "Iterable",
"logicField": "message.order.items",
"condition": {
"type": "group",
"operator": "AND",
"conditions": [
{
"type": "rule",
"field": "message.type",
"comparison": "equals",
"value": "order.created"
}
]
}
}
Example: Complex Nested Condition for Sports Events
Create an Event with complex AND/OR logic for NFL scoring plays:
{
"organizationId": "550e8400-e29b-41d4-a716-446655440000",
"environmentId": "660e8400-e29b-41d4-a716-446655440001",
"name": "NFL Scoring Events",
"workflowEntityTypeId": "<event-type-uuid>",
"description": "Filters for NFL touchdowns, field goals, and safeties in Q4",
"tfCondition": "Single Path",
"condition": {
"type": "group",
"operator": "AND",
"conditions": [
{
"type": "rule",
"field": "message.payload.metadata.league",
"comparison": "equals",
"value": "nfl"
},
{
"type": "group",
"operator": "OR",
"conditions": [
{
"type": "rule",
"field": "message.payload.event.play_type",
"comparison": "equals",
"value": "touchdown"
},
{
"type": "rule",
"field": "message.payload.event.play_type",
"comparison": "equals",
"value": "field_goal"
},
{
"type": "rule",
"field": "message.payload.event.play_type",
"comparison": "equals",
"value": "safety"
}
]
},
{
"type": "rule",
"field": "message.payload.game.quarter",
"comparison": "equals",
"value": 4
}
]
}
}
Example: Event with Regex and String Conditions
Create an Event that uses regex pattern matching:
{
"organizationId": "550e8400-e29b-41d4-a716-446655440000",
"environmentId": "660e8400-e29b-41d4-a716-446655440001",
"name": "Email Domain Filter",
"workflowEntityTypeId": "<event-type-uuid>",
"description": "Filters for corporate email addresses",
"tfCondition": "Single Path",
"condition": {
"type": "group",
"operator": "AND",
"conditions": [
{
"type": "rule",
"field": "message.user.email",
"comparison": "exists",
"value": null
},
{
"type": "rule",
"field": "message.user.email",
"comparison": "regex",
"value": "^[a-zA-Z0-9._%+-]+@(company\\.com|corporate\\.org)$"
},
{
"type": "rule",
"field": "message.user.email",
"comparison": "not_contains",
"value": "test"
}
]
}
}
Example: Numeric Range with Multiple Conditions
Create an Event that filters by numeric ranges:
{
"organizationId": "550e8400-e29b-41d4-a716-446655440000",
"environmentId": "660e8400-e29b-41d4-a716-446655440001",
"name": "High Value Orders",
"workflowEntityTypeId": "<event-type-uuid>",
"description": "Filters for high-value orders that need special handling",
"tfCondition": "True/False",
"condition": {
"type": "group",
"operator": "AND",
"conditions": [
{
"type": "rule",
"field": "message.type",
"comparison": "equals",
"value": "order.placed"
},
{
"type": "rule",
"field": "message.order.total",
"comparison": "greater_than_or_equal",
"value": 1000
},
{
"type": "rule",
"field": "message.order.itemCount",
"comparison": "greater_than",
"value": 5
},
{
"type": "group",
"operator": "OR",
"conditions": [
{
"type": "rule",
"field": "message.customer.tier",
"comparison": "equals",
"value": "gold"
},
{
"type": "rule",
"field": "message.customer.tier",
"comparison": "equals",
"value": "platinum"
}
]
}
]
}
}
Example: Event with Arguments and Script
Create an Event that uses arguments for configurable thresholds:
{
"organizationId": "550e8400-e29b-41d4-a716-446655440000",
"environmentId": "660e8400-e29b-41d4-a716-446655440001",
"name": "Configurable Alert Threshold",
"workflowEntityTypeId": "<event-type-uuid>",
"description": "Alerts when metrics exceed configurable thresholds",
"tfCondition": "True/False",
"condition": {
"type": "group",
"operator": "AND",
"conditions": [
{
"type": "rule",
"field": "message.type",
"comparison": "equals",
"value": "metric.report"
}
]
},
"script": "var meetsThreshold = message.payload.value > parseFloat(alertThreshold); ___result___ = meetsThreshold;",
"arguments": [
{
"argumentName": "alertThreshold",
"argumentValue": "100",
"argumentDescription": "Threshold value that triggers an alert"
}
]
}
Multi-Branch Logic Examples
Here are comprehensive examples of multi-branch logic patterns used in real workflows.
Pattern: Event Type Router
Route different event types to appropriate handlers:
{
"name": "Event Type Router",
"tfCondition": "Multi",
"logicField": "eventType",
"script": "var eventType = message.payload.event?.type || 'unknown';",
"logic": [
{ "name": "Touchdown Handler", "value": "touchdown" },
{ "name": "Field Goal Handler", "value": "field_goal" },
{ "name": "Interception Handler", "value": "interception" },
{ "name": "Fumble Handler", "value": "fumble" },
{ "name": "Default Handler", "value": "*" }
]
}
Pattern: Geographic Router
Route by geographic region:
{
"name": "Geographic Router",
"tfCondition": "Multi",
"logicField": "region",
"script": "var country = message.user.country; var region = ['US','CA','MX'].includes(country) ? 'americas' : ['GB','DE','FR','IT'].includes(country) ? 'europe' : ['JP','CN','KR','AU'].includes(country) ? 'apac' : 'other';",
"logic": [
{ "name": "Americas", "value": "americas" },
{ "name": "Europe", "value": "europe" },
{ "name": "Asia-Pacific", "value": "apac" },
{ "name": "Rest of World", "value": "other" }
]
}
Pattern: Sentiment-Based Router
Route based on computed sentiment:
{
"name": "Sentiment Router",
"tfCondition": "Multi",
"logicField": "sentiment",
"script": "var score = message.analysis?.sentimentScore || 0; var sentiment = score > 0.5 ? 'positive' : score < -0.5 ? 'negative' : 'neutral';",
"logic": [
{ "name": "Positive Response", "value": "positive" },
{ "name": "Neutral Response", "value": "neutral" },
{ "name": "Negative Response", "value": "negative" }
]
}
Pattern: Time-Based Router
Route based on time of day:
{
"name": "Time-Based Router",
"tfCondition": "Multi",
"logicField": "timeSlot",
"script": "var hour = new Date().getHours(); var timeSlot = hour >= 9 && hour < 17 ? 'business' : hour >= 17 && hour < 22 ? 'evening' : 'overnight';",
"logic": [
{ "name": "Business Hours", "value": "business" },
{ "name": "Evening Hours", "value": "evening" },
{ "name": "Overnight", "value": "overnight" }
]
}
Related Topics
- Event Entity — Uses conditions for filtering
- evaluateCondition Script — Runtime evaluation function
- Entity Evaluators — V8 execution details
- Entity API Submission — Full API reference