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

# Cloud Functions

Las Cloud Functions ejecutan tu JavaScript cada vez que ocurre un evento seleccionado de Nexor. Nexor entrega el objeto del evento a tu función como `ctx`, donde puedes inspeccionarlo y transformarlo, actualizar el lead, llamar a cualquier API HTTP externa y devolver un resultado para el historial de ejecuciones.

Usa una Cloud Function cuando una integración necesite lógica personalizada, no solo una copia de un evento. Por ejemplo, puedes adaptar un lead calificado al formato de tu CRM, avisar a un equipo solo sobre conversiones de alto valor o enviar datos de reuniones a tu propio backend sin alojar un procesador de eventos aparte.

<Info>
  Las Cloud Functions están en **Avanzado → Cloud Functions**. Cada función escucha un trigger, y ese trigger determina la forma de `ctx`.
</Info>

## Cómo funciona

1. Ocurre un evento en Nexor, como un cambio de estado de un lead.
2. Nexor invoca las Cloud Functions activas asociadas a ese trigger.
3. La función recibe el objeto específico del evento como `ctx` y se ejecuta en un entorno JavaScript aislado.
4. Nexor guarda la salida de consola, las solicitudes HTTP, el valor devuelto, los cambios del lead, el estado y la duración en el historial de ejecuciones.

Una función escucha el evento seleccionado en toda tu organización de Nexor. Para limitarla a un agente, estado, canal u otra condición, revisa los campos correspondientes de `ctx` y termina la ejecución cuando no coincidan. Nexor ejecuta como máximo 25 funciones activas coincidentes por evento; si hay más, las funciones excedentes se omiten.

Las Cloud Functions están diseñadas para procesadores de eventos breves. Cada ejecución tiene un timeout de 8 segundos.

## Crear una función

<Note>
  Solo los administradores de la organización pueden crear, editar, ejecutar manualmente, pausar o eliminar Cloud Functions. Los demás usuarios pueden ver las funciones, el historial de ejecuciones y los nombres de las variables de entorno.
</Note>

<Steps>
  <Step title="Nombra la función y elige un trigger">
    Ve a **Avanzado → Cloud Functions**, haz clic en **Nueva función**, ingresa un nombre descriptivo y selecciona el evento que debe ejecutar tu código.
  </Step>

  <Step title="Revisa el payload">
    Abre la pestaña **Payload** del editor. Allí verás un `ctx` de ejemplo para el trigger seleccionado. Haz clic en un campo para insertarlo en el código y contempla que algunos campos pueden ser `null` o no estar presentes en un evento real.
  </Step>

  <Step title="Escribe la lógica de integración">
    Usa los datos del evento, los helpers integrados para leads y `axios` o `fetch` para implementar la acción. Agrega API keys, tokens y URLs de endpoints como variables de entorno en vez de colocar secretos en el código.
  </Step>

  <Step title="Guarda y prueba">
    Guarda para desplegar la función y luego haz clic en **Ejecutar** para correr la versión desplegada con un `ctx` de ejemplo editable. Revisa la salida, las llamadas de red, el valor devuelto y los cambios propuestos para el lead.
  </Step>

  <Step title="Activa y monitorea">
    Mantén **Activa** habilitado para ejecutar la función automáticamente. Abre **Registros** para revisar ejecuciones posteriores o pausa la función sin eliminar su código.
  </Step>
</Steps>

<Note>
  El trigger no se puede cambiar después de crear la función porque define la suscripción al evento y el payload. Crea otra función si necesitas reaccionar a un evento diferente.
</Note>

## Triggers disponibles

Cada función se asocia a uno de los siguientes 23 eventos.

### Leads

| Trigger               | Se ejecuta cuando                           |
| --------------------- | ------------------------------------------- |
| `lead.created`        | Un nuevo lead entra al embudo.              |
| `lead.updated`        | Se editan uno o más campos del lead.        |
| `lead.status_changed` | Un lead pasa de un estado a otro.           |
| `lead.assigned`       | Un lead se asigna a un agente humano.       |
| `lead.tag_added`      | Se aplica una etiqueta a un lead.           |
| `lead.unsubscribed`   | Un lead se da de baja a través de WhatsApp. |

### Información

| Trigger                 | Se ejecuta cuando                                             |
| ----------------------- | ------------------------------------------------------------- |
| `information.collected` | El agente extrae un nuevo dato o variable de la conversación. |
| `information.updated`   | Un dato recopilado previamente cambia de valor.               |

### Conversaciones

| Trigger             | Se ejecuta cuando                                         |
| ------------------- | --------------------------------------------------------- |
| `message.received`  | Llega un mensaje entrante por cualquier canal.            |
| `message.sent`      | El agente envía un mensaje saliente.                      |
| `call.completed`    | Una llamada de voz termina y su transcripción está lista. |
| `handoff.requested` | El agente escala el lead a un humano.                     |

### Conversiones

| Trigger               | Se ejecuta cuando                        |
| --------------------- | ---------------------------------------- |
| `conversion.detected` | Se registra una conversión para un lead. |

### Reuniones

| Trigger               | Se ejecuta cuando                                 |
| --------------------- | ------------------------------------------------- |
| `meeting.created`     | Se agenda una reunión con un lead.                |
| `meeting.rescheduled` | Una reunión se mueve a un nuevo horario.          |
| `meeting.completed`   | Una reunión finaliza, con transcripción opcional. |
| `meeting.no_show`     | Un lead no asiste a una reunión agendada.         |

### Tareas y ejecuciones del agente

| Trigger                   | Se ejecuta cuando                                    |
| ------------------------- | ---------------------------------------------------- |
| `task.created`            | Se crea una tarea de seguimiento programada.         |
| `task.executed`           | Se ejecuta una tarea de seguimiento programada.      |
| `workflow.run_started`    | Un lead se inscribe en un agente.                    |
| `workflow.status_entered` | Un lead entra a un estado específico de un agente.   |
| `workflow.status_left`    | Un lead sale de un estado de un agente.              |
| `workflow.run_completed`  | Una ejecución del agente llega a un estado terminal. |

<Tip>
  Usa `lead.status_changed` cuando necesites tanto el estado anterior como el nuevo. Usa `workflow.status_entered` o `workflow.status_left` cuando tu lógica dependa específicamente de la entrada o salida de una etapa.
</Tip>

## Trabajar con el objeto del evento

La forma de `ctx` depende del trigger. Puede incluir identificadores y campos de primer nivel, además de objetos anidados como `lead`, estados, cambios, metadatos, participantes o el payload de una tarea. Entre los campos comunes están `lead_id`, `client_id`, `workflow_id` y los timestamps, pero algunos pueden ser `null` o no estar presentes según cómo haya ocurrido el evento.

Usa la pestaña **Payload** para explorar el objeto de ejemplo y luego revisa **Entrada · ctx** en la salida o los registros para ver el payload recibido por una ejecución específica. Protege los campos opcionales en el código de producción en vez de asumir que todos los campos del ejemplo estarán presentes.

La función puede usar los siguientes valores, helpers y características del lenguaje. Los elementos integrados del entorno no requieren imports.

| Valor o helper          | Propósito                                                                                                    |
| ----------------------- | ------------------------------------------------------------------------------------------------------------ |
| `ctx`                   | El payload completo específico del trigger.                                                                  |
| `lead`                  | El objeto del lead derivado de `ctx.lead`, o un objeto vacío cuando el evento no incluye una copia del lead. |
| `updateLead(patch)`     | Pone en cola un patch para el lead de Nexor.                                                                 |
| `updateMetadata(patch)` | Pone en cola keys para fusionar en `lead.metadata` sin reemplazar las demás.                                 |
| `env.NAME`              | Lee una variable de entorno de la organización durante la ejecución.                                         |
| `axios`                 | Hace solicitudes HTTP con `get`, `post`, `put`, `patch`, `delete`, `head` u `options`.                       |
| `fetch`                 | Hace solicitudes HTTP de más bajo nivel.                                                                     |
| `console`               | Captura entradas de `log`, `info`, `warn`, `error` y `debug` en la salida de la ejecución.                   |
| `helpers.uuid()`        | Genera un UUID.                                                                                              |
| `helpers.now()`         | Devuelve la hora actual.                                                                                     |
| `return`                | Guarda un valor JSON serializable como resultado de la ejecución.                                            |

`updateLead` y `updateMetadata` cambian la copia de `lead` dentro del entorno aislado y guardan los efectos correspondientes. Nexor los aplica solo después de una ejecución automática exitosa. No se aplican si la función genera un error, alcanza el timeout o se ejecuta manualmente desde el editor.

## Enviar un evento fuera de Nexor

Este ejemplo asocia `lead.status_changed` con un endpoint de un CRM. Filtra por el estado `qualified`, crea el payload externo a partir de `ctx`, lo envía con un token secreto y registra la sincronización exitosa en el lead de Nexor.

```javascript theme={null}
export default async function onLeadStatusChanged(ctx) {
  if (ctx.to_status?.key !== "qualified") {
    return { skipped: true };
  }

  const payload = {
    type: "lead.status_changed",
    occurred_at: ctx.changed_at,
    lead_id: ctx.lead_id,
    workflow_run_id: ctx.workflow_run_id,
    status: {
      from: ctx.from_status?.key ?? null,
      to: ctx.to_status?.key ?? null,
    },
    reason: ctx.reason ?? null,
  };

  const response = await axios.post(env.CRM_EVENTS_URL, payload, {
    headers: {
      Authorization: `Bearer ${env.CRM_API_TOKEN}`,
    },
  });

  updateMetadata({
    last_crm_sync_at: helpers.now(),
  });

  console.log("CRM response:", response.status);
  return { synced: true, status: response.status };
}
```

Puedes usar el mismo patrón con cualquier servicio HTTP: un CRM, data warehouse, API interna, endpoint de notificaciones, plataforma de automatización u otro sistema que acepte solicitudes.

## Variables de entorno

Los administradores gestionan las variables de la organización desde la sección **Variables de entorno** de la página de Cloud Functions. Los demás usuarios pueden ver los nombres, pero no los valores. Lee una variable en el código como `env.NAME`, por ejemplo `env.CRM_API_TOKEN`.

Los valores de las variables de entorno son de solo escritura en el dashboard: una función puede leerlos durante la ejecución, pero la interfaz no puede mostrarlos después de guardarlos. Crear, reemplazar o eliminar una variable vuelve a desplegar todas las Cloud Functions guardadas de la organización.

Una organización puede guardar hasta 128 variables. Los nombres deben comenzar con una letra mayúscula y contener solo letras mayúsculas, números o guiones bajos, con un máximo de 64 caracteres. Cada valor no vacío puede contener hasta 5 KiB.

<Warning>
  Al hacer clic en **Ejecutar** se ejecuta la función desplegada. Nexor conserva `updateLead` y `updateMetadata` como efectos propuestos durante esta prueba manual, pero las llamadas de `axios` y `fetch` a sistemas externos son reales. Usa un endpoint o credenciales de prueba mientras validas la función.
</Warning>

## Revisar ejecuciones

La salida del editor y la página **Registros** te permiten seguir cada ejecución. Una ejecución incluye:

* su origen y trigger;
* el estado de éxito, error o timeout;
* la duración y el timestamp;
* el `ctx` de entrada;
* la salida de consola y los errores no controlados;
* vistas previas redactadas de solicitudes y respuestas HTTP, con bodies limitados a 16 KiB;
* el resultado devuelto; y
* los efectos sobre el lead y sus metadatos producidos por la función.

Solo se ejecuta el último código guardado y desplegado. Guarda de nuevo antes de probar cambios pendientes.

Las ejecuciones automáticas son asíncronas y no garantizan la entrega; tampoco bloquean el evento de Nexor que las invocó. Haz que las acciones externas sean idempotentes y usa los registros para monitorear su resultado.

## ¿Cloud Functions o webhooks?

Usa una Cloud Function cuando el evento necesite código: filtros, transformaciones, bifurcaciones, llamadas a varios sistemas o una escritura en el lead de Nexor. Usa un [webhook](/docs/es/api/webhooks/overview) cuando solo necesites que Nexor entregue un evento firmado a un endpoint que ya administras.

Las Cloud Functions y los webhooks usan nombres de eventos y contratos de payload diferentes. Por ejemplo, el trigger de Cloud Functions es `lead.status_changed`, mientras que el evento de webhook relacionado es `workflow_run.status_changed`. No proceses `ctx` como si fuera el envelope de un webhook.

<Warning>
  Haz que las actualizaciones de leads sean idempotentes, especialmente en funciones que reaccionan a `lead.updated` o a cambios de estado. Evita procesar el mismo estado dos veces o volver a disparar la lógica después de tu propia actualización.
</Warning>
