Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
This scheduled job automatically assigns unassigned incidents in ServiceNow to a random active user from the incident’s assignment group, but only if the incident is at least 30 minutes old.
It ensures timely triaging of new incidents and avoids backlog accumulation caused by unassigned tickets.

How It Works

Identify Eligible Incidents
Fetch all incidents from the incident table whereassigned_to is empty (unassigned) and assignment_group is not empty

Find Active Group Members
For each incident, look up the related group (sys_user_grmember table).Join with the sys_user table. This allows filtering users based on their active status.

Random Assignment
From the list of active members, pick a random user. Assign that user to the incident’s Assigned To field

Update & Log
Update the incident record in the database. Log success or skip messages to the system log
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
(function executeAutoAssignment() {
// --- CONFIGURABLE SETTINGS ---
var MINUTES_DELAY = 30; // Only assign incidents older than this many minutes

// --- COMPUTE TIME CUTOFF ---
var cutoffTime = new GlideDateTime();
cutoffTime.addMinutes(-MINUTES_DELAY); // incidents created before this time are eligible

// --- QUERY: Find eligible unassigned incidents ---
var incGr = new GlideRecord('incident');
incGr.addNullQuery('assigned_to'); // incident not yet assigned
incGr.addNotNullQuery('assignment_group'); // has an assignment group
incGr.addQuery('sys_created_on', '<=', cutoffTime); // created at least 30 minutes ago
incGr.query();

var totalAssigned = 0;

// --- LOOP THROUGH EACH ELIGIBLE INCIDENT ---
while (incGr.next()) {
var groupSysId = incGr.assignment_group.toString();
if (!groupSysId) {
gs.info('[AutoAssign] Skipped ' + incGr.number + ': No assignment group defined.');
continue;
}

// --- FETCH ACTIVE USERS IN THAT ASSIGNMENT GROUP ---
var members = getActiveGroupMembers(groupSysId);

if (members.length === 0) {
gs.info('[AutoAssign] Skipped ' + incGr.number + ': No active users found in group ' + incGr.assignment_group.name);
continue;
}

// --- PICK A RANDOM USER ---
var assignedUser = getRandomElement(members);

// --- ASSIGN AND UPDATE ---
incGr.assigned_to = assignedUser;
incGr.update();

gs.info('[AutoAssign] Incident ' + incGr.number + ' assigned to user: ' + assignedUser);
totalAssigned++;
}

gs.info('[AutoAssign] Total incidents auto-assigned: ' + totalAssigned);

// -------------------------------------------------------------------
// --- HELPER FUNCTIONS ---
// -------------------------------------------------------------------

/**
* Fetches all active users in a given assignment group.
* @param {String} groupSysId - sys_id of assignment group
* @returns {Array} - Array of user sys_ids
*/
function getActiveGroupMembers(groupSysId) {
var users = [];
var grMember = new GlideRecord('sys_user_grmember');
grMember.addQuery('group', groupSysId);
grMember.addJoinQuery('sys_user', 'user', 'sys_id');
grMember.addQuery('user.active', true);
grMember.query();

while (grMember.next()) {
users.push(grMember.user.toString());
}
return users;
}

/**
* Returns a random element from an array.
* @param {Array} arr
* @returns {*} Random element
*/
function getRandomElement(arr) {
if (!arr || arr.length === 0) return null;
var index = Math.floor(Math.random() * arr.length);
return arr[index];
}

})();

Loading