Back to Blog

Advanced Workflow Conditions with Rhai

Engineering TeamJan 22, 202510 min read

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

JSJavaScript
// Equalityuser.plan == "premium" // Numeric comparisonsuser.age >= 18event.properties.amount > 100 // Not equaluser.status != "churned"
Ln 9

Logical Operators

JSJavaScript
// AND - both must be trueuser.plan == "premium" && user.emailVerified // OR - either can be trueuser.country == "US" || user.country == "CA" // NOT - inverts the result!user.hasUnsubscribed
Ln 8

Combining Conditions

JSJavaScript
// Complex targeting(user.plan == "premium" || user.plan == "enterprise")  && user.activeProjects > 0  && !user.hasReceivedPromo
Ln 4

Available Variables

User Object

Access any user attribute:

JSJavaScript
user.id           // User identifieruser.email        // Email addressuser.name         // Full nameuser.plan         // Current planuser.createdAt    // Signup timestampuser.lastActiveAt // Last activityuser.customField  // Any custom attribute
Ln 7

Event Object

Access the triggering event:

JSJavaScript
event.name        // Event nameevent.timestamp   // When it occurredevent.properties  // Event dataevent.properties.orderIdevent.properties.amountevent.properties.items[0].name
Ln 6

Time Variables

JSJavaScript
now               // Current timestampdayOfWeek         // 0-6 (Sunday = 0)hour              // 0-23 in user's timezone
Ln 3

Advanced Patterns

Array Operations

JSJavaScript
// Check if array contains valueevent.properties.tags.contains("vip") // Check array lengthevent.properties.items.len() >= 3 // Check if empty!user.segments.is_empty()
Ln 8

String Operations

JSJavaScript
// Contains substringuser.email.contains("@company.com") // Starts withuser.plan.starts_with("enterprise") // Ends withuser.referrer.ends_with(".edu")
Ln 8

Null Handling

JSJavaScript
// Check if value existsuser.phone != () && user.phone != "" // Default valueslet plan = user.plan ?? "free";plan == "premium"
Ln 6

Date/Time Conditions

JSJavaScript
// 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 < 86400
Ln 8

Real-World Examples

High-Value Customer Targeting

JSJavaScript
// Target power users for upselluser.plan == "pro"  && user.monthlyActiveUsers > 1000  && user.integrations.len() >= 3  && now - user.lastUpgradeAt > 7776000  // 90 days
Ln 5

Geographic + Behavioral

JSJavaScript
// US users who've viewed pricing(user.country == "US" || user.country == "CA")  && user.hasViewedPricing  && !user.hasStartedTrial
Ln 4

Event-Based Segmentation

JSJavaScript
// High-value cart from repeat customerevent.name == "cart.abandoned"  && event.properties.cartValue > 200  && user.orderCount > 0  && user.lastOrderDays < 90
Ln 5

Time-Sensitive Campaigns

JSJavaScript
// Flash sale to engaged users during work hoursuser.emailEngagementScore > 0.5  && hour >= 10 && hour <= 16  && dayOfWeek >= 1 && dayOfWeek <= 5
Ln 4

Feature Gating

JSJavaScript
// Beta feature for qualifying usersuser.plan == "enterprise"  || user.betaOptIn  || user.segments.contains("early_adopters")
Ln 4

Debugging Conditions

Test in the Dashboard

Use our condition tester:

  1. Write your condition
  2. Select a sample user
  3. See the evaluation result
  4. View variable values

Common Mistakes

Wrong: Using JavaScript syntax

JSJavaScript
// This won't workuser.plan === "premium"  // Use == not ===user.tags.includes("vip")  // Use .contains()
Ln 3

Wrong: Missing quotes

JSJavaScript
// This won't workuser.plan == premium  // "premium" needs quotes
Ln 2

Wrong: Incorrect null check

JSJavaScript
// This won't workuser.phone == null  // Use != ()
Ln 2

Performance Tips

  1. Simple conditions first: Put cheap checks before expensive ones
JSJavaScript
// Good - fails fast on plan checkuser.plan == "enterprise" && user.segments.contains("whale") // Less efficient - array check happens firstuser.segments.contains("whale") && user.plan == "enterprise"
Ln 5
  1. Avoid redundant checks: Don't check the same thing twice

  2. Use appropriate operators: == for equality, contains for 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.

Try the condition builder →

Ready to get started?

Start building automated workflows today.

Fourbyfour | Revenue workflows on autopilot