# Variables integradas

Algunos datos llegan al código sin llamar a ninguna función, en variables de JavaScript ya preparadas. El conjunto depende del bloque en el que se ejecuta el código.

## Datos del contacto

En todos los bloques salvo «Webhook entrante», los datos del contacto para el que se ejecuta el código están disponibles desde el principio. En «Webhook entrante» aparecen una vez que el código encuentra al contacto con una [función de búsqueda de contacto](https://support.jetbot24.ru/es/api/javascript/contact).

| Variable | Qué contiene |
|---|---|
| `id` | ID del contacto en la plataforma |
| `bot_id` | ID del bot |
| `name` | Nombre completo del contacto |
| `first_name` | La primera palabra del nombre |
| `last_name` | La segunda palabra del nombre |
| `phone` | Teléfono |
| `email` | Email |
| `address` | Dirección |
| `username` | Nombre de usuario en el canal: `@flower_lover` en Telegram y MAX, `id123456` en VK |
| `telegram_id` | ID de la persona en Telegram |
| `max_id` | ID de la persona en MAX |
| `created_at` | Cuándo apareció el contacto en el bot, con la forma `2026-01-31 12:00:00` (UTC) |

Los valores son cadenas, incluidos `id` y `bot_id`. En «Webhook entrante», `id` y `bot_id` llegan como números, así que llévalos a la misma forma antes de compararlos: `Number(id) === 12345`.

Si al contacto le falta algo (por ejemplo, el teléfono), la variable no existe en absoluto, y referirse a ella detiene el código con un `ReferenceError`. Comprueba estas variables con `typeof`:

```js
if (typeof phone !== 'undefined') {
    setContactVariable('courier_phone', phone);
} else {
    sendMessage('Por favor, deja un número de teléfono para el repartidor.');
}
```

En «Webhook entrante», después de elegir al contacto aparecen algunas variables más, también solo si el contacto tiene un valor:

| Variable | Qué contiene |
|---|---|
| `start_message` | El primer mensaje que el contacto envió al bot |
| `amocrm_lead_id`, `amocrm_contact_id` | Los ID del negocio y del contacto en amoCRM |
| `bitrix_lead_id`, `bitrix_deal_id`, `bitrix_contact_id` | Los ID del lead, el negocio y el contacto en Bitrix24 |

Las variables del contacto y las variables globales del bot no llegan como variables preparadas: léelas con las funciones [`getContactVariable` y `getGlobalVariable`](10-variables.md).

## Respuesta del servidor

En el código del bloque [«Solicitud HTTP»](https://support.jetbot24.ru/es/chatbots/blocks/developer/http), la respuesta del servidor está en el objeto `response`:

| Campo | Qué contiene |
|---|---|
| `response.status` | El código de respuesta, un número: `200`, `404`, etc. |
| `response.body` | El cuerpo de la respuesta como cadena, tal como llegó |
| `response.data` | El cuerpo de la respuesta interpretado como JSON. Si la respuesta no es JSON, es un objeto vacío `{}` |

El código solo se inicia cuando el servidor ha respondido. Si no hay respuesta (el servidor no respondió dentro del tiempo del campo «Tiempo de espera» o no se pudo establecer la conexión), el bloque sale por la salida «Sin respuesta del servidor» y el código no se ejecuta. Una respuesta con un código de error, como `500`, es una respuesta normal: el código se ejecuta, así que comprueba `response.status` tú mismo.

El código se ejecuta después del resto de la configuración del bloque: para entonces, las variables de «Guardar la respuesta JSON en variables» ya están escritas.

```js
if (response.status !== 200) {
    sendMessage('El servicio de entrega no está disponible ahora mismo, inténtalo más tarde.');
    disableContinue();
} else if (response.data.slots && response.data.slots.length > 0) {
    setContactVariable('next_delivery', response.data.slots[0].time);
} else {
    sendMessage('No quedan horarios de entrega libres para hoy.');
}
```

## Solicitud entrante

En el código del bloque [«Webhook entrante»](https://support.jetbot24.ru/es/chatbots/blocks/developer/incoming-webhook), la solicitud entrante está en el objeto `request`:

| Campo | Qué contiene |
|---|---|
| `request.query` | Parámetros de la cadena de consulta. Los valores son cadenas |
| `request.headers` | Encabezados de la solicitud. Los nombres van en minúsculas: `request.headers['content-type']` |
| `request.body` | El cuerpo de la solicitud como cadena, tal como llegó |
| `request.data` | Todos los parámetros de la solicitud juntos: de la cadena de consulta, del formulario y de un cuerpo JSON. Los números y booleanos de JSON siguen siendo números y `true`/`false` |

Si la solicitud no tiene parámetros, `request.query` es un objeto vacío. Comprueba los campos anidados antes de usarlos, para que el código no se detenga con `undefined`:

```js
var order = request.data.order;

if (order && order.contact_id && setContactById(order.contact_id)) {
    setContactVariable('order_number', String(order.id));
    sendMessage('El pedido n.º ' + order.id + ' está empaquetado y entregado al repartidor.');
}
```

Si el remitente firma sus solicitudes, puedes comprobar la firma con la función [`hash_hmac`](30-crypto.md#hashhmac), usando `request.body` y el encabezado de la firma.

## Filas de la hoja

En el código del bloque [«Leer filas de Google Sheets»](https://support.jetbot24.ru/es/chatbots/blocks/lists/google-sheet-reader), las filas encontradas están en `sheet.data`: un array de filas, donde cada fila es un array de celdas.

- `sheet.data` contiene solo las filas que pasaron los filtros del bloque, y no más de las indicadas en «Número de registros por mensaje».
- Las celdas son cadenas. La primera celda del array es la columna `A`.
- El bloque carga las columnas hasta la más a la derecha que se menciona en su configuración. Para que el código reciba también otras columnas, llama a `setColumnRange("A:F")` con el rango que necesitas al principio del código: el bloque lee esta llamada antes de consultar la hoja. Google no envía las celdas vacías del final de una fila, así que las filas pueden tener longitudes distintas.
- Si no se encuentran filas, el código no se ejecuta: el bloque sale por la salida «No se encontraron registros».

```js
setColumnRange("A:C");

var rows = sheet.data;
var total = 0;

for (var i = 0; i < rows.length; i++) {
    total += Number(rows[i][2] || 0);
}

setContactVariable('order_total', total);
```

Aquí la columna `C` contiene el precio del ramo, y el código suma los precios de todas las filas encontradas.
