Przejdź do głównej zawartości

Dokumentacja skryptów

Ten dokument zawiera kompleksową dokumentację dotyczącą pisania skryptów w regułach workflow. Skrypty pozwalają na implementację zaawansowanej logiki automatyzacji przy użyciu JavaScript.


Przegląd​

Akcja Uruchom skrypt w regułach workflow wykonuje kod JavaScript, aby zautomatyzować złożone scenariusze obsługi zgłoszeń. Skrypty działają w środowisku piaskownicy z dostępem do danych zgłoszenia, kontekstu wiadomości i funkcji pomocniczych.

Kluczowe funkcje:

  • Odczyt i modyfikacja właściwości zgłoszenia
  • Dostęp do informacji o kliencie i właścicielu
  • Praca z polami niestandardowymi
  • Używanie logiki warunkowej i pętli
  • 10-sekundowy limit czasu wykonania dla bezpieczeństwa

Obiekt Ticket​

Obiekt ticket jest podstawowym kontekstem dla Twoich skryptów. Zapewnia dostęp do odczytu i zapisu danych zgłoszenia.

Właściwości tylko do odczytu​

// Podstawowe informacje o zgłoszeniu
ticket.id // Ciąg UUID
ticket.subject // Temat zgłoszenia

// Aktualny status (obiekt)
ticket.status.id // UUID statusu
ticket.status.code // Kod statusu (np. "open", "closed")
ticket.status.name // Nazwa wyświetlana statusu

// Aktualny priorytet (obiekt)
ticket.priority.id // UUID priorytetu
ticket.priority.name // Nazwa wyświetlana priorytetu

// Aktualny dział (obiekt)
ticket.department.id // UUID działu
ticket.department.name // Nazwa wyświetlana działu

// Przypisany właściciel (obiekt, może być undefined)
ticket.owner.id // UUID użytkownika
ticket.owner.email // Email użytkownika
ticket.owner.firstname // Imię użytkownika
ticket.owner.lastname // Nazwisko użytkownika

// Informacje o kliencie (obiekt)
ticket.customer.id // UUID klienta
ticket.customer.email // Email klienta
ticket.customer.firstname // Imię klienta
ticket.customer.lastname // Nazwisko klienta
ticket.customer.name // Pełne imię i nazwisko klienta

// Folder i tagi
ticket.folder // Aktualny folder: "INBOX", "ASSIGNED", "SPAM", "ARCHIVE"
ticket.tags // Tablica ciągów tagów

Właściwości do zapisu​

Możesz modyfikować te właściwości poprzez bezpośrednie przypisanie:

// Ustaw status według kodu lub ID
ticket.status = "closed";
ticket.status = "550e8400-e29b-41d4-a716-446655440000";

// Ustaw priorytet według nazwy lub ID
ticket.priority = "High";
ticket.priority = "550e8400-e29b-41d4-a716-446655440001";

// Ustaw dział według nazwy lub ID
ticket.department = "Sales";
ticket.department = "550e8400-e29b-41d4-a716-446655440002";

// Ustaw właściciela według emaila lub ID
ticket.owner = "[email protected]";
ticket.owner = "550e8400-e29b-41d4-a716-446655440003";

// Ustaw folder
ticket.folder = "ASSIGNED";
ticket.folder = "SPAM";
ticket.folder = "ARCHIVE";
ticket.folder = "INBOX";

// Ustaw tagi (zastępuje wszystkie istniejące tagi)
ticket.tags = ["urgent", "vip"];

Pola niestandardowe​

Pola niestandardowe mogą być odczytywane i zapisywane przy użyciu ich kodu (a nie nazwy wyświetlanej).

Odczyt pól niestandardowych​

// Bezpośredni dostęp do wartości pola niestandardowego
var orderId = ticket.order_id; // Pole tekstowe
var amount = ticket.order_amount; // Pole liczbowe
var isVip = ticket.is_vip; // Pole logiczne
var region = ticket.region; // Pole wyboru

Zapis pól niestandardowych​

// Ustaw tekstowe pole niestandardowe
ticket.order_id = "ORD-12345";

// Ustaw liczbowe pole niestandardowe
ticket.order_amount = 199.99;

// Ustaw logiczne pole niestandardowe
ticket.is_vip = true;

// Ustaw pole wyboru
ticket.category = "billing";

// Ustaw pole daty (format ISO 8601)
ticket.due_date = "2024-12-31T23:59:59Z";
ticket.due_date = "2024-12-31";

Obiekt Message​

Obiekt message jest dostępny, gdy reguła jest wyzwalana przez zdarzenie wiadomości (Nowa odpowiedź klienta, Nowa odpowiedź pracownika itp.).

if (message) {
message.id // UUID wiadomości
message.body_text // Treść wiadomości (zwykły tekst)
message.body_html // Treść wiadomości (HTML)
message.createdAt // Znacznik czasu ISO 8601
}

Przykład:

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

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

Funkcje pomocnicze​

getStatuses()​

Zwraca tablicę wszystkich dostępnych statusów.

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

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

getPriorities()​

Zwraca tablicę wszystkich dostępnych priorytetów.

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

getDepartments()​

Zwraca tablicę wszystkich dostępnych działów.

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

getUsers()​

Zwraca tablicę wszystkich dostępnych użytkowników (agentów).

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

fetch()​

Wykonuje zapytania HTTP do zewnętrznych API. Synchroniczne - zwraca wynik bezpośrednio.

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

Opcje: method (GET/POST/PUT/DELETE), headers (obiekt), body (ciąg lub obiekt)

Przykład: Pobierz dane z CRM i zaktualizuj pola niestandardowe

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";
}
}

Przykład: POST do webhooka

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

Uwagi: Tylko HTTPS, limit czasu 5s, limit odpowiedzi 1MB, zablokowane sieci wewnętrzne.


Popularne wzorce​

Przypisanie warunkowe​

// Ustaw priorytet na podstawie tematu
if (ticket.subject.toLowerCase().includes("urgent")) {
ticket.priority = "High";
} else if (ticket.subject.toLowerCase().includes("question")) {
ticket.priority = "Low";
}

Routing działu​

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";
}

Logika oparta na domenie klienta​

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

// Obsługa klientów korporacyjnych
if (domain === "bigcorp.com" || domain === "enterprise.org") {
ticket.priority = "High";
ticket.department = "Enterprise Support";
ticket.is_enterprise = true;
}

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

Zarządzanie tagami​

// Dodaj tagi bez utraty istniejących
var existingTags = ticket.tags || [];
existingTags.push("processed");
existingTags.push("automated");
ticket.tags = existingTags;

Praca z wiadomościami​

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

// Wykryj słowa kluczowe frustracji
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;
}
}
}

Przypisanie rotacyjne​

var users = getUsers();
if (users.length > 0) {
// Proste przypisanie rotacyjne oparte na hashu ID zgłoszenia
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;
}

Obsługa błędów​

Skrypty są wykonywane w bezpiecznym środowisku:

  • Błędy składni są przechwytywane i logowane; skrypt jest pomijany.
  • Nieprawidłowe wartości pól (np. nieistniejąca nazwa statusu) są ignorowane.
  • Limity czasu (10 sekund) zapobiegają nieskończonym pętlom.
  • Błędy nie przenoszą się na inne reguły lub komponenty systemu.

Najlepsze praktyki:

// Sprawdź null/undefined przed dostępem do właściwości
if (ticket.customer && ticket.customer.email) {
// Bezpieczny dostęp do ticket.customer.email
}

if (message) {
// Bezpieczny dostęp do właściwości wiadomości
}

// Użyj try-catch dla złożonej logiki
try {
var data = JSON.parse(ticket.custom_json);
ticket.parsed_field = data.value;
} catch (e) {
// Obsłuż błąd w sposób elegancki
}

Ograniczenia​

  • Limit czasu wykonania: Skrypty są przerywane po 10 sekundach.
  • Brak dostępu do systemu plików: Operacje na plikach nie są dostępne.
  • Brak trwałego stanu: Zmienne nie są zachowywane między wykonaniami skryptów.
  • Pola tylko do odczytu: ticket.id, ticket.subject, ticket.customer nie mogą być modyfikowane.
  • JavaScript ES5: Nowoczesne funkcje JavaScript (funkcje strzałkowe, const/let itp.) mogą nie być dostępne.