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
Propiedad Tipo Descripció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 cronctx.isEventbooleantrue si es trigger eventctx.isHttpbooleantrue si es request HTTPctx.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" }
}
}
handler : async ( input , ctx ) => {
if ( ctx . isCron ) {
ctx . trigger . type ; // "cron"
ctx . trigger . cron ; // "0 9 * * *"
ctx . trigger . cronName ; // "recordatorio-mañana" (opcional)
}
}
handler : async ( input , ctx ) => {
if ( ctx . isEvent ) {
ctx . trigger . type ; // "event"
ctx . trigger . event ; // "pago.completado"
}
}
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
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.