Перейти к содержанию

Expressions, values, and operators of Automation Rules

This section describes the use of expressions in automation rules: what expressions, values (variables), and operators exist, and how they are used in the system when creating a rule. There are many values and operators available for use in rules. The expressions are grouped by type and are listed below along with usage examples.

Terminology

In the context of automation rules, the following terms are used, which have different interpretations:
Expression is a construction containing the value(s) and operator(s).
Value (variable) - a specific quantity (numbers, text, logical quantities, dates, etc.).
The operator is an action. The operator sets a command or connects conditions to each other: what exactly needs to be done with the values.

Example: some_expression: a + 3, where some_expression is the name of the expression, a + 3 is the expression itself, a and 3 are values (or variables), + is the operator.

Basic principles

Please note: Expressions calculate values, which are then used in the condition and actions of the automation rule. Each line of the expression block has a name and a formula: name: expression (as in the example above: some_expression: a + 3). The name becomes the value (variable) of the rule and can be further used in conditions, actions, and subsequent expressions.

The expression is written in the format: Expression name: value

The expression name consists of Latin letters, numbers, and underscores. As a value, you can use:

  • a link to a field or related record: requested_by, requested_by.manager, requests[first];
  • the previous value of the field separated by the suffix _was: status_was, team_was, custom_fields_was.priority;
  • a string in single or double quotes;
  • number: 10, 3.5;
  • static value: accepted, incident',high`;
  • value of the custom field: custom_fields.priority;
  • the found record: find(person, "ivan@example.com ");
  • several records found: find_all(ci, "server");
  • full-text search result: search(req, "printer");
  • a newly created record: new(task) or new(task, template_name);
  • comparison, formula, ternary operator, or function.

A sign ! before referring to the value, inverts the boolean value if it supports a logical interpretation. For strings and other non-logical values, this does not turn the value into a text operation, but is used as a logical negation.

If the name is not found among the fields of the current record, previously calculated expressions, predefined values, and numbers, the system treats it as a static string. Therefore, fixed sets of predefined values are often written without quotation marks: status = completed.

The names of expressions cannot match reserved words and internal context keys. You cannot name the expression index, errors, or safe_attachments; predefined values and names that the condition language uses are also reserved.

Basic principles - type conversions and empty values

The system does not require the user to explicitly specify the types. When calculating, it brings the values to the desired form:
Boolean value: any non-empty value is considered true;
string: entries are displayed using an item, name, or display name, arrays of up to 100 items are separated by commas, large arrays are shown as the number of items;
number: Numeric strings, numbers, arrays, and records are reduced to a number according to internal rules;
Date/time: ISO8601 dates and times are recognized, as well as objects that support date/time;
Array: Regular arrays, ActiveRecord architectural pattern relationships, and deferred associations are supported.

An empty value usually stops further calculation and gives an empty result. Exceptions are specified: for example, empty? and blank? if the value is empty, "true" is returned.

Predefined values

Please note: if the name is not found as a field of the current record or as a previously calculated expression, the system checks a set of predefined values.

Value Result Purpose
now current date and time used for calculations relative to the current moment
today the current date is used for calculations relative to the current day
true the base boolean value is true the constant of truth
false the base boolean value is false the lie constant
empty a special empty string is used to compare a value with an empty string
nil empty result (zero) the constant of the missing value
null empty result (zero) alternative to nil
updated_by the person who made the change (the person who initiated the implementation of the automation rule by updating the record to which this automation rule applies) is taken from the saved change context, the current user session, or the verification mode
triggered_at the trigger time in UTC is taken from the context of the rule execution; if there is none, the current moment is used
rule_account rule space the space where the automation rule is defined (to which the rule belongs)
rule_app_instance the installed rule application the application from which the rule came (if any)
related_note linked comment (created when the automation rule was executed) available for triggers related to adding a comment; if no comment was created, the value is empty; when using the "When adding a comment" trigger, this value is always present if the user responsible for automation has rights to read the comment
related_internal_note related internal comment (an internal comment created when the automation rule was executed) available for triggers related to adding an internal comment; if no comment has been created, the value is empty

Important: at the top level of the expression, the name of the previously evaluated expression takes precedence over the field of the current record. Inside array functions, where an array element becomes the current object, the element fields are read before the name of the top-level expression.

Previous field values

The field ID can be used to find the value of this field. For example, to get the current value of the workflow Topic field, you can use the following expression:

  • workflow.subject

However, you can also find the previous value of the record field, that is, the value that the field had before saving the record and triggering the automation rule. This is done by adding _was after the field ID. For example, for the "Subject" field in the workflow, the expression looks like this:

  • workflow.subject_was

The suffix _was refers to the value of the field at the time the rule was triggered.
The previous values are only available for the record that started the rule. Inside the array filter, they do not refer to the array element; in template validation mode, the system adds an error if *_was is used outside the top level.

Syntax Result Purpose
pole_was the previous value of the field is used to compare the old and new state of the record
custom_fields_was.code the previous value of the user field used to check changes to user fields
custom_data_was.code previous value of the user field historical record option for user data

Logical operators

Used for:
value A or value B
value A and value B

Examples of expressions Result
a or b (for example, if a is true, then b is either true or false) true
a or b (for example, if b is true, then a is either true or false) true
a or b (for example, a is false, and b is false) false
a and b (for example, a is true and b is true) true
a and b (for example, a is false, and/or b is false) false

Forms of expressions: Comparison - Equality

Used for:
value-A = value-B
value-A != value-B

Syntax Arguments Result Assignment
left = right two values true or false checks for equality
left != right two values true or false checks for inequality
left < right two values true or false checks that the left value is less than the right
left <= right two values true or false checks that the left value is less than or equal to the right
left > right two values true or false checks that the left value is greater than the right
left >= right two values true or false checks that the left value is greater than or equal to the right
left contains right two values true or false checks whether the value is included
left *= right two values true or false alternative to the contains operation
left starts_with right two values true or false checks the beginning of a string or value
left ^= right two values true or false alternative to the starts_with operation
left ends_with right two values true or false checks the end of the string or values
left $= right two values true or false alternative to the ends_with operation
left is_blank one value true or false checks an empty value
left is_present single value true or false checks for a non-empty value
left in [value1, value2] value and array true or false checks that the value is included in the array
left not_in [value1, value2] value and array true or false checks that the value is not in the array

The array in in and not_in is written in square brackets. Array elements can be strings, value references, or other simple variables.

Comparisons bring values to a comparable form. Dates are compared as dates, numbers are compared as numbers, fixed sets of values are compared by position within their set, and the remaining values are compared as strings. For contains, the array is checked as a set of string representations of elements; for starts_with and ends_with, the first or last element on the array is checked, respectively.

Arrays support an empty array []. For backward compatibility, some unquoted string values with spaces are also allowed in array elements, but for new rules it is better to write strings in quotation marks.

Examples of expressions Result
'text' = 'text' true
'text' != 'text' false
'' = 'text' false
'text' = "" false
" = "" true
"a\"b" = 'a"b' true
'a\'b' = "a'b" true
status = in_progress true
status = assigned false
team = 'Database Administration' true
team = 9 false
team.id = 9 true
team.id = 12 false

Comparison - Less, More (examples)

Used for:
value-A < value-B
value-A <= value-B
value-A > value-B
value-A >= value-B

Examples of expressions Result
‘a’ < ‘a’ false
‘a’ <= ‘a’ true
‘a’ > ‘a’ false
‘a’ >= ‘a’ true
‘a’ < ‘b’ true
‘b’ > ‘a’ true
‘a’ > ‘b’ false
‘’ < ’text’ true
‘text’ > ’ true
status < completed true
status < registered false /
completed < status false
registered <status true
team < ‘Application Development’ false /
team < ‘Service Desk’ true
‘Application Development’ <team true
‘Service Desk' < team false /
team.id < 100 true
team.id < 1 false /
100 < team.id false
1 < team.id true

Comparison - Contains (examples)

Used for:
the value in the array
the value is not in the array

Examples of expressions Result
a in [a,b] true
a not_in [a,b] false /
b in [a,b] true
c in [a,b] false
ab in [a,b] false
ab in [] false
’ in [] true
’ in [a,b] false
’ in [a,,b] true
a in [ a , b ] true
status in [in_progress] true
status in [assigned, accepted, in_progress, waiting_for_customer] true
status in [assigned,completed] false /
team in [Application Development,Database Administration,Service Desk] true
team in [Application Development,Service Desk] false
team.id in [8,9,10] true
team.id in [11,12,13] false
11.0 in [11,12,13] true
11 in [11.0,12.0,13.0] true
team.id in [8.0,9.0,10.0] true
team.id in [8.1,9.1,10.1] false

Comparison is Similar (examples)

The operators are used:
* the ‘contains’ operator
^ the ‘starts_with’ operator
$ the 'ends_with’ operator

Examples of expressions Result
‘ivan.ivanov@proproduct.ru’ *= ‘ivanov’ true
‘ivan.ivanov@proproduct.ru’ ^= ‘ivanov’ false /
‘ivan.ivanov@proproduct.ru ’ *= ‘ivan’ true
‘ivan.ivanov@proproduct.ru’ ^= ‘ivan’ true
‘ivan.ivanov@proproduct.ru’ $= ‘ivan’ false /
‘ivan.ivanov@proproduct.ru ’ $= ‘proproduct’ false /
‘ivan.ivanov@proproduct.ru ’ $= ‘proproduct.ru ’ true

Comparison - Presence (examples)

Used for:
the value is empty
the value is present

Examples of expressions Result
team.name is_blank false (the name of the command is required, as it must contain a value)
request.custom_fields.my_date is_present true if the UI extension field "my_date" is defined and contains a non-empty value, false otherwise

Formulas

The operators are used:
+ is an 'addition’ or ‘union’ operator
- the ‘subtraction’ operator
* the ‘multiplication’ operator
/ the division operator
% is the "multiplication modulo" operator

Note that the + sign acts as a "concatenation" operator if the value to the left of it is a text string. Otherwise, it acts as an "addition" operator.

Syntax Arguments Result Purpose
left + right two values number, string, date/time, duration or array adds numbers, joins strings, adds seconds or duration to date/time, combines compatible arrays
left - right two values number, date/time or duration subtracts numbers, subtracts seconds or duration from date/time, returns duration between two dates/time
left * right two values number multiplies numeric values
left / right two values number or nil divides numeric values; returns an empty result when divided by zero
left % right two values number or nil returns the remainder of the division; returns an empty result when divided by zero
left and right two values boolean value (true/false) logical And after converting both values to a logical form
left or right two values boolean value (true/false) logical OR after converting both values to a logical form

In the formula chain, the system takes into account the priority of the operators: %, then * and /, then + and -, then and, then or.

Examples of expressions Result
1 + 1 2.0
2 1 1.0
2 * 5 10.0
6 / 3 2.0
15 % 6 3.0
1 1 1 + 1 4.0
1 + 2 * 6 % 4 5.0
‘start’ + ‘_at’ + ’ field’ the "start_at" field
1 + team.name 1.0
1 + team.id 8.0
2.0 + team 9.0
team + 3.0 10.0
created_at + 3.days 3 days after the creation date
team.id ++ team.name 7.0
+ team.id ++ team.name 7 – Service Desk
‘{{team_id}} {{team_name}}’ 7 – Service Desk
created_at 4.hours 4 hours before the creation date
5 / 5 1.0
5 / 0 zero (nil)

The path to get the variable (the path of the value)

An expression that extracts a variable always starts with an entry for which an automation rule is defined.

After the initial value is set, you can add a path, for example:

1 request.requested_by.manager.name
2 requests[first].subject
3 find_all(ci, "server").select(status = in_production).map(name).join(", ")

Syntax Arguments Result Assignment
.field the name of the field or connection to the record the value of the field or the associated record goes to the attribute or connection of the current value
.custom_fields.The code user field code user field value reads user field from custom_fields
.custom_data.code user field code user field value historical user data access option
[first] no the first element of the array returns the first element of the collection
[last] none last element of the array returns the last element of the collection
[N] position number array element returns an element by position, positive positions are counted from 1, negative positions are counted from the end of the array
[#ID] record ID array element searches the array for a record with the specified ID
["name"] string array element searches the array for an entry by subject, if there is one, otherwise by name
[expression] the name of an expression with a number or string array element uses the value of another expression as an index or name
[N..M] two positions part of the array returns a range of elements; positive positions are counted from 1

If the index is not applied to an array, an empty result is returned when executing; when checking the template, the system adds a validation error.

The available fields depend on the type of record. The server restricts the list of allowed attributes for each type of record: for example, the request has a status, subject, person "requested by whom" (initiator) (requested_by), person "requested for" (requested_for), service component (service_instance), team, member), custom_fields, comments, tags, and other fields; in turn, the task has its own set. The full list of fields is large and is stored in the code as a whitelist; The syntax for accessing fields is described, rather than duplicating the entire whitelist by record type.

The path inside custom_fields / custom_data is not checked according to the UI extension scheme when evaluating the expression. When executing the rule, the system reads user fields as a key-value data structure (hash) and returns the value for the specified key; if there is no key, the result becomes empty. In the validation and template mode, the system does not know the active UI extension scheme for a specific field and considers the value of the user field to be a string.

Some of the old names are supported as an alternative for backward compatibility: the value of custom_data corresponds to the value of custom_fields; the value of change for the request and task corresponds to the workflow; the value of change_type corresponds to the value of workflow_type; the value of workflow_manager the service has the value of change_manager; the value of changes for a release corresponds to the value of workflows; the value of internal for a comment corresponds to the value of internal_account; the value of sitename for a space corresponds to its identifier.

Examples of using expressions are given below.

Examples of expressions Result
status approved
workflow.status progress suspended (progress_halted)
created_at 2017-09-12T14:00:00Z
planned_duration 8
workflow.tasks[first] 1st workflow task
workflow.tasks[1] 1st workflow task
workflow.tasks[last] last workflow task
workflow.tasks[-1] last workflow task
workflow.tasks[#20122] task with ID 20122 in the workflow
workflow.tasks[1].custom_fields.name the value of the UI extension field with the identifier "name" from the workflow task
workflow.tasks[1].custom_fields.你好,世界 value of the UI extension field with the identifier "你好,世界" from the workflow task
workflow.tasks[#20122].subject Change controller approval
workflow.tasks[“Change controller approval”].id 20122.0
workflow.tasks[‘Change controller approval’] 20122.0
workflow.tasks[first].notes[first].text text from the first comment of the first workflow task
workflow.tasks[first].notes[first].person.name name of the person who added the first comment on the first workflow task

Manipulating arrays

Array functions are applied to a collection or array separated by a dot. If the initial value is empty, most functions return an empty result; empty? returns "true".

Function Arguments Result Details
. join("separator") separator string string converts each element of the array into a string and connects the elements with the specified separator
.map(field) a reference to a field relative to an array element an array of values for each element calculates the specified field or path and returns an array of results; nested arrays are prohibited in verification mode
.select(condition) binary comparison array of elements leaves elements for which the condition is true; the condition is calculated in the context of the current element of the array
.reject(condition) binary comparison array of elements excludes elements for which the condition is true
.detect(condition) binary comparison single element or empty result returns the first element for which the condition is true
.any? no boolean value (true/false) checks for the presence of at least one element in the array
.any?(condition) binary comparison boolean value (true/false) verifies that at least one element of the array satisfies the condition
.all?(condition) binary comparison boolean value (true/false) verifies that all elements of the array satisfy the condition
.none? no boolean value (true/false) checks that there are no elements in the array
.none?(condition) binary comparison boolean value (true/false) checks that no element of the array satisfies the condition
.empty? no boolean value (true/false) checks that the array is empty; returns "true" for an empty initial value
.count no number returns the number of elements
.count(condition) binary comparison number returns the number of elements satisfying the condition
.size no number returns the number of elements
.size(condition) binary comparison number works like count(condition): counts elements that satisfy the condition
.sum no number converts elements to numbers and returns the sum
.sum(condition) binary comparison number converts elements to numbers and summarizes those values for which the condition is true
.min no one element or an empty result removes empty elements and returns the minimum value
.max no one element or an empty result removes empty elements and returns the maximum value

The size and empty functions? They can also work with a string, but they still refer to array functions if the syntax matches a massive function. When checking the type, the system distinguishes between a string and a collection. The condition for sum(condition) is applied after the elements have been converted to numeric form; if you need to filter records by fields, it is better to use select(condition) first, then map(numeric field) and only after that sum.

The path to retrieve the collection (examples)

An expression retrieving a collection always starts with an entry for which an automation rule is defined, or uses the find_all operation.

Examples of expressions Result
cis All CIs related to the current task
workflow.requests[first].cis All requests related to the first workflow request
cis.size The number of CIs associated with the current task
cis.count The number of CIs associated with the current task
workflow.tasks.select(status = registered) Workflow tasks with the status "Registered"
workflow.tasks.reject(status = registered) Workflow tasks that do not have the "Registered" status
workflow.tasks.select(status = failed) + workflow.tasks.select(status = rejected) Workflow tasks with the status "Failed" in combination with workflow tasks with the status "Rejected"
cis.empty? True if no CIs are attached to the current task, false otherwise
cis.any? True if at least one CIs is linked to the current task, false otherwise
cis.any?(status = in_production) True if any CIs with the status in production are attached to the current task, false otherwise. Returns false if no CIs are associated with the task
cis.all?(status = in_production) True if all CIs related to the current task have the status "in production", false otherwise. Returns `true' if no keys are associated with the task
cis.none?(status = in_production) True if the current task is not associated with the status "in production", false otherwise. Returns `true' if the task is not linked to
workflow.tasks.select(category = approval).reject(finished_at != nil) All approval tasks related to the workflow that have not yet been completed
workflow.tasks.select(category = implementation).map(member) All participants in the implementation tasks related to the workflow
person.permissions.detect(account = ‘dc’).workflow_manager Is this person a workflow manager in the data center space?

Searching and creating records, including extracting unrelated records

The following functions are available for searching and retrieving records that are not related to the record for which the automation rule is defined, as well as for creating records.
These functions are used as the initial value of the expression up to the point and the path functions.

Syntax Arguments Result Assignment
find(type, value) record type, number, or string one record or an empty result searches for one record of an available type based on a specific source value
find_all(type, value) record type, number, string, or array of numbers/rows record array searches for all suitable records of the available type
search(type, string) record type, search string array of records, maximum 50 performs a full-text search for user-accessible records of the specified type
new(task) the type of record being created new task creates a new task in memory for further filling with actions
new(task, template) type of record being created, name/ID/template record new task with the applied template creates a new task and applies the found task template

For find and find_all, the request model is converted to a request, and the historical name change is converted to a workflow. The search is not available for Account (space) and Customer (customer), as well as for types that do not have allowed attributes or substitution columns.

For search, the type must support global search. The results are additionally filtered by the user's viewing access.

The value of new currently supports only the creation of tasks. If a template is passed, the template value must be a number, a string, or a found record of the task template.

Search examples.

Examples of expressions Result
find(person, ‘singileeva.klavdiya@pro-product.ru ’) Claudia Singileeva
find(person, ‘singileeva.klavdiya@pro-product.ru’).job_title Position of Klavdia Singileeva
find(person, workflow.requests[first].custom_fields.email) A record of a person based on the email address specified in the email field of the UI extension of the first workflow-related request
find(service_instance, 2334) Service instance with ID 2334
find(service_instance, ‘Minsk Network’) An instance of the Minsk Network service
find(ci, precursors[first].custom_fields.ci_id) Searching for a CIs based on the CIs ID selected in the UI extension of the previous task
find(ci, ‘unknown') Zero (nil)
find_all(person, ‘Singileeva Klavdiya’) List of all persons with the name of Klavdi Singileyev
find_all(ci, custom_fields.impacted_assets) An array of all CIs selected in the UI extensions field with multiple answer options
search(ci, ‘SPARCS’).detect(status = in_production) An array of all CIs in operation from a list containing no more than 50 items obtained using a global search for the keyword "SPARCS".

Examples of creating new records (for tasks only).

Examples of expressions Result
new(task) A new empty task has appeared in the rule space
new(task, ‘Finalize the change plan') A new task based on the provided template

String manipulation

String functions convert the original value to a string, with the exception of the to_date_time function, which converts the value to a date/time. If the original value is empty, empty? and blank? return "true", present? returns "false", the other functions return an empty result.

Function Arguments Result Details
. size no number returns the length of the string
.length no number returns the length of the string
.strip no line removes spaces at the beginning and end of the line
.lstrip no line removes spaces at the beginning of the line
.rstrip no line removes spaces at the end of the line
.squish no line removes extreme spaces and compresses sequences of spaces inside the line
.squeeze no string compresses duplicate characters according to the rules of the Ruby string operation
.reverse no string returns the string in reverse order
.upcase no string converts the string to uppercase
.downcase no string lowercases the string
.swapcase no string reverses the letter case
.capitalize no string capitalizes the first letter and lowercases the rest
.titleize no string brings words to the form with the uppercase first letter without removing characters from the result
.empty? no boolean value (true/false) checks an empty string
.blank? no boolean value (true/false) checks for an empty string or a string of spaces
.present? no boolean value (true/false) checks a non-empty value
.to_number no number converts a string to a floating-point number
.to_date_time no date/time or an empty result converts an ISO8601 date or ISO8601 time to a date/time
.split("separator") string array of strings splits the string according to the specified separator
.split(/regular expression/) regular expression array of strings splits a string according to a regular expression
.match?("string") string boolean value (true/false) checks for a match with the string as with an escaped pattern
.match?(/regular expression/) regular expression boolean value (true/false) checks for a regular expression match
.start_with?(value) value boolean value (true/false) checks that the string starts with the passed value
.end_with?(value) value boolean value (true/false) checks that the string ends with the passed value
.include?(value) value boolean value (true/false) checks that the string contains the passed value
.exclude?(value) value boolean value (true/false) checks that the string does not contain the passed value
.slice(N) number string returns the part of the string from position N to the end; the positive position is counted from 1
.slice(N, length) two numbers string returns the part of the string from the N position of the specified length; the positive position is counted from 1
.ljust(length) number string complements the string on the right with spaces up to the specified length
.ljust(length, placeholder) number and value string complements the string on the right with the specified placeholder
.rjust(length) number string complements the string on the left with spaces up to the specified length
.rjust(length, placeholder) number and value string complements the string on the left with the specified placeholder
.replace("what", "what") string and string string replaces all occurrences of the first string with the second
.replace(/regular expression/, "for what") regular expression and string string replaces all regular expression matches with the second string

String arguments in quotation marks are interpolated by the rule values. Regular expressions are executed with a limit of 4 seconds; if the limit is exceeded, the system adds an execution error and returns an empty result.

The following are examples of string manipulation in automation rules.

Examples of expressions Result
’hello’.lstrip Removes the initial space (‘hello’).
’hello ’.rstrip Removes spaces at the end of the string (‘hello’).
‘hello’.start_with?(‘hell’) The truth. True if the string starts with one of the specified suffixes.
‘hello’.end_with?(‘lo’) The truth. True if the string ends with one of the specified suffixes.
‘table’.match?(‘bl’) True. The value is "True" if the pattern is found in the string.
s=‘foo’, s.include?(‘f’) True. True if self contains another string.
s=‘foo’, s.exclude?('t’) True. True if self does not contain another string.
‘hello’.ljust(10) If an integer is longer than the length of the string, returns a string with left padding.
‘hello’.rjust(10, ‘oh’) If the integer is greater than the length of the string, returns a right-aligned string with padding.
subject.size Number of characters is 28.
subject.length Number of characters is 28.
’spacey string ’.strip Remove the leading and ending spaces.
’spacey string ’.squish Replace multiple spaces with a single space and remove the leading and ending spaces.
’spaceeeey ssstring ’.squeeze Replace sequences of identical characters with a single character.
‘desserts'.reverse Swap characters (‘stressed’).
‘r-service’.upcase All letters are uppercase.
‘R-SERVICE’.downcase All letters are lowercase.
‘hI tHERE’.swap Lowercase letters to uppercase and vice versa (‘Hi There’).
’ ’.empty? The truth. Returns "true" if the string is empty or contains only spaces.
’ ’.blank? The truth. Returns "true" if the string is empty or contains only spaces.
’ ’.present? Lies. Returns "true" if the string contains characters other than spaces.
‘break-me-up'.split(‘-’) Split a string into an array of strings by separator ([‘break’, ‘me’, ‘up’]).
‘break-me-up’.split(/[eau]+/) Split a string into an array of strings using the separator regular expression ([‘br’, ‘k-m’, ‘-’, ‘p’]).
‘break-me-up'.slice(3) Take a line starting from the specified file index.md and then (‘eak-me-up’).
‘break-me-up'.slice(-5) Take a line starting from the specified file index.md and then (‘me-up’).
‘break-me-up'.slice(3,2) Take a fixed number of characters from a given file index.md (‘ea’).
‘break-me-up'.replace(‘-’, ’ ’) Replace all occurrences with another string (‘break me up’).
‘break-me-up’.replace(/[eau]+/, ‘*’) Replace all occurrences of regular expression with another string (‘br*k-m*-*p’).
‘break-me-up'.replace(/([eau]+)/, ‘\1’) Replace all occurrences of regular expression with another string using capture groups (‘br*ea*k-m*e*-*u*p’).
[‘break’,‘me’,‘up’].join(’and ’) Combine the array elements using the specified separator (‘break and me and up’).
‘10.428571428571429'.to_number Convert string to number (10.428571428571429).

Manipulating numbers

Numeric functions convert the original value to a number. If the value is empty, the function returns an empty result.

Function Arguments Result Details
.round no number rounds a number to an integer
.round(precision) number number rounds the number to the specified number of digits
.to_string no string converts a number to a string

The following are examples of usage in automation rules.

Examples of expressions Result
10.428571428571429.to_string Convert a number to a string (‘10.428571428571429’).
10.428571428571429.round Rounding to an integer (10).
10.428571428571429.round(2) Rounding to the specified number of decimal places (10.43).

Date and time manipulation

Syntax What Result is applied to Purpose
.seconds / .second number duration interprets the number as seconds
.minutes / .minute number duration interprets the number as minutes
.hours / .hour number duration interprets the number as hours
.days / .day number duration interprets the number as days
.weeks / .week number duration interprets the number as weeks
.months / .month number duration interprets the number as months
.years / .year number duration interprets the number as years
.ago number or duration date/time subtracts the duration from the current moment; if there is a number on the left, it is considered seconds
.from_now number or duration date/time adds the duration to the current moment; if there is a number on the left, it counts as seconds
.is_monday ... .is_sunday date/time boolean value (true/false) checks the day of the week
.year, .month, .day date/time number returns year, month, or day
.hour, .minute, .second date/time number returns hour, minute, or second
.day_of_week date/time number returns the number of the day of the week
.day_of_year date/time number returns the number of the day in the year
.utc date/time date/time returns the same instant in Coordinated Universal Time (UTC)
.in_time_zone(hours) a string or value that gives the string date/time translates the date/time to the specified time zone; if the time zone is unknown, it adds an error
.iso8601` no string returns the date/time in the ISO8601 standard format

Please note: Some values support dot-separated attributes, although they are not domain record fields.

Please note: date and time functions .in_time_zone(clock_time) and .iso8601 first try to bring the original value to the date/time. Strings are recognized only in the ISO8601 date (YYYY-MM-DD) or ISO8601 time format.

The following are examples of usage in automation rules.

Examples of expressions Result
now >1.seconds ago <1.seconds from now (>1.seconds.ago <1.seconds.from_now)
today >1 day ago <1 day from now (>1.day.ago <1.day.from_now)
1.second.ago >2 seconds ago <0 seconds from now (>2.seconds.ago <0.seconds.from_now)
2.seconds.ago >3 seconds ago <1 second ago (>3.seconds.ago <1.second.ago)
1.minute.ago >61 seconds ago <59 seconds ago (>61.seconds.ago <59.seconds.ago)
2.minutes.ago >121 seconds ago <119 seconds ago (>121.seconds.ago <119.seconds.ago)
1.hour.ago >61 minutes ago <59 minutes ago (>61.minutes.ago <59.minutes.ago)
2.hours.ago >121 minutes ago <119 minutes ago (>121.minutes.ago <119.minutes.ago)
1.day.ago >25 hours ago <23 hours ago (>25.hours.ago <23.hours.ago)
2.days.ago >49 hours ago <47 hours ago (>49.hours.ago <47.hours.ago)
1.week.ago >8 days ago <6 days ago (>8.days.ago <6.days.ago)
2.weeks.ago >15 days ago <13 days ago (>15.days.ago <13.days.ago)
1.month.ago >32 days ago <27 days ago (>32.days.ago <27.days.ago)
2.months.ago >63 days ago <56 days ago (>63.days.ago <56.days.ago)
1.year.ago >366 days ago <364 days ago (>366.days.ago <364.days.ago)
2.years.ago >732 days ago <729 days ago (>732.days.ago <729.days.ago)
1.second.from_now >0.seconds.from_such <2.seconds.from now (>0.seconds.from_now <2.seconds.from_now)
2.seconds.from_now >1.seconds.from_such <3.seconds.from now (>1.seconds.from_now <3.second.from_now)
1.minute.from_now >59.seconds.from_such <61.seconds.from now (>59.seconds.from_now <61.seconds.from_now)
2.minutes.from_now >119.seconds.from_such <121.seconds.from now (>119.seconds.from_now <121.seconds.from_now)
1.hour.from_now >59 minutes from now <61 minutes from now (>59.minutes.from_now <61.minutes.from_now)
2.hours.from_now >119 minutes from now <121 minutes from now (>119.minutes.from_now <121.minutes.from_now)
1.day.from_now >23.hours.from_such <25.hours.currently (>23.hours.from_now <25.hours.from_now)
2.days.from_now >47.hours.currently <49.hours.currently (>47.hours.from_now <49.hours.from_now)
1.week.from_now >6.days.from_such <8.days.from now (>6.days.from_now <8.days.from_now)
2.weeks.from_now >13.days.from_such <15.days.from now (>13.days.from_now <15.days.from_now)
1.month.from_now >27 days from now <32 days from now (>27.days.from_now <32.days.from_now)
2.months.from_now >56.days.from_such <63.days.from now (>56.days.from_now <63.days.from_now)
1.year.from_now >364.days.currently <366.days.from now (>364.days.from_now <366.days.from_now)
2.years.from_now >729.days.currently <732 days.from now (>729.days.from_now <732.days.from_now)
planned_duration.hours.from_now >79.hours.currently <81.hours.currently (>79.hours.from_now <81.hours.from_now)
now.year Year, for example, 2019
now.month Month of the year, for example, the third (March)
now.day Day of the month, for example, 21
now.hour Hour of the day, for example, 19
now.minute Minute of the hour, for example, 45
now.second Second of a minute, for example, 12
now.day_of_year Day of the year, for example, 80
now.day_of_week Day of the week, for example, 4 (Thursday)
now.is_monday The day is Monday, for example, false
now.is_tuesday The day is Tuesday, for example, false
now.is_vednesday The day is Wednesday, for example, false
now.is_thursday The day is Thursday, for example, false
now.is_friday The day is Friday, for example, false
now.is_saturday The day is Saturday, for example, false
now.is_sunday The day is Sunday, for example, false
now.utc The date and time match in the UTC time zone
custom_fields.my_date_time.to_date_time Convert string date and time value obtained from custom fields to date and time format
now.in_time_zone(person.time_zone) The date and time match in the person's time zone
now.in_time_zone(rule_account.time_zone) The date and time match the time zone of the space in which the rule was created
now.in_time_zone(‘Minsk’) The same date and time in the specified time zone
now.iso8601 The same date and time in the ISO8601 standard format
duration(created_at, now) The number of minutes between creation and the current moment
template.support_hours.target_at(now, 8.hours, ‘Moscow’) Target date calculated based on support hours from the request template, start time and duration, for the Moscow time zone

Calendar manipulation

Calendar functions are applied to a value of the calendar type. If the original value is not a calendar, the function returns an empty result, and when checking the rule, the system adds an error.

Function Arguments Result Details
.target_at(start, duration) date/time, number, or duration value date/time calculates the target time according to the calendar: adds the working duration from the start time; the duration is passed in seconds and converted into minutes inside the function
.target_at(start, duration, time zone) date/time, duration, time zone string date/time same, but with a specific time zone
.duration(beginning, end) two dates/times number calculates the working duration between two calendar points
.duration(start, end, time zone) two dates/times, time zone string number the same, but with a specific time zone

If no time zone is specified, the time zone of the automation rule space is used. If the transmitted time zone is unknown, the system adds an error and returns an empty result.

Ternary statements are ternary operators

Syntax Arguments Result Assignment
condition ? if yes : if there is a condition and two values one of the two values returns the second value if the condition is non-empty, otherwise the third
condition then if else if not condition and two values one of the two values alternative notation of the ternary operator

When checking the rule in template mode, both results must have a compatible type. For example, you can't return a record in one branch and an array of records in another.

Examples of expressions Result
true then ‘yes’ else ‘no’ yes (‘yes’)
!true then ‘yes’ else ‘no’ no (‘no’)
is_assigned then teamA.id else teamB.id id of team A, if is_assigned is true
true ? ‘yes’ : ‘no’ yes (‘yes’)
!true ? ‘yes’ : ‘no’ no (‘no’)
is_assigned ? teamA.id : teamB.id id of team A, if is_assigned is true

String interpolation

You can use expressions within expressions. However, an expression can only be used if it is already defined, so the order of the expressions is important. The example below works because the expression "note" is defined before it is used in the expression "hello_note":

  • note: notes[last]
  • hello_note: “hello {{note}}”

You can change the order of expressions by dragging them up or down to ensure that each expression is defined before it is used in another expression.

Suggestions from the Rule Editor

The rule editor gets lists of functions, operators, predefined values, types, and allowed fields from the server metadata. Therefore, the names of the functions in the hints correspond to the server constants: if the function is in array_functions, string_functions, number_functions, date_time_functions or calendar_functions, the editor can show it in the appropriate place of the expression.

The hints depend on the specific type of the current value.:

  • Array functions are shown only for collection values;
  • string functions - for strings only;
  • numeric functions - for integers and fractions;
  • Date/time functions - for date, time, and types of accurate date/time capture of an event;
  • Calendar functions - only for calendar;
  • find, find_all, search and new are shown at the beginning of the value if the current position is not inside another function of the same type.;
  • Hints for _was are built from allowed fields of the current type and are not shown for collection fields.

However, there may be some discrepancies.:

Script Server Editor
start_with?(...), end_with?(...), include?(...), exclude?(...) The argument can be a variable. Parameter validation accepts a string in quotes or a regular expression, as for split / match?. The variable may be highlighted as an editor error.
ljust(length, placeholder), rjust(length, placeholder) The second argument can be a variable. The second argument is accepted as a string in quotation marks.
target_at(start, duration) The second argument can be a variable or an integer, and the runtime converts the value to a number. The editor check expects an integer type for the second argument.
Models for find, find_all, search The runtime additionally prohibits some types: for example, find(account, ...) and find(customer, ...) unavailable. Model name hints can show the type that the runtime will reject later.
Parentheses for array functions without parameters Allowed any?, none?, empty?, count, size, sum, min, max without parameters; the filter is allowed only for some functions. The editor shows all the names from the server list. If the user manually adds brackets to the function without a filter, the highlight may not match the server data.

Thus, the function names of the editor's suggestions are synchronized with the server, but the editor is not an exact copy of all the options for arguments. In a dispute, the server and the nodes of the expression runtime remain the source of truth.