メインコンテンツまでスキップ

スクリプトリファレンス

このドキュメントは、ワークフロールールでスクリプトを書くための包括的なリファレンスを提供します。スクリプトを使用すると、JavaScriptを使用して高度な自動化ロジックを実装できます。


概要​

ワークフロールールのRun Scriptアクションは、複雑なチケット処理シナリオを自動化するためにJavaScriptコードを実行します。スクリプトは、チケットデータ、メッセージコンテキスト、ヘルパー関数にアクセスできる分離された環境で実行されます。

主な機能:

  • チケットプロパティの読み取りと変更
  • 顧客と所有者情報へのアクセス
  • カスタムフィールドの操作
  • 条件付きロジックとループの使用
  • 安全性のための10秒の実行タイムアウト

Ticketオブジェクト​

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オブジェクト​

messageオブジェクトは、メッセージイベント(New Customer Reply、New Staff Replyなど)によってルールがトリガーされたときに利用可能です。

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

例: webhookへのPOST

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など)は利用できない場合があります。