Skip to main content
El paso code.javascript ejecuta un script en un entorno aislado. Úsalo para transformar datos, validar, armar payloads o integrar fuentes que no cubre un HTTP simple.

Campos del paso

Contrato de ejecución

  1. La API resuelve plantillas en input.
  2. El sandbox recibe ese objeto como global input.
  3. Tu código debe asignar output = ....
  4. Ese output es la salida del paso (y response.body para capture).
Consulta Variables y contexto para armar input y pasar datos entre pasos.

Pasar variables desde un paso anterior

Declara en input lo que necesitas del trigger, de context o de steps.<n>.output. Luego léelo como input.* en el script.
Para publicar datos al siguiente paso:
  1. Asigna output = { ... }.
  2. En el paso siguiente usa {{steps.N.output.<campo>}}, o
  3. Declara capture y lee {{context.<clave>}}.

Objetos y APIs disponibles

Zona horaria

  • Trigger cron: DateTime.now() usa la timezone del trigger.
  • Otros triggers (p. ej. webhook): la zona efectiva es UTC.

Buen ejemplo: normalizar y validar

Script equivalente (más legible):

Buen ejemplo: llamar una API con fetch

Pasa token, referencia y monto por input con plantillas; no los incrustes en code.

Reutilizar archivos de pasos anteriores

Consulta Archivos entre pasos para ver el contrato completo, límites y un ejemplo GNP → JavaScript. Los archivos de los pasos anteriores están disponibles automáticamente. No necesitas agregarlos al input:
Métodos disponibles: Para crear un JSON o XML:
Sólo puedes leer artefactos de pasos anteriores de la misma ejecución. Las referencias no contienen rutas del bucket ni URLs persistentes.

Detener el flujo con workflow.stop

Llama workflow.stop(motivo?) para terminar la ejecución al acabar este paso. La ejecución queda como exitosa y los pasos siguientes aparecen con estado skipped (Omitido). El detalle de la ejecución muestra stoppedAtStepIndex y stopReason.
  • workflow.stop() sólo marca la ejecución; el código sigue hasta terminar o hasta un return.
  • Para salir en ese momento usa return valor: el valor que regreses es el output del paso. Un return; vacío deja el output sin valor.
  • Para fallar el paso usa throw new Error(...); workflow.stop() es para terminar sin error.

Enviar y leer correos con gmail

Declara gmailCredentialKey en el paso para habilitar el global gmail con esa cuenta. Igual que Enviar correo con Gmail, guardar o publicar una automatización con Gmail requiere permisos de administrador y una cuenta conectada. La cuenta va en gmailCredentialKey. El objeto de gmail.send() es solo el mensaje: los campos, la respuesta en hilo y los adjuntos están en Campos del mensaje. Las plantillas {{...}} se resuelven en input; dentro de code lee input.*. La comparación entre el paso y esta función está en Elige la interfaz.
gmail.send(message) envía el mensaje del paso gmail.send. La cuenta queda fuera de ese objeto. El correo enviado no vuelve a disparar Nuevo correo en Gmail: el trigger ignora los mensajes de la cuenta conectada. Devuelve { messageId, threadId, idempotentReplay }. Guarda messageId si un seguimiento posterior debe responder en el mismo hilo. gmail.getThread(threadId) lee el hilo desde Gmail y devuelve { id, messages: [{ id, from, to, cc, subject, text, snippet, internalDate, attachmentNames }] }, del mensaje más antiguo al más reciente.

Analizar adjuntos con files.analyze

files.analyze({ storagePath, instructions?, schema? }) lee un adjunto de un trigger Gmail y lo analiza con IA. Acepta PDF, DOCX e imágenes (JPEG, PNG, WEBP, GIF) de hasta 25 MB.
  • Sin schema devuelve { text } con un resumen estructurado; con schema (un objeto JSON Schema con type: "object") devuelve { data }.
  • También devuelve filename, mimeType y cached. El resultado se guarda: analizar otra vez el mismo archivo con las mismas instrucciones y esquema no vuelve a llamar al modelo.

Guardar un archivo en un tablero

files.open(ref) acepta tanto un WorkflowFileRef como el objeto de un adjunto Gmail. El file handle puede guardar el binario real en un campo files; no necesitas descargarlo, subir multipart ni usar una API key.
El backend obtiene el tenant del token de ejecución y valida que el database, record y field existan, que el campo sea files, y que cumpla MIME, tamaño y maxFiles. Si el paso se reintenta, devuelve el mismo archivo sin duplicarlo.
  • storagePath sólo acepta adjuntos Gmail del mismo tenant.

Ejemplo: responder a una aseguradora

Automatización con trigger gmail_email_received. input recibe {{trigger.body.message.threadId}}, {{trigger.body.message.id}}, {{trigger.body.message.from}}, {{trigger.body.message.attachments}} y tu API key y tablero de solicitudes:
Para clasificar la respuesta con IA antes de este paso, usa Criterio IA o llama a tu agente con fetch. En una automatización de seguimiento, guarda el messageId del primer gmail.send y úsalo como replyToMessageId en cada seguimiento.

Buen ejemplo: fechas con DateTime

Malos ejemplos

No asignar output

Sin output, el paso no deja un resultado útil para pasos siguientes ni para capture.

Usar require o APIs de sistema

El sandbox no expone require, process, ni acceso al sistema de archivos del runner. Usa input, fetch/axios, mysql o sftp.

Leer el trigger directo sin pasarlo por input

trigger no existe como global. Declara "referencia": "{{trigger.body.referencia}}" en input y usa input.referencia.

Mutar estado “global” entre pasos

Cada paso corre en un proceso aislado. Comparte datos con output + capture/context o con el input del siguiente paso.

MySQL (opcional)

Pasa host, usuario y contraseña por input (idealmente desde el body del webhook o un secreto que tú controles en tu integración). No hardcodees credenciales en code.

SFTP (opcional)

Límites prácticos

  • El script corre con "use strict".
  • Usa throw new Error("...") para fallar el paso con un mensaje claro.
  • Los console.* se recortan si son muy grandes; no uses logs para transportar el resultado final: usa output.
  • Prefiere pasos cortos y deterministas; deja esperas largas al paso Esperar.

Ejemplo de solicitud completo