| 4 minutes read | Level: Intermediate | Last Updated: October 2025 |
Split by Custom Expression
In certain flows, it is necessary to deliver different responses to different contacts based on their previous selections or stored profile attributes, such as location, batch start date, or opt-in status.
The Custom Expression is useful in scenarios where it is necessary to:
- Branch the flow according to a contact’s attribute values
- Compare dates or times
- Perform calculations within the flow (for example, days since registration)
- Combine multiple variables into a single output
Split by a custom expression` uses a coding syntax to match the response received or profile attribute.
The expression follows a format such as:
<%= if (variable_name == "string" or number), do: 1, else: 0 %>
Custom Expressions cheatsheet
1. Get Today's Date (IST)
<%= Timex.today("Asia/Kolkata") |> Date.to_string() %>
2. Get Today's Date and Time (IST)
<%= DateTime.now!("Asia/Kolkata") |> DateTime.to_string() %>
3. Adding the Date and Time Stamp
To capture the date and time. Example - start time of a flow and the end time of a flow, following custom expression can be used
<%= DateTime.now!("Asia/Kolkata") |> Calendar.strftime("%H:%M:%S") %>
Add a Update Contact node and pass the mentioned expression.
4. Calculating the Time Difference
Use case: To calculate the time taken by a contact to complete the flow. Considering the prerequisite that the start time and end time are captured at the flow level in separate variables, the difference can be calculated using the following expression.
<%= Time.diff(Time.from_iso8601!("@contact.fields.time_end"), Time.from_iso8601!("@contact.fields.time_start"), :second) %>
The above expression calculates the difference between @contact.fields.time_end and @contact.fields.time_start in seconds. And the screenshot below updates this difference to a contact variable @contact.fields.timer using update the contact node.
5. Calculating the Difference Between Two Dates
Use case: Calculating the date difference between the current date and a given date (e.g., batch start date or onboarding date of the contact). Here, @calendar.current_date is used to store the batch start date at the time of onboarding.
@calendar.current_date returns the date in the format D/0M/YYYY, where:
D = day without a leading zero
0M = month with a leading zero
YYYY = full numeric year
For example:
- 2nd January 2025 → 2/01/2025
- 11th October 2024 → 11/10/2024
The following expression can be used to calculate the difference in days between the current date and the stored batch start date:
<%= "@contact.fields.batch_start_date"|>Timex.parse!("{D}/{0M}/{YYYY}") |> then(&(Timex.diff(Timex.now(), &1, :day))) %>
In the screenshot, this expression calculates the date difference and updates the value to a new flow result: @results.datediff
6. Concatenating Strings or Variables
- To combine two variables in a contact field.
- In the given example,
@results.Var1@results.Var2are joined.
- Use Case: Suppose
@results.grade.categorycontains the value 2 and@contact.fields.s_acpcontains the value 4, then the the value of the@contact.fields.present_grade_acpis updated to value of “Grade 2 ACP 4”, By simply writing Grade@results.grade.categoryACP@contact.fields.s_acpto update a contact field calledpresent_grade_acp.
- Similarly, other example of concatenating the node is the following node which Updates the value of
@contact.fields.cumulative_acp - By adding a comma and the value contained in
@contact.fields.present_grade_acpto the already existing values in@contact.fields.cumulative_acp - Suppose the
@contact.fields.cumulative_acpis set to 0, and suppose the value of@contact.fields.present_grade_acpcontains the value Grade 1 ACP 1, then after the node is encountered, the updated value of@contact.fields.cumulative_acpbecomes 0, Grade 2 ACP 1 - In the next flow, if the
@contact.fields.present_grade_acpcontains the value Grade 1 ACP 2, then after encountering the same node, the value of @contact.fields.cumulative_acp is updated to 0, Grade 1 ACP 1, Grade 2 ACP 1 - In this way, a contact variable can be used to store the history of progression/ paths taken by a contact.
7. Converting a string to lowercase.
- Any input variable can be converted to lowercase by using the following expression:
<%= String.downcase(“@results.resultname”) %> - In the above expression
@results.resultnamecan be replaced with the string or the flow variable or the contact variable containing the string that needs to be converted to lowercase. - In the screenshot given below, two tasks are happening at once The flow variable
@results.flow_keyword.inputis getting converted to the lowercase The lowercase value of flow variable@results.flow_keyword.inputis getting saved to the contact variable keyword
Use case: Same flow can be started using multiple keywords. The keyword entered by a contact is used to determine which partner org, city and school is the contact representing. This data is picked up from a separate google sheet maintained by the NGO. Thus reducing the step by the contact to share details like org, school name, city.
8. Validating Date Format and Range
WhatsApp interface does not enable providing a calendar menu to select and enter dates. In order to accomplish collection of cleaner date format, following custom expression can be used:
To capture the date in DD/MM/YYYY format(Validating date input using Split By or Wait for Response)
- Use
split bynode or in thewait for responseinclude the validation condition formatches regexand check the following . In the given examplesplit bywas used with the following regex:
^(0[1-9]|[12][0-9]|3[01])/(0[1-9]|1[0-2])/(?:202[5-9]|2030)$
How it works:
-
(0[1-9]|[12][0-9]|3[01])- Ensures the DD value (numbers before the /) is between 01 and 31. -
(0[1-9]|1[0-2])- Ensures the MM value does not exceed 12. -
(?:202[5-9]|2030)- Ensures the YYYY value is between 2025 and 2030. -
Customisation: You can modify the regex to match other formats, such as MM/DD/YYYY or DD-MM-YYYY, by adjusting the sequence and separators accordingly.
9. Validating Time Format (24 Hour)
Users can use a Split By node or, in a Wait for Response node, include a validation condition with Matches Regex to validate time inputs.
In the given example, the regex used is:
([01][0-9]|2[0-3]):([0-5][0-9])$
How it works:
([01][0-9]|2[0-3])→ Ensures the hour value is between 00 and 23.([0-5][0-9])→ Ensures the minutes value is between 00 and 59.:→ The colon acts as the delimiter between hours and minutes.
Advanced Syntax Examples
- Syntax to check if contact belongs to a specific collection (collection 1 or collection 2)
<%= if "collection 1" in @contact.in_groups, do: 1, else: if "collection 2" in @contact.in_groups, do: 2, else: 3 %>
Add a Split by expression node and the above mentioned expression.
-
Syntax to check if the contact is registered or not.
<%= if "@contact.fields.is_registered" == "1" , do: 1, else: 0 %> -
Syntax to check if the contact has opted-in or not.
<%= if @contact.optin_status == true, do: 1, else: 2%>
- Any variable created and saved can be used to make decisions within a
Split By custom expression. - Writing the correct syntax for a
Split By expressionrequires some coding knowledge. If you have specific requirements or need help crafting the right expression, please reach out to us on Discord. We’ll be happy to share the exact syntax tailored to your needs.