Condition Expressions
Introduction
Conditions can be used to control how triggers and workflows are executed. A condition uses a simple expression language to return a boolean (true/false) value.
- Triggers - If a condition is added to a trigger it is evaluated when the trigger (event or webhook) is processed. If the condition evaluates to false the workflow specified in the trigger will not be executed.
- Workflow (all steps except Start) - An optional condition can be specified. If the condition evaluates to false the step is skipped.
- Workflow Test Step - A condition is used to evaluate which branch of the test should be followed - true or false.
- Workflow End Step - An optional "failed" condition can be configured to specify if the workflow should be marked as failed.
Syntax
- Strings are specified in single quotes.
-
Variable names can be specified in curly brackets.
- The expression inside the curly brackets uses string interpolation to build the result.
- The curly brackets can be omitted if:
- The first character of the name is A-Z, a-z, or underscore
- The rest of the name only uses characters A-Z, a-z, 0-9, underscore (_), dot (.), and square brackets ([ or ]).
-
Parenthesis can be used to group expressions.
-
Operators
Operator Description Example == Equal (case insensitive for strings) status == 'success' != Not Equal (case insensitive for strings) status != 'failed' > Greater Than (numeric only) score > 50.0 >= GreaterThan or Equal To (numeric only) score >= 55 < Less Than (numeric only) score < 50.0 <= Less Than or Equal To (numeric only) score <= 55 and Logical AND status == 'success' and score > 50.0 or Logical OR status == 'success' or score > 50.0 not Logical NOT not Time(wfsystem.starttime, 800, 1700) ! Same as 'not' !Time(wfsystem.starttime, 800, 1700) -
Functions can be used for more complex scenarios. See the Functions section below.
Examples
- status == 'Test'
- {status} == 'Test'
- status == 'Test' and score > 0.50
- (status != 'Test') and (score > 0.50)
NOTE: A variable name that does not exist evaluates as an empty string.
The expression {doesnotexist} == ''
will be true.
Values (constants)
Can be: string, numeric or boolean.
- String can be expressed as values between single quotes (e.g. 'value' ). Inside a string, curly braces can be used to express a variable name.
- Numeric values are expressed as digits, or as hexadecimal numbers started with 0x. Real numbers can be used, the decimal separator must be a dot (.)
- Boolean values can be expressed as true (true, on, yes) or false (false, off, no).
Examples
- simple string:
'user name'
- string with variable:
'age is {wfresult.age}'
- natural number:
23, 0xf95c
- real number:
3.1416
Arrays
All variable names are strings: name
, index
, etc. During condition evaluation the variable name is resolved by looking up the variable name to retrieve the value.
Variable names can contain square brackets such as name[0]
or attachments[1].data
. If a variable name lookup fails because it does not exist and the variable name contains square brackets, an attempt is made to do variable substitution and attempt the lookup again. This allows using variables as array indexes.
The variable name inside of the array index must not start with a number: digit (0-9), plus: +, minus: -, or dot (.).
Functions can be used inside of an array index but:
- The expression must be inside of curly brackets to be parsed correctly
- The function must be preceded by a question mark - "?"
Examples
The variables are:
index = '2' name[0] = 'name_zero' name[1] = 'name_one' name[2] = 'name_two' name[3] = 'name_three'
Condition | Value | Variable Lookups Performed |
---|---|---|
name[2] | name_two | name[2] - succeeded |
name[index] | name_two | name[index] - failed name[2] - succeeded |
{name[?Add(index, 1)]} | name_three | name[3] - succeeded |
Functions
- Functions are used by using the function name with the parameters in parenthesis.
- Functions can be used in conditions.
- Functions can be used in string interpolation such as in a workflow
Set step.
- The first character of the interpolation (inside the curly brackets) should be a '?' to mark the rest of the interpolation as an expression to be evaluated instead of as a variable name.
- Example:
"The next value is {?Add(counter, 1)}"
- Function parameters can be constant values (see above) or properties from the current context
- If a property of the current context will be used as a function parameter, then its name must start with '_' or a letter, and next characters can only be '_', alphanumeric, or '.'
- Functions can be nested, as the parameter of a function call can be another function call.
- Example:
{?Replace(Trim(input),'b','c')}
- Example:
Examples
The following examples are conditions using functions.
Function | Description |
---|---|
Add(index, 1) >= 5 |
Add 1 to the variable 'index' |
Left(attachments[0].name, ':') |
Get the text to the left of a colon in the variable 'attachments[0].name' |
Left(attachments[index].name, ':') |
Get the text to the left of a colon in the variable 'attachments[index].name' |
Left(fullname, ',') != '' |
Get the text to the left of a comma in the variable 'fullname' |
Variable Functions
Variable functions are used to determine the state of a variable.
Function | Description | Example | Returns |
---|---|---|---|
IsDefined(name) | Returns true if a variable of name is present | IsDefined('status') |
|
IsDefined(propname) |
If propname has a value of 'status' then the variable status is checked. | ||
IsDefined({propname}) |
If propname has a value of 'status' then the variable status is checked. | ||
IsEmpty(name) | Returns true if a variable of name is either not defined or has an empty value | IsEmpty('status') |
|
IsNumeric(value) | Returns true if a variable has a numeric value. | IsNumeric(score) |
true if score has a numeric value (e.g. 50) |
GetValue('property name') | Gets value of the property with the specified name. This can be used when the property name contains illegal characters. | GetValue('message') |
'Hello' if message variable has value 'Hello'. |
String Functions
Function | Description | Example | Returns |
---|---|---|---|
Left(input, split) | Split a string on the first occurrence of split and returns the left side. If split is not found the entire value is returned; The return value is not trimmed |
Left('Last, First', ',') |
'Last' |
Left(input, split, trim) | The optional third parameter (boolean) specifies if the value should be trimmed. |
Left('Last , First', ',', true) |
'Last' |
Right(input, split) | Split a string and on the first occurrence of split and returns the right side If split is not found empty string is returned. The return value is not trimmed |
Right('Last, 'First', ',') |
' First' |
Right(input, split, trim) | The optional third parameter (boolean) specifies if the value should be trimmed. | Right('Last, First', ',', true) |
'First' |
Trim(input) | Trim whitespace from the beginning and end of the input and return it. | Trim(' abc ') |
'abc' |
Substring(input,count) | Returns the first 'count' characters of the string. If the string is less than 'count' length the entire string is returned. |
Substring('abcdefgh',2) |
'ab' |
Replace(input, find, replacement) | Replace all instances of find with replacement in input and returns the result. | Replace('abc-def-123', '-', 'QQ') |
'abcQQdefQQ123' |
Regex(input, pattern) | Matches the input against the regex pattern and returns the matched part of the string | Regex('abcde', '^abc') |
'abc' |
Regex(input, pattern, flags) | Matches the input against the regex pattern and returns the matched part of the string. The third parameter provides options for regex match. Options: 'i' = ignore case 's' = single line mode(change meaning of dot(.)) 'm' = multiline mode(changes meaning of ^ and $) 'x' = ignore pattern whitespace |
Regex('abc', '^abc', 'is') |
'abc' |
RegexMatch(input, pattern) | Check if the input value matches a regular expression pattern. | RegexMatch('abc', '^abc$') RegexMatch('abc-456-4532', '\d{3}') |
true in both cases |
RegexMatch(input, pattern, flags) | The optional flags parameter specifies how the regular expression is evaluated. The flag parameter is a string: 'i' - case insensitive search 's' - single line mode 'm' - multiline mode 'x' - ignore pattern whitespace |
RegexMatch('ABC', 'abc', 'i') RegexMatch('ABC', 'abc', 'is') |
|
RegexReplace(input, pattern, replacement) | Same as Replace except that the find argument is a regular expression. | RegexReplace('abc123def456', '\d', 'M') Replace all digits with 'M'. |
'abcMMMdefMMM' |
RegexReplace(input, pattern, replacement, flags) | The optional flags parameter specifies how the regular expression is evaluated. The flags parameter is the same as the RegexMatch function. |
||
UrlEncode(input) | URL encode a string. This is used when building a URL to send to an adapter command. | UrlEncode('a b c') |
'a+b+c' |
DateFormat(input, format) | Format a date time using the given format string. The format strings are the .NET DateTime format strings. |
DateFormat('2018-02-05T17:00:03-05:00', 'g') |
2/5/2018 5:00 PM |
GetUUID() | Returns a random generated Universal Unique Identifier. | GetUUID() |
90e51d3b-b116-4a4d-8dbd-b4f655796375 |
GetDigits(count) | Returns a random generated sequence of digits containing count digits. | GetDigits(4) |
0719 |
Numeric Functions
Function | Description | Example | Returns |
---|---|---|---|
Add(input) | Add one to the variable input and return the result | Add(counter) |
Returns '4' if counter has the value '3'. |
Add(counter, addend) | Add the two values together and return the result | Add(counter, 4) |
Returns '7' if counter has the value '3'. |
Up to five values can be passed in. They are added together. | Add(1, counter, 7, score, 2) |
Returns '18' if counter is '-4' and score is '12'. |
Date/Time Functions
Date and time functions can be used to evaluate a date/time string. Adapters can send a date/time property in an event or command response.
The format of the input string must be one of:
- YYYY-MM-DDTHH:MM:SS
- YYYY-MM-DDTHH:MM:SS.sss
The time zone can be added. If it is missing, the default time zone is used.
The default time zone can be set in the Administration > Workflow page. If the default time zone field is blank then the server local time zone is used.
Examples:
Time String | TimeZone |
---|---|
2018-02-05T17:00:03 | No timezone - uses default time zone. |
2018-02-05T17:00:03Z | UTC timezone |
2018-02-05T17:00:03-05:00 | Timezone of -5 hours from UTC |
2018-02-05T17:00:03+02:00 | Timezone of +2 hours from UTC |
When evaluating the date time function the argument is converted to a date/time in the default time zone before the check is made.
System level date time properties are available during trigger evaluation and when workflows are started:
- When a trigger (event or webhook) is being evaluated there are system level properties available to use in the condition:
- wfsystem.starttime - a string with the trigger start date time in local time zone of the server
- wfsystem.starttimeUTC - a string with the trigger start date time in UTC time zone.
- When a workflow is started the following system level properties are automatically added to the workflow:
- wfsystem.starttime - a string with the workflow start date time in local time zone of the server
- wfsystem.starttimeUTC - a string with the workflow start date time in UTC time zone.
There are eight date time functions. All of these functions convert the passed in time string to the default time zone and then examples are described below. The function names are:
- Year - use the year component
- Month - use the month component
- Day - use the day component
- Hour - use the hour component (0 to 23)
- Minute - use the minute component
- DayOfWeek - use the day of week component (0 = Sunday through 6 = Saturday)
- Date - Combine the Month/Day as (Month*100)+Day - so December 8 is the value 1208.
- Time - Combine the Hour/Minutes as (Hour*100)+Minute - so 3:45 PM is the value 1545.
Each function has three forms it can be called in. Each form takes the date time string as the first parameter.
- One parameter: Returns the value for the component (based on the function name).
- Two parameters: Returns true if the component (based on the function name) equals the second parameter.
- Three parameters: Returns true if the component (based on the function name) is between the second and third parameters. This is an inclusive compare (
value >= parameter2 and value <= parameter3
)
Examples
These examples can be used in a trigger or workflow condition. They use the wfsystem.starttime variable but could use any variable that is in the supported format - such as matchTime from the Neoface watch match event, or the wfsystem.starttimeUTC variable (since the time is converted to the default time zone when being evaluated).
Example 1: Check if it is between 8 AM and 5 PM:
- Three parameter version: Time(wfsystem.starttime, 800, 1659)
Example 2: Check if the day of week is Monday:
- One parameter version: DayOfWeek(wfsystem.starttime) == 1
- Two parameter version: DayOfWeek(wfsystem.starttime, 1)
Example 3: Check if the date is December 25:
- One parameter version: Date(wfsystem.starttime) == 1225
- Two parameter version: Date(wfsystem.starttime, 1225)
- Three parameter version: Date(wfsystem.starttime, 1225, 1225)
Other Examples:
- Composing a string from various input values:
[Entry {i}]: The id is {id} and the text is '{?Trim(text)}'
- Increment a numeric value:
The next id is {?Add(id)}
- Math on values:
Quantity {quantity1} and {quantity2} and a total of {?Add(quantity1, quantity2)}
- Condition:
{i} <= '10'