Skip to content

Build

Expressions

Write small formulas to compute values and check conditions in Set variables, Switch and Filter.

Where you write expressions#

An expression is a one-line formula, like in a spreadsheet. You write them in:

  • Set variables: each row's value, for example trim(@full_name).
  • Switch: the value to route on, and Condition cases such as value > 100.
  • Filter: Expression conditions, which must be true or false.

The editor checks what you type as you go. Looks good means it can be read; otherwise it says what's wrong and at which character.

The building blocks#

WriteMeansExample
@nameThe customer's answer to the step called name, or a value from Set variables@city is Haifa
#nameData: from a Catch Hook or HTTP step, Set variables, or the system (#cphone, #channel, #now)#order.items[0].sku
"text" or 'text'Fixed text. Always in quotes"Tel Aviv"
12, 3.5Numbers, without quotes@age >= 18
true, false, nullYes, no, and "no value"exists(#coupon) == false
[1, 2], {"a": 1}A list, an object#status in ["paid", "sent"]

The text forms {{@city}} and {{#order.id}} work too, so you can paste a variable from a message.

Operators#

OperatorDoesExampleResult
+ - * / %Math. Number-like text counts as a number@age + 1 with age 3132
+ on two textsJoins them"Tel" + " Aviv"Tel Aviv
== != < <= > >=Compare. Numbers as numbers, dates as dates"31" > 18true
&& || ! (or and or not)And, or, not@age >= 18 && @city == "Haifa"true / false
in, not inIs in a list, text or object"a" in "abc"true
??Fallback when missing or empty@nickname ?? "there"there
cond ? a : bIf / elsenumber(@age) >= 18 ? "adult" : "minor" with age 15minor

Functions can also be written after a value: @city.lower() is the same as lower(@city).

Test an expression#

  1. 1

    Open the test

    Under the expression, click Test expression.

  2. 2

    Add sample values

    In Sample variables, write one per line: @age = 31, #tour = {"name": "Jaffa"}. If the expression reads fine, click Add the variables this expression uses to list them for you.

  3. 3

    Pin the time (optional)

    For date functions, add a line like now = 2026-10-16T09:00+03:00. Include your time-zone offset: without it the time is read as UTC.

  4. 4

    Run it

    Click Run. The Result shows the value and its type: text, number, true / false, date, list or object. In a Switch condition, also fill in Switch value to test with.

Tests never send messages or alerts, so try as many values as you like, including empty and wrong answers.

Functions: Text#

Click Functions under any expression to see this list and insert a function at the cursor.

FunctionDoesExampleResult
length(x)Characters in a text, items in a list or keys in an objectlength("Tel Aviv")8
lower(text)Lowercaselower("YES")yes
upper(text)Uppercaseupper("tlv")TLV
trim(text)Removes spaces at both endstrim(" Noa ")Noa
contains(textOrList, value)Text contains a part, or a list contains an itemcontains(["he", "en"], "en")true
startsWith(text, prefix)Text starts with a prefixstartsWith(#cphone, "972")true
endsWith(text, suffix)Text ends with a suffixendsWith(@email, ".co.il")true for noa@shop.co.il
replace(text, find, with)Replaces every occurrence (plain text)replace("050-123-4567", "-", "")0501234567
split(text, separator)Splits text into a listsplit("red,green,blue", ",")["red","green","blue"]
join(list, separator)Joins a list into text (default ", ")join(["Sun", "Mon", "Tue"], " / ")Sun / Mon / Tue
substr(text, start, count)Part of a text; start counts from 0substr("ORD-12345", 4)12345
indexOf(textOrList, value)Position (from 0), or -1 when missingindexOf("hello", "l")2
matches(text, pattern, flags)Regular expression search; flag "i" ignores casematches(@id, "^\d{9}$")true for 123456789

Functions: Convert#

FunctionDoesExampleResult
text(x)Converts to texttext(42)42 (text)
number(x)Converts text such as "42" or "3.5" to a numbernumber("3.5") + 14.5
int(x)Whole number part (drops decimals)int("7.9")7
bool(x)true / false; "true", "yes", "1" and "כן" are truebool("yes")true
json(x)The value as JSON textjson({"id": 7, "tags": ["a"]}){"id":7,"tags":["a"]}

Functions: Numbers#

FunctionDoesExampleResult
round(number, digits)Rounds; halves go away from zeroround(4.567, 2)4.57
floor(number)Rounds downfloor(4.9)4
ceil(number)Rounds upceil(4.1)5
abs(number)Absolute valueabs(-3)3
min(a, b, ...) or min(list)Smallest numbermin(3, 7, 1)1
max(a, b, ...) or max(list)Largest numbermax([120, 80, 95])120
sum(list)Adds the numbers of a listsum([10, 20, 5])35

Functions: Empty values#

FunctionDoesExampleResult
default(x, fallback)x, or the fallback when x is missing or emptydefault(@city, "Tel Aviv")Tel Aviv when no city
coalesce(a, b, ...)The first value that isn't missing or emptycoalesce(@nickname, @full_name, "there")Noa
isEmpty(x)true when x is missing, "", [] or {}isEmpty(@notes)true when skipped
exists(x)true when x has a value (isn't missing)exists(#coupon)false when no coupon was sent

Functions: Lists and objects#

In these examples #items is [{"sku": "TSHIRT-M", "qty": 2}, {"sku": "CAP", "qty": 1}] and #tours is [{"name": "Jaffa", "price": 80}, {"name": "Galilee", "price": 150}].

FunctionDoesExampleResult
keys(object)The keys of an objectkeys({"a": 1, "b": 2})["a","b"]
values(object)The values of an objectvalues({"a": 1, "b": 2})[1,2]
first(list)First item (empty for an empty list)first([5, 6, 7])5
last(list)Last itemlast([5, 6, 7])7
pluck(list, "field")The field of every objectpluck(#items, "sku")["TSHIRT-M","CAP"]
find(list, "field", value)First object whose field equals valuefind(#items, "sku", "CAP").qty1
count(list, "field", value)How many objects have that field valuecount(#orders, "status", "paid")2
unique(list)Removes repeated itemsunique([1, 2, 2, 3])[1,2,3]
sortBy(list, "field", "asc" | "desc")Sorts by a field; empty values go lastmap(sortBy(#tours, "price", "desc"), item.name)["Galilee","Jaffa"]
byLang(object, "HE", "EN")Picks language versions: name_HE / name_EN become namebyLang(#tour, "HE").nameיפו
byLang(list, "field", "EN")Just that field, in that languagebyLang(#tours, "name", "EN")["Jaffa","Galilee"]
filter(list, condition)The items for which the condition is truefilter(#tours, item.price > 100)the Galilee tour
map(list, expression)A new list with the expression applied to each itemmap(#tours, item.name)["Jaffa","Galilee"]

In filter() and map(), item is the current item and index its position (from 0). They chain: #tours.filter(item.price > 100).map(item.name) gives ["Galilee"]. byLang() falls back to the second language (default EN) when a version is missing or empty.

Functions: Dates and holidays#

Dates use Israel time (Asia/Jerusalem) unless you pass a time zone. Date answers such as 13/10/2026 work directly in date functions. A date shows as DD/MM/YYYY HH:mm, or DD/MM/YYYY at midnight.

FunctionDoesExampleResult
now(timeZone)Current date and timenow("Europe/London")15/10/2026 12:30
today(timeZone)Today at 00:00today()15/10/2026
parseDate(text, format, timeZone)Reads a date. Without a format: day first, or YYYY-MM-DDparseDate("10/13/2026 14:30", "MM/DD/YYYY HH:mm")13/10/2026 14:30
formatDate(date, format)Date as text, default "DD/MM/YYYY"formatDate(now(), "DD/MM/YYYY HH:mm")15/10/2026 14:30
dayOfWeek(date)1 = Sunday ... 7 = SaturdaydayOfWeek(parseDate("16/10/2026"))6
dayName(date, "he")Name of the day, "en" (default) or "he"dayName(parseDate("16/10/2026"), "he")שישי
isFriday(date)true on FridaysisFriday(parseDate("16/10/2026"))true
isSaturday(date)true on SaturdaysisSaturday(parseDate("16/10/2026"))false
isWeekend(date)true on Friday and SaturdayisWeekend(parseDate("17/10/2026"))true
addDays(date, days)Adds days (negative subtracts)addDays(parseDate("13/10/2026"), 3)16/10/2026
addHours(date, hours)Adds hoursaddHours(parseDate("13/10/2026 09:00"), 2)13/10/2026 11:00
addMinutes(date, minutes)Adds minutesaddMinutes(parseDate("13/10/2026 09:00"), 30)13/10/2026 09:30
diffDays(from, to)Calendar days between two datesdiffDays(parseDate("13/10/2026"), parseDate("20/10/2026"))7
diffMinutes(from, to)Whole minutes between two datesdiffMinutes(parseDate("13/10/2026 09:00"), parseDate("13/10/2026 10:30"))90
minutesUntil(date)Minutes from now (negative when past)minutesUntil(parseDate("15/10/2026 16:00")) at 15:0060
daysUntil(date)Calendar days from todaydaysUntil(parseDate("01/01/2027")) on 15/10/202678
hour(date), minute(date)Hour 0-23, minute 0-59hour(parseDate("13/10/2026 14:30"))14
day(date), month(date), year(date)Day 1-31, month 1-12, yearmonth(parseDate("13/10/2026"))10
isTimeBetween(date, "09:30", "18:00")Time of day from start (included) to end (excluded); overnight worksisTimeBetween(parseDate("13/10/2026 23:30"), "20:00", "02:00")true
isIsraeliHoliday(date, "public")Israeli rest-day holiday; "all" adds Chol HaMoed, Purim, Hanukkah and moreisIsraeliHoliday(parseDate("05/12/2026"), "all")true (Hanukkah)
isHolidayEve(date)The day before a rest-day holiday (Erev Chag)isHolidayEve(parseDate("20/09/2026"))true
holidayName(date, "he", "public")The holiday's name, or empty. Hebrew by defaultholidayName(parseDate("21/09/2026"), "en")Yom Kippur
isOpenAt(hours, date)Open at that date and timeisOpenAt(#hours, parseDate("16/10/2026 14:00"))false with Friday 09:00 - 13:00
isOpenNow(hours, timeZone)Open right nowisOpenNow(#hours)true / false

Opening hours for isOpenAt and isOpenNow are an object by day: {"Sunday": "09:00 - 18:00", "Thursday": "09:00-13:00, 16:00-20:00", "Saturday": "closed"}. Use English or Hebrew day names; several ranges with commas; a range past midnight like "20:00 - 02:00" works; a missing day is closed.

Date formats use DD, MM, YYYY, YY, HH, mm and ss in any order with any separators.

Example#

A restaurant decides how to answer a booking request. In a Filter Expression condition:

Condition
!isIsraeliHoliday(parseDate(@visit_date)) && dayOfWeek(parseDate(@visit_date)) != 7 && number(@guests) <= 12

Test it with @visit_date = 16/10/2026 and @guests = 4: the result is true, so the customer goes to the booking path. With @guests = 20 it's false, and they're offered a call with the manager instead.

Common mistakes#

What you seeWhyFix
Unknown nameText without quotes, like Tel AvivWrite "Tel Aviv", or @Tel / #Tel if you meant a variable
The expression can't be readA missing quote or bracketClose every ", ( and [
Unknown functionA typo, like lenght()The message suggests the right one: length()
Wrong number of valuesToo many or too few valuesCheck the function in the Functions list
These values don't fit togetherFor example number("four")Ask with a Number step, or use default()
The expression is too big / takes too longOver 2,000 characters, or huge listsSplit it into several Set variables rows

When an expression fails while a customer is chatting, the bot doesn't stop: Set variables leaves the value empty, Filter treats the condition as false, and Switch follows Default. You get an alert so you can fix it.