Integración de Jelou WhatsApp
Integración del Bot de WhatsApp Jelou
Versión: 1.0 Última Actualización: 2025-11-20 Referencias:
algesta-agent/jelou/bot.jsonalgesta-agent/jelou/skills.jsonalgesta-agent/jelou/variables.jsonalgesta-agent/jelou/skill_26084_workflow.json- Flujo de generación de PDFalgesta-agent/jelou/skill_26085_workflow.json- Flujo de registro de orden de empresaalgesta-agent/jelou/skill_26086_workflow.json- Flujo de validación de empresa registradaalgesta-agent/jelou/skill_26087_workflow.json- Flujo de consulta de ordenalgesta-agent/jelou/skill_26088_workflow.json- Flujo de registro individualalgesta-agent/jelou/skill_26089_workflow.json- Flujo de registro de empresaalgesta-agent/jelou/skill_26090_workflow.json- Flujo de menú principal (predeterminado)
1. Descripción General
Configuración del Bot
El bot de WhatsApp de Algesta está construido en la plataforma Jelou, una plataforma de IA conversacional sin código que permite la automatización sofisticada del servicio al cliente a través de la integración con WhatsApp Business API.
Metadatos del Bot:
- ID del Bot:
b65f501f-dbba-4e5c-a0ab-c51063cfe694 - Nombre del Bot: Algesta QA
- Tipo: WhatsApp Business API
- ID del Brain:
01k2fxkq5arck1stpnvs26g4jq - ID de Compañía:
2419 - ID de App:
wiKVQI_EZDE4vsycbft9qvvO6j - Habilidad Predeterminada: 14469 (Menú principal - usuario individual registrado)
Descripción General de la Arquitectura
Jelou es una plataforma de IA conversacional sin código que proporciona:
- Constructor de Flujo Basado en Nodos: Editor de flujo visual para crear flujos conversacionales
- Soporte Multicanal: WhatsApp, chat web, Facebook Messenger y más
- Integración de IA: Integración nativa de GPT-4/GPT-4o para procesamiento de lenguaje natural
- Conectividad API: Nodos HTTP para integración de API REST con servicios backend
- Gestión de Estado: Almacenamiento de variables con TTL configurable para persistencia de sesión
- Ejecución de Código: Nodos de código JavaScript para procesamiento y transformación de datos personalizados
Propósito de la Integración
El bot de WhatsApp de Jelou sirve como el canal principal de cara al cliente para Algesta, permitiendo:
- Creación de Solicitudes de Servicio: Los usuarios pueden crear órdenes de mantenimiento y reparación directamente a través de WhatsApp
- Seguimiento de Órdenes: Consultas de estado de órdenes en tiempo real y búsqueda de historial de órdenes
- Registro de Usuarios: Incorporación automatizada tanto para usuarios individuales como para empleados de empresas
- Gestión de Empresas: Flujos de registro de empresas y validación de empleados
- Entrega de Documentos: Generación y entrega automatizada de PDF para confirmaciones de órdenes
- Disponibilidad 24/7: Servicio al cliente continuo sin intervención humana
Stack Tecnológico
- Plataforma Conversacional: Jelou (plataforma de IA sin código)
- Canal de Comunicación: WhatsApp Business API
- Modelos de IA:
- GPT-4o / GPT-4o-mini para clasificación de servicios
- GPT-4.1 con Vision para procesamiento de imágenes e identificación de activos
- Azure GPT-4o como modelo de respaldo
- Integración Backend: APIs REST vía nodos HTTP
- Scripting: JavaScript (ES6+) en nodos de código
- Gestión de Estado: Jelou Memory v2 con TTL de 1 hora
2. Skills Catalog
The bot consists of 7 interconnected skills that handle different conversational flows. Skills are triggered by AI-powered intent detection (Brain) or explicit transitions from other skills.
| Skill ID | Workflow ID | Name | Purpose | Trigger Type | Entry Point |
|---|---|---|---|---|---|
| 14463 | 26084 | pdf orden generada | Generate and send order confirmation PDF to user | BRAIN | Triggered after order creation |
| 14464 | 26085 | registrar (orden empresa) | Company order registration with AI-powered asset scanning | BRAIN | From company validation flow |
| 14465 | 26087 | consultar orden | Order inquiry and tracking by ID or phone number | BRAIN | User selects “Consultar orden” |
| 14466 | 26086 | empresa registrado | Registered company employee validation and authentication | BRAIN | From company registration flow |
| 14467 | 26088 | registro | Individual user registration and order creation flow | BRAIN | User selects “Solicitar servicio” |
| 14468 | 26089 | empresa | Company registration and employee onboarding | BRAIN | User provides company NIT |
| 14469 | 26090 | inicio (persona natural registrado) | Default entry point with main menu (Solicitar/Consultar) | BRAIN (default) | Conversation start |
Skill Flow Relationships
graph TD
A[26090: Main Menu] -->|Solicitar servicio| B[26088: Individual Registration]
A -->|Empresa| C[26089: Company Registration]
A -->|Consultar orden| D[26087: Order Inquiry]
B -->|Order created| E[26084: PDF Generation]
C -->|Company found| F[26086: Company Validation]
C -->|Company not found| G[Register Company]
F -->|Validated| H[26085: Company Order]
H -->|Order created| E
E -->|PDF sent| A
D -->|Status shown| A
3. Variables Management
The bot manages 50+ variables across 7 categories for session state, API responses, and data processing. All variables use Memory v2 with a default TTL of 3600 seconds (1 hour).
3.1 User Data Variables
Variables for individual user identification and authentication:
| Variable Name | Purpose | Type | TTL | Example Valor |
|---|---|---|---|---|
numero | Primary phone number field | String | 3600s | ”3001234567” |
new-phone | Phone during registration | String | 3600s | ”3001234567” |
employee-phone | Employee phone number | String | 3600s | ”3001234567” |
new-name | User name during registration | String | 3600s | ”Juan Pérez” |
employee-name | Employee name | String | 3600s | ”María García” |
employee-name-principal | Primary employee name | String | 3600s | ”Carlos López” |
new-email | User email during registration | String | 3600s | ”juan@example.com” |
email | Primary email field | String | 3600s | ”maria@company.com” |
employee-email | Employee email address | String | 3600s | ”maria@company.com” |
employee-email-principal | Primary employee email | String | 3600s | ”carlos@company.com” |
new-id | Individual ID number | String | 3600s | ”1234567890” |
id-nit | Company NIT or individual ID | String | 3600s | ”900123456-7” |
otp | OTP code for validation | String | 3600s | ”123456” |
otpcode | Alternative OTP field | String | 3600s | ”654321” |
new-otp | OTP during registration | String | 3600s | ”987654” |
company-otp | Company employee OTP | String | 3600s | ”456789” |
3.2 Company Data Variables
Variables for company and employee information:
| Variable Name | Purpose | Type | TTL | Example Valor |
|---|---|---|---|---|
company-name | Company legal name | String | 3600s | ”Acme Corporation S.A.S” |
company-nit | Company tax identification | String | 3600s | ”900123456-7” |
company-address | Company main address | String | 3600s | ”Calle 100 #15-20” |
company-branch | Branch office identifier | String | 3600s | ”Bogotá Norte” |
company-branch-name | Branch office name | String | 3600s | ”Sede Principal” |
employee-charge | Employee job title | String | 3600s | ”Jefe de Compras” |
purchasing-employees-list | Enumerated list of employees | String | 3600s | ”1. Juan - juan@company.com\n2. María - maria@company.com” |
company-selected-purchasing | User’s employee selection | String | 3600s | ”1” or “Juan” |
company-option-purchasing | Parsed employee data | JSON | 3600s | {"name":"Juan","email":"juan@company.com"} |
3.3 Order Data Variables
Variables for order creation and service requests:
| Variable Name | Purpose | Type | TTL | Example Valor |
|---|---|---|---|---|
problema | Problem Descripción | String | 3600s | ”El aire acondicionado no enfría” |
company-problem | Company problem Descripción | String | 3600s | ”Equipo de refrigeración dañado” |
servicio-select | AI-classified service type | String | 3600s | ”❄️ Aires-Refrigeración” |
company-select-problem | Company service selection | String | 3600s | ”⚡ Electricidad” |
imagen1 | First uploaded image URL | String | 3600s | ”https://storage.jelou.ai/…” |
imagen2 | Second uploaded image URL | String | 3600s | ”https://storage.jelou.ai/…” |
imagen3 | Third uploaded image URL | String | 3600s | ”https://storage.jelou.ai/…” |
company-image1 | Company first image | String | 3600s | ”https://storage.jelou.ai/…” |
company-image2 | Company second image | String | 3600s | ”https://storage.jelou.ai/…” |
company-image-problem | Company problem image | String | 3600s | ”https://storage.jelou.ai/…” |
location | Selected location | String | 3600s | ”Calle 80 #25-30, Bogotá” |
address | Service address | String | 3600s | ”Calle 80 #25-30” |
company-address | Company service address | String | 3600s | ”Calle 100 #15-20” |
city | Service city | String | 3600s | ”Bogotá” |
scheduled-date | Selected service date | String | 3600s | ”2025-12-15” |
scheduled-time | Selected service time | String | 3600s | ”10:00 AM - 12:00 PM” |
actual-date | Current date | String | 3600s | ”2025-11-20” |
created-order-id | Newly created order ID | String | 3600s | ”00123” |
ordersearch | Order ID for inquiry | String | 3600s | ”00123” |
orderdata | Full order details | JSON | 3600s | {"id":"00123","Estado":"Pendiente",...} |
3.4 API Response Variables
Variables storing backend API responses:
| Variable Name | Purpose | Type | TTL | Example Valor |
|---|---|---|---|---|
api-res-generate-pdf-order | PDF generation response | JSON | 3600s | {"url":"https://docs.algesta.com/..."} |
api-res-message-create | Message creation response | JSON | 3600s | {"messageId":"msg_123"} |
api-res-order-create | Order creation response | JSON | 3600s | {"orderId":"00123","Estado":"created"} |
res-list-orders | Order list response | JSON | 3600s | [{"id":"00123",...},{"id":"00124",...}] |
res-ia-list | AI-processed order list | String | 3600s | ”1. Orden #00123\n2. Orden #00124” |
api-res-list-order | Order listing response | JSON | 3600s | {"orders":[...]} |
find-user-api | User lookup response | JSON | 3600s | {"userId":"user_123","name":"Juan"} |
api-res-employee-area | Employee area response | JSON | 3600s | {"employees":[...]} |
3.5 AI Processing Variables
Variables for AI model outputs:
| Variable Name | Purpose | Type | TTL | Example Valor |
|---|---|---|---|---|
photo-ia | AI-extracted asset data from image | JSON Array | 3600s | [{"label":"Serial","Valor":"SN-12345"},{"label":"Model","Valor":"AC-3000"}] |
respuestaproblemaia | AI service classification | JSON | 3600s | {"option":"❄️ Aires-Refrigeración"} |
respuestaproblemaia2 | Alternative AI classification | JSON | 3600s | {"option":"⚡ Electricidad"} |
res-ia-list | AI-parsed order selection | String | 3600s | ”00123” |
ia-order-selected | AI-extracted order ID | String | 3600s | ”00123” |
3.6 Asset Identification Variables
Variables extracted from equipment photos using AI Vision:
| Variable Name | Purpose | Type | TTL | Example Valor |
|---|---|---|---|---|
serial-asset | Equipment serial number | String | 3600s | ”SN-12345678” |
sn-asset | Equipment S/N identifier | String | 3600s | ”S/N-ABC123” |
model-asset | Equipment model number | String | 3600s | ”AC-3000-PRO” |
3.7 Configuration Variables
System and environment variables:
| Variable Name | Purpose | Type | TTL | Example Valor |
|---|---|---|---|---|
dev | Base API URL (environment) | String | None | ”https://api-dev.algesta.com” |
local | Local environment flag | Boolean | None | false |
Documento-generate-pdf | Full PDF URL | String | 3600s | ”https://docs.algesta.com/order-00123.pdf” |
Documento-generate-pdf-part1 | PDF URL part 1 | String | 3600s | ”https://docs.algesta.com/“ |
Documento-generate-pdf-part2 | PDF URL part 2 | String | 3600s | ”order-00123.pdf” |
Variable Access Patterns
Variables are accessed in workflows through:
- Input Nodes: Store user responses directly to variables
- Code Nodes: Read/write via
$memory.get('variable')and$memory.set('variable', Valor) - HTTP Nodes: Store API responses in variables, reference in URL/body via
{{variable}} - AI Nodes: Output stored in configured variable
- Message Nodes: Display via
{{variable}}interpolation
4. Integration with Backend Microservicios
The Jelou bot integrates with Algesta backend Microservicios through REST API calls using HTTP nodes. All APIs are accessed via the {{dev}} environment variable (base URL).
4.1 Authentication Service (MS_AUTH)
Handles OTP-based user validation via SMS and email.
OTP Send Endpoint
- URL:
POST {{dev}}/api/auth/otp/send/{phoneNumber} - Propósito: Send SMS with 6-digit OTP code to user’s phone
- Path Parameters:
phoneNumber: Colombian phone format (e.g., “3001234567”)
- Response: Success/failure Estado
- Used In: Skills 26088, 26090, 26087 (individual registration and validation)
- Timeout: 30000ms
- Error Handling: Failed edge → error message “No pudimos enviar el código”
OTP Validate Endpoint
- URL:
POST {{dev}}/api/auth/otp/validate/{phoneNumber}/{otpCode} - Propósito: Verify OTP code matches sent code
- Path Parameters:
phoneNumber: Phone number fromnumerovariableotpCode: 6-digit code fromotpvariable
- Response:
{"valid": true/false} - Used In: Skills 26088, 26090, 26087
- Validation Logic: Code node checks response and branches flow
- Error Handling: Failed edge → retry OTP entry (max 3 attempts)
Employee OTP Validate Endpoint
- URL:
POST {{dev}}/api/employee/validate-otp - Request Body:
{"email": "{{employee-email}}","otp": "{{company-otp}}"}
- Propósito: Email-based OTP validation for company employees
- Used In: Skills 26086, 26089
- Response Processing: Code node extracts validation Estado
- Error Handling: Failed edge → retry OTP entry
4.2 Orders Service (MS_ORDERS)
Core order management service for creating, retrieving, and managing service orders.
Create Order Endpoint
- URL:
POST {{dev}}/api/orders - Propósito: Create new service order from WhatsApp conversation
- Request Body:
{"channel": "whatsapp","service": "❄️ Aires-Refrigeración","address": "Calle 80 #25-30","descriptionProblem": "El aire acondicionado no enfría","image1": "https://storage.jelou.ai/...","image2": "https://storage.jelou.ai/...","image3": "https://storage.jelou.ai/...","phone": "3001234567","scheduledDate": "2025-12-15","scheduledTime": "10:00 AM - 12:00 PM","city": "Bogotá","contactName": "Juan Pérez","contactEmail": "juan@example.com","nit": "900123456-7","branchName": "Sede Principal","serialAsset": "SN-12345678","snAsset": "S/N-ABC123","modelAsset": "AC-3000-PRO","purchasingContactName": "María García","purchasingContactEmail": "maria@company.com"}
- Required Fields: channel, service, address, DescripciónProblem, phone, scheduledDate, scheduledTime, city
- Optional Fields: image1-3, nit, branchName, asset fields, purchasing contact (for company orders)
- Response:
{"orderId": "00123", "Estado": "created"} - Used In: Skills 26088 (individual), 26085 (company)
- Response Processing: Code node extracts
orderIdand stores increated-order-id - Error Handling: Failed edge → error message “No pudimos crear la orden”
Get Order by ID Endpoint
- URL:
GET {{dev}}/api/orders/{orderId} - Propósito: Retrieve order details for Estado inquiry
- Path Parameters:
orderId: Order identifier (e.g., “00123”)
- Response:
{"id": "00123","status": "pending","service": "❄️ Aires-Refrigeración","address": "Calle 80 #25-30","city": "Bogotá","scheduledDate": "2025-12-15","scheduledTime": "10:00 AM - 12:00 PM","descriptionProblem": "El aire acondicionado no enfría","createdAt": "2025-11-20T10:00:00Z"}
- Used In: Skill 26087 (order inquiry)
- Response Processing: Code node formats order details for display
- Error Handling: Failed edge → “Orden no encontrada”
Get Orders by Phone Endpoint
- URL:
GET {{dev}}/api/orders/by-phone/{phoneNumber} - Propósito: List all orders for a user by phone number
- Path Parameters:
phoneNumber: Phone fromnumerovariable
- Response: Array of order objects
- Used In: Skill 26087 (when user lost order ID)
- Response Processing: Code node formats enumerated list
- Error Handling: Failed edge → “No encontramos órdenes”
Location Search Endpoint
- URL:
POST {{dev}}/api/orders/locations/search - Request Body:
{"address": "{{address}}"}
- Propósito: Validate and geocode service address
- Response: Location data with coordinates and validated address
- Used In: Skills 26088, 26085
- Response Processing: Code node checks if location exists
- Error Handling: If not found → Create Location Endpoint
Create Location Endpoint
- URL:
POST {{dev}}/api/orders/locations - Request Body:
{"address": "{{address}}","nit": "{{company-nit}}","branchName": "{{company-branch-name}}","city": "{{city}}"}
- Propósito: Register new service location for company
- Response: Created location object
- Used In: Skills 26085 (company order)
- Error Handling: Failed edge → error message
4.3 Documentos Service
Generates order confirmation PDFs for delivery via WhatsApp.
Generate PDF Endpoint
- URL:
GET {{dev}}/api/Documentos/generate-pdf/{orderId} - Propósito: Generate order confirmation PDF Documento
- Path Parameters:
orderId: Order ID fromcreated-order-idvariable
- Response:
{"url": "https://docs.algesta.com/order-00123.pdf"} - Used In: Skill 26084 (PDF generation)
- Response Processing: Code node extracts URL and stores in
Documento-generate-pdf - Error Handling: Failed edge → “No pudimos generar tu archivo de orden”
- Delivery: PDF URL sent as file message node to user
4.4 Messages Service
Logs WhatsApp conversation messages for audit trail and analytics.
Create Message Endpoint
- URL:
POST {{dev}}/api/messages - Request Body:
{"phoneNumber": "{{numero}}","messageContent": "User message or bot response text","associatedOrder": "{{created-order-id}}"}
- Propósito: Store WhatsApp messages for compliance and analytics
- Response: Message ID
- Used In: Throughout all skills (multiple HTTP nodes)
- Error Handling: Non-blocking (failed edge doesn’t stop flow)
4.5 Companies Service
Manages company registration and lookup.
Find by NIT Endpoint
- URL:
GET {{dev}}/api/companies/find-by-nit?nit={nit} - Propósito: Look up company by tax identification number
- Query Parameters:
nit: Colombian NIT format (e.g., “900123456-7”)
- Response: Company object or 404
- Used In: Skill 26089 (company registration)
- Response Processing: Code node checks if company exists
- Conditional Branch: Found → skill 26086, Not Found → register company
Register Company Endpoint
- URL:
POST {{dev}}/api/companies/register - Request Body:
{"name": "{{company-name}}","address": "{{company-address}}","branchName": "{{company-branch-name}}","nit": "{{company-nit}}"}
- Propósito: Register new company in system
- Response: Created company object
- Used In: Skill 26089
- Error Handling: Failed edge → “No pudimos registrar la empresa”
4.6 Employee Service
Manages company employee registration and validation.
Register Employee Endpoint
- URL:
POST {{dev}}/api/employee/register - Request Body:
{"nit": "{{company-nit}}","charge": "{{employee-charge}}","name": "{{employee-name}}","email": "{{employee-email}}","phone": "{{employee-phone}}","area": "purchasing"}
- Propósito: Register employee in purchasing department
- Response: Employee object
- Used In: Skills 26089, 26086
- Error Handling: Failed edge → “No pudimos registrar el empleado”
Get Employees by Area Endpoint
- URL: Inferred from workflow (not explicitly shown)
- Propósito: Retrieve employees in purchasing department for contact selection
- Response: Array of employee objects
- Used In: Skill 26085 (company order for purchasing contact)
- Response Processing: Code node formats enumerated list
4.7 Users Service
Manages individual user registration and lookup.
Find User Endpoint
- URL:
GET {{dev}}/api/users/find-by-phone/{phoneNumber} - Propósito: Look up existing user by phone number
- Path Parameters:
phoneNumber: Phone fromnumerovariable
- Response: User object or 404
- Used In: Skill 26090, 26088
- Conditional Branch: Found → proceed to order, Not Found → registration
Create User Endpoint
- URL:
POST {{dev}}/api/users - Request Body:
{"name": "{{new-name}}","email": "{{new-email}}","phone": "{{new-phone}}","role": "customer"}
- Propósito: Register new individual user
- Response: Created user object
- Used In: Skill 26088 (registration)
- Error Handling: Failed edge → “No pudimos registrar el usuario”
4.8 API Integration Patterns
Common patterns across all API integrations:
HTTP Node Configuration
{ "method": "POST/GET", "url": "{{dev}}/api/endpoint", "timeout": 30000, "retries": 0, "headers": {}, "body": { "field": "{{variable}}" }, "saveResponseIn": "api-response-variable"}Error Handling Pattern
- Success Edge: Proceeds to next node (data processing or next API call)
- Failed Edge: Routes to error message node with user-friendly message
- Code Node Processing: Wraps API response access in try-catch
try {const response = $context.httpResponseBody;const data = JSON.parse(response);$memory.set('processed-data', data.field);} catch (error) {console.log('API Error:', error);$memory.set('error-message', 'Error processing response');}
Variable Interpolation
- URL Parameters:
{{dev}}/api/orders/{{created-order-id}} - Request Body:
{"phone": "{{numero}}", "name": "{{new-name}}"} - Query Parameters:
?nit={{company-nit}}&branch={{company-branch}}
Response Processing
Code nodes extract and transform API responses:
const response = $context.httpResponseBody;const orderData = JSON.parse(response);$memory.set('created-order-id', orderData.orderId);$memory.set('order-status', orderData.status);Environment Configuration
- Dev Environment:
devvariable stores base URL (e.g.,https://api-dev.algesta.com) - No Authentication: Assumes internal network or API gateway handles auth
- Timeout: 30-second timeout for all requests
- No Retry: Retries disabled (0) to prevent duplicate Operaciones
5. AI-Powered Funcionalidades
The Jelou bot leverages multiple AI models for intelligent conversation handling, service classification, and image processing.
5.1 Service Type Detection
AI Task Configuration:
- Model: GPT-4o / GPT-4o-mini
- Fallback Model: Azure GPT-4o
- Propósito: Analyze user’s problem Descripción and automatically classify into service category
- Node Type: AI_LOGIC (AI Task)
Service Categories (13 types):
- 🧱 Albañilería
- 🎨 Pintura
- 🔑 Cerrajería
- 🚰 Plomería
- ⚡ Electricidad
- ❄️ Aires-Refrigeración
- 📺 Electrónica
- 🏥 Electromedicina
- 🪑 Tapicería-Mobiliario
- 🏗️ Adecuaciones/Obras Civiles
- 🔧 Mecánica
- 🪚 Carpintería
- ❓ Otra
AI Prompt:
Analiza la siguiente descripción del problema y clasifica el tipo de servicio necesario.
Descripción: {{problema}}
Responde ÚNICAMENTE con un JSON en este formato:{"option": "<categoría>"}
Categorías disponibles:- "🧱 Albañilería"- "🎨 Pintura"- "🔑 Cerrajería"- "🚰 Plomería"- "⚡ Electricidad"- "❄️ Aires-Refrigeración"- "📺 Electrónica"- "🏥 Electromedicina"- "🪑 Tapicería-Mobiliario"- "🏗️ Adecuaciones/Obras Civiles"- "🔧 Mecánica"- "🪚 Carpintería"- "❓ Otra"Workflow:
- User provides problem Descripción → stored in
problemavariable - AI Task node processes Descripción with GPT-4o
- Response stored in
respuestaproblemaiavariable - Code node extracts
optionfield and stores inservicio-select - Bot presents confirmation: “Identificamos que necesitas ❄️ Aires-Refrigeración, ¿es correcto?”
- User confirms or manually selects different service
Example:
- Input:
"El aire acondicionado no enfría bien y hace ruido extraño" - AI Output:
{"option": "❄️ Aires-Refrigeración"} - Variable:
servicio-select = "❄️ Aires-Refrigeración"
Error Handling:
- If AI fails → fallback to manual service selection (Lista node with 13 options)
- If AI returns invalid format → Code node catches error and triggers manual selection
Used In: Skills 26088 (individual), 26085 (company)
5.2 Image Processing for Asset Identification
AI Agent Configuration:
- Model: GPT-4.1 with Vision capabilities
- Propósito: Extract equipment information from photos (serial numbers, model, S/N)
- Node Type: AI_AGENT (AI Agent with tools)
AI Agent Prompt:
Analiza la imagen del equipo y extrae la siguiente información visible en etiquetas, placas o marcas:
1. **Serial Number** (Serial, N° Serie, Serial No)2. **S/N** (S/N, Serial Number)3. **Model Number** (Modelo, Model, Model No)
Responde en formato JSON array:[ {"label": "Serial", "value": "SN-12345678"}, {"label": "S/N", "value": "S/N-ABC123"}, {"label": "Model No", "value": "AC-3000-PRO"}, {"label": "mediaUrl", "value": "{{company-image1}}"}]
Si no encuentras información visible, responde con arrays vacíos.Input: Image URL from company-image1 variable (user-uploaded photo)
Output Structure:
[ {"label": "Serial", "value": "SN-12345678"}, {"label": "S/N", "value": "S/N-ABC123"}, {"label": "Model No", "value": "AC-3000-PRO"}, {"label": "mediaUrl", "value": "https://storage.jelou.ai/..."}]Response Processing (Code Node):
try { const photoIA = $memory.get('photo-ia'); const photoData = JSON.parse(photoIA);
// Extract specific fields const serialObj = photoData.find(item => item.label === 'Serial'); const snObj = photoData.find(item => item.label === 'S/N'); const modelObj = photoData.find(item => item.label === 'Model No');
// Store in individual variables with fallback const serial = serialObj?.value || `JELOU-${Date.now()}`; const sn = snObj?.value || `JELOU-${Date.now()}`; const model = modelObj?.value || 'No detectado';
$memory.set('serial-asset', serial); $memory.set('sn-asset', sn); $memory.set('model-asset', model);
console.log(`Asset extracted: Serial=${serial}, S/N=${sn}, Model=${model}`);} catch (error) { console.log('Error processing photo-ia:', error); // Fallback values const timestamp = Date.now(); $memory.set('serial-asset', `JELOU-${timestamp}`); $memory.set('sn-asset', `JELOU-${timestamp}`); $memory.set('model-asset', 'No detectado');}Fallback Logic:
- If AI cannot extract data → generates
JELOU-{timestamp}identifier - If image is unclear → user receives message “No pudimos leer la información, pero registramos la orden con la foto”
Use Case: Company order registration (skill 26085) for equipment maintenance
- Employee uploads photo of broken equipment (AC unit, refrigerator, medical device)
- AI extracts asset identifiers
- Data included in order for technician reference
Used In: Skill 26085 (company order registration)
5.3 Order Selection from List
AI Task Configuration:
- Model: GPT-4o-mini (faster, cheaper model for simple parsing)
- Propósito: Parse user’s selection from enumerated order list
- Node Type: AI_LOGIC (AI Task)
Scenario: User has multiple orders and selects one from list
AI Prompt:
El usuario tiene las siguientes órdenes:
{{data-res-order}}
El usuario seleccionó: {{select-order}}
Extrae el ID de la orden seleccionada (sin el símbolo #).Responde ÚNICAMENTE con el ID numérico.
Ejemplo:- Si selecciona "1" → responde con el ID de la primera orden- Si selecciona "Orden #00123" → responde "00123"Input Variables:
data-res-order: Enumerated list of orders1. Orden #00123 - Aires-Refrigeración - Pendiente2. Orden #00124 - Electricidad - En progreso3. Orden #00125 - Plomería - Completadaselect-order: User’s response (e.g., “1”, “la primera”, “00123”)
Output: Order ID without # symbol stored in ia-order-selected variable
- Example:
"00123"
Workflow:
- User requests order Estado but doesn’t remember ID
- Bot retrieves orders by phone:
GET /api/orders/by-phone/{phone} - Code node formats enumerated list
- Bot displays list → user selects
- AI parses selection → extracts order ID
- Bot retrieves order details:
GET /api/orders/{ia-order-selected} - Bot displays order Estado
Used In: Skill 26087 (order inquiry)
5.4 Employee Selection from List
AI Agent Configuration:
- Model: GPT-4.1
- Propósito: Parse user’s selection from purchasing employees list
- Node Type: AI_AGENT
Scenario: Company order registration - selecting purchasing contact for approval
AI Agent Prompt:
El usuario debe seleccionar un contacto de compras de la siguiente lista:
{{purchasing-employees-list}}
El usuario respondió: {{company-selected-purchasing}}
Extrae la información en formato JSON:{ "name": "Nombre del empleado", "email": "email@company.com"}
Si el usuario indica que NO quiere actualizar o mantener datos anteriores, responde:"No actualizar datos"Input Variables:
purchasing-employees-list: Enumerated employee list1. Juan Pérez - juan.perez@company.com2. María García - maria.garcia@company.com3. Carlos López - carlos.lopez@company.comcompany-selected-purchasing: User’s selection (e.g., “1”, “Juan”, “el primero”, “no cambiar”)
Output (stored in company-option-purchasing):
- JSON format (if employee selected):
{"name": "Juan Pérez","email": "juan.perez@company.com"}
- Text format (if no change):
"No actualizar datos"
Response Processing (Code Node):
const selection = $memory.get('company-option-purchasing');try { const parsed = JSON.parse(selection); $memory.set('purchasing-contact-name', parsed.name); $memory.set('purchasing-contact-email', parsed.email);} catch { // User said "no change" - use previous contact // Keep existing values in variables console.log('User opted not to update purchasing contact');}Used In: Skill 26085 (company order registration)
5.5 AI Model Configuration
Model Selection Strategy:
- GPT-4o: Complex tasks (service classification with 13 categories)
- GPT-4o-mini: Simple parsing tasks (order selection, number extraction)
- GPT-4.1 Vision: Image processing (asset identification)
- Azure GPT-4o: Fallback model if primary fails
Memory Version: v2 (required for variable access in AI prompts)
Error Handling:
- AI failures route to manual input nodes
- Timeout: Inherits from workflow settings (30 seconds)
- Fallback: Azure GPT-4o model automatically used if primary fails
Best Practices:
- Clear, structured prompts with examples
- JSON output format for structured data
- Fallback to manual input if AI fails
- Console logging for debugging AI responses
- Variable validation after AI processing
6. State Management and Flow Control
The Jelou platform uses a node-based workflow system with sophisticated state management and conditional branching.
6.1 Node Types
Each workflow consists of interconnected nodes that perform specific functions:
START Node
- Propósito: Entry point for each skill workflow
- Configuration: No configuration required
- Edges: Always has one outgoing “default” edge
- Example: Every skill has one START node that begins the conversation flow
INPUT Node (Pregunta)
- Propósito: Collect user input and store in variable
- Configuration:
saveResponseIn: Variable name to store user’s responseprompt: Message displayed to userinputType: text, image, Documento, audio, videovalidation: Optional regex or format validation
- Example:
{"nodeTypeId": "INPUT","title": "Solicitar número de teléfono","configuration": {"saveResponseIn": "numero","prompt": "Por favor, ingresa tu número de teléfono (10 dígitos):","inputType": "text"}}
- Edges: Default edge proceeds to next node after input collected
HTTP Node (API)
- Propósito: Make REST API calls to backend services
- Configuration:
Método: GET, POST, PUT, DELETEurl: Endpoint URL with variable interpolationheaders: HTTP headers (usually empty - no auth)body: Request body for POST/PUT (JSON with variables)timeout: 30000ms (30 seconds)retries: 0 (no retries)saveResponseIn: Variable to store response
- Example:
{"nodeTypeId": "HTTP","title": "Crear orden","configuration": {"method": "POST","url": "{{dev}}/api/orders","timeout": 30000,"retries": 0,"body": {"channel": "whatsapp","service": "{{servicio-select}}","phone": "{{numero}}","descriptionProblem": "{{problema}}"},"saveResponseIn": "api-res-order-create"}}
- Edges:
success: API call succeeded (2xx response)failed: API call failed (4xx/5xx response or timeout)
CODE Node
- Propósito: Execute JavaScript for data processing and transformation
- Configuration:
code: JavaScript code string (ES6+)- Memory access:
$memory.get('variable'),$memory.set('variable', Valor) - Context access:
$context.httpResponseBody,$context.userMessage
- Example:
// Extract order ID from API responsetry {const response = $context.httpResponseBody;const orderData = JSON.parse(response);const orderId = orderData.orderId;$memory.set('created-order-id', orderId);console.log('Order created:', orderId);} catch (error) {console.log('Error parsing response:', error);$memory.set('error-message', 'Error al crear orden');}
- Edges: Default edge (code execution always succeeds)
- Error Handling: Try-catch blocks within code, errors logged to console
CHANNEL_MESSAGE Node (Texto/Botones/Lista)
- Propósito: Send messages, buttons, or selection lists to user
- Types:
- Texto: Plain text message with variable interpolation
- Botones: Text with button options (quick replies)
- Lista: Text with dropdown list options
- Configuration:
message: Message text with{{variable}}interpolationbuttons: Array of button objects (for Botones type)listItems: Array of list items (for Lista type)
- Example Texto:
{"nodeTypeId": "CHANNEL_MESSAGE","title": "Confirmación orden","configuration": {"message": "✅ ¡Tu orden #{{created-order-id}} ha sido registrada!\n\nServicio: {{servicio-select}}\nFecha: {{scheduled-date}}\nHora: {{scheduled-time}}"}}
- Example Botones:
{"nodeTypeId": "CHANNEL_MESSAGE","title": "Menú principal","configuration": {"message": "¿Qué deseas hacer?","buttons": [{"label": "Solicitar servicio", "value": "solicitar"},{"label": "Consultar orden", "value": "consultar"}]}}
- Example Lista:
{"nodeTypeId": "CHANNEL_MESSAGE","title": "Seleccionar servicio","configuration": {"message": "Selecciona el tipo de servicio:","listItems": [{"title": "⚡ Electricidad", "value": "electricidad"},{"title": "🚰 Plomería", "value": "plomeria"},{"title": "❄️ Aires-Refrigeración", "value": "aires"}]}}
- Edges: Default edge (message sent, awaits user response in next INPUT node)
CONDITIONAL Node
- Propósito: Branch flow based on conditions (regex, empty checks, type validation)
- Configuration:
variable: Variable to evaluateconditions: Array of condition objects with regex, operators, or custom logic
- Example:
{"nodeTypeId": "CONDITIONAL","title": "Validar si usuario existe","configuration": {"variable": "find-user-api","conditions": [{"type": "empty","edge": "user-not-found"},{"type": "not-empty","edge": "user-found"}]}}
- Edges: Named edges based on conditions
user-found: Variable is not emptyuser-not-found: Variable is emptyphone-valid: Regex matches phone formatif-hour: Time-based condition
AI_LOGIC Node (AI Task)
- Propósito: Execute AI model for classification, extraction, or generation
- Configuration:
model: GPT-4o, GPT-4o-mini, Azure GPT-4oprompt: AI instruction with variable interpolationsaveResponseIn: Variable to store AI outputtemperature: 0.3 (low for consistent classification)
- Example:
{"nodeTypeId": "AI_LOGIC","title": "Clasificar servicio","configuration": {"model": "gpt-4o","prompt": "Analiza: {{problema}}\nClasifica en una de estas categorías...","saveResponseIn": "respuestaproblemaia","temperature": 0.3}}
- Edges:
success: AI processed successfullyfailed: AI failed (timeout, API error) → fallback to manual input
AI_AGENT Node
- Propósito: Execute AI agent with vision and tool capabilities
- Configuration:
model: GPT-4.1 (with vision)prompt: Agent instruction with image analysistools: Available tools for agent (image processing, web search)saveResponseIn: Variable to store agent output
- Example:
{"nodeTypeId": "AI_AGENT","title": "Extraer info de imagen","configuration": {"model": "gpt-4.1","prompt": "Analiza la imagen {{company-image1}} y extrae Serial, S/N, Model...","tools": ["vision"],"saveResponseIn": "photo-ia"}}
- Edges: Default edge (agent execution always Completos)
SKILL Node
- Propósito: Transition to another skill workflow
- Configuration:
targetSkillId: ID of skill to transition topreserveContext: Whether to maintain variables (default: true)
- Example:
{"nodeTypeId": "SKILL","title": "Ir a registro empresa","configuration": {"targetSkillId": 14468,"preserveContext": true}}
- Edges: No edges (flow ends in current skill, starts in target skill)
6.2 Edge Types
Edges connect nodes and define flow progression:
| Edge Type | Description | Usage |
|---|---|---|
default | Standard flow progression | Most nodes (INPUT, CODE, MESSAGE) |
success | Successful API call or operation | HTTP nodes, AI nodes |
failed | Failed API call or operation | HTTP nodes, AI nodes (error handling) |
user-found | User exists in Base de datos | CONDITIONAL nodes |
user-not-found | User doesn’t exist | CONDITIONAL nodes |
phone-valid | Phone format is valid | CONDITIONAL nodes with regex |
company-found | Company exists | CONDITIONAL nodes |
if-hour | Time-based condition | CONDITIONAL nodes for scheduling |
validar-imagen | Image validation passed | CONDITIONAL nodes for image checks |
6.3 State Persistence
Variables stored in Jelou Memory with configurable TTL:
Memory Version v2
- Access in Code Nodes:
// Get variableconst phoneNumber = $memory.get('numero');// Set variable$memory.set('created-order-id', '00123');// Delete variable$memory.delete('temp-data');// Check if existsconst hasPhone = $memory.has('numero');
Context Object
- HTTP Response Access:
const response = $context.httpResponseBody; // Raw response stringconst statusCode = $context.httpStatusCode; // HTTP status code
- User Message Access:
const userInput = $context.userMessage; // User's last message
Variable Lifecycle
- Creation: First set via INPUT node or Code node
- TTL: 3600 seconds (1 hour) by default
- Expiration: Variable deleted after TTL, user must restart flow
- Persistence: Variables persist across skill transitions if
preserveContext: true
6.4 Error Handling Patterns
Robust error handling throughout workflows:
Try-Catch in Code Nodes
try { const response = $context.httpResponseBody; const data = JSON.parse(response); $memory.set('processed-data', data.field); console.log('Success:', data);} catch (error) { console.log('Error processing response:', error); $memory.set('error-flag', true); $memory.set('error-message', error.toString());}Failed Edges from HTTP Nodes
- Pattern: HTTP node → success edge → next step
- Error: HTTP node → failed edge → error message node
- Example:
[HTTP: Create Order] --success--> [Code: Extract Order ID] --default--> [Message: Confirmation]|--failed--> [Message: "No pudimos crear la orden"]
API Error Messages
User-friendly error messages for failed Operaciones:
- “No pudimos enviar el código de verificación”
- “No pudimos crear la orden, intenta nuevamente”
- “No pudimos generar tu archivo de orden”
- “No encontramos órdenes asociadas a tu número”
- “No pudimos registrar la empresa”
Retry Options
- HTTP Retries: Disabled (
retries: 0) to prevent duplicate Operaciones - Manual Retry: User can restart flow from main menu
- Timeout: 30-second timeout prevents indefinite waits
Validation Before API Calls
Code nodes validate data before expensive API calls:
// Validate phone formatconst phone = $memory.get('numero');const phoneRegex = /^3\d{9}$/;if (!phoneRegex.test(phone)) { $memory.set('validation-error', 'Formato de teléfono inválido'); // Conditional node routes to error message}
// Validate required fieldsconst name = $memory.get('new-name');const email = $memory.get('new-email');if (!name || !email) { $memory.set('validation-error', 'Faltan campos requeridos');}AI Fallback Logic
- Primary AI fails → Fallback to Azure GPT-4o model
- Both AI models fail → Manual input (Lista or Botones node)
- Example: Service classification fails → User selects from 13-option list
6.5 Workflow Orchestration
Complex flows orchestrated through skill transitions and conditional branching:
Skill Transition Example
graph LR
A[Skill 26090: Main Menu] -->|User: Solicitar| B[Skill 26088: Registration]
B -->|Order Created| C[Skill 26084: PDF Generation]
C -->|PDF Sent| A
Conditional Branching Example
graph TD
A[Check User Exists] -->|Found| B[Proceed to Order]
A -->|Not Found| C[Collect Name]
C --> D[Collect Email]
D --> E[Collect ID]
E --> F[Register User]
F --> B
Nested Conditional Logic
Company registration flow with multiple decision points:
- Collect NIT → Check if company exists
- If Found: Validate employee → Check if registered
- If Employee Found: Proceed to order creation
- If Employee Not Found: Register employee → Proceed to order
- If Company Not Found: Register company → Register employee → Proceed to order
7. Mermaid Diagrams
Visual representations of key user flows and system interactions. This Sección includes at least one diagram per skill, along with additional end-to-end flows to illustrate the Completo user journey.
7.1 Main Menu Flow (Skill 26090)
sequenceDiagram
participant User
participant Jelou
participant AuthAPI
participant OrdersAPI
User->>Jelou: Start conversation
Jelou->>User: "¡Hola! 👋 Bienvenido a Algesta"
Jelou->>User: Menu buttons (Solicitar/Consultar)
alt Solicitar Servicio
User->>Jelou: Select "Solicitar servicio"
Jelou->>User: Request phone number
User->>Jelou: Provide phone (3001234567)
Jelou->>AuthAPI: POST /api/auth/otp/send/3001234567
AuthAPI-->>Jelou: OTP sent
AuthAPI-->>User: SMS with OTP code
Jelou->>User: "Ingresa el código OTP"
User->>Jelou: Provide OTP (123456)
Jelou->>AuthAPI: POST /api/auth/otp/validate/3001234567/123456
AuthAPI-->>Jelou: ✓ Validation success
Jelou->>OrdersAPI: GET /api/users/find-by-phone/3001234567
alt User Found
OrdersAPI-->>Jelou: User data
Note over Jelou: Transition to Skill 26088
else User Not Found
OrdersAPI-->>Jelou: 404 Not Found
Jelou->>User: "Necesitamos registrarte"
Note over Jelou: Collect name, email, ID
Note over Jelou: Register user → Skill 26088
end
else Consultar Orden
User->>Jelou: Select "Consultar orden"
Note over Jelou: Transition to Skill 26087
end
7.2 Company Order Registration Flow (Skill 26085)
sequenceDiagram
participant User as Company Employee
participant Jelou
participant AI as GPT-4/Vision
participant OrdersAPI
participant DocsAPI
Note over User,DocsAPI: User already validated via Skill 26086
Jelou->>User: "Envía una foto del equipo dañado"
User->>Jelou: Upload asset photo
Jelou->>AI: AI Agent (GPT-4.1 Vision): Extract asset info
AI-->>Jelou: [{"label":"Serial","value":"SN-12345"},...]
Note over Jelou: Code node processes photo-ia
Note over Jelou: Extract serial-asset, sn-asset, model-asset
Jelou->>User: "Describe el problema"
User->>Jelou: "El compresor no arranca"
Jelou->>AI: AI Task (GPT-4o): Classify service
AI-->>Jelou: {"option":"❄️ Aires-Refrigeración"}
Jelou->>User: "Identificamos **❄️ Aires-Refrigeración**, ¿correcto?"
User->>Jelou: "Sí, correcto"
Jelou->>User: "Envía fotos adicionales (opcional)"
User->>Jelou: Upload 2 more images
Jelou->>User: "Selecciona dirección"
User->>Jelou: Select from company locations
Jelou->>User: "Selecciona fecha"
User->>Jelou: "2025-12-15"
Jelou->>User: "Selecciona horario"
User->>Jelou: "10:00 AM - 12:00 PM"
Jelou->>OrdersAPI: GET /api/employee/purchasing-area
OrdersAPI-->>Jelou: List of purchasing employees
Jelou->>User: "Selecciona contacto de compras:\n1. Juan - juan@co.com\n2. María - maria@co.com"
User->>Jelou: "1"
Jelou->>AI: AI Agent (GPT-4.1): Parse selection
AI-->>Jelou: {"name":"Juan","email":"juan@co.com"}
Jelou->>OrdersAPI: POST /api/orders<br/>{channel, service, address, description,<br/>images, phone, date, time, city,<br/>nit, branch, serial, sn, model,<br/>purchasingContact}
OrdersAPI-->>Jelou: {"orderId":"00123"}
Note over Jelou: Transition to Skill 26084 (PDF)
Jelou->>DocsAPI: GET /api/documents/generate-pdf/00123
DocsAPI-->>Jelou: {"url":"https://docs.algesta.com/00123.pdf"}
Jelou->>User: Send PDF file via WhatsApp
Jelou->>User: "✅ ¡Orden #00123 registrada!\n\nSerá revisada por el área de compras."
7.3 PDF Generation Flow (Skill 26084)
sequenceDiagram
participant User
participant Jelou
participant DocsAPI as Documents Service
Note over User,DocsAPI: Triggered after order creation (Skills 26085 or 26088)
Note over Jelou: Memory: created-order-id = "00123"
Jelou->>DocsAPI: GET /api/documents/generate-pdf/00123
alt PDF Generation Success
DocsAPI-->>Jelou: {"data": {"pdfUrl": "https://docs.algesta.com/order-00123.pdf"}}
Note over Jelou: Code node processes response
Note over Jelou: Extract pdfUrl from response.data.pdfUrl
Note over Jelou: Split URL into two parts (part1 + part2)
Note over Jelou: Store in memory: document-generate-pdf-part1, document-generate-pdf-part2
Jelou->>User: Send PDF file attachment
Note over User: File: "Orden generada"
Note over User: WhatsApp displays PDF document
else PDF Generation Failed
DocsAPI-->>Jelou: HTTP error or invalid response
Note over Jelou: Code node catches error
Note over Jelou: Store error in memory: document-generate-pdf-error
Jelou->>User: "No pudimos generar tu archivo de orden en este momento, pero tu orden ya ha sido registrada correctamente con nosotros."
end
Note over Jelou: Flow complete - returns to calling skill
7.4 Registered Company Validation Flow (Skill 26086)
sequenceDiagram
participant User as Company Employee
participant Jelou
participant AuthAPI as Auth Service
participant OrdersAPI as Orders/Locations Service
participant NextSkill as Skill 26085
Note over User,NextSkill: Triggered from Skill 26089 when company already exists
Note over Jelou: Memory: company-nit is already set
Jelou->>User: "¡Genial! Tu empresa se encuentra en nuestra base de datos.\n\nPara continuar, necesitamos validar tu identidad.\n\nPor favor indícame tu número de celular"
User->>Jelou: "3001234567"
Note over Jelou: Store in employee-phone
Jelou->>AuthAPI: POST /api/auth/otp/send/3001234567
alt OTP Send Success
AuthAPI-->>User: SMS with 6-digit OTP code
AuthAPI-->>Jelou: Success response
Jelou->>User: "📩 Por favor, ingresa el código que te acabamos de enviar."
User->>Jelou: "123456"
Note over Jelou: Store in company-otp
Jelou->>AuthAPI: POST /api/auth/otp/validate/3001234567/123456
alt OTP Validation Success
AuthAPI-->>Jelou: Validation success
Jelou->>User: "✅ Verificación exitosa. Continuemos.\n\nAhora, ingresa tu correo empresarial."
User->>Jelou: "maria@company.com"
Note over Jelou: Store in employee-email-principal
Jelou->>User: "¡Perfecto! Continuemos con tu solicitud.\n\nIndícanos tu nombre"
User->>Jelou: "María García"
Note over Jelou: Store in employee-name-principal
Jelou->>User: "Ahora, ¿En qué ciudad necesitas el servicio?"
User->>Jelou: "Bogotá"
Note over Jelou: Store in city
Jelou->>User: "Ahora, por favor indícame la dirección exacta sin nombres (ej: C.1 #23-45)"
User->>Jelou: "Calle 100 #15-20"
Note over Jelou: Store in company-address
Jelou->>OrdersAPI: POST /api/orders/locations/search<br/>{"address": "Calle 100 #15-20"}
alt Location Found
OrdersAPI-->>Jelou: {"data": {"address": "Calle 100 #15-20, Bogotá"}}
Note over Jelou: Code node extracts validated address
Note over Jelou: Update company-address with validated value
Jelou->>User: "La sede Calle 100 #15-20, corresponde esta dirección.\n\n¿Esta correcta esta información?"
Note over User: Buttons: "Si, es correcto" | "Elegir otra sede"
alt Address Confirmed
User->>Jelou: Click "Si, es correcto"
Note over Jelou: Transition to Skill 26085 (Company Order Registration)
Jelou->>NextSkill: Start company order flow
else Choose Different Address
User->>Jelou: Click "Elegir otra sede"
Note over Jelou: Loop back to address input
Jelou->>User: "Ahora, por favor indícame la dirección exacta sin nombres (ej: C.1 #23-45)"
end
else Location Not Found
OrdersAPI-->>Jelou: 404 or error response
Jelou->>User: "No encontramos la dirección que nos proporcionaste."
Note over User: Buttons: "Escribir de nuevo" | "Añadir dirección"
alt Retry Address
User->>Jelou: Click "Escribir de nuevo"
Note over Jelou: Loop back to address input
Jelou->>User: "Ahora, por favor indícame la dirección exacta sin nombres (ej: C.1 #23-45)"
else Add New Location
User->>Jelou: Click "Añadir dirección"
Jelou->>User: "¡Genial! Escribe el Nombre de la sede (Ej. Nueva EPS Los cambulos)"
User->>Jelou: "Sede Norte"
Note over Jelou: Store in company-branch-name
Jelou->>OrdersAPI: POST /api/orders/locations<br/>{"address": "Calle 100 #15-20", "nit": "900123456-7",<br/>"branchName": "Sede Norte", "city": "Bogotá"}
OrdersAPI-->>Jelou: Location created
Note over Jelou: Transition to Skill 26085 (Company Order Registration)
Jelou->>NextSkill: Start company order flow
end
end
else OTP Validation Failed
AuthAPI-->>Jelou: Validation failed
Jelou->>User: "Error en validar Codigo te enviaremos uno nuevo."
Note over Jelou: Loop back to send new OTP
Jelou->>AuthAPI: POST /api/auth/otp/send/3001234567
end
else OTP Send Failed
AuthAPI-->>Jelou: Send error
Jelou->>User: "No pudimos enviar el código. Intenta de nuevo."
end
7.6 Order Inquiry Flow (Skill 26087)
sequenceDiagram
participant User
participant Jelou
participant AuthAPI
participant OrdersAPI
participant AI as GPT-4o-mini
Jelou->>User: "¿Tienes el número de orden?"
alt User Has Order ID
User->>Jelou: "00123"
Jelou->>OrdersAPI: GET /api/orders/00123
OrdersAPI-->>Jelou: Order details
Jelou->>User: "📋 Orden #00123\n\nServicio: Aires-Refrigeración\nEstado: En progreso\nFecha: 2025-12-15\nDirección: Calle 80 #25-30"
else User Lost Order ID
User->>Jelou: "No tengo el número"
Jelou->>User: "Ingresa tu teléfono"
User->>Jelou: "3001234567"
Jelou->>AuthAPI: POST /api/auth/otp/send/3001234567
AuthAPI-->>User: SMS with OTP
Jelou->>User: "Ingresa el código OTP"
User->>Jelou: "123456"
Jelou->>AuthAPI: POST /api/auth/otp/validate/3001234567/123456
AuthAPI-->>Jelou: ✓ Validation success
Jelou->>OrdersAPI: GET /api/orders/by-phone/3001234567
OrdersAPI-->>Jelou: [Order1, Order2, Order3]
Note over Jelou: Code node formats enumerated list
Jelou->>User: "Selecciona una orden:\n1. Orden #00123 - Aires - Pendiente\n2. Orden #00124 - Electricidad - En progreso\n3. Orden #00125 - Plomería - Completada"
User->>Jelou: "2"
Jelou->>AI: AI Task: Parse selection from list
AI-->>Jelou: "00124" (extracted order ID)
Jelou->>OrdersAPI: GET /api/orders/00124
OrdersAPI-->>Jelou: Order details
Jelou->>User: "📋 Orden #00124\n\nServicio: Electricidad\nEstado: En progreso\nTécnico: Carlos López\nFecha: 2025-12-10"
end
Jelou->>User: "¿Necesitas ayuda con algo más?"
User->>Jelou: Select option or return to menu
7.7 Individual User Registration Flow (Skill 26088)
sequenceDiagram
participant User
participant Jelou
participant AI as GPT-4o
participant UsersAPI
participant OrdersAPI
Note over User,OrdersAPI: User validated via OTP in Skill 26090
Jelou->>UsersAPI: GET /api/users/find-by-phone/{phone}
alt User Not Found
UsersAPI-->>Jelou: 404 Not Found
Jelou->>User: "Necesitamos registrarte"
Jelou->>User: "Ingresa tu nombre completo"
User->>Jelou: "Juan Pérez"
Jelou->>User: "Ingresa tu email"
User->>Jelou: "juan@example.com"
Jelou->>User: "Ingresa tu cédula"
User->>Jelou: "1234567890"
Jelou->>UsersAPI: POST /api/users<br/>{name, email, phone, role: "customer"}
UsersAPI-->>Jelou: User created
else User Found
UsersAPI-->>Jelou: User data
Note over Jelou: Skip registration
end
Jelou->>User: "Describe el problema"
User->>Jelou: "El aire acondicionado no enfría"
Jelou->>AI: AI Task (GPT-4o): Classify service type
AI-->>Jelou: {"option":"❄️ Aires-Refrigeración"}
Jelou->>User: "Identificamos **❄️ Aires-Refrigeración**, ¿es correcto?"
User->>Jelou: "Sí"
Jelou->>User: "Envía fotos del problema (hasta 3)"
User->>Jelou: Upload image 1
User->>Jelou: Upload image 2
User->>Jelou: "Listo" (no more images)
Jelou->>User: "Ingresa la dirección del servicio"
User->>Jelou: "Calle 80 #25-30"
Jelou->>User: "Selecciona la ciudad"
User->>Jelou: "Bogotá"
Jelou->>User: "Selecciona la fecha"
User->>Jelou: "2025-12-15"
Jelou->>User: "Selecciona el horario"
User->>Jelou: "10:00 AM - 12:00 PM"
Jelou->>OrdersAPI: POST /api/orders<br/>{channel: "whatsapp", service, address,<br/>descriptionProblem, images, phone,<br/>scheduledDate, scheduledTime, city,<br/>contactName, contactEmail}
OrdersAPI-->>Jelou: {"orderId":"00123"}
Note over Jelou: Transition to Skill 26084 (PDF)
Jelou->>User: Send PDF file
Jelou->>User: "✅ ¡Tu orden #00123 ha sido registrada!\n\nUn técnico se pondrá en contacto contigo."
7.8 Company Registration Flow (Skill 26089)
sequenceDiagram
participant User as New Employee
participant Jelou
participant CompaniesAPI
participant EmployeeAPI
participant AuthAPI
Jelou->>User: "Ingresa el NIT de la empresa"
User->>Jelou: "900123456-7"
Jelou->>CompaniesAPI: GET /api/companies/find-by-nit?nit=900123456-7
alt Company Not Found
CompaniesAPI-->>Jelou: 404 Not Found
Jelou->>User: "Empresa no registrada. Vamos a registrarla."
Jelou->>User: "Nombre de la empresa"
User->>Jelou: "Acme Corporation S.A.S"
Jelou->>User: "Dirección principal"
User->>Jelou: "Calle 100 #15-20"
Jelou->>User: "Ciudad"
User->>Jelou: "Bogotá"
Jelou->>User: "Nombre de la sede"
User->>Jelou: "Sede Principal"
Jelou->>CompaniesAPI: POST /api/companies/register<br/>{name, address, branchName, nit}
CompaniesAPI-->>Jelou: Company created
Jelou->>User: "Empresa registrada. Ahora registremos tu usuario."
Jelou->>User: "Tu nombre"
User->>Jelou: "María García"
Jelou->>User: "Tu email corporativo"
User->>Jelou: "maria@acme.com"
Jelou->>User: "Tu teléfono"
User->>Jelou: "3001234567"
Jelou->>User: "Tu cargo"
User->>Jelou: "Jefe de Compras"
Jelou->>EmployeeAPI: POST /api/employee/register<br/>{nit, name, email, phone, charge, area: "purchasing"}
EmployeeAPI-->>Jelou: Employee created
EmployeeAPI-->>User: Email with OTP code
Jelou->>User: "Te enviamos un código a tu email"
User->>Jelou: "123456"
Jelou->>AuthAPI: POST /api/employee/validate-otp<br/>{email, otp}
AuthAPI-->>Jelou: ✓ Validation success
Note over Jelou: Transition to Skill 26085 (Company Order)
else Company Found
CompaniesAPI-->>Jelou: Company data
Note over Jelou: Transition to Skill 26086 (Employee Validation)
end
7.9 End-to-End Flow: Individual to Order
graph TD
Start[User: "Hola"] --> Menu[Skill 26090: Main Menu]
Menu --> MenuMsg["Show: Solicitar/Consultar"]
MenuMsg --> Decision1{User Selection}
Decision1 -->|Solicitar| Phone[Request Phone]
Phone --> OTP1[Send OTP]
OTP1 --> ValidateOTP1[Validate OTP]
ValidateOTP1 --> CheckUser[Check User Exists]
CheckUser -->|Not Found| Register[Skill 26088: Registration]
CheckUser -->|Found| Register
Register --> CollectName[Collect Name/Email/ID]
CollectName --> CreateUser[POST /api/users]
CreateUser --> Problem[Request Problem Description]
Problem --> AIClassify[AI: Classify Service GPT-4o]
AIClassify --> ConfirmService[Confirm Service Type]
ConfirmService --> Images[Request Images 1-3]
Images --> Address[Request Address & City]
Address --> Schedule[Request Date & Time]
Schedule --> CreateOrder[POST /api/orders]
CreateOrder --> PDF[Skill 26084: Generate PDF]
PDF --> SendPDF[Send PDF to User]
SendPDF --> Confirmation[Show Confirmation Message]
Confirmation --> End[Return to Main Menu]
Decision1 -->|Consultar| Inquiry[Skill 26087: Order Inquiry]
Inquiry --> InquiryFlow[Order Tracking Flow]
InquiryFlow --> End
8. User Flows Documentoation
Detailed end-to-end user journeys with step-by-step interactions.
8.1 Individual User Registration and Order Creation
Scenario: New user requests service for the first time via WhatsApp.
Flow Steps:
-
Conversation Start (Skill 26090: Main Menu)
- User sends “Hola” or any message to bot
- Bot responds: “¡Hola! 👋 Bienvenido a Algesta. ¿En qué podemos ayudarte?”
- Bot displays buttons: [Solicitar servicio] [Consultar orden]
-
Service Request Selection
- User taps “Solicitar servicio”
- Bot: “Por favor, ingresa tu número de teléfono (10 dígitos):”
-
Phone Validation with OTP
- User provides phone: “3001234567”
- Bot calls:
POST /api/auth/otp/send/3001234567 - User receives SMS with 6-digit OTP
- Bot: “Te enviamos un código por SMS. Ingrésalo aquí:”
- User provides OTP: “123456”
- Bot validates:
POST /api/auth/otp/validate/3001234567/123456 - If invalid: “Código incorrecto, intenta nuevamente” (max 3 attempts)
- If valid: Proceed to next step
-
User Lookup (Transition to Skill 26088: Registration)
- Bot calls:
GET /api/users/find-by-phone/3001234567 - If user NOT found:
- Bot: “No encontramos tu registro. Vamos a crearte una cuenta.”
- Bot: “Ingresa tu nombre completo:”
- User: “Juan Pérez”
- Bot: “Ingresa tu email:”
- User: “juan@example.com”
- Bot: “Ingresa tu número de cédula:”
- User: “1234567890”
- Bot calls:
POST /api/userswith {name, email, phone, role: “customer”}
- If user found: Skip registration
- Bot calls:
-
Problem Descripción
- Bot: “Describe el problema que tienes:”
- User: “El aire acondicionado no enfría bien y hace un ruido extraño”
- Bot stores in
problemavariable
-
AI Service Classification
- Bot calls AI Task (GPT-4o) with problem Descripción
- AI analyzes and returns:
{"option": "❄️ Aires-Refrigeración"} - Bot: “Identificamos que necesitas ❄️ Aires-Refrigeración, ¿es correcto?”
- User: “Sí, correcto”
- If user says no: Bot displays list of 13 service types for manual selection
-
Image Upload (Up to 3 Images)
- Bot: “Envía una foto del problema (puedes enviar hasta 3 fotos):”
- User uploads image 1 → stored in
imagen1 - Bot: “Foto 1 recibida. ¿Quieres enviar otra? (Sí/No)”
- User: “Sí”
- User uploads image 2 → stored in
imagen2 - Bot: “Foto 2 recibida. ¿Quieres enviar otra? (Sí/No)”
- User: “No”
- Bot proceeds (images 1 and 2 uploaded, image 3 empty)
-
Address and City Collection
- Bot: “Ingresa la dirección donde necesitas el servicio:”
- User: “Calle 80 #25-30”
- Bot: “Selecciona la ciudad:”
- Bot displays list: [Bogotá] [Medellín] [Cali] [Barranquilla] [Otras]
- User selects: “Bogotá”
-
Scheduled Date and Time Selection
- Bot: “Selecciona la fecha para el servicio:”
- Bot displays date picker or list of next 7 days
- User selects: “2025-12-15”
- Bot: “Selecciona el horario:”
- Bot displays: [8:00 AM - 10:00 AM] [10:00 AM - 12:00 PM] [2:00 PM - 4:00 PM] [4:00 PM - 6:00 PM]
- User selects: “10:00 AM - 12:00 PM”
-
Order Creation
- Bot calls:
POST /api/orderswith:{"channel": "whatsapp","service": "❄️ Aires-Refrigeración","address": "Calle 80 #25-30","descriptionProblem": "El aire acondicionado no enfría bien y hace un ruido extraño","image1": "https://storage.jelou.ai/image1.jpg","image2": "https://storage.jelou.ai/image2.jpg","image3": "","phone": "3001234567","scheduledDate": "2025-12-15","scheduledTime": "10:00 AM - 12:00 PM","city": "Bogotá","contactName": "Juan Pérez","contactEmail": "juan@example.com"} - API responds:
{"orderId": "00123", "Estado": "created"} - Bot stores order ID in
created-order-id
- Bot calls:
-
PDF Generation (Transition to Skill 26084)
- Bot calls:
GET /api/Documentos/generate-pdf/00123 - API responds:
{"url": "https://docs.algesta.com/order-00123.pdf"} - Bot sends PDF file to user via WhatsApp
- User receives downloadable PDF Documento
- Bot calls:
-
Confirmation Message
- Bot:
✅ ¡Tu orden #00123 ha sido registrada exitosamente!📋 Resumen:Servicio: ❄️ Aires-RefrigeraciónFecha: 15 de diciembre de 2025Horario: 10:00 AM - 12:00 PMDirección: Calle 80 #25-30, BogotáUn técnico se pondrá en contacto contigo pronto.Puedes consultar el estado de tu orden en cualquier momento.
- Bot returns to main menu (Skill 26090)
- Bot:
Decision Points:
- User exists? → Skip registration vs. Collect user data
- AI classification correct? → Proceed vs. Manual selection
- More images? → Continue upload vs. Proceed to next step
- OTP valid? → Continue vs. Retry (max 3 attempts)
Variables Created:
numero,new-name,new-email,new-id,otp,problema,servicio-select,imagen1,imagen2,address,city,scheduled-date,scheduled-time,created-order-id
API Calls:
POST /api/auth/otp/send/{phone}POST /api/auth/otp/validate/{phone}/{otp}GET /api/users/find-by-phone/{phone}POST /api/users(if new user)POST /api/ordersGET /api/Documentos/generate-pdf/{orderId}
Skills Used: 26090 → 26088 → 26084
8.2 Company Employee Order Creation
Scenario: Company employee requests maintenance service for equipment.
Flow Steps:
-
Conversation Start (Skill 26090: Main Menu)
- User sends message to bot
- Bot displays main menu buttons
- User selects “Solicitar servicio”
-
Company Flow Entry (Skill 26089: Company Registration)
- Bot: “¿Eres usuario individual o empresa?”
- User: “Empresa”
- Bot: “Ingresa el NIT de tu empresa:”
- User: “900123456-7”
-
Company Lookup
- Bot calls:
GET /api/companies/find-by-nit?nit=900123456-7 - If company FOUND: Proceed to step 4
- If company NOT found:
- Bot collects company data (name, address, city, branch)
- Bot calls:
POST /api/companies/register - Bot collects employee data (name, email, phone, charge)
- Bot calls:
POST /api/employee/register - Bot sends email OTP → User validates
- Bot calls:
-
Employee Validation (Skill 26086: Company Validation)
- Bot: “Ingresa tu teléfono corporativo:”
- User: “3001234567”
- Bot calls:
POST /api/auth/otp/send/3001234567 - User receives SMS OTP
- User provides OTP code
- Bot validates OTP
- Bot: “Ingresa tu email corporativo:”
- User: “maria@acme.com”
- Bot: “Ingresa tu nombre:”
- User: “María García”
- Bot: “Ingresa tu cargo:”
- User: “Supervisor de Mantenimiento”
-
Branch and Address Selection (Transition to Skill 26085: Company Order)
- Bot: “Selecciona la sede donde necesitas el servicio:”
- Bot displays company locations from Base de datos
- User selects: “Sede Norte - Calle 100 #15-20”
- Bot: “Selecciona la ciudad:”
- User: “Bogotá”
-
Asset Photo Upload
- Bot: “Envía una foto del equipo con la placa visible:”
- User uploads photo of equipment showing serial number plate
- Bot calls AI Agent (GPT-4.1 Vision) to extract asset info
- AI processes image and returns:
[{"label": "Serial", "value": "SN-12345678"},{"label": "S/N", "value": "S/N-ABC123"},{"label": "Model No", "value": "AC-3000-PRO"},{"label": "mediaUrl", "value": "https://storage.jelou.ai/..."}]
- Code node extracts and stores:
serial-asset,sn-asset,model-asset - Bot: ”✓ Información del equipo capturada”
- If AI fails to read: Uses fallback
JELOU-{timestamp}identifier
-
Problem Descripción
- Bot: “Describe el problema con el equipo:”
- User: “El compresor del aire acondicionado no arranca y la unidad no enfría”
- Bot stores in
company-problemvariable
-
AI Service Classification
- Bot calls AI Task (GPT-4o) with problem Descripción
- AI returns:
{"option": "❄️ Aires-Refrigeración"} - Bot: “Identificamos que necesitas ❄️ Aires-Refrigeración, ¿es correcto?”
- User: “Sí”
-
Additional Images
- Bot: “Envía fotos adicionales del problema (opcional):”
- User uploads image of compressor → stored in
company-image1 - Bot: “¿Quieres enviar otra foto?”
- User uploads image of control panel → stored in
company-image2 - Bot: “¿Quieres enviar otra foto?”
- User: “No, es todo”
-
Scheduled Date and Time
- Bot: “Selecciona la fecha para el servicio:”
- User selects: “2025-12-15”
- Bot: “Selecciona el horario:”
- User selects: “10:00 AM - 12:00 PM”
-
Purchasing Contact Selection
- Bot calls:
GET /api/employee/area/purchasing?nit=900123456-7 - Bot receives list of purchasing department employees
- Bot formats enumerated list:
Selecciona el contacto de compras para aprobación:1. Juan Pérez - juan.perez@acme.com2. Carlos López - carlos.lopez@acme.com3. Ana Martínez - ana.martinez@acme.com
- User: “1”
- Bot calls AI Agent (GPT-4.1) to parse selection
- AI returns:
{"name": "Juan Pérez", "email": "juan.perez@acme.com"} - Bot stores in
company-option-purchasing
- Bot calls:
-
Order Creation
- Bot calls:
POST /api/orderswith:{"channel": "whatsapp","service": "❄️ Aires-Refrigeración","address": "Calle 100 #15-20","descriptionProblem": "El compresor del aire acondicionado no arranca y la unidad no enfría","image1": "https://storage.jelou.ai/asset-photo.jpg","image2": "https://storage.jelou.ai/compressor.jpg","image3": "https://storage.jelou.ai/control-panel.jpg","phone": "3001234567","scheduledDate": "2025-12-15","scheduledTime": "10:00 AM - 12:00 PM","city": "Bogotá","contactName": "María García","contactEmail": "maria@acme.com","nit": "900123456-7","branchName": "Sede Norte","serialAsset": "SN-12345678","snAsset": "S/N-ABC123","modelAsset": "AC-3000-PRO","purchasingContactName": "Juan Pérez","purchasingContactEmail": "juan.perez@acme.com"} - API responds:
{"orderId": "00123", "Estado": "created"}
- Bot calls:
-
PDF Generation (Transition to Skill 26084)
- Bot calls:
GET /api/Documentos/generate-pdf/00123 - Bot sends PDF to user
- Bot sends PDF to purchasing contact email
- Bot calls:
-
Confirmation
- Bot:
✅ ¡Orden #00123 registrada exitosamente!📋 Resumen:Empresa: Acme Corporation S.A.S (NIT: 900123456-7)Sede: Sede NorteServicio: ❄️ Aires-RefrigeraciónEquipo: AC-3000-PRO (S/N: SN-12345678)Fecha: 15 de diciembre de 2025Horario: 10:00 AM - 12:00 PMLa orden será revisada por Juan Pérez (Compras) para aprobación.Te notificaremos cuando esté aprobada.
- Bot:
Key Differences from Individual Flow:
- NIT-based company validation
- Employee registration and validation
- Asset photo with AI extraction
- Branch/location selection from company locations
- Purchasing contact selection for approval
- Additional order fields (nit, branch, asset info, purchasing contact)
Skills Used: 26090 → 26089 → 26086 → 26085 → 26084
8.3 Order Tracking
Scenario: User wants to check the Estado of their order.
Flow Steps:
-
Conversation Start (Skill 26090: Main Menu)
- User sends message to bot
- Bot displays main menu
- User selects “Consultar orden”
-
Order ID Request (Transition to Skill 26087: Order Inquiry)
- Bot: “¿Tienes el número de orden? (Ejemplo: 00123)”
- User has two options:
- Option A: Provide order ID
- Option B: “No tengo el número” / “Lo perdí”
Path A: User Has Order ID
-
Direct Order Lookup
- User: “00123”
- Bot calls:
GET /api/orders/00123 - If order found:
- Bot displays order Estado:
📋 Orden #00123Estado: 🟡 En progresoServicio: ❄️ Aires-RefrigeraciónFecha programada: 15 de diciembre de 2025Horario: 10:00 AM - 12:00 PMDirección: Calle 80 #25-30, BogotáTécnico asignado: Carlos LópezTeléfono técnico: 3009876543Descripción: El aire acondicionado no enfría bien y hace un ruido extrañoFecha de creación: 20 de noviembre de 2025
- Bot displays order Estado:
- If order NOT found:
- Bot: “No encontramos la orden #00123. Verifica el número o búscala por teléfono.”
-
Additional Options
- Bot displays buttons:
- [Ver mis otras órdenes]
- [Preguntas frecuentes]
- [Volver al menú]
- Bot displays buttons:
Path B: User Lost Order ID
-
Phone Validation
- User: “No tengo el número”
- Bot: “Ingresa tu número de teléfono:”
- User: “3001234567”
-
OTP Validation
- Bot calls:
POST /api/auth/otp/send/3001234567 - User receives SMS OTP
- Bot: “Ingresa el código OTP:”
- User: “123456”
- Bot calls:
POST /api/auth/otp/validate/3001234567/123456 - If invalid: Retry (max 3 attempts)
- Bot calls:
-
Retrieve Order List
- Bot calls:
GET /api/orders/by-phone/3001234567 - If orders found:
- Code node formats enumerated list
- Bot displays:
Encontramos 3 órdenes:1. Orden #00123Servicio: ❄️ Aires-RefrigeraciónEstado: 🟡 En progresoFecha: 15/12/20252. Orden #00124Servicio: ⚡ ElectricidadEstado: 🟢 CompletadaFecha: 10/12/20253. Orden #00125Servicio: 🚰 PlomeríaEstado: 🔴 PendienteFecha: 20/12/2025Responde con el número de la orden que deseas consultar (ejemplo: 1)
- If no orders found:
- Bot: “No encontramos órdenes asociadas a tu número. ¿Quieres crear una nueva orden?”
- Bot calls:
-
User Selects Order
- User: “2” (selects second order)
- Bot calls AI Task (GPT-4o-mini) to parse selection
- AI extracts order ID from list: “00124”
- Bot stores in
ia-order-selected
-
Display Order Details
- Bot calls:
GET /api/orders/00124 - Bot displays detailed order Estado (same format as Path A)
- Bot calls:
-
FAQ Option
- Bot: “¿Necesitas ayuda con algo más?”
- Bot displays: [Preguntas frecuentes] [Volver al menú]
- If user selects FAQ:
Preguntas Frecuentes:❓ ¿Cuánto demora la asignación del técnico?Normalmente entre 2-4 horas hábiles.❓ ¿Puedo reprogramar la fecha?Sí, contacta a nuestro soporte al 300-1234567.❓ ¿Qué pasa si el técnico no llega?Contacta inmediatamente al técnico asignado o a soporte.❓ ¿Cómo puedo cancelar la orden?Contacta a soporte al 300-1234567.
Order Estado Types:
- 🔴 Pendiente: Order created, awaiting assignment
- 🟡 En progreso: Technician assigned, service En Progreso
- 🟢 Completada: Service Completod successfully
- ⚫ Cancelada: Order canceled
- 🟠 Aprobación pendiente: (Company orders) Awaiting purchasing approval
Skills Used: 26090 → 26087
8.4 Company Registration
Scenario: New company employee wants to register their company and create an order.
Flow Steps:
-
Conversation Start (Skill 26090: Main Menu)
- User sends message to bot
- Bot displays main menu
- User indicates company flow (could be through “Soy de una empresa” button)
-
Company NIT Entry (Skill 26089: Company Registration)
- Bot: “Ingresa el NIT de tu empresa (ejemplo: 900123456-7):”
- User: “900555666-3”
-
Company Lookup
- Bot calls:
GET /api/companies/find-by-nit?nit=900555666-3 - If company FOUND: Transition to Skill 26086 (employee validation)
- If company NOT found: Continue with registration
- Bot calls:
-
Company Information Collection
- Bot: “No encontramos tu empresa. Vamos a registrarla.”
- Bot: “Nombre legal de la empresa:”
- User: “TechCorp Solutions S.A.S”
- Bot: “Dirección principal de la empresa:”
- User: “Carrera 50 #30-20”
- Bot: “Ciudad:”
- Bot displays list of cities
- User: “Medellín”
- Bot: “Nombre de la sede o sucursal:”
- User: “Sede Principal”
-
Company Registration
- Bot calls:
POST /api/companies/registerwith:{"name": "TechCorp Solutions S.A.S","address": "Carrera 50 #30-20","branchName": "Sede Principal","nit": "900555666-3"} - API responds: Company created successfully
- Bot: ”✓ Empresa registrada exitosamente”
- Bot calls:
-
Employee Information Collection
- Bot: “Ahora necesitamos registrar tu usuario como empleado.”
- Bot: “Tu nombre completo:”
- User: “Andrea Gómez”
- Bot: “Tu email corporativo:”
- User: “andrea.gomez@techcorp.com”
- Bot: “Tu teléfono:”
- User: “3105556677”
- Bot: “Tu cargo en la empresa:”
- User: “Gerente de Operaciones”
-
Employee Registration
- Bot calls:
POST /api/employee/registerwith:{"nit": "900555666-3","charge": "Gerente de Operaciones","name": "Andrea Gómez","email": "andrea.gomez@techcorp.com","phone": "3105556677","area": "purchasing"} - API responds: Employee created
- Backend sends email to andrea.gomez@techcorp.com with OTP code
- Bot calls:
-
Email OTP Validation
- Bot: “Te enviamos un código de verificación a andrea.gomez@techcorp.com”
- User checks email and receives OTP: “987654”
- Bot: “Ingresa el código de verificación:”
- User: “987654”
- Bot calls:
POST /api/employee/validate-otpwith:{"email": "andrea.gomez@techcorp.com","otp": "987654"} - If valid: Proceed to order creation
- If invalid: Retry (max 3 attempts), option to resend code
-
Transition to Company Order Creation
- Bot: ”✓ ¡Registro completado exitosamente!”
- Bot: “Ahora puedes crear tu primera orden de servicio.”
- Transition to Skill 26085 (Company Order Registration)
- Continue with asset photo upload and order creation flow (see Sección 8.2)
Variables Created:
company-nit,company-name,company-address,company-branch-name,city,employee-name,employee-email,employee-phone,employee-charge,company-otp
API Calls:
GET /api/companies/find-by-nit?nit={nit}POST /api/companies/registerPOST /api/employee/registerPOST /api/employee/validate-otp
Skills Used: 26090 → 26089 → 26085
Error Scenarios:
- Company already exists: Redirect to Skill 26086 (employee validation)
- Invalid NIT format: Regex validation, retry input
- Invalid email format: Regex validation, retry input
- OTP expired: Resend OTP option
- API failure: “No pudimos registrar la empresa, intenta más tarde”
9. Configuration and Despliegue
Operational aspects of the Jelou WhatsApp bot integration.
9.1 Environment Configuration
Environment Variables
| Variable | Purpose | Example Valor | Required |
|---|---|---|---|
dev | Base API URL for backend services | https://api-dev.algesta.com | Yes |
local | Local environment flag | false | No |
Variable Management:
- Set in Jelou platform: Bot Settings > Variables > Environment Variables
- No TTL (permanent configuration)
- Accessible via
{{dev}}in HTTP nodes - Environment-specific Valors:
- Development:
https://api-dev.algesta.com - Staging:
https://api-staging.algesta.com - Production:
https://api.algesta.com
- Development:
Bot Configuration
Core Settings (from bot.json):
{ "id": "b65f501f-dbba-4e5c-a0ab-c51063cfe694", "name": "Algesta QA", "type": "WHATSAPP", "brainId": "01k2fxkq5arck1stpnvs26g4jq", "companyId": 2419, "appId": "wiKVQI_EZDE4vsycbft9qvvO6j", "defaultSkillId": 14469}- Bot ID: Unique identifier for this bot instance
- Bot Name: Display name (not visible to users, for admin reference)
- Type: WHATSAPP (WhatsApp Business API integration)
- Brain ID: Jelou AI brain configuration for intent detection
- Company ID: Jelou platform company account identifier
- App ID: Jelou application identifier
- Default Skill: 14469 (inicio - persona natural registrado) - entry point for all conversations
WhatsApp Business API Configuration
Requisitos:
- WhatsApp Business API account
- Verified business profile
- Phone number connected to WhatsApp Business API
- Webhook URL configured to Jelou platform
Jelou Integration Settings:
- Webhook URL:
https://jelou.ai/webhooks/whatsapp/{companyId}/{botId} - Webhook verification token: Managed by Jelou
- Message types supported: text, image, Documento, audio, video
9.2 Jelou Platform Settings
Bot Settings
Default Skill Configuration:
- Default Skill ID: 14469 (inicio - persona natural registrado)
- Trigger Type: BRAIN (AI-powered intent detection)
- Propósito: Entry point for all new conversations
- Fallback: If Brain cannot detect intent, route to default skill
Memory Configuration:
- Memory Version: v2 (required for code node variable access)
- Default TTL: 3600 seconds (1 hour)
- Max Variable Size: 10 KB per variable
- Total Memory Limit: 100 KB per session
Session Management:
- Session Timeout: 24 hours of inactivity
- Session Reset: User can restart by typing “menú” or “inicio”
- Context Preservation: Variables persist across skill transitions
HTTP Node Configuration
Default HTTP Settings (applied to all HTTP nodes):
{ "timeout": 30000, "retries": 0, "followRedirects": true, "validateSSL": true, "headers": { "Content-Type": "application/json" }}- Timeout: 30 seconds (30000ms)
- Retries: Disabled (0) to prevent duplicate Operaciones (order creation, user registration)
- Follow Redirects: Enabled for API gateway routing
- SSL Validation: Enabled for security
- No Authentication Headers: Assumes internal network or API gateway handles auth
AI Model Configuration
AI Task Settings:
{ "primaryModel": "gpt-4o", "fallbackModel": "azure-gpt-4o", "temperature": 0.3, "maxTokens": 1000, "timeout": 15000}- Primary Model: GPT-4o (OpenAI)
- Fallback Model: Azure GPT-4o (if primary fails)
- Temperature: 0.3 (low for consistent classification)
- Max Tokens: 1000 tokens per AI call
- Timeout: 15 seconds
AI Agent Settings:
{ "model": "gpt-4.1", "tools": ["vision"], "temperature": 0.5, "maxTokens": 2000, "timeout": 20000}- Model: GPT-4.1 with Vision capabilities
- Tools: Vision enabled for image processing
- Temperature: 0.5 (slightly higher for creative extraction)
- Max Tokens: 2000 tokens (image analysis requires more tokens)
- Timeout: 20 seconds
9.3 Workflow Export Format
Workflows are exported as JSON files from Jelou platform for version control and Documentoation.
File Structure:
algesta-agent/jelou/├── bot.json # Bot configuration├── skills.json # Skills catalog├── variables.json # Variables definitions├── skill_26084_workflow.json # PDF generation workflow├── skill_26085_workflow.json # Company order registration├── skill_26086_workflow.json # Registered company validation├── skill_26087_workflow.json # Order inquiry├── skill_26088_workflow.json # Individual registration├── skill_26089_workflow.json # Company registration└── skill_26090_workflow.json # Main menu (default)Workflow JSON Structure:
{ "id": 26090, "skillId": 14469, "name": "inicio (persona natural registrado)", "nodes": [ { "id": "node_001", "workflowId": 26090, "nodeTypeId": "START", "title": "Inicio", "configuration": {}, "position": {"posX": 100, "posY": 100}, "state": "active" }, { "id": "node_002", "workflowId": 26090, "nodeTypeId": "CHANNEL_MESSAGE", "title": "Menú principal", "configuration": { "message": "¡Hola! 👋 Bienvenido a Algesta", "buttons": [ {"label": "Solicitar servicio", "value": "solicitar"}, {"label": "Consultar orden", "value": "consultar"} ] }, "position": {"posX": 300, "posY": 100}, "state": "active" } ], "edges": [ { "id": "edge_001", "type": "default", "sourceId": "node_001", "targetId": "node_002", "configuration": {}, "state": "active" } ]}Node Configuration Fields:
id: Unique node identifierworkflowId: Parent workflow IDnodeTypeId: Node type (START, INPUT, HTTP, CODE, etc.)title: Node name for visual workflow editorconfiguration: Node-specific settings (prompts, URLs, code, etc.)position: X/Y coordinates for visual editorstate: Activo/inActivo (disabled nodes not executed)
Edge Configuration Fields:
id: Unique edge identifiertype: Edge type (default, success, failed, conditional)sourceId: Source node IDtargetId: Target node IDconfiguration: Conditional logic for conditional edgesstate: Activo/inActivo
9.4 Maintenance Considerations
Workflow Changes
Making Changes:
- Log in to Jelou platform: https://app.jelou.ai
- Navigate to: Bots > Algesta QA > Skills
- Select skill to edit
- Use visual workflow editor to:
- Add/remove nodes
- Modify node configurations
- Add/remove edges
- Test workflow with simulator
- Save changes
- Export updated workflow JSON for version control
Important Notes:
- Workflow changes are NOT made by editing JSON files
- JSON files are exports for Documentoation/backup Propósitos
- Always test changes in staging environment before production
- Use workflow versioning in Jelou (snapshot feature)
Variable TTL Management
Default TTL: 3600 seconds (1 hour)
Adjusting TTL:
- Short sessions (15 min):
900seconds - for quick inquiries - Standard sessions (1 hour):
3600seconds - default for order creation - Extended sessions (4 hours):
14400seconds - for complex company registrations
TTL Best Practices:
- Keep sensitive data (OTP, email) with short TTL (15 min)
- Order data can have longer TTL (1 hour) for user convenience
- Environment variables (dev, local) have no TTL (permanent)
AI Model Fallback Configuration
Primary Model Failure Scenarios:
- OpenAI API timeout
- Rate limit exceeded
- Model unavailable
Fallback Strategy:
- Retry primary model once (automatic)
- Switch to Azure GPT-4o fallback
- If both fail, route to manual input node
Configuration:
{ "aiTask": { "primary": { "provider": "openai", "model": "gpt-4o", "maxRetries": 1 }, "fallback": { "provider": "azure", "model": "gpt-4o", "maxRetries": 0 } }}API Endpoint Updates
Updating Backend URLs:
- Update
devenvironment variable in Jelou - No workflow changes required (all HTTP nodes use
{{dev}}interpolation) - Test all API integrations after URL change
Adding New API Endpoints:
- Create new HTTP node in workflow
- Configure Método, URL, body
- Add success/failed edges
- Add Code node to process response
- Test with Jelou simulator
API Versioning:
- Current:
/api/v1/orders(implicit v1) - Future:
/api/v2/orders(explicit versioning) - Update all HTTP nodes if API version changes
Monitoring and Debugging
Jelou Platform Monitoring:
- Bot Analytics: Dashboard > Analytics > Algesta QA
- Total conversations
- Activo sessions
- Skill usage distribution
- AI classification accuracy
- API call success rates
Logs and Debugging:
- Conversation Logs: Bots > Algesta QA > Conversations
- View full conversation history
- See node execution flow
- Inspect variable Valors at each step
- Review API request/response
- Code Node Logs:
console.log()statements visible in conversation logs - Error Tracking: Failed API calls logged with error messages
Key Métricas to Monitor:
- Order Creation Success Rate: Target > 95%
- OTP Validation Success Rate: Target > 90%
- AI Classification Accuracy: Target > 85%
- Average Conversation Length: Baseline 10-15 messages
- Session Drop-off Rate: Target < 20%
Despliegue Process
Development → Staging → Production:
-
Development Environment:
- Bot:
Algesta Dev - Environment Variable:
dev = https://api-dev.algesta.com - Test all changes with sample data
- Bot:
-
Staging Environment:
- Bot:
Algesta Staging - Environment Variable:
dev = https://api-staging.algesta.com - Run QA test cases
- Validate with real WhatsApp numbers (test accounts)
- Bot:
-
Production Environment:
- Bot:
Algesta QA(production bot) - Environment Variable:
dev = https://api.algesta.com - Deploy during low-traffic hours
- Monitor first 100 conversations closely
- Bot:
Rollback Procedure:
- Jelou platform: Skills > {Skill Name} > Versions
- Select previous stable version
- Click “Restore Version”
- Verify in simulator
- Notify users if needed
Security Considerations
Data Protection:
- OTP codes stored with 15-minute TTL
- Phone numbers hashed in long-term storage (handled by backend)
- Email addresses not logged in plain text
- Image URLs use signed URLs with expiration (Jelou storage)
Access Control:
- Jelou platform access restricted to authorized personnel
- Role-based permissions: Admin, Developer, Viewer
- API keys for backend integration secured in Jelou environment variables
- No authentication credentials in workflow JSON files
Compliance:
- GDPR: User data retention policy (1 year)
- Right to deletion: Handled by backend
/api/users/deleteEndpoint - Data portability: Export conversation history available
- WhatsApp Business Policy: Compliant with WhatsApp terms
10. Referencias Cruzadas
Related Documentoation and system integration points.
10.1 Backend Microservicios
Primary Documentoation:
backend-microservices-overview.md- Descripción General of all backend servicesorders-Microservicio.md- Orders service (order creation, retrieval, Estado management)notifications-Microservicio.md- Notifications service (SMS OTP, email OTP, push notifications)auth-Microservicio.md- Authentication service (OTP validation, session management)users-Microservicio.md- Users service (individual user management)companies-Microservicio.md- Companies service (company and employee management)Documentos-Microservicio.md- Documentos service (PDF generation)
Integration Points:
- Orders Created via WhatsApp: Tagged with
channel: "whatsapp"for analytics - Order Estado Updates: When order Estado changes in dashboard, notifications sent via WhatsApp (not yet implemented in bot workflows)
- User Authentication: OTP validation shared between web dashboard and WhatsApp bot
- Documento Generation: PDFs generated by docs service, delivered via WhatsApp
10.2 API Gateway
Documentoation: api-gateway.md
Gateway Routing:
- Base URL:
https://api.algesta.com - Gateway routes requests to appropriate Microservicio:
/api/orders/*→ Orders Microservicio/api/auth/*→ Auth/Notifications Microservicio/api/users/*→ Users Microservicio/api/companies/*→ Companies Microservicio/api/employee/*→ Employee Management Microservicio/api/Documentos/*→ Documentos Microservicio/api/messages/*→ Messages Microservicio
Rate Limiting:
- Bot requests exempt from rate limiting (internal traffic)
- API Gateway recognizes Jelou platform IPs as trusted
Authentication:
- Bot requests bypass authentication (internal network)
- Future: JWT token in
Authorizationheader for external bot Despliegues
10.3 Frontend Dashboard
Documentoation: frontend-dashboard-overview.md
Dashboard Integration:
- Orders View: Orders created via WhatsApp appear in dashboard with
channelbadge - Order Assignment: Admins assign technicians to WhatsApp orders
- Estado Updates: Estado changes in dashboard trigger notifications to users (future feature)
- User Management: Admins can view users registered via WhatsApp
- Company Management: Admins can manage companies registered via WhatsApp
User Flow:
- User creates order via WhatsApp → Order appears in dashboard
- Admin assigns technician → Technician receives notification
- Technician updates Estado → User receives WhatsApp notification (future)
- Order Completod → User receives confirmation via WhatsApp (future)
10.4 Notification System
Documentoation: notifications-Microservicio.md
Notification Channels:
- SMS OTP: Sent via Twilio/AWS SNS for phone validation
- Email OTP: Sent via SendGrid/AWS SES for employee validation
- WhatsApp Messages: Sent via Jelou platform (current bot messages)
- Push Notifications: (Future) Mobile app notifications
Integration with Bot:
- OTP Send:
POST /api/auth/otp/send/{phone}triggers SMS - Email OTP:
POST /api/employee/registertriggers email - Future: Order Estado changes trigger WhatsApp messages via Jelou API
WhatsApp Template Messages (Future Enhancement):
- Order confirmation template
- Order Estado update template
- Technician assigned template
- Appointment reminder template (24 hours before)
- Service completion template
10.5 Inter-Service Communication
Documentoation: inter-service-communication.md
Event-Driven Arquitectura:
- Order Created Event: Published by Orders service when order created
- Subscribers: Notifications service (future: send confirmation WhatsApp message)
- Order Estado Changed Event: Published when Estado updated
- Subscribers: Notifications service → WhatsApp bot (future)
- Employee Registered Event: Published by Employee service
- Subscribers: Notifications service (send welcome email)
Current Bot Integration:
- Synchronous: Bot makes REST API calls to backend services
- Future: Asynchronous event-driven updates via webhooks
Webhook Configuration (Future):
{ "webhooks": [ { "event": "order.status_changed", "url": "https://jelou.ai/webhooks/algesta/order-status", "method": "POST", "headers": { "Authorization": "Bearer {jelouApiKey}" } } ]}10.6 Provider Assignment
Documentoation: provider-management.md
Flow After Order Creation:
- User creates order via WhatsApp → Order created with
Estado: "Pendiente" - Admin reviews order in dashboard → Assigns technician (provider)
- Order Estado changes to
"assigned" - Technician receives notification with order details
- (Future) User receives WhatsApp message: “Tu orden #00123 ha sido asignada al técnico Carlos López”
Provider Data in Bot:
- Display in Order Inquiry: If order has assigned technician, show:
- Technician name
- Technician phone
- Estimated arrival time
Integration Points:
GET /api/orders/{orderId}returns provider data if assigned- Bot displays provider info in order Estado message
10.7 Documento Generation and Storage
Documentoation: Documentos-Microservicio.md
PDF Generation Flow:
- Order created via WhatsApp → Bot transitions to Skill 26084
- Bot calls:
GET /api/Documentos/generate-pdf/{orderId} - Documentos service:
- Retrieves order details from Orders service
- Generates PDF using template (company logo, order details, terms)
- Stores PDF in cloud storage (AWS S3 / GCP Storage)
- Returns signed URL with 24-hour expiration
- Bot sends PDF file to user via WhatsApp
- User receives downloadable PDF Documento
PDF Content:
- Company header (Algesta logo)
- Order number and creation date
- Service type and Descripción
- Customer/company information
- Scheduled date and time
- Address and location
- Images (embedded or as links)
- Terms and conditions
- Contact information
Storage Locations:
- Cloud Storage: AWS S3 bucket
algesta-Documentos-prod - File Path:
/orders/{year}/{month}/{orderId}.pdf - Access: Signed URLs with 24-hour expiration
- Backup: Daily backups to secondary storage
10.8 Analytics and Reporting
Documentoation: analytics-Descripción General.md (if exists)
Bot Analytics:
-
Order Creation Funnel:
- Users start conversation: 1000
- Users Completo phone validation: 850 (85%)
- Users Completo problem Descripción: 800 (80%)
- Users Complete order creation: 720 (72%)
- Orders created successfully: 700 (70%)
-
Service Type Distribution:
- Aires-Refrigeración: 30%
- Electricidad: 25%
- Plomería: 20%
- Other: 25%
-
User Type Distribution:
- Individual users: 65%
- Company employees: 35%
-
Response Times:
- Average time to create order: 5-7 minutes
- Average messages per conversation: 12-15
- Peak hours: 9 AM - 12 PM, 2 PM - 5 PM
Integration with Analytics Platform:
- Order data synced to analytics Base de datos
- Bot conversation data exported from Jelou
- Dashboards in BI tool (Tableau/Power BI/Looker)
10.9 Related Technical Documentoation
Jelou Platform Documentoation:
- Jelou Official Docs - Platform Documentoation
- WhatsApp Business API Docs - WhatsApp integration
- GPT-4 API Docs - AI model Documentoation
Algesta Technical Docs:
api-reference.md- Completo API Endpoint referenceBase de datos-schema.md- Base de datos structure for orders, users, companiesdeployment-guide.md- Infrastructure and Despliegue proceduresPruebas-strategy.md- QA test cases for bot workflowstroubleshooting.md- Common issues and solutions
10.10 Data Flow Diagram
Completo data flow from WhatsApp user to backend services:
graph TB
A[WhatsApp User] -->|Message| B[WhatsApp Business API]
B -->|Webhook| C[Jelou Platform]
C -->|AI Processing| D[GPT-4/Vision]
D -->|Classification| C
C -->|HTTP Request| E[API Gateway]
E -->|Route| F{Microservice}
F -->|/api/auth/*| G[Auth/Notifications MS]
F -->|/api/orders/*| H[Orders MS]
F -->|/api/users/*| I[Users MS]
F -->|/api/companies/*| J[Companies MS]
F -->|/api/documents/*| K[Documents MS]
F -->|/api/messages/*| L[Messages MS]
G -->|SMS OTP| A
H -->|Order Data| M[(PostgreSQL)]
K -->|PDF| N[Cloud Storage]
N -->|Signed URL| C
C -->|PDF File| B
B -->|Delivery| A
M -->|Sync| O[Analytics DB]
O -->|Reports| P[BI Dashboard]
Conclusión
The Jelou WhatsApp bot integration provides Algesta with a powerful, AI-driven customer service channel that handles:
- User Onboarding: Automated registration for individuals and companies
- Order Creation: Guíad conversational flow with AI-powered service classification
- Order Tracking: Real-time Estado inquiries with order history
- Documento Delivery: Automated PDF generation and WhatsApp delivery
- Multi-User Support: Distinct flows for individual users and company employees
- Asset Management: AI vision for equipment identification from photos
Capacidades Clave:
- 24/7 availability without human intervention
- Natural language processing for problem Descripción
- Image analysis for asset identification
- OTP-based security for user validation
- Comprehensive backend integration via REST APIs
Próximos Pasos:
- Implement order Estado update notifications via WhatsApp
- Add appointment reminders (24 hours before scheduled service)
- Enhance FAQ with dynamic responses based on order context
- Implement feedback collection after service completion
- Add multi-language support (English, Spanish)
- Integrate payment collection for invoices
For questions or support, refer to:
- Jelou Platform: support@jelou.ai
- Backend API: [Algesta API Documentoation]
- Technical Issues: [Algesta Engineering Team]
Version: 1.0 Last Updated: 2025-11-20 Maintained By: Algesta Engineering Team