From 03924e3051b48f9102ff8e105f6876e60cc28862 Mon Sep 17 00:00:00 2001 From: Indra-kolge <123245160+Indra-kolge@users.noreply.github.com> Date: Sun, 19 Oct 2025 01:01:39 +0530 Subject: [PATCH 1/3] Add daily summary email script for incidents --- .../Daily Summary Email/script.js | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 Server-Side Components/Scheduled Jobs/Daily Summary Email/script.js diff --git a/Server-Side Components/Scheduled Jobs/Daily Summary Email/script.js b/Server-Side Components/Scheduled Jobs/Daily Summary Email/script.js new file mode 100644 index 0000000000..6dfe35a169 --- /dev/null +++ b/Server-Side Components/Scheduled Jobs/Daily Summary Email/script.js @@ -0,0 +1,98 @@ +(function() { + var groupName = 'Incident Management'; + var emailFrom = 'no-reply@yourcompany.com'; + var emailSubject = 'ServiceNow Daily Summary'; + + var todayStart = new GlideDateTime(); + todayStart.setDisplayValue(gs.beginningOfToday()); + + var dayAgo = new GlideDateTime(); + dayAgo.addDaysUTC(-1); + + // Open Incidents (not closed) + var grOpenInc = new GlideAggregate('incident'); + grOpenInc.addAggregate('COUNT'); + grOpenInc.addQuery('state', '!=', '7'); + grOpenInc.query(); + grOpenInc.next(); + var openIncidents = grOpenInc.getAggregate('COUNT'); + + // Pending Approvals + var grApprovals = new GlideAggregate('sysapproval_approver'); + grApprovals.addAggregate('COUNT'); + grApprovals.addQuery('state', 'requested'); + grApprovals.query(); + grApprovals.next(); + var pendingApprovals = grApprovals.getAggregate('COUNT'); + + // SLAs Breached Today + var grSLA = new GlideAggregate('task_sla'); + grSLA.addAggregate('COUNT'); + grSLA.addQuery('breach_time', '>=', todayStart); + grSLA.addQuery('stage', 'breached'); + grSLA.query(); + grSLA.next(); + var breachedSLAs = grSLA.getAggregate('COUNT'); + + // High Priority Incidents (P1 & P2 open) + var grHighPri = new GlideAggregate('incident'); + grHighPri.addAggregate('COUNT'); + grHighPri.addQuery('priority', 'IN', '1,2'); + grHighPri.addQuery('state', '!=', '7'); + grHighPri.query(); + grHighPri.next(); + var highPriorityOpen = grHighPri.getAggregate('COUNT'); + + // Incidents unassigned > 24 hours + var grUnassigned = new GlideAggregate('incident'); + grUnassigned.addAggregate('COUNT'); + grUnassigned.addQuery('assigned_to', 'ISEMPTY'); + grUnassigned.addQuery('opened_at', '<=', dayAgo); + grUnassigned.addQuery('state', '!=', '7'); + grUnassigned.query(); + grUnassigned.next(); + var unassignedOld = grUnassigned.getAggregate('COUNT'); + + var emailBody = ''; + emailBody += ' *ServiceNow Daily Summary (' + gs.nowDate() + ')*\n\n'; + emailBody += '• Open Incidents: ' + openIncidents + '\n'; + emailBody += '• Pending Approvals: ' + pendingApprovals + '\n'; + emailBody += '• SLAs Breached Today: ' + breachedSLAs + '\n'; + emailBody += '• High Priority Incidents (P1/P2): ' + highPriorityOpen + '\n'; + emailBody += '• Unassigned Incidents > 24h: ' + unassignedOld + '\n'; + emailBody += '\n'; + var recipients = []; + + var group = new GlideRecord('sys_user_group'); + if (group.get('name', groupName)) { + var m2m = new GlideRecord('sys_user_grmember'); + m2m.addQuery('group', group.sys_id); + m2m.query(); + while (m2m.next()) { + var user = m2m.user.getRefRecord(); + if (user.active && user.email) { + recipients.push(user.email.toString()); + } + } + } else { + gs.error('Group "' + groupName + '" not found. No emails sent.'); + return; + } + + if (recipients.length === 0) { + gs.info('No active users with email found in group "' + groupName + '". No emails sent.'); + return; + } + + for (var i = 0; i < recipients.length; i++) { + var email = new GlideRecord('sys_email'); + email.initialize(); + email.type = 'send-ready'; + email.recipients = recipients[i]; + email.from = emailFrom; + email.subject = emailSubject; + email.body = emailBody; + email.insert(); + } + +})(); From f51f2b8b8dd13cd8fed5c523fca7cf3353ecd499 Mon Sep 17 00:00:00 2001 From: Indra-kolge <123245160+Indra-kolge@users.noreply.github.com> Date: Sun, 19 Oct 2025 01:03:02 +0530 Subject: [PATCH 2/3] README.md This README provides details on the daily summary email job, including its use case, recipients, and purpose. --- .../Scheduled Jobs/Daily Summary Email/README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 Server-Side Components/Scheduled Jobs/Daily Summary Email/README.md diff --git a/Server-Side Components/Scheduled Jobs/Daily Summary Email/README.md b/Server-Side Components/Scheduled Jobs/Daily Summary Email/README.md new file mode 100644 index 0000000000..4b0d09de36 --- /dev/null +++ b/Server-Side Components/Scheduled Jobs/Daily Summary Email/README.md @@ -0,0 +1,13 @@ +Use Case: Daily Summary Notification Email +This scheduled job sends a daily email to a specific IT group with a quick summary of important IT service metrics, including: +Number of open incidents +Pending approvals +SLAs breached today +High priority incidents (P1/P2) +Incidents unassigned for more than 24 hours + +Who receives it? +Active members of a designated ServiceNow group (like Incident Management or IT Operations). + +Why? +To give IT teams and managers daily visibility into workload, critical issues, and bottlenecks so they can act quickly and keep service running smoothly. From 2abb969d1efc5ef99be3d78e4df037160ef60699 Mon Sep 17 00:00:00 2001 From: Carlos Camacho <56931121+kmxo@users.noreply.github.com> Date: Sat, 18 Oct 2025 20:02:07 -0300 Subject: [PATCH 3/3] Update script.js Fixing Breach Time field name --- .../Scheduled Jobs/Daily Summary Email/script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Server-Side Components/Scheduled Jobs/Daily Summary Email/script.js b/Server-Side Components/Scheduled Jobs/Daily Summary Email/script.js index 6dfe35a169..50e0566ae7 100644 --- a/Server-Side Components/Scheduled Jobs/Daily Summary Email/script.js +++ b/Server-Side Components/Scheduled Jobs/Daily Summary Email/script.js @@ -28,7 +28,7 @@ // SLAs Breached Today var grSLA = new GlideAggregate('task_sla'); grSLA.addAggregate('COUNT'); - grSLA.addQuery('breach_time', '>=', todayStart); + grSLA.addQuery('planned_end_time', '>=', todayStart); //Breach time is the field Label grSLA.addQuery('stage', 'breached'); grSLA.query(); grSLA.next();