Pular para o conteúdo principal

Referencia de Scripts

Este documento fornece uma referencia abrangente para escrever scripts em regras de fluxo de trabalho. Scripts permitem que voce implemente logica de automacao avancada usando JavaScript.


Visao Geral​

A acao Run Script em regras de fluxo de trabalho executa codigo JavaScript para automatizar cenarios complexos de tratamento de tickets. Scripts sao executados em um ambiente isolado com acesso a dados de tickets, contexto de mensagens e funcoes auxiliares.

Recursos principais:

  • Ler e modificar propriedades de tickets
  • Acessar informacoes de cliente e proprietario
  • Trabalhar com campos personalizados
  • Usar logica condicional e loops
  • Timeout de execucao de 10 segundos para seguranca

Objeto Ticket​

O objeto ticket e o contexto principal para seus scripts. Ele fornece acesso de leitura e escrita aos dados do ticket.

Propriedades Somente Leitura​

// Informacoes basicas do ticket
ticket.id // String UUID
ticket.subject // Linha de assunto do ticket

// Status atual (objeto)
ticket.status.id // UUID do status
ticket.status.code // Codigo do status (por exemplo, "open", "closed")
ticket.status.name // Nome de exibicao do status

// Prioridade atual (objeto)
ticket.priority.id // UUID da prioridade
ticket.priority.name // Nome de exibicao da prioridade

// Departamento atual (objeto)
ticket.department.id // UUID do departamento
ticket.department.name // Nome de exibicao do departamento

// Proprietario atribuido (objeto, pode ser undefined)
ticket.owner.id // UUID do usuario
ticket.owner.email // E-mail do usuario
ticket.owner.firstname // Primeiro nome do usuario
ticket.owner.lastname // Sobrenome do usuario

// Informacoes do cliente (objeto)
ticket.customer.id // UUID do cliente
ticket.customer.email // E-mail do cliente
ticket.customer.firstname // Primeiro nome do cliente
ticket.customer.lastname // Sobrenome do cliente
ticket.customer.name // Nome completo do cliente

// Pasta e tags
ticket.folder // Pasta atual: "INBOX", "ASSIGNED", "SPAM", "ARCHIVE"
ticket.tags // Array de strings de tag

Propriedades Gravaveis​

Voce pode modificar essas propriedades por atribuicao direta:

// Definir status por codigo ou ID
ticket.status = "closed";
ticket.status = "550e8400-e29b-41d4-a716-446655440000";

// Definir prioridade por nome ou ID
ticket.priority = "High";
ticket.priority = "550e8400-e29b-41d4-a716-446655440001";

// Definir departamento por nome ou ID
ticket.department = "Sales";
ticket.department = "550e8400-e29b-41d4-a716-446655440002";

// Definir proprietario por e-mail ou ID
ticket.owner = "[email protected]";
ticket.owner = "550e8400-e29b-41d4-a716-446655440003";

// Definir pasta
ticket.folder = "ASSIGNED";
ticket.folder = "SPAM";
ticket.folder = "ARCHIVE";
ticket.folder = "INBOX";

// Definir tags (substitui todas as tags existentes)
ticket.tags = ["urgent", "vip"];

Campos Personalizados​

Campos personalizados podem ser lidos e escritos usando seu codigo (nao o nome de exibicao).

Lendo Campos Personalizados​

// Acessar valor de campo personalizado diretamente
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 select

Escrevendo Campos Personalizados​

// Definir campo personalizado de texto
ticket.order_id = "ORD-12345";

// Definir campo personalizado numerico
ticket.order_amount = 199.99;

// Definir campo personalizado booleano
ticket.is_vip = true;

// Definir campo personalizado select
ticket.category = "billing";

// Definir campo personalizado de data (formato ISO 8601)
ticket.due_date = "2024-12-31T23:59:59Z";
ticket.due_date = "2024-12-31";

Objeto Message​

O objeto message esta disponivel quando a regra e acionada por um evento de mensagem (New Customer Reply, New Staff Reply, etc.).

if (message) {
message.id // UUID da mensagem
message.body_text // Conteudo da mensagem (texto simples)
message.body_html // Conteudo da mensagem (HTML)
message.createdAt // Timestamp ISO 8601
}

Exemplo:

if (message && message.body_text) {
var bodyLower = message.body_text.toLowerCase();

if (bodyLower.includes("cancel subscription")) {
ticket.department = "Retention";
ticket.priority = "High";
}
}

Funcoes Auxiliares​

getStatuses()​

Retorna um array de todos os status disponiveis.

var statuses = getStatuses();
// Retorna: [{ id: "...", code: "open", name: "Open" }, ...]

// Encontrar um status especifico
for (var i = 0; i < statuses.length; i++) {
if (statuses[i].code === "pending") {
ticket.status = statuses[i].id;
break;
}
}

getPriorities()​

Retorna um array de todas as prioridades disponiveis.

var priorities = getPriorities();
// Retorna: [{ id: "...", name: "Low" }, { id: "...", name: "High" }, ...]

getDepartments()​

Retorna um array de todos os departamentos disponiveis.

var departments = getDepartments();
// Retorna: [{ id: "...", name: "Support" }, { id: "...", name: "Sales" }, ...]

getUsers()​

Retorna um array de todos os usuarios disponiveis (agentes).

var users = getUsers();
// Retorna: [{ id: "...", email: "[email protected]", firstname: "John", lastname: "Doe" }, ...]

fetch()​

Faz requisicoes HTTP para APIs externas. Sincrono - retorna resultado diretamente.

var response = fetch(url, options);
// response: { ok, status, statusText, text, json }

Opcoes: method (GET/POST/PUT/DELETE), headers (objeto), body (string ou objeto)

Exemplo: Buscar do CRM e atualizar 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";
}
}

Exemplo: POST para webhook

var response = fetch("https://hooks.example.com/helpdesk", {
method: "POST",
body: { ticket_id: ticket.id, customer_email: ticket.customer.email }
});

Notas: Apenas HTTPS, timeout de 5s, limite de resposta de 1MB, redes internas bloqueadas.


Padroes Comuns​

Atribuicao Condicional​

// Definir prioridade com base no assunto
if (ticket.subject.toLowerCase().includes("urgent")) {
ticket.priority = "High";
} else if (ticket.subject.toLowerCase().includes("question")) {
ticket.priority = "Low";
}

Roteamento 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 Baseada em Dominio do Cliente​

if (ticket.customer && ticket.customer.email) {
var email = ticket.customer.email;
var domain = email.split("@")[1];

// Tratamento de cliente enterprise
if (domain === "bigcorp.com" || domain === "enterprise.org") {
ticket.priority = "High";
ticket.department = "Enterprise Support";
ticket.is_enterprise = true;
}

// Instituicao educacional
if (domain.endsWith(".edu")) {
ticket.segment = "education";
}
}

Gerenciamento de Tags​

// Adicionar tags sem perder as existentes
var existingTags = ticket.tags || [];
existingTags.push("processed");
existingTags.push("automated");
ticket.tags = existingTags;

Trabalhando com Mensagens​

if (message && message.body_text) {
var body = message.body_text.toLowerCase();

// Detectar palavras-chave de frustracao
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;
}
}
}

Atribuicao Round-Robin​

var users = getUsers();
if (users.length > 0) {
// Round-robin simples baseado em hash do ID do 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;
}

Tratamento de Erros​

Scripts sao executados em um ambiente seguro:

  • Erros de sintaxe sao capturados e registrados; o script e ignorado.
  • Valores de campo invalidos (por exemplo, nome de status inexistente) sao ignorados.
  • Timeouts (10 segundos) previnem loops infinitos.
  • Erros nao cascateiam para outras regras ou componentes do sistema.

Melhores praticas:

// Verificar null/undefined antes de acessar propriedades
if (ticket.customer && ticket.customer.email) {
// Seguro para acessar ticket.customer.email
}

if (message) {
// Seguro para acessar propriedades de message
}

// Usar try-catch para logica complexa
try {
var data = JSON.parse(ticket.custom_json);
ticket.parsed_field = data.value;
} catch (e) {
// Tratar erro graciosamente
}

Limitacoes​

  • Timeout de execucao: Scripts sao terminados apos 10 segundos.
  • Sem acesso ao sistema de arquivos: Operacoes de arquivo nao estao disponiveis.
  • Sem estado persistente: Variaveis nao persistem entre execucoes de script.
  • Campos somente leitura: ticket.id, ticket.subject, ticket.customer nao podem ser modificados.
  • JavaScript ES5: Recursos modernos do JavaScript (arrow functions, const/let, etc.) podem nao estar disponiveis.