> ## Documentation Index
> Fetch the complete documentation index at: https://docs.jelou.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Code

> Execute custom JavaScript to transform data and apply complex logic

The **Code** node lets you run custom JavaScript within your flow. It is useful for operations that cannot be achieved with standard nodes: transforming data, performing calculations, manipulating text, or integrating custom business logic.

## Accessing variables

Inside the Code node you can read and write flow variables using predefined global objects.

### Context (\$context)

Variables that persist only during the current flow execution:

```javascript theme={null}
// Read
const name = $context.get('name')
const name = $context.get('name', 'John') // with default value

// Write
$context.set('lastOrder.status', 'delivered')
$context.set('user', { name: 'John', plan: 'gold' })
```

### Memory (\$memory)

Variables that persist across workflows, tools, and nodes. They support time-to-live (TTL):

```javascript theme={null}
// Primitives (string, number, boolean) - optional TTL
$memory.set('name', 'John')
$memory.set('attempts', 3, 3600) // expires in 1 hour

// JSON - TTL required (in seconds, maximum 86,400 = 1 day)
$memory.setJson('user', { name: 'John', plan: 'gold' }, 86400)

// Files - async, TTL required (maximum 604,800 = 1 week)
await $memory.setFile('receipt', base64String, 604800, 'application/pdf')
```

#### Reading

```javascript theme={null}
const name = $memory.get('name')
const user = $memory.getJson('user')
const url = $memory.getFile('receipt').toUrl()           // temporary URL
const base64 = await $memory.getFile('receipt').toBase64()
```

#### Deletion

```javascript theme={null}
$memory.delete('temporary')
$memory.delete(['tmp1', 'tmp2', 'cache']) // multiple keys
```

#### Limits by data type

| Type        | Maximum size   | TTL      | Maximum TTL       |
| :---------- | :------------- | :------- | :---------------- |
| **String**  | 255 characters | Optional | —                 |
| **Number**  | 15 digits      | Optional | —                 |
| **Boolean** | —              | Optional | —                 |
| **JSON**    | 15 KB          | Required | 86,400s (1 day)   |
| **File**    | 10 MB          | Required | 604,800s (1 week) |

<Warning>
  The methods `$memory.setFile()`, `$memory.getFile().toBase64()`, and `$memory.getFile().toRaw()` are **asynchronous**. You must use `await` when calling them.
</Warning>

### Migration from legacy nodes

1. Create a new **Code (Memory V2)** node.
2. Copy and paste the script from the legacy node.
3. Use the new available methods (`$memory.setJson`, `$memory.setFile`, etc.) if needed.

### User (\$user)

Information about the contact interacting with your flow:

```javascript theme={null}
const userId = $user.get('id')
const userName = $user.get('names')
```

### Message (\$message)

The last message sent by the user:

```javascript theme={null}
const text = $message.get('text')
const type = $message.get('type')       // TEXT, IMAGE, AUDIO, VIDEO, LOCATION, FILE
const attachmentUrl = $message.get('mediaUrl')
const lat = $message.get('lat')
const lng = $message.get('lng')
```

### Input/Output ($input, $output)

For communication between tools and workflows:

```javascript theme={null}
const city = $input.get('city', 'Quito')  // with default value
$output.set('data', result)
```

### HTTP responses

If you saved the response from an API node:

```javascript theme={null}
let apiResponse = $context.getHttpResponse('apiResponse')
apiResponse = apiResponse.json()

$memory.set('name', apiResponse.data.user.name)
```

<Warning>
  The key in `$context.getHttpResponse()` must match exactly the one you configured in the "Save response" field of the API node.
</Warning>

## Available utilities

### Logger

Logs values for debugging in key-value format. Logs appear in the execution history:

```javascript theme={null}
// Primitives are stored as-is
$utils.logger.log('userId', 1245)
$utils.logger.log('status', 'active')

// Objects and arrays are converted to string (truncated to 512 characters)
$utils.logger.log('orderData', { id: 1, name: 'christian' })
```

<Warning>
  Each node allows a maximum of **10 log entries**. The value of each entry has a limit of **512 characters**.
</Warning>

### Crypto

Standard cryptographic functions:

```javascript theme={null}
$utils.crypto.createHash('sha256')
$utils.crypto.createHmac('sha256', key)
$utils.crypto.randomBytes(32)
```

### Lodash

Utilities for manipulating arrays, objects, and strings:

```javascript theme={null}
$utils._.get(object, 'nested.path', defaultValue)
$utils._.uniq(array)
$utils._.chunk(array, size)
$utils._.merge(object1, object2)
```

<Tip>
  **Allowed MIME types for `$memory.setFile()`:**

  | Category  | Types                                                                   |
  | :-------- | :---------------------------------------------------------------------- |
  | Text      | `text/plain`                                                            |
  | JSON/XML  | `application/json`, `application/xml`, `text/xml`                       |
  | Images    | `image/jpeg`, `image/png`, `image/gif`                                  |
  | Videos    | `video/mp4`, `video/ogg`, `video/webm`, `video/x-msvideo`, `video/mpeg` |
  | Audio     | `audio/mpeg`, `audio/wav`, `audio/ogg`, `audio/aac`, `audio/flac`       |
  | Documents | `application/pdf`                                                       |
</Tip>
