ユースケース このワークフローは、ヘルプデスクプロジェクトに関連する拡張機能を提供します。
エージェントが、ヘルプデスクと同じ時間制約や SLA の対象ではない別の部門で処理する必要があるチケットに遭遇した場合、課題追跡にコピー アクションを使用して、チケットのコピーを別のプロジェクトの課題として作成できます。これは、たとえば、報告者が開発チームで対処する必要があるバグレポートや機能要求を送信するときに便利です。
ヘルプデスクエージェントは、同じ報告者によって以前に送信されたサポートリクエストと一致するチケットを見つけた場合、チケットの 1 つを重複としてマークできます。これにより、コミュニケーションが 1 つのスレッドに統合され、エージェントが矛盾する回答を提供するのを防ぐことができます。エージェントは、重複 リンクを使用するか、チケットのアクションメニューのチケットを手動で結合する オプションを使用して、チケットを重複としてマークできます。
エージェントが報告者から別のサポートリクエストとして処理する必要がある応答を受信した場合、コメントからの新しいチケット アクションを使用できます。これにより、コメントテキストが取得され、新しいチケットの説明フィールドにコピーされ、エージェントに概要を入力するよう求められます。
エージェントがチケット内の報告者に応答すると、チケットを保留 状態に移行して SLA タイマーを一時停止できます。この状態は、エージェントが報告者が質問に答えるか、実行されたアクションを確認するのを待っていることを示します。
報告者が保留 として設定されたチケットにコメントを追加すると、そのチケットは自動的に再度開かれます。これは、アクティブな SLA ポリシーに従って解決時間が確実に追跡されるようにできます。
モジュール このワークフローは、ヘルプデスクプロジェクトでチケットを処理するために使用できるいくつかのルールをサポートしています。
課題追跡にコピー このルールは、ヘルプデスクプロジェクトのチケットに適用されるサービスレベル契約に従って処理されることが意図されていないリクエストをエージェントが処理できます。エージェントがチケットでこのアクションを選択すると、次のようになります。
新しい課題が作成されるターゲットプロジェクトを選択するように求められます。
対象プロジェクトの選択を確認すると、チケットのコピーが対象プロジェクトの課題として作成されます。
ヘルプデスクチケットから新しい課題へのリンクが自動的に追加されます。
このアクションは、現在のヘルプデスクプロジェクトでエージェントライセンスが付与されているユーザーのみが使用できます。標準ユーザーまたは他のヘルプデスクプロジェクトのエージェントには、チケットで使用可能なアクションのリストにこのオプションは表示されません。
const workflow = require('@jetbrains/youtrack-scripting-api/workflow');
const entities = require('@jetbrains/youtrack-scripting-api/entities');
exports.rule = entities.Issue.action({
title: 'Copy to issue tracker',
command: 'copy to issue',
guard: (ctx) => {
return ctx.issue.project.isAgent(ctx.currentUser) && ctx.issue.isReported;
},
action: function (ctx) {
workflow.check(ctx.userInput.projectType.typeName !== "Helpdesk", "Please select a standard issue-tracking project")
const issue = ctx.issue;
const newIssue = issue.copy(ctx.userInput);
workflow.message('A copy of this ticket was created in the {0} project as <a href="{1}">{2}</a>', ctx.userInput.name, newIssue.url, newIssue.id);
issue.links['relates to'].add(newIssue);
},
requirements: {
Relates: {
type: entities.IssueLinkPrototype,
outward: 'relates to'
}
},
userInput: {
type: entities.Project,
description: 'Target project'
}
});
重複したチケットを統合する このルールは、ヘルプデスクプロジェクトで重複したチケットを管理するために使用されます。チケットが別のチケットの重複としてマークされている場合、この変更時ルールは両方のチケットが同じユーザーによって報告されたかどうかをチェックします。
const entities = require('@jetbrains/youtrack-scripting-api/entities');
const workflow = require('@jetbrains/youtrack-scripting-api/workflow');
exports.rule = entities.Issue.onChange({
title: 'Merge duplicate tickets',
guard: (ctx) => {
return ctx.issue.links['duplicates'].added.isNotEmpty();
},
action: (ctx) => {
const duplicate = ctx.issue.links['duplicates'].added.first();
workflow.check(duplicate.reporter.login === ctx.issue.reporter.login,
"You can only merge tickets where the reporter is the same person")
const commnet = ctx.issue.addComment("This ticket was merged into {0}, which was also reported by you.", duplicate.id)
commnet.permittedUsers.clear()
commnet.permittedGroups.clear()
},
requirements: {
Duplicate: {
type: entities.IssueLinkPrototype,
outward: 'is duplicated by',
inward: 'duplicates'
}
}
});
YouTrack によって提供された元のワークフロースクリプトでは、workflow.i18n 関数が使用されています。これは、ローカライズされたメッセージ文字列を参照するためにのみ使用される内部関数です。このワークフローコードをコピーしてカスタマイズできるようにするために、サンプルからこの関数を削除しました。既定のワークフローを編集していて、メッセージテキストをカスタマイズする場合は、コードからこれらの関数も削除することをお勧めします。
ワークフロー内のローカライズされたメッセージの詳細については、ローカライズされたワークフローメッセージ を参照してください。
チケットを手動でマージする このアクションルールにより、エージェントは merge with コマンドを使用して重複したチケットをマージできます。エージェントがこのコマンドを指定すると、マージするチケットの ID を入力するよう求められます。
このアクションにより、重複 リンクが現在のチケットに適用され、上記の重複したチケットを統合する ワークフロールールがトリガーされます。
const entities = require('@jetbrains/youtrack-scripting-api/entities');
exports.rule = entities.Issue.action({
title: 'Merge tickets manually',
command: 'merge with',
guard: function (ctx) {
return ctx.issue.project.isAgent(ctx.currentUser) && ctx.issue.isReported;
},
action: function (ctx) {
const source = ctx.issue;
const target = ctx.userInput;
source.links['duplicates'].add(target);
},
requirements: {
Duplicate: {
type: entities.IssueLinkPrototype,
outward: 'is duplicated by',
inward: 'duplicates'
}
},
userInput: {
type: entities.Issue,
description: 'Target ticket for merge'
}
});
この変更時ルールは、報告者がコメントを追加するたびに、状態 フィールドの値を保留 からオープン に自動的に変更します。
const entities = require('@jetbrains/youtrack-scripting-api/entities');
exports.rule = entities.Issue.onChange({
title: 'Reopen ticket when reporter adds a comment',
guard: (ctx) => {
return !ctx.issue.comments.added.isEmpty() &&
ctx.issue.reporter.login === ctx.issue.comments.added.first().author.login &&
ctx.issue.fields.State.name === ctx.State.Pending.name;
},
action: (ctx) => {
ctx.issue.fields.State = ctx.State.Open;
},
requirements: {
State: {
type: entities.State.fieldType,
Pending: {},
Open: {}
}
}
});
このアクションルールにより、エージェントはチケット内のコメントのテキストをヘルプデスクプロジェクト内の別のチケットを報告するための基礎として使用できるようになります。エージェントは、新しいチケットの概要を入力するように求められます。
このアクションが適用されると、新しいチケットを参照するコメントが元のチケットに投稿されます。元のコメントへのリンクを含むコメントも新しいチケットに追加されます。
const entities = require('@jetbrains/youtrack-scripting-api/entities');
const workflow = require('@jetbrains/youtrack-scripting-api/workflow');
exports.rule = entities.IssueComment.action({
title: 'New ticket from comment',
command: 'toTicket',
guard: function (ctx) {
return ctx.issueComment.permittedGroups.isEmpty() && ctx.issueComment.permittedUsers.isEmpty() && ctx.issueComment.issue.project.isAgent(ctx.currentUser)
},
action: function (ctx) {
const description = ctx.issueComment.text;
let issue = ctx.issueComment.issue;
const author = issue.reporter;
const project = issue.project;
const commentIssue = new entities.Issue(author, project, ctx.userInput);
commentIssue.description = description;
const info = issue.addComment('A related ticket ({0}) has been created based on a comment from this ticket.', commentIssue.id)
commentIssue.addComment('This ticket was created from a [comment in another ticket]({0}).', ctx.issueComment.url)
info.permittedUsers.clear()
info.permittedGroups.clear()
},
userInput: {
type: 'string',
description: 'Ticket summary'
}
});
YouTrack によって提供された元のワークフロースクリプトでは、workflow.i18n 関数が使用されています。これは、ローカライズされたメッセージ文字列を参照するためにのみ使用される内部関数です。このワークフローコードをコピーしてカスタマイズできるようにするために、サンプルからこの関数を削除しました。既定のワークフローを編集していて、メッセージテキストをカスタマイズする場合は、コードからこれらの関数も削除することをお勧めします。
ワークフロー内のローカライズされたメッセージの詳細については、ローカライズされたワークフローメッセージ を参照してください。
報告者に通知し、保留中のチケットを自動的に閉じる このスケジュール規則は、状態 フィールドの値が保留 であるチケットをチェックします。
チケットが 7 日以上保留されている場合、リマインダーが報告者に送信されます。
2 回目のリマインダーは 14 日後に送信されます。
チケットが 21 日経っても保留中の場合は、チケットにコメントが投稿され、その状態は Solved に設定されます。
var entities = require('@jetbrains/youtrack-scripting-api/entities');
var workflow = require('@jetbrains/youtrack-scripting-api/workflow');
const firstReminderPolicyDays = 7;
const secondReminderPolicyDays = 14;
const retentionPolicyDays = 21;
const oneDayMillis = 24 * 60 * 60 * 1000;
exports.rule = entities.Issue.onSchedule({
title: "Remind reporters and close pending tickets automatically",
cron: '0 0 0 * * ?',
search: 'State: Pending',
action: function (ctx) {
const reporter = ctx.issue.reporter;
let lastPublicComment = null;
ctx.issue.comments.forEach(comment => {
if (comment.author.login === reporter.login) {
lastPublicComment = null;
} else if (comment.permittedUsers.isEmpty() && comment.permittedGroups.isEmpty()) {
lastPublicComment = comment;
}
});
if (lastPublicComment === null) {
console.trace('Checking ticket ' + ctx.issue.id + ', last comment is not from the agent');
return;
}
const pendingIntervalDays = (ctx.ruleStarted - lastPublicComment.created) / oneDayMillis;
if (pendingIntervalDays < firstReminderPolicyDays) {
console.trace('Checking ticket ' + ctx.issue.id + ', too early to remind, pending = ' + pendingIntervalDays);
return;
}
if (pendingIntervalDays > retentionPolicyDays + 1) {
console.trace('Checking ticket ' + ctx.issue.id + ', too late to remind, pending = ' + pendingIntervalDays);
return;
}
const firstReminderOverdue = pendingIntervalDays - firstReminderPolicyDays;
if (firstReminderOverdue > 0 && firstReminderOverdue < 1) {
reporter.notifyOnCase('reporterReminder', {}, ctx.issue);
return;
}
const secondReminderOverdue = pendingIntervalDays - secondReminderPolicyDays;
if (secondReminderOverdue > 0 && secondReminderOverdue < 1) {
const params = {
'autoCloseDays': retentionPolicyDays - secondReminderPolicyDays
};
reporter.notifyOnCase('reporterReminder', params, ctx.issue);
return;
}
const autoCloseOverdue = pendingIntervalDays - retentionPolicyDays;
if (autoCloseOverdue >= 0 && autoCloseOverdue < 1) {
ctx.issue.fields.State = ctx.State.Solved;
const params = {
'responseTimeoutDays': retentionPolicyDays
};
reporter.notifyOnCase('reporterTicketClosed', params, ctx.issue);
}
},
requirements: {
State: {
type: entities.State.fieldType,
Pending: {},
Solved: {
name: 'Solved',
isResolved: true
}
}
}
});
YouTrack によって提供された元のワークフロースクリプトでは、workflow.i18n 関数が使用されています。これは、ローカライズされたメッセージ文字列を参照するためにのみ使用される内部関数です。このワークフローコードをコピーしてカスタマイズできるようにするために、サンプルからこの関数を削除しました。既定のワークフローを編集していて、メッセージテキストをカスタマイズする場合は、コードからこれらの関数も削除することをお勧めします。
ワークフロー内のローカライズされたメッセージの詳細については、ローカライズされたワークフローメッセージ を参照してください。
リマインダーの送信と放棄されたチケットのクローズの時間枠をカスタマイズする場合は、ワークフローコードで次の値を直接変更できます。
値
説明
firstReminderPolicyDays
最初のリマインダーを送信するまでに待機する日数。
secondReminderPolicyDays
2 回目のリマインダーを送信するまで待機する日数。
retentionPolicyDays
チケットを自動的に閉じるまで待機する日数。
最初の返信の作成者にチケットを割り当てる 未割り当てのチケットがエージェントからコメントを受け取ると、この変更時ルールにより、コメントの作成者であるエージェントにチケットが自動的に割り当てられます。
const entities = require('@jetbrains/youtrack-scripting-api/entities');
exports.rule = entities.Issue.onChange({
title: 'Assign ticket to author of first reply',
guard: (ctx) => {
const issue = ctx.issue;
if (!issue.fields.Assignee && issue.comments.added.isNotEmpty() && issue.project.isAgent(ctx.currentUser)) {
let hasAgentComment = false;
let result = true;
issue.comments.forEach(function (comment) {
if (result && issue.project.isAgent(comment.author)) {
if (hasAgentComment) {
result = false;
} else {
hasAgentComment = true;
}
}
})
return result;
}
return false;
},
action: (ctx) => {
const issue = ctx.issue
if (issue.project.findFieldByName(ctx.Assignee.name).findValueByLogin(ctx.currentUser.login)) {
issue.fields.Assignee = ctx.currentUser;
}
},
requirements: {
Assignee: {
type: entities.User.fieldType
}
}
});