Expressions
Expressions are GripoFlow’s built-in feature for creating dynamic values within your workflows. Instead of using fixed values, you can reference workflow data, perform calculations, transform text, and evaluate conditions at runtime. Every time a workflow runs, GripoFlow evaluates each expression using the latest available data. This enables your workflows to adapt automatically to changing inputs and outputs without requiring additional workflow nodes.
Why Use Expressions?
Expressions help you build smarter and more flexible workflows by allowing you to:
- Access data from previous workflow nodes.
- Use incoming data from the inbound-webhook payload/query/header.
- Perform Array manipulation.
- Accessing Connection Secretes in secure way.
- Format and manipulate text.
- Compare values and create conditions.
- Work with arrays and dates.
The following table provides an overview of the supported expression categories. Click any category to jump directly to its explanation.
| Category | Examples |
|---|---|
| Variables | A1.outcome • A1.outcome.name • flow.input • workflow.id |
| Literals | 42 • 3.14 • "Hello" • 'World' • true • false • nil |
| Operators | + • - • * • / • % • == • != • > • < • >= • <= • && • ` |
| String Functions | upper() • lower() • trim() • split() • replace() |
| Array Functions | len() • first() • last() • append() • contains() |
| Map Functions | keys() • values() • get() • hasKey() |
| Predicate Functions | all() • any() • filter() • map() |
| Date Functions | now() • date() • formatDate() • parseDate() • addDays() • addMonths() • addYears() |
| Number Functions | abs() • ceil() • floor() • round() • min() • max() • sum() • avg() • random() |
| Bitwise Functions | bitAnd() • bitOr() • bitXor() • bitNot() • leftShift() • rightShift() |
| Type Conversion Functions | string() • number() • boolean() • list() • map() • date() |
| Miscellaneous Functions | coalesce() • typeof() • uuid() • ifNull() • isNull() • isEmpty() |
Variables
Variables let you build dynamic workflows by accessing data from anywhere in your workflow. Use them to reference the output of previous nodes, create workflow variables that can be shared across every node, access incomming inbound-webhook payloads, headers, and query parameters, and securely use connection credentials without exposing sensitive information. This makes it easy to create flexible, reusable, and data-driven workflows that automatically adapt to the information flowing through them
Activity Data
Every workflow activity exposes the result of its execution through the output property.
If an activity ID is A1, you can access its complete output using:
activity.A1.outputAccess a specific property:
activity.A1.output.nameactivity.A1.output.emailactivity.A1.output.statusExample:
activity.A1.output.customer.address.cityLoop Data
Inside a Loop activity, the current item being processed is available through the item property.
If the loop activity ID is A1, you can access the current loop item using:
activity.A1.itemAccess a specific property:
activity.A1.item.nameactivity.A1.item.emailactivity.A1.item.idExample:
activity.A1.item.customer.address.cityWorkflow Variables
Workflow variables contain values that are provided as workflow inputs. These variables are available throughout the workflow and are commonly used for configuration values and user-provided data.
Access a workflow variable using:
input.repoNameAccess another workflow variable:
input.environmentinput.regionExample:
input.repository.ownerConnection Variables
Connection variables provide access to the credentials and configuration of a configured connection. These values are automatically available to your workflow and can be referenced whenever authentication or connection details are required.
Access a configured connection:
flow.connection.azure.gripoAzureAccess a specific property:
flow.connection.azure.gripoAzure.accessTokenflow.connection.azure.gripoAzure.subscriptionIdflow.connection.azure.gripoAzure.tenantIdExample:
flow.connection.azure.gripoAzure.clientIdTrigger Variables
Trigger variables provide information about the event that started the workflow. Depending on the trigger type, you can access the request payload, headers, and query parameters.
Access the request payload:
flow.trigger.payloadAccess request headers:
flow.trigger.headerAccess query parameters:
flow.trigger.queryAccess a specific value:
flow.trigger.payload.nameflow.trigger.header.authorizationflow.trigger.query.idExample:
flow.trigger.payload.customer.emailLiterals
Literals are fixed values written directly in an expression. They represent values such as numbers, strings, booleans, arrays, maps, bytes, and nil.
| Type | Examples |
|---|---|
| Comment | // Comment • /* Comment */ |
| Boolean | true • false |
| Integer | 42 • 0x2A • 0o52 • 0b101010 |
| Float | 0.5 • .5 |
| String | "Hello" • 'World' |
| Array | [1, 2, 3] |
| Map | {a: 1, b: 2, c: 3} |
| Nil | nil |
| Bytes | b"hello" • b'\xff\x00' |
Comments
Comments are ignored during expression evaluation.
Single-line comment:
// This is a commentMulti-line comment:
/*
This is a
multi-line comment.
*/Boolean
Boolean values represent logical conditions.
truefalseInteger
Integers are whole numbers.
420x2A0o520b101010Float
Floating-point values represent decimal numbers.
0.5.53.14String
Strings can be enclosed in either single or double quotes.
"Hello World"'Hello World'Strings support escape sequences.
"Hello\nWorld""Column1\tColumn2""\u0041"Multiline Strings
Use backticks for multiline strings.
`Hello
World`Operators
Operators allow you to perform calculations, compare values, evaluate conditions, access data, manipulate strings, and build dynamic expressions.
| Operator Type | Operators |
|---|---|
| Arithmetic | + • - • * • / • % • ^ • ** |
| Comparison | == • != • < • > • <= • >= |
| Logical | ! • not • && • and • ` |
| Conditional | ?: • ?? • if else |
| Membership | . • [] • ?. • in |
| String | + • contains • startsWith • endsWith |
| Regex | matches |
| Range | .. |
| Slice | [:] |
| Pipe | ` |
Arithmetic Operators
Arithmetic operators perform mathematical calculations.
| Operator | Description |
|---|---|
+ | Addition |
- | Subtraction |
* | Multiplication |
/ | Division |
% | Modulus (remainder) |
^ or ** | Exponent |
Examples:
5 + 210 - 46 * 320 / 510 % 32 ** 3Comparison Operators
Comparison operators compare two values and return true or false.
| Operator | Description |
|---|---|
== | Equal |
!= | Not equal |
> | Greater than |
< | Less than |
>= | Greater than or equal |
<= | Less than or equal |
Examples:
10 == 10age >= 18count != 0Logical Operators
Logical operators combine or negate boolean expressions.
| Operator | Description |
|---|---|
! or not | NOT |
&& or and | AND |
| ` |
Examples:
age >= 18 && verified!isEmptyactive || adminConditional Operators
Conditional operators allow expressions to return different values based on conditions.
Ternary Operator
age >= 18 ? "Adult" : "Minor"Nil Coalescing
The ?? operator returns the left value if it is not nil; otherwise it returns the right value.
author.User?.Name ?? "Anonymous"Equivalent to:
author.User != nil ? author.User.Name : "Anonymous"If Else
Multiline conditions can be written using if else.
if score >= 50 {
"Pass"
} else {
"Fail"
}Membership Operators
Membership operators access properties, array elements, and determine whether a value exists.
Access Object Properties
Both expressions are equivalent.
user.Nameuser["Name"]Access Array Elements
array[0]array[-1]-1 represents the last element.
Check Membership
Use the in operator to determine whether a value exists.
"John" in ["John", "Jane"]"name" in {
name: "John",
age: 30
}Optional Chaining
The ?. operator safely accesses nested properties.
author.User?.NameEquivalent to:
author.User != nil ? author.User.Name : nilString Operators
String operators manipulate text values.
Concatenation
"Hello " + "World"Contains
contains(name, "John")Starts With
startsWith(email, "admin")Ends With
endsWith(fileName, ".pdf")Regex Operator
Use matches to compare a string against a regular expression.
email matches "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"Range Operator
The .. operator creates a range of integers.
1..3Result:
[1, 2, 3]Another example:
5..10Slice Operator
The slice operator [:] returns a portion of an array.
Given:
array = [1, 2, 3, 4, 5]Examples:
array[1:4]Result:
[2, 3, 4]array[1:-1]Result:
[2, 3, 4]array[:3]Result:
[1, 2, 3]array[3:]Result:
[4, 5]array[:]Result:
[1, 2, 3, 4, 5]Pipe Operator
The pipe operator (|) passes the result of the left expression as the first argument of the function on the right.
user.Name | lower() | split(" ")Equivalent to:
split(lower(user.Name), " ")The pipe operator makes expressions easier to read by chaining multiple operations together.
String Functions
String functions allow you to manipulate and transform text values within expressions. They can be used to remove characters, change letter case, split text, replace content, repeat strings, and search for specific values.
| Function | Description |
|---|---|
trim() | Removes whitespace or specified characters from both ends of a string. |
trimPrefix() | Removes a prefix from a string. |
trimSuffix() | Removes a suffix from a string. |
upper() | Converts a string to uppercase. |
lower() | Converts a string to lowercase. |
split() | Splits a string into an array. |
splitAfter() | Splits a string after the delimiter. |
replace() | Replaces occurrences of a substring. |
repeat() | Repeats a string multiple times. |
indexOf() | Returns the index of the first occurrence of a substring. |
lastIndexOf() | Returns the index of the last occurrence of a substring. |
hasPrefix() | Checks whether a string starts with a prefix. |
hasSuffix() | Checks whether a string ends with a suffix. |
trim()
Removes whitespace from both ends of a string. You can also specify characters to remove.
Syntax
trim(str[, chars])Examples:
trim(" Hello ")Returns:
"Hello"trim("__Hello__", "_")Returns:
"Hello"trimPrefix()
Removes the specified prefix if the string starts with it.
Syntax
trimPrefix(str, prefix)Example:
trimPrefix("HelloWorld", "Hello")Returns:
"World"trimSuffix()
Removes the specified suffix if the string ends with it.
Syntax
trimSuffix(str, suffix)Example:
trimSuffix("HelloWorld", "World")Returns:
"Hello"upper()
Converts all characters in a string to uppercase.
Syntax
upper(str)Example:
upper("hello")Returns:
"HELLO"lower()
Converts all characters in a string to lowercase.
Syntax
lower(str)Example:
lower("HELLO")Returns:
"hello"split()
Splits a string into an array using the specified delimiter.
Syntax
split(str, delimiter[, n])Examples:
split("apple,orange,grape", ",")Returns:
["apple", "orange", "grape"]split("apple,orange,grape", ",", 2)Returns:
["apple", "orange,grape"]splitAfter()
Splits a string after each occurrence of the delimiter.
Syntax
splitAfter(str, delimiter[, n])Examples:
splitAfter("apple,orange,grape", ",")Returns:
["apple,", "orange,", "grape"]splitAfter("apple,orange,grape", ",", 2)Returns:
["apple,", "orange,grape"]replace()
Replaces every occurrence of a substring with another string.
Syntax
replace(str, old, new)Example:
replace("Hello World", "World", "Universe")Returns:
"Hello Universe"repeat()
Repeats a string the specified number of times.
Syntax
repeat(str, n)Example:
repeat("Hi", 3)Returns:
"HiHiHi"indexOf()
Returns the index of the first occurrence of a substring.
If the substring is not found, -1 is returned.
Syntax
indexOf(str, substring)Example:
indexOf("apple pie", "pie")Returns:
6lastIndexOf()
Returns the index of the last occurrence of a substring.
If the substring is not found, -1 is returned.
Syntax
lastIndexOf(str, substring)Example:
lastIndexOf("apple pie apple", "apple")Returns:
10hasPrefix()
Returns true if the string starts with the specified prefix.
Syntax
hasPrefix(str, prefix)Example:
hasPrefix("HelloWorld", "Hello")Returns:
truehasSuffix()
Returns true if the string ends with the specified suffix.
Syntax
hasSuffix(str, suffix)Example:
hasSuffix("HelloWorld", "World")Returns:
trueExample
The following example demonstrates multiple string functions working together.
upper(
trim(
replace(input.name, "_", " ")
)
)If:
input.name = " john_doe "The result is:
"JOHN DOE"Array Functions
Array functions help you search, filter, transform, sort, and summarize collections of data. They are commonly used to process lists returned by activities or workflow variables.
| Function | Description |
|---|---|
map() | Transforms each element in an array. |
filter() | Returns elements that match a condition. |
find() | Returns the first matching element. |
count() | Counts the number of matching elements. |
sum() | Returns the sum of numeric values. |
first() | Returns the first element. |
last() | Returns the last element. |
sort() | Sorts an array. |
groupBy() | Groups elements by a property. |
join() | Joins array elements into a string. |
map()
Creates a new array by applying an expression to every element.
Syntax
map(array, predicate)Example:
map(users, .Name)Returns:
["John", "Jane", "Mike"]filter()
Returns a new array containing only elements that satisfy a condition.
Syntax
filter(array, predicate)Example:
filter(users, .Age >= 18)Returns:
[
{Name: "John", Age: 25},
{Name: "Jane", Age: 30}
]find()
Returns the first element that matches a condition.
Syntax
find(array, predicate)Example:
find(users, .Name == "John")Returns:
{Name: "John", Age: 25}count()
Returns the number of elements that satisfy a condition.
Syntax
count(array[, predicate])Example:
count(users, .Age >= 18)Returns:
5sum()
Returns the total of all numeric values.
Syntax
sum(array[, predicate])Example:
sum([10, 20, 30])Returns:
60Another example:
sum(accounts, .Balance)first()
Returns the first element in an array.
Syntax
first(array)Example:
first(users)Returns:
{Name: "John", Age: 25}last()
Returns the last element in an array.
Syntax
last(array)Example:
last(users)Returns:
{Name: "Mike", Age: 28}sort()
Sorts an array in ascending order. Use "desc" for descending order.
Syntax
sort(array[, order])Examples:
sort([3, 1, 4])Returns:
[1, 3, 4]sort([3, 1, 4], "desc")Returns:
[4, 3, 1]groupBy()
Groups array elements based on a property.
Syntax
groupBy(array, predicate)Example:
groupBy(users, .Department)Returns:
{
IT: [...],
HR: [...],
Sales: [...]
}join()
Combines array elements into a single string.
Syntax
join(array[, delimiter])Examples:
join(["apple", "orange", "grape"], ", ")Returns:
"apple, orange, grape"join(["a", "b", "c"])Returns:
"abc"Example
The following example filters active users, extracts their names, and joins them into a comma-separated string.
filter(users, .Active)
| map(.Name)
| join(", ")Result:
"John, Jane, Mike"Map Functions
Map functions allow you to work with key-value pairs. They are useful for retrieving the keys or values stored in a map.
| Function | Description |
|---|---|
keys() | Returns all keys from a map as an array. |
values() | Returns all values from a map as an array. |
keys()
Returns an array containing all keys in a map.
Syntax
keys(map)Example:
keys({
name: "John",
age: 30,
city: "London"
})Returns:
["name", "age", "city"]values()
Returns an array containing all values in a map.
Syntax
values(map)Example:
values({
name: "John",
age: 30,
city: "London"
})Returns:
["John", 30, "London"]Example
The following example retrieves the keys and values from a workflow output.
keys(activity.A1.output)Returns:
["id", "name", "email"]values(activity.A1.output)Returns:
[101, "John", "john@example.com"]Predicate Functions
Predicate functions evaluate conditions for each element in an array. They are commonly used with functions such as filter(), map(), all(), any(), and find() to select, transform, or validate data.
| Function | Description |
|---|---|
all() | Returns true if all elements satisfy a condition. |
any() | Returns true if at least one element satisfies a condition. |
one() | Returns true if exactly one element satisfies a condition. |
none() | Returns true if no elements satisfy a condition. |
Predicate Syntax
A predicate is an expression that evaluates to true or false for each element in an array.
Syntax
filter(array, predicate)Example:
filter(0..9, {# % 2 == 0})Returns:
[0, 2, 4, 6, 8]When working with arrays of objects or maps, you can omit the # symbol and access properties directly.
filter(users, .Age >= 18)Braces are optional for simple predicates.
filter(users, .Active)all()
Returns true if every element satisfies the predicate. If the array is empty, it returns true.
Syntax
all(array, predicate)Example:
all(users, .Age >= 18)Returns:
trueany()
Returns true if at least one element satisfies the predicate.
Syntax
any(array, predicate)Example:
any(users, .Role == "Admin")Returns:
trueone()
Returns true if exactly one element satisfies the predicate.
Syntax
one(array, predicate)Example:
one(users, .Primary == true)Returns:
truenone()
Returns true if no elements satisfy the predicate.
Syntax
none(array, predicate)Example:
none(users, .Status == "Blocked")Returns:
trueNested Predicates
Predicates can be nested to work with related collections.
Example:
filter(posts, {
let post = #;
any(.Comments, .Author == post.Author)
})This example returns posts where at least one comment was written by the same author as the post.
Example
The following expression filters active users and checks whether all of them are verified.
all(
filter(users, .Active),
.Verified
)Result:
trueTip: Predicate functions are commonly used with array functions such as
filter(),map(),find(), andcount()to build powerful data-processing expressions.
Date Functions
Date functions allow you to create, compare, and manipulate dates and times within GRiPOFlow expressions. They are useful for scheduling workflows, calculating durations, and working with timestamps.
| Function | Description |
|---|---|
now() | Returns the current date and time. |
duration() | Creates a duration value from a string. |
date() | Converts a string into a date. |
timezone() | Returns a timezone object. |
Working with Dates
You can perform arithmetic and comparisons directly on date values.
Calculate the time between two dates:
activity.A1.output.createdAt - now()Add a duration to a date:
activity.A1.output.createdAt + duration("1h")Compare two dates:
activity.A1.output.createdAt > now() - duration("1h")now()
Returns the current date and time.
Syntax
now()Example:
now()Get the current year:
now().Year()duration()
Creates a duration from a string.
Syntax
duration(str)Supported units:
ns– Nanosecondsusorµs– Microsecondsms– Millisecondss– Secondsm– Minutesh– Hours
Example:
duration("30m")duration("1h")date()
Converts a string into a date value.
Syntax
date(str)or
date(str, format, timezone)Examples:
date("2025-08-14")date("2025-08-14T10:30:00Z")date(
"2025-08-14 10:30:00",
"2006-01-02 15:04:05",
"UTC"
)Useful date methods:
date("2025-08-14").Year()date("2025-08-14").Month()date("2025-08-14").Day()Other available methods include:
Hour()Minute()Second()Weekday()YearDay()
timezone()
Returns a timezone object.
Syntax
timezone(str)Examples:
timezone("UTC")timezone("Europe/Zurich")Convert a date to another timezone:
date("2025-08-14 10:30:00")
.In(timezone("UTC"))Example
Calculate whether an activity was created within the last hour.
activity.A1.output.createdAt >
now() - duration("1h")Number Functions
Number functions perform common mathematical operations within GRiPOFlow expressions.
| Function | Description |
|---|---|
max() | Returns the larger of two numbers. |
min() | Returns the smaller of two numbers. |
abs() | Returns the absolute value. |
ceil() | Rounds a number up. |
floor() | Rounds a number down. |
round() | Rounds to the nearest whole number. |
max()
Returns the larger of two numbers.
Syntax
max(number1, number2)Example:
max(5, 7)Returns:
7min()
Returns the smaller of two numbers.
Syntax
min(number1, number2)Example:
min(5, 7)Returns:
5abs()
Returns the absolute value of a number.
Syntax
abs(number)Example:
abs(-5)Returns:
5ceil()
Rounds a number up to the nearest whole number.
Syntax
ceil(number)Example:
ceil(1.5)Returns:
2floor()
Rounds a number down to the nearest whole number.
Syntax
floor(number)Example:
floor(1.5)Returns:
1round()
Rounds a number to the nearest whole number.
Syntax
round(number)Example:
round(1.5)Returns:
2Example
Calculate the total cost and round it to the nearest whole number.
round(
sum(activity.A1.output.costs)
)Bitwise Functions
Bitwise functions perform operations directly on the binary representation of integers. They are useful for working with flags, permissions, masks, and other low-level numeric operations.
| Function | Description |
|---|---|
bitand() | Performs a bitwise AND operation. |
bitor() | Performs a bitwise OR operation. |
bitxor() | Performs a bitwise XOR operation. |
bitnand() | Performs a bitwise AND NOT operation. |
bitnot() | Performs a bitwise NOT operation. |
bitshl() | Shifts bits to the left. |
bitshr() | Shifts bits to the right. |
bitushr() | Performs an unsigned right shift. |
bitand()
Returns the result of a bitwise AND operation.
Syntax
bitand(int1, int2)Example:
bitand(0b1010, 0b1100)Returns:
0b1000bitor()
Returns the result of a bitwise OR operation.
Syntax
bitor(int1, int2)Example:
bitor(0b1010, 0b1100)Returns:
0b1110bitxor()
Returns the result of a bitwise XOR operation.
Syntax
bitxor(int1, int2)Example:
bitxor(0b1010, 0b1100)Returns:
0b0110bitnand()
Returns the result of a bitwise AND NOT operation.
Syntax
bitnand(int1, int2)Example:
bitnand(0b1010, 0b1100)Returns:
0b0010bitnot()
Returns the result of a bitwise NOT operation.
Syntax
bitnot(int)Example:
bitnot(0b1010)Returns:
-0b1011bitshl()
Shifts the bits of a number to the left.
Syntax
bitshl(int, shift)Example:
bitshl(0b101101, 2)Returns:
0b10110100bitshr()
Shifts the bits of a number to the right.
Syntax
bitshr(int, shift)Example:
bitshr(0b101101, 2)Returns:
0b1011bitushr()
Performs an unsigned right shift operation.
Syntax
bitushr(int, shift)Example:
bitushr(-0b101, 2)Returns:
4611686018427387902Example
The following example combines two permission flags using a bitwise OR operation.
bitor(0b0011, 0b0100)Returns:
0b0111Type Conversion Functions
Type conversion functions allow you to convert values between different data types. They are useful when working with workflow inputs, activity outputs, JSON data, and encoded values.
| Function | Description |
|---|---|
type() | Returns the data type of a value. |
int() | Converts a value to an integer. |
float() | Converts a value to a floating-point number. |
string() | Converts a value to a string. |
toJSON() | Converts a value into a JSON string. |
fromJSON() | Parses a JSON string into an object or array. |
toBase64() | Encodes a string into Base64 format. |
fromBase64() | Decodes a Base64 string. |
toPairs() | Converts a map into key-value pairs. |
fromPairs() | Converts key-value pairs into a map. |
type()
Returns the data type of a value.
Syntax
type(value)Examples:
type(42)Returns:
"int"type("Hello")Returns:
"string"type(now())Returns:
"time.Time"Common return types include:
nilboolintuintfloatstringarraymap
int()
Converts a value to an integer.
Syntax
int(value)Example:
int("123")Returns:
123float()
Converts a value to a floating-point number.
Syntax
float(value)Example:
float("123.45")Returns:
123.45string()
Converts any value to its string representation.
Syntax
string(value)Example:
string(123)Returns:
"123"toJSON()
Converts a value into a JSON string.
Syntax
toJSON(value)Example:
toJSON({
name: "John",
age: 30
})fromJSON()
Converts a JSON string into an object or array.
Syntax
fromJSON(value)Example:
fromJSON('{"name":"John","age":30}')toBase64()
Encodes a string into Base64 format.
Syntax
toBase64(value)Example:
toBase64("Hello World")Returns:
"SGVsbG8gV29ybGQ="fromBase64()
Decodes a Base64 encoded string.
Syntax
fromBase64(value)Example:
fromBase64("SGVsbG8gV29ybGQ=")Returns:
"Hello World"toPairs()
Converts a map into an array of key-value pairs.
Syntax
toPairs(map)Example:
toPairs({
name: "John",
age: 30
})Returns:
[
["name", "John"],
["age", 30]
]fromPairs()
Converts an array of key-value pairs into a map.
Syntax
fromPairs(array)Example:
fromPairs([
["name", "John"],
["age", 30]
])Returns:
{
name: "John",
age: 30
}Miscellaneous Functions
Miscellaneous functions provide utility operations for working with arrays, maps, and strings.
| Function | Description |
|---|---|
len() | Returns the length of a string, array, or map. |
get() | Returns an element from an array or a value from a map. |
len()
Returns the number of elements in an array or map, or the number of characters in a string.
Syntax
len(value)Examples:
len([1, 2, 3])Returns:
3len({
name: "John",
age: 30
})Returns:
2len("Hello")Returns:
5get()
Returns the element at the specified index or the value associated with a key.
If the index is out of range or the key does not exist, nil is returned.
Syntax
get(value, key)Examples:
get([1, 2, 3], 1)Returns:
2get({
name: "John",
age: 30
}, "name")Returns:
"John"get(activity.A1.output, "email")Returns the value of the email property if it exists; otherwise, it returns nil.