# Action Expressions

Write expressions that control when Flux actions execute.

In this document, we explain the syntax of the expressions you can use in **Action Condition** and some **Action Config** fields. These expressions are used to access and evaluate the [Message and Context](https://docs.soracom.io/en/services/flux#message-and-context) of event messages received from the channel. In action condition fields, you can use these expressions to conditionally execute actions based on data in event message. In some action config fields, you can also use these expressions to dynamically customize the input data for the action.

## Action Condition Expressions

In action conditions, expressions evaluate to a boolean value (`true` or `false`).

The condition is evaluated each time the channel receives a new event. If the result of the evaluation is `true`, the action is executed.

For example, this expression is evaluated as `true` when the **Message** of an event sent to the channel is `{"temperature": 42}` and the current day of the week in UTC is Monday.

```
(payload.temperature - 2.12) >= 32.8 && getUTCDayOfWeek(now()) == 1
```

Similarly, the following expression is evaluated as `true` when the **Message** sent from the event source is `{"clickTypeName": "SINGLE"}` or when the **Context** sent to the channel contains `{"protocol": "http"}`.

```
startsWith(toUpperCase(event.payload.clickTypeName), "SINGLE") || context.protocol == "http"
```

## Action Config Expressions

In supported action config input fields, expressions evaluate to strings.

The action config expression is evaluated when the action is executed. The evaluated result is used as the action's input.

For example, if the event is `{"presignedUrls": {"get": "https://example.com"}}`, the output of the following expression will be `<https://example.com|Image>`.

```
<${event.payload.presignedUrls.get}|Image>
```

For another example, if the event is `{"output": {"people": 3, "people_with_blue_shirts": 0}}`, the output of the following expression will be `There are 3 people. Among them, 0 are wearing blue shirts!`.

```
There are ${payload.output.people} people. Among them, ${payload.output.people_with_blue_shirts} are wearing blue shirts!
```

Likewise, to get the number of elements in the `weather` array from `{"weather": ["sunny", "cloudy", "rain"]}` in the MESSAGE (the output data of the previous channel), use the following expression:

```
${len(payload.weather)}
```

## Expression Syntax Reference

Expressions in Action Condition and Action Config fields can include variables, operators, and functions. The following is a reference of the syntax you can use in these expressions.

### Variables

| Variable | Description |
| - | - |
| `payload` | The Message sent to the channel. If it's a JSON object, you can access JSON object values using syntax such as `payload.temperature` or `payload.values[1].foo["click type"]`. If it's not a JSON object, `payload` is treated as a string. |
| `context` | A JSON object corresponding to the Context sent to the channel. The schema of the object varies by event type. Refer to each Event Source reference for more details. For example: [IoT Device Event Source](https://docs.soracom.io/en/services/flux/iot-device) |
| `event.payload` | The original Message sent from the event source to the channel. |
| `event.context` | A JSON object corresponding to the Context sent from the event source to the channel. |

> [!NOTE]
>
> `payload` and `event.payload` have the same value in the channel that first received the event message from an event source. Similarly, `context` and `event.context` also have the same value.

### Operators

When working with expressions, you can use a variety of operators to combine or compare values. For example, to multiply a temperature reading by 100, you could write:

`${payload.temp * 100}`

This returns the product of `payload.temp` and 100, multiplying your temperature value by 100.

| Operator | Description |
| - | - |
| \` | |
| `&&` | Logical AND: Returns `true` if both conditions are `true`. |
| `? :` | Ternary operator: Used as `a ? b : c`, it returns `b` if the condition `a` is evaluated as `true`, and `c` if evaluated as `false`. For example: `event.payload.click_type == 1 ? "Single click" : "Double click"` |
| `==` | Equal to: Returns `true` if the values are equal. |
| `!=` | Not equal to: Returns `true` if the values are not equal. |
| `>=` | Greater than or equal to: Returns `true` if the left value is greater than or equal to the right value. |
| `>` | Greater than: Returns `true` if the left value is greater than the right value. |
| `<=` | Less than or equal to: Returns `true` if the left value is less than or equal to the right value. |
| `<` | Less than: Returns `true` if the left value is less than the right value. |
| `+` | Addition: Returns the sum of two values. |
| `-` | Subtraction: Returns the difference of two values. |
| `*` | Multiplication: Returns the product of two values. |
| `/` | Division: Returns the quotient of two values. |
| `%` | Modulus: Returns the remainder when the left value is divided by the right value. |
| `**` | Exponentiation: Returns the result of raising the left value to the power of the right value. |

### Functions

#### Evaluating Values

| Function | Description |
| - | - |
| `includes(string, value)` | Checks if `string` contains `value`, returning `true` or `false`. |
| `startsWith(string, prefix)` | Checks if `string` begins with `prefix`, returning `true` or `false`. |
| `endsWith(string, suffix)` | Checks if `string` ends with `suffix`, returning `true` or `false`. |

#### Data Conversion

| Function | Description |
| - | - |
| `toLowerCase(string)` | Converts `string` to lowercase. |
| `toUpperCase(string)` | Converts `string` to uppercase. |
| `int(value)` | Converts a `string` or `number` to an integer. Decimal values are truncated. |
| `toNumber(string)` | Converts a `string` to a number. |
| `toString(number)` | Converts a `number` to a string. |
| `abs(number)` | Returns the absolute value of `number`. |
| `ceil(number)` | Rounds `number` up to the nearest integer. |
| `floor(number)` | Rounds `number` down to the nearest integer. |
| `round(number)` | Rounds `number` to the nearest integer. |
| `max(number1, number2)` | Returns the larger of the two specified numbers. `number1` and `number2` must be integers. |
| `min(number1, number2)` | Returns the smaller of the two specified numbers. `number1` and `number2` must be integers. |
| `len(value)` | Returns the length of a string or array. The length of a string is determined by counting the number of Unicode code points. For an array, use a variable that contains an array (e.g. `len(payload)`) |

#### Time Processing

> [!NOTE]
>
> **Note:**
>
> Functions below that require an input must use one of the following formats:
>
> **Date string**:
>
> - `YYYY-MM-DDThh:mm:ssTZD` (e.g., `2025-01-23T04:56:30+01:00`)
> - `YYYY-MM-DDThh:mm:ss.sssTZD` (e.g., `2025-01-23T04:56:30.456+01:00`)
>
> **Unix time (milliseconds)**: Only functions that accept `value` as an argument support Unix time (milliseconds) (e.g. `1738817506000`).
>
> - **Unix times must be in milliseconds.** Using Unix time in second format (e.g., `1738817506`) will result in incorrect output.
> - If a decimal value is used for milliseconds, it will result in incorrect output (e.g., `1738817506.789`).

| Function | Description |
| - | - |
| `now()` | Returns current Unix time (milliseconds). |
| `datetime(iso_string)` | Converts a date string to Unix time (milliseconds).\*2 |
| `datetimeFromISOString(iso_string)` | Converts a date string to Unix time (milliseconds).\*2 |
| `getUTCYear(value)` | Returns the UTC year, where `value` can be a Unix time (milliseconds) or a date string.\*2 |
| `getUTCMonth(value)` | Returns the UTC month, where `value` can be a Unix time (milliseconds) or a date string.\*2 |
| `getUTCDate(value)` | Returns the UTC day, where `value` can be a Unix time (milliseconds) or a date string.\*2 |
| `getUTCHours(value)` | Returns the UTC hour, where `value` can be a Unix time (milliseconds) or a date string.\*2 |
| `getUTCMinutes(value)` | Returns the UTC minute, where `value` can be a Unix time (milliseconds) or a date string.\*2 |
| `getUTCSeconds(value)` | Returns the UTC second, where `value` can be a Unix time (milliseconds) or a date string.\*2 |
| `getUTCMilliseconds(value)` | Returns the UTC milliseconds, where `value` can be a Unix time (milliseconds) or a date string.\*2 |
| `getUTCDayOfWeek(value)` | Returns the UTC day of the week as a number (0 = Sunday), where `value` can be a Unix time (milliseconds) or a date string.\*2 |
| `addSeconds(value, number)` | Adds the specified `number` of seconds, where `value` can be a Unix time (milliseconds) or a date string.\*1,\*2 |
| `addMinutes(value, number)` | Adds the specified `number` of minutes, where `value` can be a Unix time (milliseconds) or a date string.\*1,\*2 |
| `addHours(value, number)` | Adds the specified `number` of hours, where `value` can be a Unix time (milliseconds) or a date string.\*1,\*2 |
| `addDays(value, number)` | Adds the specified `number` of days, where `value` can be a Unix time (milliseconds) or a date string.\*1,\*2 |
| `addMonths(value, number)` | Adds the specified `number` of months, where `value` can be a Unix time (milliseconds) or a date string.\*1,\*2 |
| `addYears(value, number)` | Adds the specified `number` of years, where `value` can be a Unix time (milliseconds) or a date string.\*1,\*2 |

1. The function rounds down if `number` is a decimal.
2. Required date string format: `YYYY-MM-DDThh:mm:ssTZD` (e.g., `2025-01-23T04:56:30+01:00`) or `YYYY-MM-DDThh:mm:ss.sssTZD` (e.g., `2025-01-23T04:56:30.456+01:00`)

#### Math Functions

| Function | Description |
| - | - |
| `Math.acos(number)` | Returns the inverse cosine (arccosine) of a number in radians. |
| `Math.acosh(number)` | Returns the inverse hyperbolic cosine of a specified number. |
| `Math.asin(number)` | Returns the inverse sine (arcsine) of a number in radians. |
| `Math.asinh(number)` | Returns the inverse hyperbolic sine of a specified number. |
| `Math.atan(number)` | Returns the inverse tangent (arctangent) of a number in radians. |
| `Math.atanh(number)` | Returns the inverse hyperbolic tangent of a specified number. |
| `Math.cbrt(number)` | Returns the cube root of a specified number. |
| `Math.cos(number)` | Returns the cosine of a specified angle in radians. |
| `Math.cosh(number)` | Returns the hyperbolic cosine of a specified number. |
| `Math.exp(number)` | Returns Euler’s number (e) raised to the power of a specified number. |
| `Math.log(number)` | Returns the natural logarithm of a specified number. |
| `Math.log10(number)` | Returns the base 10 logarithm of a specified number. |
| `Math.log2(number)` | Returns the base 2 logarithm of a specified number. |
| `Math.random()` | Returns a pseudo-random number between 0 (inclusive) and 1 (exclusive). |
| `Math.sign(number)` | Returns the sign of a specified number. Returns 0 if the number is 0, -1 if it is negative, and 1 if it is positive. |
| `Math.sin(number)` | Returns the sine of a specified angle in radians. |
| `Math.sinh(number)` | Returns the hyperbolic sine of a specified number. |
| `Math.tan(number)` | Returns the tangent of a specified angle in radians. |
| `Math.tanh(number)` | Returns the hyperbolic tangent of a specified number. |
| `Math.degreesToRadians(number)` | Converts an angle in degrees to radians. |
| `Math.radiansToDegrees(number)` | Converts an angle in radians to degrees. |
