# Conditional workflow helpers

> Conditional workflow helpers let you automate dynamic messaging in Kustomer based on specific criteria or conditions.

Source: https://help.kustomer.com/en_us/conditional-workflow-helpers-Syb3Z7TfJg

Last updated: 2026-06-11T18:59:50.508Z

Conditional workflow helpers let you automate dynamic messaging in Kustomer based on specific criteria or conditions. For example, you can reference a customer's gender correctly if their gender is known, or include special instructions for customers who are part of a VIP program. 

### In this article:

*   [If / Unless](#if-unless)
*   [Else](#else)
*   [Cond](#cond)
*   [If Cond](#if-cond)
*   [Is Empty](#empty)
*   [Or](#or)

### If / Unless

The `{{#if}}` block helper checks to see if the value of an attribute exists, as determined by being truthy, and outputs a string value accordingly. This helper only checks to see if the value exists; it does not verify a specific value.

For example, a customer’s country attribute can be checked when writing an automated note and included if it exists.

*   **Given steps.1.locations.country = “USA”**  
    `{{#if steps.1.locations.country}}Customer is from: {{{steps.1.locations.country}}}{{/if}}` resolves to the string `"Customer is from: USA"`  
      
    
*   **Given steps.1.locations.country = null**  
    `{{#if steps.1.locations.country}}Customer is from: {{{steps.1.locations.country}}}{{/if}}` resolves to an empty string

The `{{#unless}}` block helper behaves with the opposite functionality, and displays a string of text when the value of an attribute does not exist, as determined by being falsy (for instance, if a customer does not have a country listed).

*   **Given steps.1.locations.country = null**  
    `{{#unless steps.1.locations.country}}No country found{{/unless}}`resolves to the string `"No country found"`

While the number value `0` is usually interpreted as falsy, an optional parameter `includeZero` can be used to interpret the value as truthy instead.

*   `{{#if 0}}zero is true{{/if}}` resolves to an empty string
*   `{{#if 0 includeZero=true}}zero is true{{/if}}` resolves to the string `"zero is true"`
*   `{{#unless 0 includeZero=true}}zero is false{{/unless}}` resolves to an empty string

A variant `/#fn:ifExists` function helper is also available to output a string of text when an input is found to have an existing value. Values that are determined to exist by this variant helper deviate from the above definition in that they automatically include the number value `0`, as well as the boolean value `false`.

*   **Given steps.1.id = "12345"**  
    `/#fn:ifExists,steps.1.id,hello world` resolves to the string `"hello world"`

### Else

`{{else}}` is a dedicated sub-helper block, available for use in conjunction with any block helper syntax. It extends conditional functionality by allowing multiple block helper statements to be chained together. If an initial block helper statement resolves in a `null` value, an `{{else}}` block can be inlcuded to attempt additional helper arguments, or to output a default value.

*   `{{#if steps.1.locations.country}}{{{steps.1.locations.country}}}{{else if steps.1.locations.region}}{{{steps.1.locations.region}}}{{else}}No country found{{/if}}`
*   ``{{#unless steps.1.locations.region}}No region found{{else unless steps.1.locations.country}}No country found{{else}}`{{{steps.1.locations.country}}}`{{/unless}}``

### Cond

The `{{cond}}` helper takes if/unless statements a step further by checking an attribute for a specific value and outputting a static string of text. Using conditionals allows for more granularity, allowing for a more dynamic output.

*   **Given steps.1.location.country = "USA"**  
    `{{cond steps.1.location.country USA='United States' CA='Canada' MX='Mexico'}}` resolves to the string `"United States"`  
      
    
*   **Given steps.1.location.country = "CA"**  
    `{{cond steps.1.location.country USA='United States' CA='Canada' MX='Mexico'}}` resolves to the string `"Canada"`

This helper can also be used to check for boolean values `true` or `false`.

*   **Given steps.1.custom.vip = true**  
    `{{{cond steps.1.custom.vip true='Customer is VIP' false='Customer is not VIP'}}}` resolves to the string `"Customer is VIP"`

You can also implement conditionals in conjunction with multi-level lists. This allows you to create custom messaging based on a dropdown selection. When using this helper to check the value of a multilevel list on a Klass object, IDs of each reviewed value are needed.

**Note:** To find value IDs for a multi-level list, [make a GET request](https://developer.kustomer.com/kustomer-api-docs/reference/getcustomattributemetadata#getcustomattributemetadata) to the API endpoint for the appropriate resource Klass - `/v1/metadata/:resource` - and review data for the multi-level list attribute in question.

For example, an organization has a custom "resolutionTree" attribute on the conversation Klass. Level 1 of the list has a 'troubleshooting' option, with 'resolved' and 'bug' featured as nested level 2 options.

*   **Given steps.1.custom.resolutionTree = "troubleshooting.bug"**  
    `{{{cond steps.1.custom.resolutionTree [troubleshooting.resolved]='Issue resolved' [troubleshooting.bug]='Bug report requested'}}}` resolves to the string `"Bug report requested"`

A variant `/#fn:cond` function helper is also available with similar functionality.

*   **Given steps.1.location.country = "MX"**  
    `/#fn:cond,steps.1.location.country,USA=United States,CA=Canada,MX=Mexico` resolves to the string `"Mexico"`

### If Cond

The `{{#ifCond}}` block helper combines the functionality of the `{{#if}}` and `{{cond}}` helpers by outputting a dynamic string, based on a specific attribute value. Attributes queried in this helper can be compared against strings, numbers, booleans, and null.

*   **Given steps.1.subject = "Out of office"**  
    `{{#ifCond steps.1.subject '==' 'Out of office'}}Ignore email{{/ifCond}}` resolves to the string `"Ignore email"`

When calling data paths inside the opening and closing blocks, you will need to reference one directory level up.

*   **Given steps.1.custom.counterNum = 11**  
    `{{#ifCond steps.1.custom.counterNum '>=' 10}}The number has reached {{{../steps.1.custom.counterNum}}}{{/ifCond}}` resolves to the string `"The number has reached 11"`

Because it is a block helper, `{{#ifCond}}` has access to the `{{else}}` sub-helper block, allowing multiple statements to be chained together.

*   `{{#ifCond steps.1.custom.countNum '>' 10}}has exceeded 10{{else ifCond ../steps.1.custom.countNum '==' 10}}is 10{{else}}is only {{../steps.1.custom.countNum}}{{/ifCond}}`

This helper supports the following operators:

*   `==` (equals)
*   `===` (strict equals)
*   `!=` (not equals)
*   `!==` (strict not equals)
*   `>` (greater than)
*   `<` (less than)
*   `>=` (greater than or equal to)
*   `<=` (less than or equal to)
*   `&&` (both values are truthy)
*   `||` (at least one value is truthy)

### Is Empty

`{{#isEmpty}}` outputs a string if an accepted value is an empty object or array. Objects are considered empty if they have no own enumerable string-keyed properties. Arrays are considered empty if they have a length of 0.

*   **Given steps.1.attributes.data = an empty object**  
    `{{#isEmpty steps.1.attributes.data}}it's empty!{{/isEmpty}}` resolves to the string `"it's empty!"`

Like `{{#ifCond}}`, data paths used for string interpolation must reference one directory level up.

*   **Given steps.1.attributes.data = an empty object**  
    `{{#isEmpty steps.1.attributes.data}}{{toJSON ../steps.1.attributes.data}}{{/isEmpty}}` resolves to the string `"{}"`

Like all block helpers, `{{#isEmpty}}` has access to the `{{else}}` sub-helper block, allowing multiple statements to be chained together.

*   `{{#isEmpty steps.1.attributes.data.array1}}Array 1 is empty{{else isEmpty ../steps.1.attributes.data.array2}}Array 2 is empty{{else}}Neither array 1 or 2 is empty{{/isEmpty}}`

For help interpreting arrays and objects as stringified JSON, see [JSON Data helpers](http://help.kustomer.com/json-data-helpers-r1C1c9E4Je).

### Or

The `{{or}}` helper accepts two values and returns the first truthy value or the last falsy value.

*   **Given steps.1.attributes.data = {"val1": "1", "val2": ""}**  
    `{{or steps.1.attributes.data.val1 steps.1.attributes.data.val2}}` resolves to the string `"1"`  
      
    `{{or steps.1.attributes.data.val2 steps.1.attributes.data.val1}}` resolves to the string `"1"`

### **Regex syntax in workflows**

The Generic Regex Match action supports standard regular expression syntax but does not support inline flags such as (?i) for case-insensitive matching.

If you use an unsupported flag, the workflow returns an "Invalid regular expression" error.

To perform case-insensitive matching, use character classes instead of flags.

**Goal**

**Unsupported syntax**

**Supported syntax**

Match "Refund" or "refund"

`(?i)refund`

`[Rr]efund`

Match "Social Media" in any case

`(?i)social media`

`[Ss]ocial [Mm]edia`

Match "Embroidery" in any case

`(?i)embroidery`

`[Ee]mbroidery`

The ****Test String**** field in the regex match action allows you to verify your expression against a sample string before activating the workflow.

#### **Use inBusinessHours with a specific business schedule**

By default, the `/#fn:inBusinessHours` helper evaluates against the organization's default business schedule. To target a specific business schedule, append the schedule ID after a comma with no space:

`/#fn:inBusinessHours,SCHEDULE_ID`

To find the schedule ID:

1.  From the left navigation, click ****Settings****. The Settings page opens.
2.  In the ****Settings**** page, click ****Administration****, then select ****Business Schedules****.
3.  Select the schedule you want to use. The schedule ID appears in the URL.

****Business Hours vs. Business Schedules:**** Business Schedules (under ****Settings**** > ****Administration**** > ****Business Schedules****) define operating hours, timezone, and holidays. Business Hours (under ****Apps**** > ****Chat**** > ****Settings****) is a chat-specific availability setting that controls only when the chat widget appears as available. The `/#fn:inBusinessHours` helper reads from Business Schedules, not Business Hours.

****Important:**** The `/#fn:inBusinessHours` helper cannot be evaluated directly inside a `kustomer.transform.generic` action step parameter. To use this helper in a workflow, first capture the helper's boolean result in a transform step, then reference that output in subsequent transition conditions.

### Related articles:

*   [Understand workflow helpers](https://help.kustomer.com/workflow-helpers-SJ3hjT7gr)
*   [Date and math workflow helpers](https://help.kustomer.com/date-math-SkIBvB1Eyx)
*   [String modifying workflow helpers](https://help.kustomer.com/string-modifying-helpers-r1GsopXX1x)
*   [JSON data workflow helpers](https://help.kustomer.com/json-data-helpers-r1C1c9E4Je)
*   [Data validation workflow helpers](https://help.kustomer.com/data-validation-r1ODn2K4kg)
*   [Understand handlebars](https://help.kustomer.com/handlebars-SkrtP_kHJl)
