Referencia de Scripts
Este documento proporciona una referencia completa para escribir scripts en reglas de flujo de trabajo. Los scripts le permiten implementar logica de automatizacion avanzada usando JavaScript.
Descripcion general
La accion Run Script en las reglas de flujo de trabajo ejecuta codigo JavaScript para automatizar escenarios complejos de manejo de tickets. Los scripts se ejecutan en un entorno aislado con acceso a datos de tickets, contexto de mensaje y funciones auxiliares.
Caracteristicas clave:
- Leer y modificar propiedades de tickets
- Acceder a informacion del cliente y propietario
- Trabajar con campos personalizados
- Usar logica condicional y bucles
- Tiempo de espera de ejecucion de 10 segundos para seguridad
Objeto Ticket
El objeto ticket es el contexto principal para sus scripts. Proporciona acceso de lectura y escritura a los datos del ticket.
Propiedades de solo lectura
// Informacion basica del ticket
ticket.id // String UUID
ticket.subject // Linea de asunto del ticket
// Estado actual (objeto)
ticket.status.id // UUID del estado
ticket.status.code // Codigo de estado (ej., "open", "closed")
ticket.status.name // Nombre para mostrar del estado
// Prioridad actual (objeto)
ticket.priority.id // UUID de prioridad
ticket.priority.name // Nombre para mostrar de prioridad
// Departamento actual (objeto)
ticket.department.id // UUID del departamento
ticket.department.name // Nombre para mostrar del departamento
// Propietario asignado (objeto, puede ser undefined)
ticket.owner.id // UUID del usuario
ticket.owner.email // Correo electronico del usuario
ticket.owner.firstname // Nombre del usuario
ticket.owner.lastname // Apellido del usuario
// Informacion del cliente (objeto)
ticket.customer.id // UUID del cliente
ticket.customer.email // Correo electronico del cliente
ticket.customer.firstname // Nombre del cliente
ticket.customer.lastname // Apellido del cliente
ticket.customer.name // Nombre completo del cliente
// Carpeta y etiquetas
ticket.folder // Carpeta actual: "INBOX", "ASSIGNED", "SPAM", "ARCHIVE"
ticket.tags // Arreglo de strings de etiquetas
Propiedades escribibles
Puede modificar estas propiedades mediante asignacion directa:
// Establecer estado por codigo o ID
ticket.status = "closed";
ticket.status = "550e8400-e29b-41d4-a716-446655440000";
// Establecer prioridad por nombre o ID
ticket.priority = "High";
ticket.priority = "550e8400-e29b-41d4-a716-446655440001";
// Establecer departamento por nombre o ID
ticket.department = "Sales";
ticket.department = "550e8400-e29b-41d4-a716-446655440002";
// Establecer propietario por correo electronico o ID
ticket.owner = "[email protected]";
ticket.owner = "550e8400-e29b-41d4-a716-446655440003";
// Establecer carpeta
ticket.folder = "ASSIGNED";
ticket.folder = "SPAM";
ticket.folder = "ARCHIVE";
ticket.folder = "INBOX";
// Establecer etiquetas (reemplaza todas las etiquetas existentes)
ticket.tags = ["urgent", "vip"];
Campos personalizados
Los campos personalizados se pueden leer y escribir usando su codigo (no el nombre para mostrar).
Lectura de campos personalizados
// Acceder al valor del campo personalizado directamente
var orderId = ticket.order_id; // Campo de texto
var amount = ticket.order_amount; // Campo numerico
var isVip = ticket.is_vip; // Campo booleano
var region = ticket.region; // Campo de seleccion
Escritura de campos personalizados
// Establecer campo personalizado de texto
ticket.order_id = "ORD-12345";
// Establecer campo personalizado numerico
ticket.order_amount = 199.99;
// Establecer campo personalizado booleano
ticket.is_vip = true;
// Establecer campo personalizado de seleccion
ticket.category = "billing";
// Establecer campo personalizado de fecha (formato ISO 8601)
ticket.due_date = "2024-12-31T23:59:59Z";
ticket.due_date = "2024-12-31";
Objeto Message
El objeto message esta disponible cuando la regla se activa por un evento de mensaje (New Customer Reply, New Staff Reply, etc.).
if (message) {
message.id // UUID del mensaje
message.body_text // Contenido del mensaje (texto plano)
message.body_html // Contenido del mensaje (HTML)
message.createdAt // Marca de tiempo ISO 8601
}
Ejemplo:
if (message && message.body_text) {
var bodyLower = message.body_text.toLowerCase();
if (bodyLower.includes("cancel subscription")) {
ticket.department = "Retention";
ticket.priority = "High";
}
}
Funciones auxiliares
getStatuses()
Devuelve un arreglo de todos los estados disponibles.
var statuses = getStatuses();
// Devuelve: [{ id: "...", code: "open", name: "Open" }, ...]
// Encontrar un estado especifico
for (var i = 0; i < statuses.length; i++) {
if (statuses[i].code === "pending") {
ticket.status = statuses[i].id;
break;
}
}
getPriorities()
Devuelve un arreglo de todas las prioridades disponibles.
var priorities = getPriorities();
// Devuelve: [{ id: "...", name: "Low" }, { id: "...", name: "High" }, ...]
getDepartments()
Devuelve un arreglo de todos los departamentos disponibles.
var departments = getDepartments();
// Devuelve: [{ id: "...", name: "Support" }, { id: "...", name: "Sales" }, ...]
getUsers()
Devuelve un arreglo de todos los usuarios disponibles (agentes).
var users = getUsers();
// Devuelve: [{ id: "...", email: "[email protected]", firstname: "John", lastname: "Doe" }, ...]
fetch()
Realiza solicitudes HTTP a APIs externas. Sincrono - devuelve el resultado directamente.
var response = fetch(url, options);
// response: { ok, status, statusText, text, json }
Opciones: method (GET/POST/PUT/DELETE), headers (objeto), body (string u objeto)
Ejemplo: Obtener de CRM y actualizar campos personalizados
var response = fetch("https://api.example.com/customers/" + ticket.customer.email, {
headers: { "Authorization": "Bearer YOUR_API_KEY" }
});
if (response.ok && response.json) {
ticket.customer_tier = response.json.tier;
ticket.lifetime_value = response.json.lifetime_value;
if (response.json.tier === "enterprise") {
ticket.priority = "High";
}
}
Ejemplo: POST a webhook
var response = fetch("https://hooks.example.com/helpdesk", {
method: "POST",
body: { ticket_id: ticket.id, customer_email: ticket.customer.email }
});
Notas: Solo HTTPS, tiempo de espera de 5s, limite de respuesta de 1MB, redes internas bloqueadas.
Patrones comunes
Asignacion condicional
// Establecer prioridad segun el asunto
if (ticket.subject.toLowerCase().includes("urgent")) {
ticket.priority = "High";
} else if (ticket.subject.toLowerCase().includes("question")) {
ticket.priority = "Low";
}
Enrutamiento de departamento
var subject = ticket.subject.toLowerCase();
if (subject.includes("billing") || subject.includes("payment") || subject.includes("invoice")) {
ticket.department = "Billing";
} else if (subject.includes("technical") || subject.includes("bug") || subject.includes("error")) {
ticket.department = "Technical Support";
} else if (subject.includes("sales") || subject.includes("pricing") || subject.includes("quote")) {
ticket.department = "Sales";
}
Logica basada en dominio del cliente
if (ticket.customer && ticket.customer.email) {
var email = ticket.customer.email;
var domain = email.split("@")[1];
// Manejo de clientes empresariales
if (domain === "bigcorp.com" || domain === "enterprise.org") {
ticket.priority = "High";
ticket.department = "Enterprise Support";
ticket.is_enterprise = true;
}
// Institucion educativa
if (domain.endsWith(".edu")) {
ticket.segment = "education";
}
}
Gestion de etiquetas
// Agregar etiquetas sin perder las existentes
var existingTags = ticket.tags || [];
existingTags.push("processed");
existingTags.push("automated");
ticket.tags = existingTags;
Trabajar con mensajes
if (message && message.body_text) {
var body = message.body_text.toLowerCase();
// Detectar palabras clave de frustracion
var frustrationKeywords = ["frustrated", "angry", "terrible", "worst", "unacceptable"];
for (var i = 0; i < frustrationKeywords.length; i++) {
if (body.includes(frustrationKeywords[i])) {
ticket.priority = "High";
ticket.needs_attention = true;
break;
}
}
}
Asignacion Round-Robin
var users = getUsers();
if (users.length > 0) {
// Simple round-robin basado en hash de ID de ticket
var ticketHash = 0;
for (var i = 0; i < ticket.id.length; i++) {
ticketHash += ticket.id.charCodeAt(i);
}
var assigneeIndex = ticketHash % users.length;
ticket.owner = users[assigneeIndex].email;
}
Manejo de errores
Los scripts se ejecutan en un entorno seguro:
- Errores de sintaxis se capturan y registran; el script se omite.
- Valores de campo invalidos (ej., nombre de estado inexistente) se ignoran.
- Tiempos de espera (10 segundos) previenen bucles infinitos.
- Los errores no se propagan a otras reglas o componentes del sistema.
Mejores practicas:
// Verificar null/undefined antes de acceder a propiedades
if (ticket.customer && ticket.customer.email) {
// Seguro acceder a ticket.customer.email
}
if (message) {
// Seguro acceder a propiedades de message
}
// Usar try-catch para logica compleja
try {
var data = JSON.parse(ticket.custom_json);
ticket.parsed_field = data.value;
} catch (e) {
// Manejar error elegantemente
}
Limitaciones
- Tiempo de espera de ejecucion: Los scripts se terminan despues de 10 segundos.
- Sin acceso al sistema de archivos: Las operaciones de archivo no estan disponibles.
- Sin estado persistente: Las variables no persisten entre ejecuciones de script.
- Campos de solo lectura:
ticket.id,ticket.subject,ticket.customerno se pueden modificar. - ES5 JavaScript: Las caracteristicas modernas de JavaScript (funciones de flecha, const/let, etc.) pueden no estar disponibles.