Expressions in On-chat.live: Dynamic Message Personalization Guide

Expressions

Overview

Excellent gets its name from borrowing some of the syntax and function names of formulas in Microsoft Excel™, though it has evolved over time and similarities are now much fewer. It is an expression based templating language which aims to make it easy to generate text from a context of values.

Templates

Templates can contain single variables or more complex expressions. A single variable is embedded using the __at__ character. For example the template Hi@foo contains a single variable which at runtime will be replaced with the value of foo in the context.

More complex expressions can be embedded using the __at__(...) syntax. For example the template Hi@("Dr " & upper(foo)) takes the value of foo, converts it to uppercase, and then prefixes it with another string.

The __at__ symbol can be escaped in templates by repeating it, e.g, Hi@__at__twitter will output Hi@twitter.

Types

Array

Is an array of items.

          @(array(1, "x", true)) → [1, x, true]
          @(array(1, "x", true)[1]) → x
          @(count(array(1, "x", true))) → 3
          @(json(array(1, "x", true))) → [1,"x",true]

Boolean

Is a boolean true or false.

  @(true) → true
  @(1 = 1) → true
  @(1 = 2) → false
  @(json(true)) → true

Date

Is a Gregorian calendar date value.

  @(date_from_parts(2019, 4, 11)) → 2019-04-11
  @(format_date(date_from_parts(2019, 4, 11))) → 11-04-2019
  @(json(date_from_parts(2019, 4, 11))) → "2019-04-11"

DateTime

Is a datetime value.

  @(datetime("1979-07-18T10:30:45.123456Z")) → 1979-07-18T10:30:45.123456Z
  @(format_datetime(datetime("1979-07-18T10:30:45.123456Z"))) → 18-07-1979 05:30
  @(json(datetime("1979-07-18T10:30:45.123456Z"))) → "1979-07-18T10:30:45.123456Z"

Function

Is a callable function.

  @(upper) → upper
  @(array(upper)[0]("abc")) → ABC
  @(json(upper)) → null

Number

Is a whole or fractional number.

  @(1234) → 1234
  @(1234.5678) → 1234.5678
  @(format_number(1234.5670)) → 1,234.567
  @(json(1234.5678)) → 1234.5678

Object

Is an object with named properties.

  @(object("foo", 1, "bar", "x")) → {bar: x, foo: 1}
  @(object("foo", 1, "bar", "x").bar) → x
  @(object("foo", 1, "bar", "x")["bar"]) → x
  @(count(object("foo", 1, "bar", "x"))) → 2
  @(json(object("foo", 1, "bar", "x"))) → {"bar":"x","foo":1}

Text

Is a string of characters.

  @("abc") → abc
  @(text_length("abc")) → 3
  @(upper("abc")) → ABC
  @(json("abc")) → "abc"

Time

Is a time of day.

  @(time_from_parts(16, 30, 45)) → 16:30:45.000000
  @(format_time(time_from_parts(16, 30, 45))) → 16:30
  @(json(time_from_parts(16, 30, 45))) → "16:30:45.000000"

Operators

Overview

Operators are fundamental in expressions, providing the ability to perform arithmetic, comparison, and other operations on values. Here’s an overview of common operators.

+ Add

Adds two numbers.

  @(2 + 3) → 5
  @(fields.age + 10) → 33

& Concatenate

Joins two text values together.

  @("hello" & " " & "bar") → hello bar
  @("hello" & null) → hello

/ Divide

Divides a number by another.

  @(4 / 2) → 2
  @(3 / 2) → 1.5
  @(46 / fields.age) → 2
  @(3 / 0) → ERROR

= Equal

Returns true if two values are equal.

  @("hello" = "hello") → true
  @("hello" = "bar") → false
  @(1 = 1) → true

^ Exponent

Raises a number to the power of another.

  @(2 ^ 8) → 256
        

> Greater Than

Returns true if the first number is greater than the second.

  @(2 > 3) → false
  @(4 > 3) → true

< Less Than

Returns true if the first number is less than the second.

  @(2 < 3) → true
  @(4 < 3) → false

* Multiply

Multiplies two numbers.

  @(3 * 2) → 6
  @(fields.age * 3) → 69

!= Not Equal

Returns true if two values are not equal.

  @("hello" != "hello") → false
  @("hello" != "bar") → true

Functions

Functions

Expressions have access to a set of built-in functions which can be used to perform more complex tasks. Functions are called using the __at__(function_name(args..)) syntax, and can take as arguments either literal values __at__(length(split("1 2 3", " ")) or variables in the context __at__(title(contact.name)).

__at__(length(split("1 2 3", " ")) or variables in the context __at__(title(contact.name)).

abs(number)

Returns the absolute value of number

and(values…)

Returns whether all the given values are truthy.

array(values…)

Takes multiple values and returns them as an array.

attachment_parts(attachment)

Parses an attachment into its different parts

boolean(value)

Tries to convert value to a boolean.

An error is returned if the value can’t be converted.

char(code)

Returns the character for the given UNICODE code.

It is the inverse of code.

clean(text)

Removes any non-printable characters from text.

code(text)

Returns the UNICODE code for the first character of text.

It is the inverse of char.

concat(array1, array2)

Returns the result of concatenating two arrays.

count(value)

Returns the number of items in the given array or properties on an object.

It will return an error if it is passed an item which isn’t countable.

date(value)

Tries to convert value to a date.

If it is text then it will be parsed into a date using the default date format. An error is returned if the value can’t be converted.

date_from_parts(year, month, day)

Creates a date from year, month and day.

datetime(value)

Tries to convert value to a datetime.

If it is text then it will be parsed into a datetime using the default date and time formats. An error is returned if the value can’t be converted.

datetime_add(datetime, offset, unit)

Calculates the date value arrived at by adding offset number of unit to the datetime

Valid durations are “Y” for years, “M” for months, “W” for weeks, “D” for days, “h” for hour, “m” for minutes, “s” for seconds

datetime_diff(date1, date2, unit)

Returns the duration between date1 and date2 in the unit specified.

Valid durations are “Y” for years, “M” for months, “W” for weeks, “D” for days, “h” for hour, “m” for minutes, “s” for seconds.

datetime_from_epoch(seconds)

Converts the UNIX epoch time seconds into a new date.

default(value, default)

Returns value if is not empty or an error, otherwise it returns default.

epoch(date)

Converts date to a UNIX epoch time.

The returned number can contain fractional seconds.

extract(object, properties)

Takes an object and extracts the named property.

extract_object(object, properties…)

Takes an object and returns a new object by extracting only the named properties.

field(text, index, delimiter)

Splits text using the given delimiter and returns the field at index.

The index starts at zero. When splitting with a space, the delimiter is considered to be all whitespace.

foreach(values, func, [args…])

Creates a new array by applying func to each value in values.

If the given function takes more than one argument, you can pass additional arguments after the function.

foreach_value(object, func, [args…])

Creates a new object by applying func to each property value of object.

If the given function takes more than one argument, you can pass additional arguments after the function.

format(value)

Formats value according to its type.

format_date(date, [,format])

Formats date as text according to the given format.

If format is not specified then the environment’s default format is used. The format string can consist of the following characters. The characters ’ ‘,’:‘,’,‘, ’T’, ‘-’ and ’_’ are ignored. Any other character is an error.

  • YY - last two digits of year 0-99
  • YYYY - four digits of year 0000-9999
  • M - month 1-12
  • MM - month, zero padded 01-12
  • MMM - month Jan-Dec (localized)
  • MMMM - month January-December (localized)
  • D - day of month, 1-31
  • DD - day of month, zero padded 01-31
  • EEE - day of week Mon-Sun (localized)
  • EEEE - day of week Monday-Sunday (localized)

format_datetime(datetime [,format [,timezone]])

Formats datetime as text according to the given format.

If format is not specified then the environment’s default format is used. The format string can consist of the following characters. The characters ’ ‘,’:‘,’,‘, ’T’, ‘-’ and ’_’ are ignored. Any other character is an error.

  • YY - last two digits of year 0-99
  • YYYY - four digits of year 0000-9999
  • M - month 1-12
  • MM - month, zero padded 01-12
  • MMM - month Jan-Dec (localized)
  • MMMM - month January-December (localized)
  • D - day of month, 1-31
  • DD - day of month, zero padded 01-31
  • EEE - day of week Mon-Sun (localized)
  • EEEE - day of week Monday-Sunday (localized)
  • h - hour of the day 1-12
  • hh - hour of the day, zero padded 01-12
  • t - twenty four hour of the day 0-23
  • tt - twenty four hour of the day, zero padded 00-23
  • m - minute 0-59
  • mm - minute, zero padded 00-59
  • s - second 0-59
  • ss - second, zero padded 00-59
  • fff - milliseconds
  • ffffff - microseconds
  • fffffffff - nanoseconds
  • aa - am or pm (localized)
  • AA - AM or PM (localized)
  • Z - hour and minute offset from UTC, or Z for UTC
  • ZZZ - hour and minute offset from UTC

Timezone should be a location name as specified in the IANA Time Zone database, such as “America/Guayaquil” or “America/Los_Angeles”. If not specified, the current timezone will be used. An error will be returned if the timezone is not recognized.

format_location(location)

Formats the given location as its name.

format_number(number, places [, humanize])

Formats number to the given number of decimal places.

An optional third argument humanize can be false to disable the use of thousand separators.

format_time(time [,format])

Formats time as text according to the given format.

If format is not specified then the environment’s default format is used. The format string can consist of the following characters. The characters ’ ‘,’:‘,’,‘, ’T’, ‘-’ and ’_’ are ignored. Any other character is an error.

  • h - hour of the day 1-12
  • hh - hour of the day, zero padded 01-12
  • t - twenty four hour of the day 0-23
  • tt - twenty four hour of the day, zero padded 00-23
  • m - minute 0-59
  • mm - minute, zero padded 00-59
  • s - second 0-59
  • ss - second, zero padded 00-59
  • fff - milliseconds
  • ffffff - microseconds
  • fffffffff - nanoseconds
  • aa - am or pm (localized)
  • AA - AM or PM (localized)

format_urn(urn)

Formats urn into human friendly text.

html_decode(text)

HTML decodes text

if(test, value1, value2)

Returns value1 if test is truthy or value2 if not.

If the first argument is an error that error is returned.

is_error(value)

Returns whether value is an error

join(array, separator)

Joins the given array of strings with separator to make text.

json(value)

Returns the JSON representation of value.

lower(text)

Converts text to lowercase.

max(numbers…)

Returns the maximum value in numbers.

mean(numbers…)

Returns the arithmetic mean of numbers.

min(numbers…)

Returns the minimum value in numbers.

mod(dividend, divisor)

Returns the remainder of the division of dividend by divisor.

now()

Returns the current date and time in the current timezone.

number(value)

Tries to convert value to a number.

An error is returned if the value can’t be converted.

object(pairs…)

Takes property name value pairs and returns them as a new object.

or(values…)

Returns whether if any of the given values are truthy.

parse_datetime(text, format [,timezone])

Parses text into a date using the given format.

The format string can consist of the following characters. The characters ’ ‘,’:‘,’,‘, ’T’, ‘-’ and ’_’ are ignored. Any other character is an error.

  • YY - last two digits of year 0-99
  • YYYY - four digits of year 0000-9999
  • M - month 1-12
  • MM - month, zero padded 01-12
  • D - day of month, 1-31
  • DD - day of month, zero padded 01-31
  • h - hour of the day 1-12
  • hh - hour of the day 01-12
  • t - twenty four hour of the day 1-23
  • tt - twenty four hour of the day, zero padded 01-23
  • m - minute 0-59
  • mm - minute, zero padded 00-59
  • s - second 0-59
  • ss - second, zero padded 00-59
  • fff - milliseconds
  • ffffff - microseconds
  • fffffffff - nanoseconds
  • aa - am or pm
  • AA - AM or PM
  • Z - hour and minute offset from UTC, or Z for UTC
  • ZZZ - hour and minute offset from UTC

Timezone should be a location name as specified in the IANA Time Zone database, such as “America/Guayaquil” or “America/Los_Angeles”. If not specified, the current timezone will be used. An error will be returned if the timezone is not recognized.

Note that fractional seconds will be parsed even without an explicit format identifier. You should only specify fractional seconds when you want to assert the number of places in the input format.

parse_datetime will return an error if it is unable to convert the text to a datetime.

parse_json(text)

Tries to parse text as JSON.

If the given text is not valid JSON, then an error is returned

parse_time(text, format)

Parses text into a time using the given format.

The format string can consist of the following characters. The characters ’ ‘,’:‘,’,‘, ’T’, ‘-’ and ’_’ are ignored. Any other character is an error.

  • h - hour of the day 1-12
  • hh - hour of the day, zero padded 01-12
  • t - twenty four hour of the day 1-23
  • tt - twenty four hour of the day, zero padded 01-23
  • m - minute 0-59
  • mm - minute, zero padded 00-59
  • s - second 0-59
  • ss - second, zero padded 00-59
  • fff - milliseconds
  • ffffff - microseconds
  • fffffffff - nanoseconds
  • aa - am or pm
  • AA - AM or PM

Note that fractional seconds will be parsed even without an explicit format identifier. You should only specify fractional seconds when you want to assert the number of places in the input format.

parse_time will return an error if it is unable to convert the text to a time.

percent(number)

Formats number as a percentage.

rand()

Returns a single random number between [0.0-1.0).

rand_between()

A single random integer in the given inclusive range.

read_chars(text)

Converts text into something that can be read by IVR systems.

ReadChars will split the numbers such as they are easier to understand. This includes splitting in 3s or 4s if appropriate.

regex_match(text, pattern [,group])

Returns the first match of the regular expression pattern in text.

An optional third parameter group determines which matching group will be returned.

remove_first_word(text)

Removes the first word of text.

repeat(text, count)

Returns text repeated count number of times.

replace(text, needle, replacement [, count])

Replaces up to count occurrences of needle with replacement in text.

If count is omitted or is less than 0 then all occurrences are replaced.

replace_time(datetime)

Returns a new datetime with the time part replaced by the time.

reverse(array)

Returns a new array with the values of array reversed.

round(number [,places])

Rounds number to the nearest value.

You can optionally pass in the number of decimal places to round to as places. If places < 0, it will round the integer part to the nearest 10^(-places).

round_down(number [,places])

Rounds number down to the nearest integer value.

You can optionally pass in the number of decimal places to round to as places.

round_up(number [,places])

Rounds number up to the nearest integer value.

You can optionally pass in the number of decimal places to round to as places.

sort(array)

Returns a new array with the values of array sorted.

split(text, [,delimiters])

Splits text into an array of separated words.

Empty values are removed from the returned list. There is an optional final parameter delimiters which is string of characters used to split the text into words.

sum(array)

Sums the items in the given array.

text(value)

Tries to convert value to text.

An error is returned if the value can’t be converted.

text_compare(text1, text2)

Returns the dictionary order of text1 and text2.

The return value will be -1 if text1 comes before text2, 0 if they are equal and 1 if text1 comes after text2.

text_length(value)

Returns the length (number of characters) of value when converted to text.

text_slice(text, start [, end])

Returns the portion of text between start (inclusive) and end (exclusive).

If end is not specified then the entire rest of text will be included. Negative values for start or end start at the end of text.

time(value)

Tries to convert value to a time.

If it is text then it will be parsed into a time using the default time format. An error is returned if the value can’t be converted.

time_from_parts(hour, minute, second)

Creates a time from hour, minute and second

title(text)

Capitalizes each word in text.

today()

Returns the current date in the environment timezone.

trim(text, [,chars])

Removes whitespace from either end of text.

There is an optional final parameter chars which is string of characters to be removed instead of whitespace.

trim_left(text, [,chars])

Removes whitespace from the start of text.

There is an optional final parameter chars which is string of characters to be removed instead of whitespace.

trim_right(text, [,chars])

Removes whitespace from the end of text.

There is an optional final parameter chars which is string of characters to be removed instead of whitespace.

tz(date)

Returns the name of the timezone of date.

If no timezone information is present in the date, then the current timezone will be returned.

tz_offset(date)

Returns the offset of the timezone of date.

The offset is returned in the format [+/-]HH:MM. If no timezone information is present in the date, then the current timezone offset will be returned.

unique(array)

Returns the unique values in array.

upper(text)

Converts text to uppercase.

url_encode(text)

Encodes text for use as a URL parameter.

urn_parts(urn)

Parses a URN into its different parts

week_number(date)

Returns the week number (1-54) of date.

The week is considered to start on Sunday and week containing Jan 1st is week number 1.

weekday(date)

Returns the day of the week for date.

The week is considered to start on Sunday so a Sunday returns 0, a Monday returns 1 etc.

word(text, index [,delimiters])

Returns the word at index in text.

Indexes start at zero. There is an optional final parameter delimiters which is string of characters used to split the text into words.

word_count(text [,delimiters])

Returns the number of words in text.

There is an optional final parameter delimiters which is string of characters used to split the text into words.

word_slice(text, start, end [,delimiters])

Extracts a sub-sequence of words from text.

The returned words are those from start up to but not-including end. Indexes start at zero and a negative end value means that all words after the start should be returned. There is an optional final parameter delimiters which is string of characters used to split the text into words.