From 2da9254ab1a15fbaf6851c7a84f9b46c81711023 Mon Sep 17 00:00:00 2001 From: trimbakeshmadhan-109 Date: Tue, 28 Oct 2025 01:17:01 +0530 Subject: [PATCH 01/22] script.js Automatically create a problem record from incident volume Use case: Automatically create a problem record if a specific Configuration Item (CI) is associated with more than a certain number of incidents within a defined timeframe. Code snippet This code can be placed in a Scheduled Script Execution or an After Insert Business Rule to check new incidents --- .../script.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 Core ServiceNow APIs/GlideAggregate/Create Problem based on incident volume/script.js diff --git a/Core ServiceNow APIs/GlideAggregate/Create Problem based on incident volume/script.js b/Core ServiceNow APIs/GlideAggregate/Create Problem based on incident volume/script.js new file mode 100644 index 0000000000..dcec063918 --- /dev/null +++ b/Core ServiceNow APIs/GlideAggregate/Create Problem based on incident volume/script.js @@ -0,0 +1,13 @@ +var incidentCheck = new GlideAggregate('incident'); + incidentCheck.addQuery('cmdb_ci', current.cmdb_ci); // Or any specific CI + incidentCheck.addQuery('opened_at', '>', 'javascript:gs.minutesAgoStart(60)'); + incidentCheck.addAggregate('COUNT'); + incidentCheck.query(); + + if (incidentCheck.next() && parseInt(incidentCheck.getAggregate('COUNT')) > 5) { + var problem = new GlideRecord('problem'); + problem.initialize(); + problem.short_description = 'Multiple incidents reported for CI: ' + current.cmdb_ci.getDisplayValue(); + problem.cmdb_ci = current.cmdb_ci; + problem.insert(); + } From c9315ec134f33bba9be4a53522c89b6c36965d1d Mon Sep 17 00:00:00 2001 From: trimbakeshmadhan-109 Date: Tue, 28 Oct 2025 01:18:16 +0530 Subject: [PATCH 02/22] README.md --- .../README.md | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 Core ServiceNow APIs/GlideAggregate/Create Problem based on incident volume/README.md diff --git a/Core ServiceNow APIs/GlideAggregate/Create Problem based on incident volume/README.md b/Core ServiceNow APIs/GlideAggregate/Create Problem based on incident volume/README.md new file mode 100644 index 0000000000..6f7afc5eac --- /dev/null +++ b/Core ServiceNow APIs/GlideAggregate/Create Problem based on incident volume/README.md @@ -0,0 +1,37 @@ +Key features +Automatic problem creation: The script uses a GlideAggregate query to count the number of incidents opened for a specific CI. +Time-based threshold: Problems are only created if more than five incidents are opened within a 60-minute window. +Targeted incidents: The script focuses on incidents related to the same CI, making it effective for identifying recurring infrastructure issues. +Customizable conditions: The number of incidents and the time frame are easily configurable within the script. +Efficient performance: The use of GlideAggregate ensures the database is queried efficiently, minimizing performance impact. + +How it works +The script is designed to be executed as a server-side script, typically within a Business Rule. When an incident is inserted or updated, the script performs the following actions: +Queries incidents: It executes a GlideAggregate query on the incident table. +Sets conditions: The query is filtered to count all incidents that meet the following conditions: +Same CI: The incident's cmdb_ci matches the cmdb_ci of the current record. +Within the last hour: The opened_at time is within the last 60 minutes. +Evaluates count: After the query is run, the script checks if the count of matching incidents exceeds the threshold (in this case, 5). +Creates problem: If the threshold is exceeded, a new problem record is initialized. +The short_description is automatically populated with a descriptive message. +The cmdb_ci is linked to the new problem record. +The new record is then inserted into the database. +Implementation steps +Create a Business Rule: +Navigate to System Definition > Business Rules. +Click New. +Configure the Business Rule: +Name: Auto Create Problem from Multiple Incidents +Table: Incident [incident] +Advanced: true +When to run: Select after and check the Insert and Update checkboxes. This ensures the script runs after an incident has been saved. +Filter conditions: Optionally, you can add conditions to limit when the script runs (e.g., cmdb_ci is not empty). +Add the script: +Navigate to the Advanced tab. +Copy and paste the script into the Script field. +Customize (optional): +Number of incidents: Change the > 5 value to adjust the threshold. +Time frame: Adjust the gs.minutesAgoStart(60) value to change the time window. +Other conditions: If you need to check for specific incident statuses or categories, add more addQuery lines to the GlideAggregate call. +Save the Business Rule. +Customization examples From 5d17de8e7e9d72872248c773dba953dce931a82a Mon Sep 17 00:00:00 2001 From: trimbakeshmadhan-109 Date: Tue, 28 Oct 2025 01:30:06 +0530 Subject: [PATCH 03/22] Script.js Identify the oldest active incident for each assignment group. This helps managers focus on long-running tickets that may require special attention. --- .../script.js | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 Core ServiceNow APIs/GlideAggregate/Find oldest Incident based Assignment Groups/script.js diff --git a/Core ServiceNow APIs/GlideAggregate/Find oldest Incident based Assignment Groups/script.js b/Core ServiceNow APIs/GlideAggregate/Find oldest Incident based Assignment Groups/script.js new file mode 100644 index 0000000000..4aabd461b1 --- /dev/null +++ b/Core ServiceNow APIs/GlideAggregate/Find oldest Incident based Assignment Groups/script.js @@ -0,0 +1,11 @@ +var ga = new GlideAggregate('incident'); + ga.addActiveQuery(); + ga.addAggregate('MIN', 'opened_at'); + ga.groupBy('assignment_group'); + ga.query(); + + while (ga.next()) { + var group = ga.assignment_group.getDisplayValue(); + var oldestIncidentDate = ga.getAggregate('MIN', 'opened_at'); + gs.info("Oldest open incident for " + group + " was created on: " + oldestIncidentDate); + } From c8c2e0642d42fc32b0393416020c9305fac204cd Mon Sep 17 00:00:00 2001 From: trimbakeshmadhan-109 Date: Tue, 28 Oct 2025 01:32:57 +0530 Subject: [PATCH 04/22] README.md --- .../README.md | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 Core ServiceNow APIs/GlideAggregate/Find oldest Incident based Assignment Groups/README.md diff --git a/Core ServiceNow APIs/GlideAggregate/Find oldest Incident based Assignment Groups/README.md b/Core ServiceNow APIs/GlideAggregate/Find oldest Incident based Assignment Groups/README.md new file mode 100644 index 0000000000..722a45ac02 --- /dev/null +++ b/Core ServiceNow APIs/GlideAggregate/Find oldest Incident based Assignment Groups/README.md @@ -0,0 +1,92 @@ +ServiceNow Script: Find Oldest Open Incidents per Group +This script leverages GlideAggregate to efficiently find the oldest active incident for each assignment group. This is a powerful tool for monitoring and reporting on potential service level agreement (SLA) risks and improving incident management processes. +Overview +The script performs the following actions: +Initializes GlideAggregate: Creates an aggregate query on the incident table. +Filters Active Incidents: Uses addActiveQuery() to restrict the search to only open (active) incidents. +Aggregates by Minimum Date: Finds the minimum (MIN) opened_at date, which represents the oldest record. +Groups by Assignment Group: Groups the results by the assignment_group to get a separate result for each team. +Iterates and Logs: Loops through the query results and logs the assignment group and the opening date of its oldest open incident. +How to use +This script is intended to be used in a server-side context within a ServiceNow instance. Common use cases include: +Scheduled Job: Run this script on a regular schedule (e.g., daily) to generate a report on aging incidents. +Script Include: Incorporate the logic into a reusable function within a Script Include, allowing other scripts to call it. +Fix Script: Execute the script as a one-off task to perform an analysis. +Script +javascript +(function findOldestIncidents() { + var ga = new GlideAggregate('incident'); + ga.addActiveQuery(); + ga.addAggregate('MIN', 'opened_at'); + ga.groupBy('assignment_group'); + ga.query(); + + while (ga.next()) { + var group = ga.assignment_group.getDisplayValue(); + var oldestIncidentDate = ga.getAggregate('MIN', 'opened_at'); + gs.info("Oldest open incident for " + group + " was created on: " + oldestIncidentDate); + } +})(); +Use code with caution. + +Installation +As a Scheduled Job +Navigate to System Definition > Scheduled Jobs. +Click New and select Automatically run a script of your choosing. +Name the job (e.g., Find Oldest Open Incidents). +Set your desired frequency and time. +Paste the script into the Run this script field. +Save and activate the job. +As a Script Include +Navigate to System Definition > Script Includes. +Click New. +Name it (e.g., IncidentHelper). +API Name: global.IncidentHelper +Script: +javascript +var IncidentHelper = Class.create(); +IncidentHelper.prototype = { + initialize: function() { + }, + + findOldestIncidents: function() { + var ga = new GlideAggregate('incident'); + ga.addActiveQuery(); + ga.addAggregate('MIN', 'opened_at'); + ga.groupBy('assignment_group'); + ga.query(); + + var results = []; + while (ga.next()) { + var group = ga.assignment_group.getDisplayValue(); + var oldestIncidentDate = ga.getAggregate('MIN', 'opened_at'); + results.push({ + group: group, + oldestIncidentDate: oldestIncidentDate + }); + } + return results; + }, + + type: 'IncidentHelper' +}; +Use code with caution. + +You can then call this function from other scripts. For example: +javascript +var helper = new IncidentHelper(); +var incidents = helper.findOldestIncidents(); +for (var i = 0; i < incidents.length; i++) { + gs.info("Oldest open incident for " + incidents[i].group + " was created on: " + incidents[i].oldestIncidentDate); +} +Use code with caution. + +Customization +Change the output: Modify the gs.info() line to instead write to a custom log, send an email, or create a report. +Refine the query: Add more addQuery() statements to filter incidents by other criteria, such as priority or category. +Change the aggregate: Use MAX instead of MIN to find the newest incident in each group. +Get incident details: To get the actual incident record (e.g., its number), you would need to perform a secondary GlideRecord query based on the aggregated data. +Dependencies +This script uses standard ServiceNow APIs (GlideAggregate, gs). No external libraries are required. +Support +For any questions or issues, please open an issue in this repository. From 14244d8b6541501ee7a8ae74854231812e3550a7 Mon Sep 17 00:00:00 2001 From: trimbakeshmadhan-109 Date: Tue, 28 Oct 2025 01:47:20 +0530 Subject: [PATCH 05/22] script.js This example searches a JSON document for all developers listed under the specified path. --- .../GlideJsonPath/GlideJsonPath Reader Example/script.js | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/script.js diff --git a/Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/script.js b/Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/script.js new file mode 100644 index 0000000000..ddfd540a46 --- /dev/null +++ b/Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/script.js @@ -0,0 +1,2 @@ +var v = new GlideJsonPath('{"lib":{"jsonpath":{"cricket":{"name":"India","players":["Rohit","Dhoni","Kholi"]}}}}'); +var l = v.read("$['lib']['jsonpath']['cricket']['players'][*]"); From 45c645dde25e769504a7857ba941cc06d67d3d8c Mon Sep 17 00:00:00 2001 From: trimbakeshmadhan-109 Date: Tue, 28 Oct 2025 01:51:09 +0530 Subject: [PATCH 06/22] README.md --- .../GlideJsonPath Reader Example/README.md | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/README.md diff --git a/Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/README.md b/Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/README.md new file mode 100644 index 0000000000..1b05e5aa11 --- /dev/null +++ b/Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/README.md @@ -0,0 +1,42 @@ +Parse JSON with GlideJsonPath +This script demonstrates how to use the GlideJsonPath API in ServiceNow to parse a complex JSON string and extract specific data. In this example, it efficiently retrieves an array of player names from a nested JSON structure representing cricket team information. +Overview +The script performs the following actions: +Initializes GlideJsonPath: A new instance of GlideJsonPath is created, passing the target JSON string as a parameter. +Reads data with JSONPath: The read() method is called with a JSONPath expression to extract the desired data. The expression "$['lib']['jsonpath']['cricket']['players'][*]" navigates to the array of players: +$ represents the root of the JSON object. +['lib'], ['jsonpath'], and ['cricket'] use bracket notation to traverse the nested object structure. +['players'] accesses the array of player names. +[*] is a wildcard that returns all elements in the players array. +Stores the result: The extracted array of player names is stored in the l variable. +Use case +This script is useful in scenarios where you need to parse JSON data returned from a REST API call or an integration. By using GlideJsonPath, you can quickly and efficiently extract specific pieces of information without writing complex code to traverse the entire JSON object manually. +How to use +This script is intended for use in a server-side context within ServiceNow, such as a Script Include or Business Rule. +Example: Script Include +javascript +var CricketJsonParser = Class.create(); +CricketJsonParser.prototype = { + initialize: function() { + }, + + getPlayers: function() { + var jsonString = '{"lib":{"jsonpath":{"cricket":{"name":"India","players":["Rohit","Dhoni","Kholi"]}}}}'; + var v = new GlideJsonPath(jsonString); + var playerNames = v.read("$['lib']['jsonpath']['cricket']['players'][*]"); + + // At this point, `playerNames` is a JavaObject array. + // You can log it or process it further. + gs.info("Extracted players: " + JSON.stringify(playerNames)); + + return playerNames; + }, + + type: 'CricketJsonParser' +}; +Use code with caution. + +Customization +JSON Data: Replace the hardcoded jsonString with the variable that holds your JSON data (e.g., the body of a REST response). +JSONPath Expression: Modify the JSONPath expression in the read() method to extract different data from your JSON structure. +Result Handling: The read() function returns a JavaObject array, not a standard JavaScript array. If you need to use JavaScript array methods (like forEach), you may need to convert it. From 3edf0bcc88e628349a36d23e68c7cb30efb057e9 Mon Sep 17 00:00:00 2001 From: trimbakeshmadhan-109 Date: Tue, 28 Oct 2025 01:53:44 +0530 Subject: [PATCH 07/22] Update README.md --- .../GlideJsonPath/GlideJsonPath Reader Example/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/README.md b/Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/README.md index 1b05e5aa11..8106a2c022 100644 --- a/Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/README.md +++ b/Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/README.md @@ -1,5 +1,6 @@ Parse JSON with GlideJsonPath This script demonstrates how to use the GlideJsonPath API in ServiceNow to parse a complex JSON string and extract specific data. In this example, it efficiently retrieves an array of player names from a nested JSON structure representing cricket team information. + Overview The script performs the following actions: Initializes GlideJsonPath: A new instance of GlideJsonPath is created, passing the target JSON string as a parameter. From fa78c36b29ca1af659fe6c8a2d8406b2b3ff63b5 Mon Sep 17 00:00:00 2001 From: trimbakeshmadhan-109 Date: Tue, 28 Oct 2025 02:01:43 +0530 Subject: [PATCH 08/22] script.js Identify inactive users who still have unresolved incidents. This helps with offboarding processes and ensures incidents aren't left unattended. --- .../script.js | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 Core ServiceNow APIs/GlideAggregate/Count Inactive Users with Active incidents/script.js diff --git a/Core ServiceNow APIs/GlideAggregate/Count Inactive Users with Active incidents/script.js b/Core ServiceNow APIs/GlideAggregate/Count Inactive Users with Active incidents/script.js new file mode 100644 index 0000000000..3699d502ce --- /dev/null +++ b/Core ServiceNow APIs/GlideAggregate/Count Inactive Users with Active incidents/script.js @@ -0,0 +1,11 @@ +var ga = new GlideAggregate('incident'); + ga.addQuery('active', true); + ga.addQuery('assigned_to.active', false); + ga.addAggregate('COUNT', 'assigned_to'); + ga.query(); + + while (ga.next()) { + var inactiveUser = ga.assigned_to.getDisplayValue(); + var taskCount = ga.getAggregate('COUNT', 'assigned_to'); + gs.info("Inactive user " + inactiveUser + " has " + IncidentCount + " active tasks."); + } From a6e23bd58ca5f781dffb723dd0d71840d90ec8e0 Mon Sep 17 00:00:00 2001 From: trimbakeshmadhan-109 Date: Tue, 28 Oct 2025 02:03:16 +0530 Subject: [PATCH 09/22] README.md --- .../README.md | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 Core ServiceNow APIs/GlideAggregate/Count Inactive Users with Active incidents/README.md diff --git a/Core ServiceNow APIs/GlideAggregate/Count Inactive Users with Active incidents/README.md b/Core ServiceNow APIs/GlideAggregate/Count Inactive Users with Active incidents/README.md new file mode 100644 index 0000000000..a51d9e2ead --- /dev/null +++ b/Core ServiceNow APIs/GlideAggregate/Count Inactive Users with Active incidents/README.md @@ -0,0 +1,46 @@ +Count Active Incidents Assigned to Inactive Users +This script uses GlideAggregate to efficiently count the number of active incidents assigned to inactive users. This is a crucial task for maintaining data hygiene and preventing incidents from being stalled due to inactive assignees. +Overview +The script performs the following actions: +Initializes GlideAggregate: Creates an aggregate query on the incident table. +Filters Records: Uses addQuery() to restrict the search to incidents that are both active (true) and assigned to a user whose active status is false. This filter uses a "dot-walk" on the assigned_to field to check the user's active status directly within the query. +Aggregates by Count: Uses addAggregate() to count the number of incidents, grouping the results by assigned_to user. +Executes and Logs: Runs the query, then loops through the results. For each inactive user found, it logs their name and the number of active incidents assigned to them. +Use case +This script is essential for regular cleanup and maintenance. It can be used in: +Scheduled Job: Automatically run the script daily or weekly to monitor for and report on incidents assigned to inactive users. +Fix Script: Perform a one-off run to identify and log all current incidents that need reassignment. +Reporting: The output from this script can be used to build a report for managers to track and reassign incidents promptly. +Script +javascript +var ga = new GlideAggregate('incident'); +ga.addQuery('active', true); +ga.addQuery('assigned_to.active', false); +ga.addAggregate('COUNT', 'assigned_to'); +ga.query(); + +while (ga.next()) { + var inactiveUser = ga.assigned_to.getDisplayValue(); + var taskCount = ga.getAggregate('COUNT', 'assigned_to'); + gs.info("Inactive user " + inactiveUser + " has " + taskCount + " active incidents."); +} +Use code with caution. + +Installation +As a Scheduled Job +Navigate to System Definition > Scheduled Jobs. +Click New and select Automatically run a script of your choosing. +Name the job (e.g., Find Incidents Assigned to Inactive Users). +Set your desired frequency and time. +Paste the script into the Run this script field. +Save and activate the job. +As a Fix Script +Navigate to System Definition > Fix Scripts. +Click New. +Name it (e.g., Find Active Incidents with Inactive Assignee). +Paste the script into the Script field. +Run the script to see the results in the System Log. +Customization +Targeted tables: Change the table name from incident to task or any other table with an assigned_to field to check for active records assigned to inactive users. +Automated reassignment: Extend the script to automatically reassign the incidents to a group or another user. This is a common practice to ensure that tickets do not get stuck in the queue. +Email notification: Instead of logging the information, modify the script to send an email notification to the group manager or another stakeholder with the list of incidents needing attention. From 484bcdda3d6c1ebf13870430d9aabd456a2ea3bf Mon Sep 17 00:00:00 2001 From: trimbakeshmadhan-109 Date: Tue, 28 Oct 2025 02:08:11 +0530 Subject: [PATCH 10/22] Update script.js --- .../GlideJsonPath/GlideJsonPath Reader Example/script.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/script.js b/Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/script.js index ddfd540a46..063812aad7 100644 --- a/Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/script.js +++ b/Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/script.js @@ -1,2 +1,3 @@ var v = new GlideJsonPath('{"lib":{"jsonpath":{"cricket":{"name":"India","players":["Rohit","Dhoni","Kholi"]}}}}'); var l = v.read("$['lib']['jsonpath']['cricket']['players'][*]"); + From 12f9ba99ae96f9b0877442212b7e43af784f2e5c Mon Sep 17 00:00:00 2001 From: trimbakeshmadhan-109 Date: Tue, 28 Oct 2025 09:40:15 +0530 Subject: [PATCH 11/22] Delete Core ServiceNow APIs/GlideAggregate/Count Inactive Users with Active incidents/README.md --- .../README.md | 46 ------------------- 1 file changed, 46 deletions(-) delete mode 100644 Core ServiceNow APIs/GlideAggregate/Count Inactive Users with Active incidents/README.md diff --git a/Core ServiceNow APIs/GlideAggregate/Count Inactive Users with Active incidents/README.md b/Core ServiceNow APIs/GlideAggregate/Count Inactive Users with Active incidents/README.md deleted file mode 100644 index a51d9e2ead..0000000000 --- a/Core ServiceNow APIs/GlideAggregate/Count Inactive Users with Active incidents/README.md +++ /dev/null @@ -1,46 +0,0 @@ -Count Active Incidents Assigned to Inactive Users -This script uses GlideAggregate to efficiently count the number of active incidents assigned to inactive users. This is a crucial task for maintaining data hygiene and preventing incidents from being stalled due to inactive assignees. -Overview -The script performs the following actions: -Initializes GlideAggregate: Creates an aggregate query on the incident table. -Filters Records: Uses addQuery() to restrict the search to incidents that are both active (true) and assigned to a user whose active status is false. This filter uses a "dot-walk" on the assigned_to field to check the user's active status directly within the query. -Aggregates by Count: Uses addAggregate() to count the number of incidents, grouping the results by assigned_to user. -Executes and Logs: Runs the query, then loops through the results. For each inactive user found, it logs their name and the number of active incidents assigned to them. -Use case -This script is essential for regular cleanup and maintenance. It can be used in: -Scheduled Job: Automatically run the script daily or weekly to monitor for and report on incidents assigned to inactive users. -Fix Script: Perform a one-off run to identify and log all current incidents that need reassignment. -Reporting: The output from this script can be used to build a report for managers to track and reassign incidents promptly. -Script -javascript -var ga = new GlideAggregate('incident'); -ga.addQuery('active', true); -ga.addQuery('assigned_to.active', false); -ga.addAggregate('COUNT', 'assigned_to'); -ga.query(); - -while (ga.next()) { - var inactiveUser = ga.assigned_to.getDisplayValue(); - var taskCount = ga.getAggregate('COUNT', 'assigned_to'); - gs.info("Inactive user " + inactiveUser + " has " + taskCount + " active incidents."); -} -Use code with caution. - -Installation -As a Scheduled Job -Navigate to System Definition > Scheduled Jobs. -Click New and select Automatically run a script of your choosing. -Name the job (e.g., Find Incidents Assigned to Inactive Users). -Set your desired frequency and time. -Paste the script into the Run this script field. -Save and activate the job. -As a Fix Script -Navigate to System Definition > Fix Scripts. -Click New. -Name it (e.g., Find Active Incidents with Inactive Assignee). -Paste the script into the Script field. -Run the script to see the results in the System Log. -Customization -Targeted tables: Change the table name from incident to task or any other table with an assigned_to field to check for active records assigned to inactive users. -Automated reassignment: Extend the script to automatically reassign the incidents to a group or another user. This is a common practice to ensure that tickets do not get stuck in the queue. -Email notification: Instead of logging the information, modify the script to send an email notification to the group manager or another stakeholder with the list of incidents needing attention. From 23f8bb31260f98bbf604ccc5109e9fb3f9fe96a5 Mon Sep 17 00:00:00 2001 From: trimbakeshmadhan-109 Date: Tue, 28 Oct 2025 09:40:42 +0530 Subject: [PATCH 12/22] Delete Core ServiceNow APIs/GlideAggregate/Count Inactive Users with Active incidents/script.js --- .../script.js | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 Core ServiceNow APIs/GlideAggregate/Count Inactive Users with Active incidents/script.js diff --git a/Core ServiceNow APIs/GlideAggregate/Count Inactive Users with Active incidents/script.js b/Core ServiceNow APIs/GlideAggregate/Count Inactive Users with Active incidents/script.js deleted file mode 100644 index 3699d502ce..0000000000 --- a/Core ServiceNow APIs/GlideAggregate/Count Inactive Users with Active incidents/script.js +++ /dev/null @@ -1,11 +0,0 @@ -var ga = new GlideAggregate('incident'); - ga.addQuery('active', true); - ga.addQuery('assigned_to.active', false); - ga.addAggregate('COUNT', 'assigned_to'); - ga.query(); - - while (ga.next()) { - var inactiveUser = ga.assigned_to.getDisplayValue(); - var taskCount = ga.getAggregate('COUNT', 'assigned_to'); - gs.info("Inactive user " + inactiveUser + " has " + IncidentCount + " active tasks."); - } From 75d8c0b78e00dfe7d871c15dd159e6fbf6798b79 Mon Sep 17 00:00:00 2001 From: trimbakeshmadhan-109 Date: Tue, 28 Oct 2025 09:41:46 +0530 Subject: [PATCH 13/22] Delete Core ServiceNow APIs/GlideAggregate/Find oldest Incident based Assignment Groups/README.md --- .../README.md | 92 ------------------- 1 file changed, 92 deletions(-) delete mode 100644 Core ServiceNow APIs/GlideAggregate/Find oldest Incident based Assignment Groups/README.md diff --git a/Core ServiceNow APIs/GlideAggregate/Find oldest Incident based Assignment Groups/README.md b/Core ServiceNow APIs/GlideAggregate/Find oldest Incident based Assignment Groups/README.md deleted file mode 100644 index 722a45ac02..0000000000 --- a/Core ServiceNow APIs/GlideAggregate/Find oldest Incident based Assignment Groups/README.md +++ /dev/null @@ -1,92 +0,0 @@ -ServiceNow Script: Find Oldest Open Incidents per Group -This script leverages GlideAggregate to efficiently find the oldest active incident for each assignment group. This is a powerful tool for monitoring and reporting on potential service level agreement (SLA) risks and improving incident management processes. -Overview -The script performs the following actions: -Initializes GlideAggregate: Creates an aggregate query on the incident table. -Filters Active Incidents: Uses addActiveQuery() to restrict the search to only open (active) incidents. -Aggregates by Minimum Date: Finds the minimum (MIN) opened_at date, which represents the oldest record. -Groups by Assignment Group: Groups the results by the assignment_group to get a separate result for each team. -Iterates and Logs: Loops through the query results and logs the assignment group and the opening date of its oldest open incident. -How to use -This script is intended to be used in a server-side context within a ServiceNow instance. Common use cases include: -Scheduled Job: Run this script on a regular schedule (e.g., daily) to generate a report on aging incidents. -Script Include: Incorporate the logic into a reusable function within a Script Include, allowing other scripts to call it. -Fix Script: Execute the script as a one-off task to perform an analysis. -Script -javascript -(function findOldestIncidents() { - var ga = new GlideAggregate('incident'); - ga.addActiveQuery(); - ga.addAggregate('MIN', 'opened_at'); - ga.groupBy('assignment_group'); - ga.query(); - - while (ga.next()) { - var group = ga.assignment_group.getDisplayValue(); - var oldestIncidentDate = ga.getAggregate('MIN', 'opened_at'); - gs.info("Oldest open incident for " + group + " was created on: " + oldestIncidentDate); - } -})(); -Use code with caution. - -Installation -As a Scheduled Job -Navigate to System Definition > Scheduled Jobs. -Click New and select Automatically run a script of your choosing. -Name the job (e.g., Find Oldest Open Incidents). -Set your desired frequency and time. -Paste the script into the Run this script field. -Save and activate the job. -As a Script Include -Navigate to System Definition > Script Includes. -Click New. -Name it (e.g., IncidentHelper). -API Name: global.IncidentHelper -Script: -javascript -var IncidentHelper = Class.create(); -IncidentHelper.prototype = { - initialize: function() { - }, - - findOldestIncidents: function() { - var ga = new GlideAggregate('incident'); - ga.addActiveQuery(); - ga.addAggregate('MIN', 'opened_at'); - ga.groupBy('assignment_group'); - ga.query(); - - var results = []; - while (ga.next()) { - var group = ga.assignment_group.getDisplayValue(); - var oldestIncidentDate = ga.getAggregate('MIN', 'opened_at'); - results.push({ - group: group, - oldestIncidentDate: oldestIncidentDate - }); - } - return results; - }, - - type: 'IncidentHelper' -}; -Use code with caution. - -You can then call this function from other scripts. For example: -javascript -var helper = new IncidentHelper(); -var incidents = helper.findOldestIncidents(); -for (var i = 0; i < incidents.length; i++) { - gs.info("Oldest open incident for " + incidents[i].group + " was created on: " + incidents[i].oldestIncidentDate); -} -Use code with caution. - -Customization -Change the output: Modify the gs.info() line to instead write to a custom log, send an email, or create a report. -Refine the query: Add more addQuery() statements to filter incidents by other criteria, such as priority or category. -Change the aggregate: Use MAX instead of MIN to find the newest incident in each group. -Get incident details: To get the actual incident record (e.g., its number), you would need to perform a secondary GlideRecord query based on the aggregated data. -Dependencies -This script uses standard ServiceNow APIs (GlideAggregate, gs). No external libraries are required. -Support -For any questions or issues, please open an issue in this repository. From 4f13513309152f52f807ad918b18ad9cd089bf94 Mon Sep 17 00:00:00 2001 From: trimbakeshmadhan-109 Date: Tue, 28 Oct 2025 09:42:00 +0530 Subject: [PATCH 14/22] Delete Core ServiceNow APIs/GlideAggregate/Find oldest Incident based Assignment Groups/script.js --- .../script.js | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 Core ServiceNow APIs/GlideAggregate/Find oldest Incident based Assignment Groups/script.js diff --git a/Core ServiceNow APIs/GlideAggregate/Find oldest Incident based Assignment Groups/script.js b/Core ServiceNow APIs/GlideAggregate/Find oldest Incident based Assignment Groups/script.js deleted file mode 100644 index 4aabd461b1..0000000000 --- a/Core ServiceNow APIs/GlideAggregate/Find oldest Incident based Assignment Groups/script.js +++ /dev/null @@ -1,11 +0,0 @@ -var ga = new GlideAggregate('incident'); - ga.addActiveQuery(); - ga.addAggregate('MIN', 'opened_at'); - ga.groupBy('assignment_group'); - ga.query(); - - while (ga.next()) { - var group = ga.assignment_group.getDisplayValue(); - var oldestIncidentDate = ga.getAggregate('MIN', 'opened_at'); - gs.info("Oldest open incident for " + group + " was created on: " + oldestIncidentDate); - } From 5328ddaee5e89cd18b04b5b2f8c22b561303b1c4 Mon Sep 17 00:00:00 2001 From: trimbakeshmadhan-109 Date: Tue, 28 Oct 2025 09:42:25 +0530 Subject: [PATCH 15/22] Delete Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/README.md --- .../GlideJsonPath Reader Example/README.md | 43 ------------------- 1 file changed, 43 deletions(-) delete mode 100644 Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/README.md diff --git a/Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/README.md b/Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/README.md deleted file mode 100644 index 8106a2c022..0000000000 --- a/Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/README.md +++ /dev/null @@ -1,43 +0,0 @@ -Parse JSON with GlideJsonPath -This script demonstrates how to use the GlideJsonPath API in ServiceNow to parse a complex JSON string and extract specific data. In this example, it efficiently retrieves an array of player names from a nested JSON structure representing cricket team information. - -Overview -The script performs the following actions: -Initializes GlideJsonPath: A new instance of GlideJsonPath is created, passing the target JSON string as a parameter. -Reads data with JSONPath: The read() method is called with a JSONPath expression to extract the desired data. The expression "$['lib']['jsonpath']['cricket']['players'][*]" navigates to the array of players: -$ represents the root of the JSON object. -['lib'], ['jsonpath'], and ['cricket'] use bracket notation to traverse the nested object structure. -['players'] accesses the array of player names. -[*] is a wildcard that returns all elements in the players array. -Stores the result: The extracted array of player names is stored in the l variable. -Use case -This script is useful in scenarios where you need to parse JSON data returned from a REST API call or an integration. By using GlideJsonPath, you can quickly and efficiently extract specific pieces of information without writing complex code to traverse the entire JSON object manually. -How to use -This script is intended for use in a server-side context within ServiceNow, such as a Script Include or Business Rule. -Example: Script Include -javascript -var CricketJsonParser = Class.create(); -CricketJsonParser.prototype = { - initialize: function() { - }, - - getPlayers: function() { - var jsonString = '{"lib":{"jsonpath":{"cricket":{"name":"India","players":["Rohit","Dhoni","Kholi"]}}}}'; - var v = new GlideJsonPath(jsonString); - var playerNames = v.read("$['lib']['jsonpath']['cricket']['players'][*]"); - - // At this point, `playerNames` is a JavaObject array. - // You can log it or process it further. - gs.info("Extracted players: " + JSON.stringify(playerNames)); - - return playerNames; - }, - - type: 'CricketJsonParser' -}; -Use code with caution. - -Customization -JSON Data: Replace the hardcoded jsonString with the variable that holds your JSON data (e.g., the body of a REST response). -JSONPath Expression: Modify the JSONPath expression in the read() method to extract different data from your JSON structure. -Result Handling: The read() function returns a JavaObject array, not a standard JavaScript array. If you need to use JavaScript array methods (like forEach), you may need to convert it. From 6750b61a4e6fdf4846b562fe97ace4a8607eb8e8 Mon Sep 17 00:00:00 2001 From: trimbakeshmadhan-109 Date: Tue, 28 Oct 2025 09:43:01 +0530 Subject: [PATCH 16/22] Delete Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/script.js --- .../GlideJsonPath/GlideJsonPath Reader Example/script.js | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/script.js diff --git a/Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/script.js b/Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/script.js deleted file mode 100644 index 063812aad7..0000000000 --- a/Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/script.js +++ /dev/null @@ -1,3 +0,0 @@ -var v = new GlideJsonPath('{"lib":{"jsonpath":{"cricket":{"name":"India","players":["Rohit","Dhoni","Kholi"]}}}}'); -var l = v.read("$['lib']['jsonpath']['cricket']['players'][*]"); - From 4e3bdeba150523f310022150c263b1b46671b506 Mon Sep 17 00:00:00 2001 From: trimbakeshmadhan-109 Date: Tue, 28 Oct 2025 12:13:35 +0530 Subject: [PATCH 17/22] GetServiceDeskAgentHelpAIUtil This is a client-callable Script Include designed for the ServiceNow platform that integrates with an external Databricks AI endpoint. Its purpose is to assist Service Desk agents by providing AI-generated responses to user queries, which can be used to populate incident information or assist in troubleshooting. The script acts as a server-side proxy, handling the client-side request, invoking a Flow Designer Action to communicate with the Databricks service, and returning the AI's response to the client. --- .../GetServiceDeskAgentHelpAIUtil | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 Server-Side Components/Script Includes/GetServiceDeskAgentHelpAIUtil diff --git a/Server-Side Components/Script Includes/GetServiceDeskAgentHelpAIUtil b/Server-Side Components/Script Includes/GetServiceDeskAgentHelpAIUtil new file mode 100644 index 0000000000..8d7d1e7942 --- /dev/null +++ b/Server-Side Components/Script Includes/GetServiceDeskAgentHelpAIUtil @@ -0,0 +1,110 @@ +var GetServiceDeskAgentHelpAIUtil = Class.create(); +GetServiceDeskAgentHelpAIutil.prototype = Object.extendsObject(global.AbstractAjaxProcessor, { + + /** + * Main function that processes a search term from a client-side call, + * sends it to a Databricks-powered AI, and returns the response. + * This function is intended to assist Service Desk agents. + * + * @returns {string} A JSON string containing the AI's response, model details, and metrics. + */ + getSearchResults: function() { + // Defines the use case for logging and metric purposes. + var usecase = "ServiceDesk Helper"; + // Gets the current user's Sys ID, though it is not used in the current implementation. + var user = gs.getUserID(); + // Retrieves the search term passed from the client-side script. + var searchText = this.getParameter("sysparm_search_key"); + // Replaces double quotes with single quotes in the search text to prevent JSON parsing issues. + searchText = searchText.replaceAll('"', "'"); + + var searchObj = { + "searchValue": searchText.toString() + }; + + // Extracts the raw search value from the object. + var search = searchObj["searchValue"]; + + // This object is structured to create a prompt for another potential AI endpoint (possibly for a brief statement), + // but it is currently not used. + var brief_statement_payload = { + "messages": [{ + "role": "system", + "content": "You are an Expert ServiceNow bot that helps the users to create an incident" + }, + { + "role": "user", + "content": gs.getProperty('user.prompt') + search + } + ] + }; + + var databricks_model_response = {}; + // Calls the internal method to get the response from the Databricks model. + var response = this.getDataBricksModelResponse(search); + // UNCOMMENT THIS WHEN WE HAVE A PROPER SOLUTION FOR BRIEF RESPONSE GENERATION + // var brief_response = this.getBriefResponse(brief_statement_payload); + // The brief response is hardcoded to an empty JSON object + // Assigns the model response to the output object. + databricks_model_response.modelResponse = response; + // Assigns a hardcoded model ID. + databricks_model_response.model_id = "Databricks Runbook"; + + // Converts the final response object to a JSON string for client-side processing. + databricks_model_response = JSON.stringify(databricks_model_response); + // Logs the final JSON string for debugging purposes. + gs.info("Service Desk Helper Results: Testing value of the final databricks response being sent: " + databricks_model_response); + + // Returns the JSON string to the calling client script. + return databricks_model_response; + }, + + /** + * This function calls the Databricks endpoint via a Flow Designer action + * to generate an answer for the user's query. + * + * @param {string} search - The user's search query. + * @returns {string} A JSON string containing the AI's response, the current date, and a trace ID. + */ + getDataBricksModelResponse: function(search) { + try { + var inputs = {}; + // Maps the search query to the input expected by the flow action. + inputs['search_query'] = search; + + // Executes the specified Flow Designer action with the provided inputs. + // The action is run in the foreground, meaning the script will wait for a response. + var result = sn_fd.FlowAPI.getRunner().action('global.genai_action').inForeground().withInputs(inputs).run(); + // Retrieves the outputs from the completed flow action. + var outputs = result.getOutputs(); + + // Extracts the model output from the flow action outputs. + var model_output = outputs['model_output']; + // Attempts to parse and extract vector response data, though the variable is not used after this line. + var databricks_vector_response = JSON.parse(model_output).databricks_output.trace.data.spans; + + // Logs the raw response from the Databricks model for debugging. + gs.info("Helper Results: Databricks flow action response: " + JSON.stringify(model_output)); + + var current_date = new GlideDateTime(); + var output = {}; + // Parses the model output to extract the AI's content. + output.response = JSON.parse(model_output).choices[0].message.content; + // Adds the current date to the output object. + output.date = current_date.getDisplayValue(); + // Logs the trace ID for tracking purposes. + gs.info("Helper Results: GEN AI flow action TraceID value: " + JSON.parse(model_output).id); + // Adds the trace ID to the output object. + output.traceID = JSON.parse(model_output).id; + // Returns the constructed output object as a JSON string. + return JSON.stringify(output); + + } catch (ex) { + // Catches any exceptions during the flow execution and logs an error. + var message = ex.getMessage(); + gs.error(message); + } + }, + + type: 'GetServiceDeskAgentHelpAIUtil' +}); From b136fd1d7543a79099283b6893bcb2d227dcf00c Mon Sep 17 00:00:00 2001 From: trimbakeshmadhan-109 Date: Tue, 28 Oct 2025 12:16:55 +0530 Subject: [PATCH 18/22] Delete Server-Side Components/Script Includes/GetServiceDeskAgentHelpAIUtil --- .../GetServiceDeskAgentHelpAIUtil | 110 ------------------ 1 file changed, 110 deletions(-) delete mode 100644 Server-Side Components/Script Includes/GetServiceDeskAgentHelpAIUtil diff --git a/Server-Side Components/Script Includes/GetServiceDeskAgentHelpAIUtil b/Server-Side Components/Script Includes/GetServiceDeskAgentHelpAIUtil deleted file mode 100644 index 8d7d1e7942..0000000000 --- a/Server-Side Components/Script Includes/GetServiceDeskAgentHelpAIUtil +++ /dev/null @@ -1,110 +0,0 @@ -var GetServiceDeskAgentHelpAIUtil = Class.create(); -GetServiceDeskAgentHelpAIutil.prototype = Object.extendsObject(global.AbstractAjaxProcessor, { - - /** - * Main function that processes a search term from a client-side call, - * sends it to a Databricks-powered AI, and returns the response. - * This function is intended to assist Service Desk agents. - * - * @returns {string} A JSON string containing the AI's response, model details, and metrics. - */ - getSearchResults: function() { - // Defines the use case for logging and metric purposes. - var usecase = "ServiceDesk Helper"; - // Gets the current user's Sys ID, though it is not used in the current implementation. - var user = gs.getUserID(); - // Retrieves the search term passed from the client-side script. - var searchText = this.getParameter("sysparm_search_key"); - // Replaces double quotes with single quotes in the search text to prevent JSON parsing issues. - searchText = searchText.replaceAll('"', "'"); - - var searchObj = { - "searchValue": searchText.toString() - }; - - // Extracts the raw search value from the object. - var search = searchObj["searchValue"]; - - // This object is structured to create a prompt for another potential AI endpoint (possibly for a brief statement), - // but it is currently not used. - var brief_statement_payload = { - "messages": [{ - "role": "system", - "content": "You are an Expert ServiceNow bot that helps the users to create an incident" - }, - { - "role": "user", - "content": gs.getProperty('user.prompt') + search - } - ] - }; - - var databricks_model_response = {}; - // Calls the internal method to get the response from the Databricks model. - var response = this.getDataBricksModelResponse(search); - // UNCOMMENT THIS WHEN WE HAVE A PROPER SOLUTION FOR BRIEF RESPONSE GENERATION - // var brief_response = this.getBriefResponse(brief_statement_payload); - // The brief response is hardcoded to an empty JSON object - // Assigns the model response to the output object. - databricks_model_response.modelResponse = response; - // Assigns a hardcoded model ID. - databricks_model_response.model_id = "Databricks Runbook"; - - // Converts the final response object to a JSON string for client-side processing. - databricks_model_response = JSON.stringify(databricks_model_response); - // Logs the final JSON string for debugging purposes. - gs.info("Service Desk Helper Results: Testing value of the final databricks response being sent: " + databricks_model_response); - - // Returns the JSON string to the calling client script. - return databricks_model_response; - }, - - /** - * This function calls the Databricks endpoint via a Flow Designer action - * to generate an answer for the user's query. - * - * @param {string} search - The user's search query. - * @returns {string} A JSON string containing the AI's response, the current date, and a trace ID. - */ - getDataBricksModelResponse: function(search) { - try { - var inputs = {}; - // Maps the search query to the input expected by the flow action. - inputs['search_query'] = search; - - // Executes the specified Flow Designer action with the provided inputs. - // The action is run in the foreground, meaning the script will wait for a response. - var result = sn_fd.FlowAPI.getRunner().action('global.genai_action').inForeground().withInputs(inputs).run(); - // Retrieves the outputs from the completed flow action. - var outputs = result.getOutputs(); - - // Extracts the model output from the flow action outputs. - var model_output = outputs['model_output']; - // Attempts to parse and extract vector response data, though the variable is not used after this line. - var databricks_vector_response = JSON.parse(model_output).databricks_output.trace.data.spans; - - // Logs the raw response from the Databricks model for debugging. - gs.info("Helper Results: Databricks flow action response: " + JSON.stringify(model_output)); - - var current_date = new GlideDateTime(); - var output = {}; - // Parses the model output to extract the AI's content. - output.response = JSON.parse(model_output).choices[0].message.content; - // Adds the current date to the output object. - output.date = current_date.getDisplayValue(); - // Logs the trace ID for tracking purposes. - gs.info("Helper Results: GEN AI flow action TraceID value: " + JSON.parse(model_output).id); - // Adds the trace ID to the output object. - output.traceID = JSON.parse(model_output).id; - // Returns the constructed output object as a JSON string. - return JSON.stringify(output); - - } catch (ex) { - // Catches any exceptions during the flow execution and logs an error. - var message = ex.getMessage(); - gs.error(message); - } - }, - - type: 'GetServiceDeskAgentHelpAIUtil' -}); From 45661ee6dcebddecd1c5eebe8dd018500062af4b Mon Sep 17 00:00:00 2001 From: trimbakeshmadhan-109 Date: Tue, 28 Oct 2025 12:20:33 +0530 Subject: [PATCH 19/22] script.js This is a client-callable Script Include designed for the ServiceNow platform that integrates with an external Databricks AI endpoint. Its purpose is to assist Service Desk agents by providing AI-generated responses to user queries, which can be used to populate incident information or assist in troubleshooting. --- .../GetServiceDeskAgentHelpAIUtil/script.js | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 Server-Side Components/Script Includes/GetServiceDeskAgentHelpAIUtil/script.js diff --git a/Server-Side Components/Script Includes/GetServiceDeskAgentHelpAIUtil/script.js b/Server-Side Components/Script Includes/GetServiceDeskAgentHelpAIUtil/script.js new file mode 100644 index 0000000000..4bbc5f5800 --- /dev/null +++ b/Server-Side Components/Script Includes/GetServiceDeskAgentHelpAIUtil/script.js @@ -0,0 +1,110 @@ +var GetServiceDeskAgentHelpAIUtil = Class.create(); +GetServiceDeskAgentHelpAIUtil.prototype = Object.extendsObject(global.AbstractAjaxProcessor, { + + /** + * Main function that processes a search term from a client-side call, + * sends it to a Databricks-powered AI, and returns the response. + * This function is intended to assist Service Desk agents. + * + * @returns {string} A JSON string containing the AI's response, model details, and metrics. + */ + getSearchResults: function() { + // Defines the use case for logging and metric purposes. + var usecase = "ServiceDesk Helper"; + // Gets the current user's Sys ID, though it is not used in the current implementation. + var user = gs.getUserID(); + // Retrieves the search term passed from the client-side script. + var searchText = this.getParameter("sysparm_search_key"); + // Replaces double quotes with single quotes in the search text to prevent JSON parsing issues. + searchText = searchText.replaceAll('"', "'"); + + var searchObj = { + "searchValue": searchText.toString() + }; + + // Extracts the raw search value from the object. + var search = searchObj["searchValue"]; + + // This object is structured to create a prompt for another potential AI endpoint (possibly for a brief statement), + // but it is currently not used. + var brief_statement_payload = { + "messages": [{ + "role": "system", + "content": "You are an Expert ServiceNow bot that helps the users to create an incident" + }, + { + "role": "user", + "content": gs.getProperty('user.prompt') + search + } + ] + }; + + var databricks_model_response = {}; + // Calls the internal method to get the response from the Databricks model. + var response = this.getDataBricksModelResponse(search); + // UNCOMMENT THIS WHEN WE HAVE A PROPER SOLUTION FOR BRIEF RESPONSE GENERATION + // var brief_response = this.getBriefResponse(brief_statement_payload); + // The brief response is hardcoded to an empty JSON object + // Assigns the model response to the output object. + databricks_model_response.modelResponse = response; + // Assigns a hardcoded model ID. + databricks_model_response.model_id = "Databricks Runbook"; + + // Converts the final response object to a JSON string for client-side processing. + databricks_model_response = JSON.stringify(databricks_model_response); + // Logs the final JSON string for debugging purposes. + gs.info("Service Desk Helper Results: Testing value of the final databricks response being sent: " + databricks_model_response); + + // Returns the JSON string to the calling client script. + return databricks_model_response; + }, + + /** + * This function calls the Databricks endpoint via a Flow Designer action + * to generate an answer for the user's query. + * + * @param {string} search - The user's search query. + * @returns {string} A JSON string containing the AI's response, the current date, and a trace ID. + */ + getDataBricksModelResponse: function(search) { + try { + var inputs = {}; + // Maps the search query to the input expected by the flow action. + inputs['search_query'] = search; + + // Executes the specified Flow Designer action with the provided inputs. + // The action is run in the foreground, meaning the script will wait for a response. + var result = sn_fd.FlowAPI.getRunner().action('global.genai_action').inForeground().withInputs(inputs).run(); + // Retrieves the outputs from the completed flow action. + var outputs = result.getOutputs(); + + // Extracts the model output from the flow action outputs. + var model_output = outputs['model_output']; + // Attempts to parse and extract vector response data, though the variable is not used after this line. + var databricks_vector_response = JSON.parse(model_output).databricks_output.trace.data.spans; + + // Logs the raw response from the Databricks model for debugging. + gs.info("Helper Results: Databricks flow action response: " + JSON.stringify(model_output)); + + var current_date = new GlideDateTime(); + var output = {}; + // Parses the model output to extract the AI's content. + output.response = JSON.parse(model_output).choices[0].message.content; + // Adds the current date to the output object. + output.date = current_date.getDisplayValue(); + // Logs the trace ID for tracking purposes. + gs.info("Helper Results: GEN AI flow action TraceID value: " + JSON.parse(model_output).id); + // Adds the trace ID to the output object. + output.traceID = JSON.parse(model_output).id; + // Returns the constructed output object as a JSON string. + return JSON.stringify(output); + + } catch (ex) { + // Catches any exceptions during the flow execution and logs an error. + var message = ex.getMessage(); + gs.error(message); + } + }, + + type: 'GetServiceDeskAgentHelpAIUtil' +}); From 5f236795baf124db903365999251d342ef7b682f Mon Sep 17 00:00:00 2001 From: trimbakeshmadhan-109 Date: Tue, 28 Oct 2025 12:21:19 +0530 Subject: [PATCH 20/22] Create README.md --- .../GetServiceDeskAgentHelpAIUtil/README.md | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 Server-Side Components/Script Includes/GetServiceDeskAgentHelpAIUtil/README.md diff --git a/Server-Side Components/Script Includes/GetServiceDeskAgentHelpAIUtil/README.md b/Server-Side Components/Script Includes/GetServiceDeskAgentHelpAIUtil/README.md new file mode 100644 index 0000000000..6c41110b51 --- /dev/null +++ b/Server-Side Components/Script Includes/GetServiceDeskAgentHelpAIUtil/README.md @@ -0,0 +1,68 @@ +GetServiceDeskAgentHelpAIUtil +Overview +This is a client-callable Script Include designed for the ServiceNow platform that integrates with an external Databricks AI endpoint. Its purpose is to assist Service Desk agents by providing AI-generated responses to user queries, which can be used to populate incident information or assist in troubleshooting. +The script acts as a server-side proxy, handling the client-side request, invoking a Flow Designer Action to communicate with the Databricks service, and returning the AI's response to the client. +Features +AI-Powered Responses: Sends user search queries to a Databricks-powered Generative AI model to get intelligent answers. +Client-Callable: Can be invoked from client-side scripts (e.g., a UI Action or Client Script) using GlideAjax. +Flow Designer Integration: Uses a Flow Designer Action to execute the REST call to the Databricks endpoint, centralizing the external API logic. +Structured Output: Returns a JSON object containing the AI's response, model metadata, and a trace ID for debugging. +Prerequisites +ServiceNow Configuration +Flow Designer Action: A Flow Designer Action named global.genai_action must be created and configured to handle the REST call to the Databricks AI endpoint. This action must have: +An input named search_query (String). +An output named model_output (String). +Databricks Connection: The Flow Designer Action must be correctly configured with the necessary credentials to connect to the external Databricks API. +System Property: A system property named user.prompt is referenced in the script. It should be created and configured with the required prompt text for the AI. +How to use +1. Calling from a Client Script +You can use GlideAjax to call the getSearchResults function from a client-side script, such as a UI Action or a Catalog Client Script. +javascript +// Example client-side script using GlideAjax +var ga = new GlideAjax('GetServiceDeskAgentHelpAIUtil'); +ga.addParam('sysparm_name', 'getSearchResults'); +ga.addParam('sysparm_search_key', g_form.getValue('short_description')); // Pass the user's input +ga.getXML(getResponse); + +function getResponse(response) { + var answer = response.responseXML.documentElement.getAttribute("answer"); + if (answer) { + var result = JSON.parse(answer); + g_form.setValue('comments', result.modelResponse); // Set the AI response in a field + } +} +Use code with caution. + +2. Using from a Server Script +The functions can also be called directly from other server-side scripts (e.g., Business Rules). +javascript +// Example server-side script +var searchKey = 'What are the steps to reset my password?'; +var aiUtil = new GetServiceDeskAgentHelpAIUtil(); +var response = aiUtil.getSearchResults(searchKey); + +gs.info(response); +Use code with caution. + +Script details +getSearchResults() +This is the main function that coordinates the process. +Retrieves the search term from the client parameters. +Calls the getDataBricksModelResponse() function to get the AI-generated answer. +Constructs a JSON object with the AI's response and model information. +Returns the JSON object as a string. +getDataBricksModelResponse(search) +This function handles the integration with the Databricks AI. +Takes the search query as a parameter. +Executes the global.genai_action Flow Designer Action. +Parses the model_output from the Flow Action's outputs. +Extracts the AI's message content and a trace ID for debugging. +Returns a stringified JSON object containing the AI's response, date, and trace ID. +Includes a try/catch block to handle and log potential errors during the integration process. +Dependencies +Flow Designer Action: global.genai_action +System Property: user.prompt +Troubleshooting +Check the Flow Execution: If the AI response is not received, check the Flow Designer execution logs to ensure global.genai_action is running successfully and the REST call to Databricks is returning a valid response. +Review System Logs: Examine the System Logs (gs.info and gs.error messages) for debugging information related to the script's execution or potential errors from the Databricks API. +Verify Databricks Credentials: Ensure that the credentials and configuration within the Flow Designer action for connecting to Databricks are correct. From 048b3e542be3b96f3fcf39378a0ecc001f1eed85 Mon Sep 17 00:00:00 2001 From: trimbakeshmadhan-109 Date: Tue, 28 Oct 2025 12:25:57 +0530 Subject: [PATCH 21/22] Delete Core ServiceNow APIs/GlideAggregate/Create Problem based on incident volume/README.md --- .../README.md | 37 ------------------- 1 file changed, 37 deletions(-) delete mode 100644 Core ServiceNow APIs/GlideAggregate/Create Problem based on incident volume/README.md diff --git a/Core ServiceNow APIs/GlideAggregate/Create Problem based on incident volume/README.md b/Core ServiceNow APIs/GlideAggregate/Create Problem based on incident volume/README.md deleted file mode 100644 index 6f7afc5eac..0000000000 --- a/Core ServiceNow APIs/GlideAggregate/Create Problem based on incident volume/README.md +++ /dev/null @@ -1,37 +0,0 @@ -Key features -Automatic problem creation: The script uses a GlideAggregate query to count the number of incidents opened for a specific CI. -Time-based threshold: Problems are only created if more than five incidents are opened within a 60-minute window. -Targeted incidents: The script focuses on incidents related to the same CI, making it effective for identifying recurring infrastructure issues. -Customizable conditions: The number of incidents and the time frame are easily configurable within the script. -Efficient performance: The use of GlideAggregate ensures the database is queried efficiently, minimizing performance impact. - -How it works -The script is designed to be executed as a server-side script, typically within a Business Rule. When an incident is inserted or updated, the script performs the following actions: -Queries incidents: It executes a GlideAggregate query on the incident table. -Sets conditions: The query is filtered to count all incidents that meet the following conditions: -Same CI: The incident's cmdb_ci matches the cmdb_ci of the current record. -Within the last hour: The opened_at time is within the last 60 minutes. -Evaluates count: After the query is run, the script checks if the count of matching incidents exceeds the threshold (in this case, 5). -Creates problem: If the threshold is exceeded, a new problem record is initialized. -The short_description is automatically populated with a descriptive message. -The cmdb_ci is linked to the new problem record. -The new record is then inserted into the database. -Implementation steps -Create a Business Rule: -Navigate to System Definition > Business Rules. -Click New. -Configure the Business Rule: -Name: Auto Create Problem from Multiple Incidents -Table: Incident [incident] -Advanced: true -When to run: Select after and check the Insert and Update checkboxes. This ensures the script runs after an incident has been saved. -Filter conditions: Optionally, you can add conditions to limit when the script runs (e.g., cmdb_ci is not empty). -Add the script: -Navigate to the Advanced tab. -Copy and paste the script into the Script field. -Customize (optional): -Number of incidents: Change the > 5 value to adjust the threshold. -Time frame: Adjust the gs.minutesAgoStart(60) value to change the time window. -Other conditions: If you need to check for specific incident statuses or categories, add more addQuery lines to the GlideAggregate call. -Save the Business Rule. -Customization examples From e99991cd091102c74692fc458ee2f3c539b861b4 Mon Sep 17 00:00:00 2001 From: trimbakeshmadhan-109 Date: Tue, 28 Oct 2025 12:26:18 +0530 Subject: [PATCH 22/22] Delete Core ServiceNow APIs/GlideAggregate/Create Problem based on incident volume/script.js --- .../script.js | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 Core ServiceNow APIs/GlideAggregate/Create Problem based on incident volume/script.js diff --git a/Core ServiceNow APIs/GlideAggregate/Create Problem based on incident volume/script.js b/Core ServiceNow APIs/GlideAggregate/Create Problem based on incident volume/script.js deleted file mode 100644 index dcec063918..0000000000 --- a/Core ServiceNow APIs/GlideAggregate/Create Problem based on incident volume/script.js +++ /dev/null @@ -1,13 +0,0 @@ -var incidentCheck = new GlideAggregate('incident'); - incidentCheck.addQuery('cmdb_ci', current.cmdb_ci); // Or any specific CI - incidentCheck.addQuery('opened_at', '>', 'javascript:gs.minutesAgoStart(60)'); - incidentCheck.addAggregate('COUNT'); - incidentCheck.query(); - - if (incidentCheck.next() && parseInt(incidentCheck.getAggregate('COUNT')) > 5) { - var problem = new GlideRecord('problem'); - problem.initialize(); - problem.short_description = 'Multiple incidents reported for CI: ' + current.cmdb_ci.getDisplayValue(); - problem.cmdb_ci = current.cmdb_ci; - problem.insert(); - }