Skip to main content

Custom Expression

2 minute read                                                                                                                 Intermediate


Splitting Responses based on Contact choices or Attribute values

There may be situations wherein a flow you would want to send different responses to different contacts based on their choices.

You can use the Split by a custom expression option to make that happen.

Split by a custom expression uses a coding syntax to match the response received or profile attribute.

The syntax will be like <%= if (Variable name == 'String' / number ), do: 1, else: 0 %>


Custom Expressions cheatsheet

1. Get today's date in IST

<%= Timex.today("Asia/Kolkata") |> Date.to_string() %>

2. Get today's date and time in IST

<%= DateTime.now!("Asia/Kolkata") |> DateTime.to_string() %>

3. Adding the date and time stamp

Use case: @calendar.current_date does not add the time stamp. To capture the date and time. Ex 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") %>

Screenshot 2025-03-31 at 9 06 22 PM

4. Calculating the time difference

Use case: to calculator the time taken by a contact to complete the flow. Considering the pre-requisite that the start time and end time are captured at the flow level in separate variables, the difference can be calculated by 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.

Screenshot 2025-03-31 at 9 06 53 PM

5. Doing calculations between dates

Use case: Calculating the date difference between the present date and the a given date (ex batch start date or a date of onboarding the contact). Considering that @calendar.current_date is being used as the expression to store the batch start date at the time of onboarding.

@calendar.current_date gets the date in the following format; D/0M/YYYY which translated to date without leading zero, month with a leading zero and full numeric year.

This means 2nd january 2025 will be represented as 2/01/2025, and 11th Oct 2024 will be represented as 11/10/2024

The following expression can then be used to calculate the difference in dates between any <%= "@contact.fields.batch_start_date"|>Timex.parse!("{D}/{0M}/{YYYY}") |> then(&(Timex.diff(Timex.now(), &1, :day))) %>

In the screenshot, the expression is used to calculate the date difference and the value of this calculation is updated to a new flow result @results.datediff

Screenshot 2025-03-31 at 9 07 50 PM

6. String concatenation function

Put two variables in the results field in the update contact node. _@results.Var1 @results.Var2

Screenshot 2023-08-30 at 12 26 12 PM
  • Contactenation of multiple strings or flow results or contact variables can be done by simply adding those values in the update the contact or update the flow result node.
  • By simply writing Grade @results.grade.category ACP @contact.fields.s_acp to update a contact field called present_grade_acp.
  • Suppose @results.grade.category contains the value 2 and @contact.fields.s_acp contains the value 4, then the the value of the @contact,fields.present_grade_acp is updated to value of “Grade 2 ACP 4” when the following node is encountered
Screenshot 2025-03-31 at 9 10 05 PM
  • 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_acp to the already existing values in @contact.fields.cumulative_acp
  • Suppose the @contact.fields.cumulative_acp is set to 0, and suppose the value of @contact.fields.present_grade_acp contains the value Grade 1 ACP 1, then after the node is encountered, the updated value of @contact.fields.cumulative_acp becomes “0, Grade 2 ACP 1”
  • In the next flow, if the @contact.fields.present_grade_acp contains 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.
Screenshot 2025-03-31 at 9 10 55 PM

7. Converting a string to lowercase.

Any input variable can be converted to lowercase by using the following expression: <%= String.downcase(“@result.resultname”) %> In the above expression @result.resultname can be replaced with the string or the flow variable or the contact variable containing the string that needs to be converted to lowercase.

Screenshot 2025-03-31 at 9 14 06 PM

In the screenshot shared, two tasks are happening at once The flow variable @results.flow_keyword.input is getting converted to the lowercase The lowercase value of flow variable @results.flow_keyword.input is 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 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

  • Use "split by" node or in your "wait for resposne" include the validation condition for "matches regex" and check the following ^(0[1-9]|[12][0-9]|3[01])/(0[1-9]|1[0-2])/(?:202[5-9]|2030)$. This is how it works:
    • (0[1-9]|[12][0-9]|3[01]) will check that the DD values ( numbers before the "/") is greater than 0 and less than 31.
    • (0[1-9]|1[0-2]) will check if the MM values dont exceed 12.
    • (?:202[5-9]|2030) - makes sure that the year entered is in the range of 2025-2030.
    • This can be customised as needed to make it MM/DD/YYYY or DD-MM-YYYY
Screenshot 2025-07-11 at 2 30 17 PM

9. Validating time format in 24 hour format

  • Use "Split by" nodee or in the "wait for response' node include the validation condition for "matches regex" and check the following ([01][0-9]|2[0-3]):([0-5][0-9])$
  • ([01][0-9]|2[0-3]) will check if the hour part of it lies between 00 to 24
  • ([0-5][0-9]) will check if the minutes part of the
  • colon (:) will be used as delimiter
  • This can be customized as needed
Screenshot 2025-07-11 at 4 57 54 PM

Syntax Examples

  1. Syntax to check if contact belongs to 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 %>

image

2 . Syntax to check if the contact is registered or not.

<%= if "@contact.fields.is_registered" == "1" , do: 1, else: 0 %>

3 . Syntax to check if the contact has opted-in or not.

<%= if @contact.optin_status == true, do: 1, else: 2%>

image

Any variable that is created and saved for contact can be used to make decisions in Split by custom expression syntax

To use Split by expression needs a bit of coding to write the correct syntax. If you have exact requirements for what needs to be done and needs assistance, please ping us on discord, we will share the correct syntax for the requirement.


Advanced Feature Webinar