Saltar al contenido principal

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.

El objeto ctx es el segundo parámetro de todo handler. Contiene información de la empresa, bot, usuario, tipo de trigger, y da acceso a secrets, mensajería, memoria y logging.
handler: async (input, ctx, request) => {
  ctx.log("Petición recibida", {
    company: ctx.company.name,
    bot: ctx.bot.channel,
    user: ctx.user.id,
    trigger: ctx.trigger.type,
  });
}

Referencia

PropiedadTipoDescripción
ctx.functionSlugstringSlug de la función
ctx.company{ id, name }Empresa del request
ctx.bot{ id, name, channel }Bot que originó el request
ctx.user{ id, names?, roomId? }Usuario de la conversación
ctx.conversation{ id?, ... }Datos de la conversación
ctx.operator{ id?, ... }Operador asignado
ctx.triggerTriggerInfoTipo de trigger (http, cron, event)
ctx.envEnvAccessorAcceso a secrets
ctx.paramsRecord<string, string>Parámetros de ruta
ctx.queryRecord<string, string>Query string params
ctx.jelouJelouSDKCliente de mensajería WhatsApp
ctx.memoryMemorySDKMemoria de sesión key-value
ctx.methodstringMétodo HTTP (GET, POST, etc.)
ctx.pathstringPath del request
ctx.requestIdstringUUID único del request
ctx.isCronbooleantrue si es trigger cron
ctx.isEventbooleantrue si es trigger event
ctx.isHttpbooleantrue si es request HTTP
ctx.skillIdstring | nullID del flujo de Brain Studio
ctx.executionIdstring | nullID de ejecución de Brain Studio
ctx.log()(...args) => voidLogger estructurado

Identidad

handler: async (input, ctx) => {
  // Empresa
  ctx.company.id;    // 42
  ctx.company.name;  // "Tienda ABC"

  // Bot
  ctx.bot.id;        // "bot-123"
  ctx.bot.name;      // "Bot de Soporte"
  ctx.bot.channel;   // "whatsapp"

  // Usuario
  ctx.user.id;       // 99
  ctx.user.names;    // "María García" (opcional)
  ctx.user.roomId;   // "room-456" (opcional)

  // Conversación y operador
  ctx.conversation.id;  // "conv-789" (opcional)
  ctx.operator.id;      // "op-012" (opcional)
}
Los datos se hidratan automáticamente desde la plataforma según los headers del request (x-bot-id, x-user-id).

Trigger

Tres tipos de trigger determinan cómo se invocó tu función:
handler: async (input, ctx) => {
  if (ctx.isHttp) {
    // Petición HTTP normal
    ctx.trigger; // { type: "http" }
  }
}
Usa los guards ctx.isCron, ctx.isEvent y ctx.isHttp en lugar de comparar ctx.trigger.type manualmente.

Request

export default define({
  description: "API con ruta parametrizada",
  input: z.object({}),
  config: { path: "/users/:id" },
  handler: async (input, ctx) => {
    ctx.method;      // "GET"
    ctx.path;        // "/users/42"
    ctx.params.id;   // "42"
    ctx.query.format // "json" (de ?format=json)
    ctx.requestId;   // "a1b2c3d4-..."

    return { userId: ctx.params.id };
  },
});

Environment (secrets)

handler: async (input, ctx) => {
  // Obtener un secret
  const apiKey = ctx.env.get("CRM_API_KEY"); // string | undefined

  // Verificar si existe
  if (ctx.env.has("WEBHOOK_SECRET")) {
    // ...
  }

  // Obtener todos (excepto internos __FN_*)
  const all = ctx.env.toObject(); // Record<string, string>
}
Las variables internas con prefijo __FN_ están bloqueadas — ctx.env.get("__FN_COMPANY_ID") retorna undefined.

Mensajería (ctx.jelou)

Envía mensajes de WhatsApp directamente desde tu función:
handler: async (input, ctx) => {
  if (ctx.jelou.available) {
    await ctx.jelou.send({
      type: "text",
      to: "+593987654321",
      text: "Tu pedido está listo",
    });
  }
}

Guía de mensajería

14 tipos de mensaje, templates HSM y manejo de errores.

Memoria (ctx.memory)

Persiste datos por sesión (key-value con TTL):
handler: async (input, ctx) => {
  if (ctx.memory.available) {
    const paso = await ctx.memory.get("paso", "inicio");
    await ctx.memory.set("paso", "confirmacion", 3600);
  }
}

Guía de memoria

Primitivos, JSON, TTL, límites y patrones comunes.

Brain Studio (skillId, executionId)

Cuando tu función es invocada desde Brain Studio como herramienta MCP:
handler: async (input, ctx) => {
  if (ctx.skillId) {
    ctx.log("Invocado desde Brain Studio", {
      skillId: ctx.skillId,         // "skill-abc-123"
      executionId: ctx.executionId, // "exec-def-456"
    });
  }
}
Estos campos son null para peticiones HTTP directas y triggers cron.

Logging

ctx.log() escribe JSON estructurado con metadatos automáticos:
handler: async (input, ctx) => {
  ctx.log("Procesando pedido", { telefono: input.telefono });
  // Escribe a stdout:
  // {
  //   "requestId": "a1b2c3d4-...",
  //   "function": "mi-funcion",
  //   "company": 42,
  //   "timestamp": "2026-04-07T15:30:01.234Z",
  //   "args": ["Procesando pedido", { "telefono": "593987654321" }]
  // }
}
Visualiza los logs con jelou logs mi-funcion.

Ejemplo completo

index.ts
import { define, z } from "@jelou/functions";

export default define({
  name: "procesar-pedido",
  description: "Procesa un pedido y notifica al cliente por WhatsApp",
  input: z.object({
    pedidoId: z.string(),
    telefono: z.string().min(10),
  }),
  handler: async (input, ctx) => {
    ctx.log("Procesando pedido", {
      pedidoId: input.pedidoId,
      company: ctx.company.id,
      bot: ctx.bot.name,
    });

    // Consultar API externa con secret
    const apiKey = ctx.env.get("ORDERS_API_KEY");
    const res = await fetch(`https://api.example.com/orders/${input.pedidoId}`, {
      headers: { Authorization: `Bearer ${apiKey}` },
    });
    const pedido = await res.json();

    // Notificar al cliente por WhatsApp
    if (ctx.jelou.available) {
      await ctx.jelou.send({
        type: "text",
        to: input.telefono,
        text: `Tu pedido ${pedido.id} está ${pedido.status}.`,
      });
    }

    // Guardar estado en memoria
    if (ctx.memory.available) {
      await ctx.memory.set("ultimo_pedido", input.pedidoId, 86400);
    }

    return {
      pedidoId: pedido.id,
      status: pedido.status,
      notificado: ctx.jelou.available,
    };
  },
});

Mensajería

Enviar WhatsApp con ctx.jelou.

Memoria

Persistir datos con ctx.memory.

Secrets

Variables de entorno cifradas.

Autenticación

Runtime tokens y funciones públicas.