Advanced Workflow Conditions with Rhai
Workflows become powerful when you can precisely control who enters them and how they branch. Learn to write conditions that target exactly the right users.
What is Rhai?
Rhai is a lightweight scripting language we use for workflow conditions. It's designed to be:
- Safe: No file system access, no network calls
- Fast: Evaluates in microseconds
- Expressive: Rich operators for complex logic
Basic Syntax
Conditions return a boolean - true to proceed, false to skip.
Simple Comparisons
// Equalityuser.plan == "premium" // Numeric comparisonsuser.age >= 18event.properties.amount > 100 // Not equaluser.status != "churned"Logical Operators
// AND - both must be trueuser.plan == "premium" && user.emailVerified // OR - either can be trueuser.country == "US" || user.country == "CA" // NOT - inverts the result!user.hasUnsubscribedCombining Conditions
// Complex targeting(user.plan == "premium" || user.plan == "enterprise") && user.activeProjects > 0 && !user.hasReceivedPromoAvailable Variables
User Object
Access any user attribute:
user.id // User identifieruser.email // Email addressuser.name // Full nameuser.plan // Current planuser.createdAt // Signup timestampuser.lastActiveAt // Last activityuser.customField // Any custom attributeEvent Object
Access the triggering event:
event.name // Event nameevent.timestamp // When it occurredevent.properties // Event dataevent.properties.orderIdevent.properties.amountevent.properties.items[0].nameTime Variables
now // Current timestampdayOfWeek // 0-6 (Sunday = 0)hour // 0-23 in user's timezoneAdvanced Patterns
Array Operations
// Check if array contains valueevent.properties.tags.contains("vip") // Check array lengthevent.properties.items.len() >= 3 // Check if empty!user.segments.is_empty()String Operations
// Contains substringuser.email.contains("@company.com") // Starts withuser.plan.starts_with("enterprise") // Ends withuser.referrer.ends_with(".edu")Null Handling
// Check if value existsuser.phone != () && user.phone != "" // Default valueslet plan = user.plan ?? "free";plan == "premium"Date/Time Conditions
// User signed up more than 7 days agonow - user.createdAt > 604800 // Only during business hourshour >= 9 && hour < 17 && dayOfWeek >= 1 && dayOfWeek <= 5 // Within 24 hours of eventnow - event.timestamp < 86400Real-World Examples
High-Value Customer Targeting
// Target power users for upselluser.plan == "pro" && user.monthlyActiveUsers > 1000 && user.integrations.len() >= 3 && now - user.lastUpgradeAt > 7776000 // 90 daysGeographic + Behavioral
// US users who've viewed pricing(user.country == "US" || user.country == "CA") && user.hasViewedPricing && !user.hasStartedTrialEvent-Based Segmentation
// High-value cart from repeat customerevent.name == "cart.abandoned" && event.properties.cartValue > 200 && user.orderCount > 0 && user.lastOrderDays < 90Time-Sensitive Campaigns
// Flash sale to engaged users during work hoursuser.emailEngagementScore > 0.5 && hour >= 10 && hour <= 16 && dayOfWeek >= 1 && dayOfWeek <= 5Feature Gating
// Beta feature for qualifying usersuser.plan == "enterprise" || user.betaOptIn || user.segments.contains("early_adopters")Debugging Conditions
Test in the Dashboard
Use our condition tester:
- Write your condition
- Select a sample user
- See the evaluation result
- View variable values
Common Mistakes
Wrong: Using JavaScript syntax
// This won't workuser.plan === "premium" // Use == not ===user.tags.includes("vip") // Use .contains()Wrong: Missing quotes
// This won't workuser.plan == premium // "premium" needs quotesWrong: Incorrect null check
// This won't workuser.phone == null // Use != ()Performance Tips
- Simple conditions first: Put cheap checks before expensive ones
// Good - fails fast on plan checkuser.plan == "enterprise" && user.segments.contains("whale") // Less efficient - array check happens firstuser.segments.contains("whale") && user.plan == "enterprise"-
Avoid redundant checks: Don't check the same thing twice
-
Use appropriate operators:
==for equality,containsfor arrays
Summary
Conditions let you target exactly the right users at the right time. Start simple and add complexity as needed. When in doubt, use the dashboard tester to verify your logic.