OpenRP Docs
Behavior Engine

Expressions

Use expressions and template strings to wire dynamic data between nodes.

Most node configuration fields let you enter a value directly. However, you can toggle any field into expression mode by clicking the {} button next to it. In expression mode, the field accepts a dynamic value — typically the output of a previous node — instead of a hard-coded constant.

Note

Some fields, like IDs, only accept expressions and don't have a constant mode. These fields won't show the {} toggle — they are already in expression mode.

Expressions

An Expression is a small piece of code that gets evaluated when the node runs.

Constants

Expressions support standard JavaScript-like literals:

TypeExamples
Number42, 3.14, -1
String'hello', "world"
Booleantrue, false
Array[1, 2, 3], ['a', 'b']
Object{ key: 'value', count: 1 }

Referencing previous nodes

The most common use of expressions is reading the output of an earlier node. Reference a node by its Node ID and access its output fields with dot notation:

getChatMessage.content;

This reads the content field from the output of the node with ID getChatMessage. You can chain property access as deep as needed:

getChat.participants.data;

Use bracket notation for array indexing:

getChat.participants.data[0];

Or keys with special characters:

$variables["my variable"];

Operators

Expressions support common operators for math, comparison, and logic:

CategoryOperators
Arithmetic+, -, *, /, %
Comparison==, ===, !=, !==, >, <, >=, <=
Logical&&, ||, !
Ternarycondition ? valueIfTrue : valueIfFalse

The + operator also concatenates strings:

"Hello, " + getChatMessage.participant.name;

Examples

Use a node output directly:

getChatMessage.content;

Arithmetic with a variable:

$variables.processedCount + 1;

Comparison — useful in an If node:

getChatMessage.content === "hello";

Ternary expression:

getChat.participants.totalCount > 2 ? "group" : "direct";

Build an object:

{ text: getChatMessage.content, chatId: myEvent.chatId }

Boolean logic combining two conditions:

$variables.attempts < 3 && !$variables.done;

Template Strings

A Template String is a text field that supports rendering expressions within it. This is done by wrapping expressions in {{ }}. Use this when you want to embed dynamic values inside longer text, like a prompt or a message.

User: {{getChatMessage.content}}

Any valid expression can go inside the braces:

{{getChatMessage.senderName}} said: {{getChatMessage.content}}

Note

If the expression evaluates to null or undefined, the placeholder is replaced with an empty string. If it evaluates to an object or array, it is converted to a JSON string.

Examples

Simple interpolation:

Hello, {{getChatMessage.participant.name}}!

Using a variable:

Attempt {{$variables.attempts}} of 3

Arithmetic operation inside a template:

{{getChat.participants.totalCount - 1}} other participants

Multiple placeholders:

[{{myEvent.chatId}}] {{getChatMessage.content}}

Built-in objects

The following objects and special variables are always available in expressions and template strings.

$variables

An object containing all variables set during the current execution.

$requestMetadata

An object containing metadata about the user and request that triggered the behavior execution:

PropertyTypeDescriptionExample
$requestMetadata.userIdstringThe unique ID of the user who initiated the execution."01a008e5-0f95-7aab-aaeb-a6d2b5c57f18"
$requestMetadata.timeZonestringThe user's IANA time zone identifier (used automatically by Date.format())."America/New_York", "Asia/Tokyo", "UTC"
$requestMetadata.localestringThe user's preferred language and regional locale tag."en-US", "ja-JP", "de-DE"

Example

User {{$requestMetadata.userId}} triggered workflow from {{$requestMetadata.timeZone}}

Math

Expressions have access to the standard JavaScript Math built-in object. All standard static methods and mathematical constants are supported:

MemberDescriptionExample
Math.random()Returns a pseudo-random floating-point number between 0 (inclusive) and 1 (exclusive).Math.random()
Math.floor(x)Returns the largest integer less than or equal to x.Math.floor(4.9) (returns 4)
Math.ceil(x)Returns the smallest integer greater than or equal to x.Math.ceil(4.1) (returns 5)
Math.round(x)Returns the value of x rounded to the nearest integer.Math.round(4.5) (returns 5)
Math.min(...v)Returns the lowest-valued number passed into it.Math.min(10, 20, 5) (returns 5)
Math.max(...v)Returns the highest-valued number passed into it.Math.max(10, 20, 5) (returns 20)
Math.abs(x)Returns the absolute value of x.Math.abs(-42) (returns 42)
Math.pow(x, y)Returns base x to the exponent power y ($x^y$).Math.pow(2, 3) (returns 8)
Math.PIRatio of the circumference of a circle to its diameter (~3.14159).Math.PI
Math.EEuler's constant and the base of natural logarithms (~2.718).Math.E

For a complete reference of all standard trigonometric, logarithmic, and rounding functions, see the official MDN Math documentation.

Date

OpenRP provides a secure, lightweight Date utility namespace in expressions and template strings. It allows you to obtain current timestamps, parse date strings, and format dates with automatic user timezone adjustment.

Date.now()

Returns the numeric timestamp in milliseconds corresponding to the current time in UTC epoch.

Date.parse(dateString)

Parses a date string (such as an ISO 8601 string from a node output) and returns the number of milliseconds since January 1, 1970, 00:00:00 UTC.

  • Signature: Date.parse(dateString: string): number
  • Reference: MDN Date.parse() Documentation
  • Example:
    Date.parse("2026-08-15T12:00:00Z"); // returns 1786795200000
    Date.parse(getChatMessage.createdAt);

Date.format(formatString?, timestamp?)

Formats a date and time string adjusted for the current user's timezone ($requestMetadata.timeZone).

  • Signature: Date.format(formatString?: string, timestamp?: number): string
  • Parameters:
    • formatString (optional, string): A formatting template composed of tokens (e.g. 'yyyy-MM-dd', 'h:mm a', 'HH:mm'). Defaults to 'yyyy-MM-dd HH:mm:ss' if omitted.
      • Supported tokens follow the date-fns format specification:
        • yyyy: 4-digit year (e.g. 2026)
        • MM: 2-digit month (01-12)
        • MMMM: Full month name (e.g. August)
        • dd: 2-digit day of the month (01-31)
        • HH: 24-hour hour (00-23)
        • h: 12-hour hour (1-12)
        • mm: 2-digit minute (00-59)
        • ss: 2-digit second (00-59)
        • a: AM/PM marker (e.g. AM, PM)
        • EEEE: Full day of the week (e.g. Saturday)
    • timestamp (optional, number): A Unix epoch timestamp in milliseconds (such as returned by Date.now() or Date.parse(...)). If omitted, it defaults to the current time (Date.now()).
Examples

Format the current time in the user's timezone:

Current Time: {{Date.format("h:mm a")}}

(Output: Current Time: 2:30 PM)

Format current date with full date and time:

Date.format(); // "2026-08-15 14:30:00"
Date.format("MMMM d, yyyy"); // "August 15, 2026"

Format a date timestamp received from an earlier node:

Message sent on {{Date.format("yyyy-MM-dd", Date.parse(getChatMessage.createdAt))}}

Format a timestamp with custom format tokens:

Date.format("yyyy-MM-dd'T'HH:mm:ss", 1786795200000);

On this page