跳至主要内容

腳本參考

本文件提供了在工作流程規則中編寫腳本的綜合參考。腳本允許您使用 JavaScript 實現進階自動化邏輯。


概述​

工作流程規則中的 執行腳本 操作執行 JavaScript 代碼以自動化複雜的工單處理場景。腳本在沙箱環境中執行,可以存取工單資料、訊息上下文和輔助函數。

主要功能:

  • 讀取和修改工單屬性
  • 存取客戶和擁有者資訊
  • 使用自訂欄位
  • 使用條件邏輯和循環
  • 10 秒執行超時以確保安全

工單物件​

ticket 物件是腳本的主要上下文。它提供對工單資料的讀取和寫入存取權限。

唯讀屬性​

// 基本工單資訊
ticket.id // UUID 字串
ticket.subject // 工單主旨行

// 當前狀態(物件)
ticket.status.id // 狀態 UUID
ticket.status.code // 狀態代碼(例如,"open"、"closed")
ticket.status.name // 狀態顯示名稱

// 當前優先順序(物件)
ticket.priority.id // 優先順序 UUID
ticket.priority.name // 優先順序顯示名稱

// 當前部門(物件)
ticket.department.id // 部門 UUID
ticket.department.name // 部門顯示名稱

// 分配的擁有者(物件,可能未定義)
ticket.owner.id // 使用者 UUID
ticket.owner.email // 使用者電子郵件
ticket.owner.firstname // 使用者名字
ticket.owner.lastname // 使用者姓氏

// 客戶資訊(物件)
ticket.customer.id // 客戶 UUID
ticket.customer.email // 客戶電子郵件
ticket.customer.firstname // 客戶名字
ticket.customer.lastname // 客戶姓氏
ticket.customer.name // 客戶全名

// 資料夾和標籤
ticket.folder // 當前資料夾:"INBOX"、"ASSIGNED"、"SPAM"、"ARCHIVE"
ticket.tags // 標籤字串陣列

可寫屬性​

您可以透過直接分配來修改這些屬性:

// 按代碼或 ID 設定狀態
ticket.status = "closed";
ticket.status = "550e8400-e29b-41d4-a716-446655440000";

// 按名稱或 ID 設定優先順序
ticket.priority = "High";
ticket.priority = "550e8400-e29b-41d4-a716-446655440001";

// 按名稱或 ID 設定部門
ticket.department = "Sales";
ticket.department = "550e8400-e29b-41d4-a716-446655440002";

// 按電子郵件或 ID 設定擁有者
ticket.owner = "[email protected]";
ticket.owner = "550e8400-e29b-41d4-a716-446655440003";

// 設定資料夾
ticket.folder = "ASSIGNED";
ticket.folder = "SPAM";
ticket.folder = "ARCHIVE";
ticket.folder = "INBOX";

// 設定標籤(替換所有現有標籤)
ticket.tags = ["urgent", "vip"];

自訂欄位​

可以使用其代碼(而非顯示名稱)讀取和寫入自訂欄位。

讀取自訂欄位​

// 直接存取自訂欄位值
var orderId = ticket.order_id; // 文字欄位
var amount = ticket.order_amount; // 數字欄位
var isVip = ticket.is_vip; // 布林欄位
var region = ticket.region; // 選擇欄位

寫入自訂欄位​

// 設定文字自訂欄位
ticket.order_id = "ORD-12345";

// 設定數字自訂欄位
ticket.order_amount = 199.99;

// 設定布林自訂欄位
ticket.is_vip = true;

// 設定選擇自訂欄位
ticket.category = "billing";

// 設定日期自訂欄位(ISO 8601 格式)
ticket.due_date = "2024-12-31T23:59:59Z";
ticket.due_date = "2024-12-31";

訊息物件​

當規則由訊息事件(新客戶回覆、新員工回覆等)觸發時,message 物件可用。

if (message) {
message.id // 訊息 UUID
message.body_text // 訊息內容(純文字)
message.body_html // 訊息內容(HTML)
message.createdAt // ISO 8601 時間戳記
}

範例:

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

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

輔助函數​

getStatuses()​

返回所有可用狀態的陣列。

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

// 查找特定狀態
for (var i = 0; i < statuses.length; i++) {
if (statuses[i].code === "pending") {
ticket.status = statuses[i].id;
break;
}
}

getPriorities()​

返回所有可用優先順序的陣列。

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

getDepartments()​

返回所有可用部門的陣列。

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

getUsers()​

返回所有可用使用者(客服人員)的陣列。

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

fetch()​

向外部 API 發出 HTTP 請求。同步 - 直接返回結果。

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

選項: method(GET/POST/PUT/DELETE)、headers(物件)、body(字串或物件)

範例:從 CRM 獲取並更新自訂欄位

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

範例:POST 到 webhook

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

注意: 僅 HTTPS、5 秒超時、1MB 回應限制、內部網路被阻止。


常見模式​

條件分配​

// 根據主旨設定優先順序
if (ticket.subject.toLowerCase().includes("urgent")) {
ticket.priority = "High";
} else if (ticket.subject.toLowerCase().includes("question")) {
ticket.priority = "Low";
}

部門路由​

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

基於客戶域名的邏輯​

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

// 企業客戶處理
if (domain === "bigcorp.com" || domain === "enterprise.org") {
ticket.priority = "High";
ticket.department = "Enterprise Support";
ticket.is_enterprise = true;
}

// 教育機構
if (domain.endsWith(".edu")) {
ticket.segment = "education";
}
}

標籤管理​

// 新增標籤而不丟失現有標籤
var existingTags = ticket.tags || [];
existingTags.push("processed");
existingTags.push("automated");
ticket.tags = existingTags;

使用訊息​

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

// 檢測挫折關鍵字
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;
}
}
}

輪流分配​

var users = getUsers();
if (users.length > 0) {
// 基於工單 ID 雜湊的簡單輪流
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;
}

錯誤處理​

腳本在安全環境中執行:

  • 語法錯誤會被捕獲並記錄;腳本被跳過。
  • 無效欄位值(例如,不存在的狀態名稱)會被忽略。
  • 超時(10 秒)防止無限循環。
  • 錯誤不會級聯到其他規則或系統組件。

最佳實踐:

// 在存取屬性之前檢查 null/undefined
if (ticket.customer && ticket.customer.email) {
// 安全存取 ticket.customer.email
}

if (message) {
// 安全存取 message 屬性
}

// 對複雜邏輯使用 try-catch
try {
var data = JSON.parse(ticket.custom_json);
ticket.parsed_field = data.value;
} catch (e) {
// 優雅地處理錯誤
}

限制​

  • 執行超時: 腳本在 10 秒後終止。
  • 無檔案系統存取: 檔案操作不可用。
  • 無持久狀態: 變數不會在腳本執行之間保持。
  • 唯讀欄位: ticket.id、ticket.subject、ticket.customer 無法修改。
  • ES5 JavaScript: 現代 JavaScript 功能(箭頭函數、const/let 等)可能不可用。