notifications
Skill41 starsChanged 6 days agoApache-2.0View on GitHub
Complete guide to email notification development including events, templates, mail scripts, and delivery troubleshooting
We split this skill into the rules it gives an agent
14 rules. 0 are common, 13 are distinctive, and 1 is very specific to this project.
0
Common
Most of the 8 edited versions we read keep these.
13
Distinctive
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 41
When to use: When building automated notifications for record changes, approvals, SLA breaches, workflow activities, or custom business …
- Distinctive: line 103
Before creating notifications, understand available events.
- Distinctive: line 133
If no existing event matches your needs, create a custom event.
- Distinctive: line 825
Symptom: No email generated after record change
- Distinctive: line 859
Check user notification preferences:
- Very specific: line 877
Solution: Check the error field in sys_email record for specific error message.
- Distinctive: line 887
Solution: Verify field exists:
- Distinctive: line 918
Use Events: Prefer event-based over direct notifications for decoupling
- Distinctive: line 919
Template Reuse: Create templates for consistent formatting across notifications
- Distinctive: line 920
Test in Sub-Production: Always test notifications in dev/test first
- Distinctive: line 923
Business Hours: Consider time zones and business hours for non-critical alerts
- Distinctive: line 925
Avoid Spam: Use digest for high-frequency events
- Distinctive: line 926
Watermarks: Keep watermarks enabled to prevent duplicate notifications
- Distinctive: line 927
Document Events: Add descriptions to custom events for maintainability
“Common” is measured: kept by at least 6 in 10 of the 8 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Email Notification Development
Overview
This skill covers the complete process of creating and managing ServiceNow email notifications:
- Understanding notification types (event-based vs direct)
- Creating email notifications with proper triggers
- Building email templates with dynamic content
- Writing mail scripts for advanced recipient logic
- Configuring SMS and push notifications
- Troubleshooting delivery issues
When to use: When building automated notifications for record changes, approvals, SLA breaches, workflow activities, or custom business events.
Prerequisites
- Roles:
admin,notification_admin, oritil(for viewing) - Access: sysevent_email_action, sysevent_email_template, sys_script_email tables
- Knowledge: GlideRecord basics, email concepts, event registry
- Related Skills: Complete
admin/workflow-creationfor workflow-triggered notifications
Notification Architecture
Core Tables
sysevent_register (Event Registry)
|
+-- sysevent_email_action (Email Notifications)
|
+-- sysevent_email_template (Email Templates)
+-- sys_script_email (Mail Scripts)
+-- cmn_notif_message (Notification Messages)Notification Types
| Type | Trigger | Use Case |
| Event-based | System/custom events | Standard approach - decoupled, reusable |
| Direct | Record conditions | Quick setup - tightly coupled to conditions |
| Workflow | Workflow activity | Part of workflow orchestration |
| Script | GlideEmailOutbound | Programmatic - full control |
Key Tables Reference
| Table | Purpose |
| sysevent_email_action | Email notification definitions |
| sysevent_email_template | Email body templates |
| sysevent_register | Event definitions |
| sys_script_email | Mail scripts for recipients |
| sys_email | Email log (sent/failed) |
| cmn_notif_message | Notification message store |
| cmn_notif_device | User notification devices |
Procedure
Step 1: Understand Event-Based vs Direct Notifications
Event-Based Notifications (Recommended):
- Triggered by events (e.g.,
incident.assigned,change.approval.rejected) - Decoupled from business rules
- Can have multiple notifications per event
- Better for complex, reusable notification logic
Direct Notifications:
- Triggered directly by record conditions
- Simpler to set up
- Tightly coupled to specific conditions
- Good for one-off notifications
Step 2: Query Existing Events
Before creating notifications, understand available events.
Query Event Registry:
Tool: SN-Query-Table
Parameters:
table_name: sysevent_register
query: table=incident
fields: sys_id,event_name,table,description,fired_by
limit: 50Common System Events:
| Event | Table | Trigger |
| incident.assigned | incident | Incident assigned to user/group |
| incident.commented | incident | Comment added |
| incident.resolved | incident | Incident resolved |
| incident.reopened | incident | Incident reopened |
| change.approval.rejected | change_request | Change approval rejected |
| change.itil.approval.rejected | change_request | ITIL change rejected |
| sc_request.approved | sc_request | Request approved |
| sla.warning | task_sla | SLA warning threshold |
| sla.breached | task_sla | SLA breached |
| approval.inserted | sysapproval_approver | Approval record created |
| task.assigned | task | Task assigned |
Step 3: Create Custom Event (Optional)
If no existing event matches your needs, create a custom event.
Create Event Registration:
Tool: SN-Create-Record
Parameters:
table_name: sysevent_register
data:
event_name: "x_custom.incident.escalated"
table: "incident"
description: "Fired when incident is escalated to management"
fired_by: "Business Rule: Incident Escalation"Fire Event from Business Rule:
// In business rule script
if (current.escalation.changes() && current.escalation > 0) {
gs.eventQueue('x_custom.incident.escalated', current, current.assigned_to, current.assignment_group);
}Fire Event via Background Script:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var inc = new GlideRecord('incident');
inc.get('number', 'INC0010001');
if (inc.isValidRecord()) {
gs.eventQueue('x_custom.incident.escalated', inc, inc.assigned_to.toString(), inc.assignment_group.toString());
gs.info('Event fired for: ' + inc.number);
}
description: "Fire custom escalation event for testing"Step 4: Create Email Notification
Basic Event-Based Notification:
Tool: SN-Create-Record
Parameters:
table_name: sysevent_email_action
data:
name: "Incident Escalation Alert"
event_name: "x_custom.incident.escalated"
sys_domain: "global"
collection: "incident"
active: true
# Subject
subject: "URGENT: Incident ${number} Escalated - ${short_description}"
# Recipients
send_to_event_creator: false
recipient_users: [user_sys_id] # Specific users
recipient_groups: [group_sys_id] # Groups
send_to_event_parm_1: true # gs.eventQueue parm1 (assigned_to)
send_to_event_parm_2: true # gs.eventQueue parm2 (assignment_group)
# Content
content_type: "text/html"
message_html: |
<html>
<body>
<h2>Incident Escalated</h2>
<p>The following incident has been escalated and requires immediate attention:</p>
<table border="1" cellpadding="5">
<tr><td><b>Number:</b></td><td>${number}</td></tr>
<tr><td><b>Priority:</b></td><td>${priority}</td></tr>
<tr><td><b>Description:</b></td><td>${short_description}</td></tr>
<tr><td><b>Assigned To:</b></td><td>${assigned_to}</td></tr>
<tr><td><b>Assignment Group:</b></td><td>${assignment_group}</td></tr>
<tr><td><b>Escalation Level:</b></td><td>${escalation}</td></tr>
</table>
<p><a href="${URI_REF}">View Incident</a></p>
</body>
</html>Direct (Condition-Based) Notification:
Tool: SN-Create-Record
Parameters:
table_name: sysevent_email_action
data:
name: "High Priority Incident Created"
# No event_name - uses conditions instead
sys_domain: "global"
collection: "incident"
action_insert: true
action_update: false
action_delete: false
condition: "priority=1^state=1" # P1, New state
active: true
subject: "P1 Incident Created: ${number}"
send_to_event_parm_1: true
content_type: "text/html"
message_html: |
<h2>Priority 1 Incident Created</h2>
<p>A new Priority 1 incident requires immediate attention.</p>
<p><b>Number:</b> ${number}</p>
<p><b>Description:</b> ${short_description}</p>
<p><a href="${URI_REF}">View Incident</a></p>Step 5: Configure Recipients
Recipient Options in sysevent_email_action:
| Field | Purpose |
recipient_users | Specific user sys_ids (comma-separated) |
recipient_groups | Group sys_ids - emails all members |
send_to_event_creator | User who triggered event |
send_to_event_parm_1 | First parameter from gs.eventQueue |
send_to_event_parm_2 | Second parameter from gs.eventQueue |
recipient_fields | Record field containing user reference |
send_self | Send to user who made change |
exclude_delegates | Skip delegate users |
email_template | Reference to reusable template |
Field-Based Recipients:
Tool: SN-Update-Record
Parameters:
table_name: sysevent_email_action
sys_id: [notification_sys_id]
data:
recipient_fields: "assigned_to,opened_by,caller_id" # Comma-separated fieldsGroup Recipients:
Tool: SN-Update-Record
Parameters:
table_name: sysevent_email_action
sys_id: [notification_sys_id]
data:
recipient_groups: [group1_sys_id],[group2_sys_id]Step 6: Create Mail Script for Dynamic Recipients
Mail scripts allow complex recipient logic beyond simple field references.
Create Mail Script:
Tool: SN-Create-Record
Parameters:
table_name: sys_script_email
data:
name: "Get On-Call Manager"
description: "Returns the on-call manager for the assignment group"
script: |
// Mail script to find on-call manager
// 'current' is the record, 'email' is the GlideEmailOutbound object
(function runMailScript(current, template, email, email_action, event) {
// Get on-call rotation for assignment group
var oncall = new GlideRecord('on_call_rotation');
oncall.addQuery('group', current.assignment_group);
oncall.addQuery('active', true);
oncall.query();
if (oncall.next()) {
// Add on-call user as recipient
var user = new GlideRecord('sys_user');
user.get(oncall.user);
if (user.isValidRecord() && user.email) {
email.addAddress('to', user.email, user.name);
gs.info('Mail script: Added recipient ' + user.email);
}
}
// Optionally add escalation manager
if (current.escalation > 1) {
var manager = current.assignment_group.manager;
if (manager && manager.email) {
email.addAddress('cc', manager.email, manager.name);
}
}
})(current, template, email, email_action, event);Associate Mail Script with Notification:
Tool: SN-Update-Record
Parameters:
table_name: sysevent_email_action
sys_id: [notification_sys_id]
data:
sys_script_mail: [mail_script_sys_id]Advanced Mail Script - Manager Hierarchy:
Tool: SN-Create-Record
Parameters:
table_name: sys_script_email
data:
name: "Get Manager Chain"
description: "Adds manager hierarchy up to specified levels"
script: |
(function runMailScript(current, template, email, email_action, event) {
var MAX_LEVELS = 3;
var userId = current.assigned_to.toString();
for (var level = 0; level < MAX_LEVELS && userId; level++) {
var user = new GlideRecord('sys_user');
user.get(userId);
if (user.isValidRecord() && user.manager) {
var manager = new GlideRecord('sys_user');
manager.get(user.manager);
if (manager.isValidRecord() && manager.email) {
email.addAddress('cc', manager.email, manager.name);
userId = manager.sys_id.toString();
} else {
break;
}
} else {
break;
}
}
})(current, template, email, email_action, event);Step 7: Create Email Template
Email templates allow reusable HTML/text formatting.
Create Email Template:
Tool: SN-Create-Record
Parameters:
table_name: sysevent_email_template
data:
name: "Incident Alert Template"
description: "Standard template for incident notifications"
subject: "${number}: ${short_description}"
message_html: |
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: Arial, sans-serif; }
.header { background-color: #1a73e8; color: white; padding: 20px; }
.content { padding: 20px; }
.details { border-collapse: collapse; width: 100%; }
.details td { border: 1px solid #ddd; padding: 10px; }
.label { background-color: #f5f5f5; font-weight: bold; width: 30%; }
.footer { background-color: #f5f5f5; padding: 15px; font-size: 12px; }
.button { background-color: #1a73e8; color: white; padding: 10px 20px; text-decoration: none; border-radius: 4px; }
</style>
</head>
<body>
<div class="header">
<h1>Incident Alert</h1>
</div>
<div class="content">
<p>An incident requires your attention:</p>
<table class="details">
<tr>
<td class="label">Number</td>
<td>${number}</td>
</tr>
<tr>
<td class="label">Priority</td>
<td>${priority}</td>
</tr>
<tr>
<td class="label">State</td>
<td>${state}</td>
</tr>
<tr>
<td class="label">Description</td>
<td>${short_description}</td>
</tr>
<tr>
<td class="label">Assigned To</td>
<td>${assigned_to}</td>
</tr>
<tr>
<td class="label">Assignment Group</td>
<td>${assignment_group}</td>
</tr>
<tr>
<td class="label">Opened</td>
<td>${opened_at}</td>
</tr>
</table>
<p style="margin-top: 20px;">
<a href="${URI_REF}" class="button">View Incident</a>
</p>
</div>
<div class="footer">
<p>This is an automated notification from ServiceNow.</p>
<p>Do not reply to this email.</p>
</div>
</body>
</html>
message: |
Incident Alert
Number: ${number}
Priority: ${priority}
State: ${state}
Description: ${short_description}
Assigned To: ${assigned_to}
Assignment Group: ${assignment_group}
View Incident: ${URI_REF}
This is an automated notification.
collection: "incident"Associate Template with Notification:
Tool: SN-Update-Record
Parameters:
table_name: sysevent_email_action
sys_id: [notification_sys_id]
data:
email_template: [template_sys_id]
# Clear inline content if using template
message_html: ""
message: ""Step 8: Email Variable Syntax
Standard Field Variables:
${field_name} - Display value of field
${field_name.name} - Reference field's name
${field_name.email} - Reference field's email
${field_name.sys_id} - Reference field's sys_id
${number} - Incident number
${short_description} - Short description
${priority} - Priority display value
${state} - State display valueSpecial Variables:
${URI} - Record URI path only
${URI_REF} - Full URL to record
${mailto:email} - Mailto link
${event.parm1} - First event parameter
${event.parm2} - Second event parameter
${current} - Current record reference
${gs.getProperty('name')} - System property valueConditional Content (Mail Script Required):
// In notification body script or template script
if (current.priority == 1) {
template.print('<span style="color: red; font-weight: bold;">CRITICAL</span>');
} else {
template.print('<span>' + current.priority.getDisplayValue() + '</span>');
}Iterating Over Related Records:
// Show related tasks in notification
template.print('<h3>Related Tasks:</h3>');
template.print('<ul>');
var tasks = new GlideRecord('sc_task');
tasks.addQuery('request_item', current.sys_id);
tasks.query();
while (tasks.next()) {
template.print('<li>' + tasks.number + ' - ' + tasks.short_description + '</li>');
}
template.print('</ul>');Step 9: Add Attachments
Include Record Attachments:
Tool: SN-Update-Record
Parameters:
table_name: sysevent_email_action
sys_id: [notification_sys_id]
data:
include_attachments: trueProgrammatic Attachment via Mail Script:
Tool: SN-Create-Record
Parameters:
table_name: sys_script_email
data:
name: "Attach Report PDF"
description: "Attaches a generated report to the email"
script: |
(function runMailScript(current, template, email, email_action, event) {
// Get attachment from related record
var attach = new GlideRecord('sys_attachment');
attach.addQuery('table_name', 'incident');
attach.addQuery('table_sys_id', current.sys_id);
attach.addQuery('content_type', 'CONTAINS', 'pdf');
attach.query();
while (attach.next()) {
// Add each PDF attachment
var gsa = new GlideSysAttachment();
var content = gsa.getContentBase64(attach);
email.addAttachment(attach.file_name, attach.content_type, content);
}
})(current, template, email, email_action, event);Step 10: Configure SMS Notifications
SMS notifications require the SMS plugin and carrier configuration.
Check SMS Capability:
Tool: SN-Query-Table
Parameters:
table_name: sys_plugins
query: name=com.snc.sms
fields: sys_id,name,activeCreate SMS Notification:
Tool: SN-Create-Record
Parameters:
table_name: sysevent_email_action
data:
name: "P1 Incident SMS Alert"
event_name: "incident.assigned"
sys_domain: "global"
collection: "incident"
condition: "priority=1"
active: true
# SMS specific
sms_alternate: true # Enable SMS option
subject: "P1: ${number}" # SMS subject (carrier dependent)
message: "P1 Incident ${number}: ${short_description}. Priority: ${priority}. View: ${URI_REF}"
content_type: "text/plain"
# Recipients
send_to_event_parm_1: trueConfigure SMS for User:
Tool: SN-Query-Table
Parameters:
table_name: cmn_notif_device
query: user=[user_sys_id]^type=SMS
fields: sys_id,phone_number,carrier,activeStep 11: Configure Push Notifications
Push notifications require the mobile plugin and device registration.
Create Push Notification:
Tool: SN-Create-Record
Parameters:
table_name: sysevent_email_action
data:
name: "Approval Required Push"
event_name: "approval.inserted"
collection: "sysapproval_approver"
active: true
# Push specific
push_message_only: true # Send push only, no email
subject: "Approval Required"
message: "You have a new approval request: ${document_id.short_description}"
# Recipients
recipient_fields: "approver"Query User's Push Devices:
Tool: SN-Query-Table
Parameters:
table_name: cmn_notif_device
query: user=[user_sys_id]^type=Push
fields: sys_id,device_name,active,last_registrationStep 12: Notification Conditions and Filtering
Advanced Condition Examples:
| Condition | Purpose |
priority=1^state!=6 | P1, not resolved |
active=true^assigned_toISEMPTY | Active, unassigned |
sys_created_onONToday@javascript:gs.beginningOfToday()@javascript:gs.endOfToday() | Created today |
priority.changes()=true | Priority field changed |
state.changesFrom(1)^state.changesTo(2) | State changed from New to In Progress |
Condition Script (Advanced):
Tool: SN-Update-Record
Parameters:
table_name: sysevent_email_action
sys_id: [notification_sys_id]
data:
advanced_condition: |
// Return true to send notification, false to skip
function advancedCondition() {
// Don't notify if CI is in maintenance window
if (current.cmdb_ci && current.cmdb_ci.maintenance) {
return false;
}
// Only notify during business hours
var now = new GlideDateTime();
var hour = now.getLocalTime().getHourOfDayLocalTime();
if (hour < 8 || hour > 18) {
return false; // Outside business hours
}
// Check if user has opted out
var prefs = new GlideRecord('sys_user_preference');
prefs.addQuery('user', current.assigned_to);
prefs.addQuery('name', 'notification.incident.optout');
prefs.addQuery('value', 'true');
prefs.query();
if (prefs.next()) {
return false;
}
return true;
}
advancedCondition();Step 13: Weight and Priority
Control notification frequency and importance.
Set Notification Weight:
Tool: SN-Update-Record
Parameters:
table_name: sysevent_email_action
sys_id: [notification_sys_id]
data:
weight: 10 # Higher weight = higher priority
digest: false # true = batch into digest
digest_interval: "" # hourly, daily if digest=true
omit_watermark: false # Watermark prevents duplicatesDigest Configuration:
Tool: SN-Create-Record
Parameters:
table_name: sysevent_email_action
data:
name: "Daily Incident Summary"
event_name: "incident.created"
collection: "incident"
active: true
digest: true
digest_interval: "daily"
digest_template: [digest_template_sys_id]
subject: "Daily Incident Summary - ${digest.count} incidents"Troubleshooting Email Delivery
Step 1: Check Email Log
Query Recent Emails:
Tool: SN-Query-Table
Parameters:
table_name: sys_email
query: type=send-ready^ORtype=sent^ORtype=send-error^sys_created_onONToday@javascript:gs.beginningOfToday()@javascript:gs.endOfToday()
fields: sys_id,type,recipients,subject,sys_created_on,error,mailbox
limit: 50
orderBy: sys_created_on
orderByDesc: trueEmail Status Types:
| Type | Meaning |
| send-ready | Queued for sending |
| sent | Successfully sent |
| send-error | Send failed |
| received | Inbound email |
| received-error | Inbound processing error |
| draft | Pending approval |
| ignored | Skipped by rule |
Find Failed Emails:
Tool: SN-Query-Table
Parameters:
table_name: sys_email
query: type=send-error^sys_created_onONLast 7 days@javascript:gs.daysAgoStart(7)@javascript:gs.daysAgoEnd(0)
fields: sys_id,recipients,subject,error,sys_created_on
limit: 100Step 2: Check Event Queue
Query Event Queue:
Tool: SN-Query-Table
Parameters:
table_name: sysevent
query: name=x_custom.incident.escalated^sys_created_onONToday@javascript:gs.beginningOfToday()@javascript:gs.endOfToday()
fields: sys_id,name,instance,parm1,parm2,state,sys_created_on
limit: 50Event States:
| State | Meaning |
| ready | Queued for processing |
| processed | Successfully processed |
| error | Processing failed |
Step 3: Verify Notification Configuration
Check Notification Is Active:
Tool: SN-Query-Table
Parameters:
table_name: sysevent_email_action
query: sys_id=[notification_sys_id]
fields: name,active,event_name,condition,recipient_users,recipient_groups,recipient_fieldsVerify Event Registration:
Tool: SN-Query-Table
Parameters:
table_name: sysevent_register
query: event_name=[your_event_name]
fields: sys_id,event_name,table,descriptionStep 4: Test Notification
Fire Test Event:
Tool: SN-Execute-Background-Script
Parameters:
script: |
// Test notification by firing event
var inc = new GlideRecord('incident');
inc.addQuery('active', true);
inc.setLimit(1);
inc.query();
if (inc.next()) {
gs.eventQueue('x_custom.incident.escalated', inc, inc.assigned_to.toString(), inc.assignment_group.toString());
gs.info('Test event fired for: ' + inc.number);
}
description: "Fire test notification event"Check Email Generation:
Tool: SN-Query-Table
Parameters:
table_name: sys_email
query: recipients=[test_email]^ORsubjectLIKE[incident_number]^sys_created_onONLast hour@javascript:gs.hoursAgoStart(1)@javascript:gs.hoursAgoEnd(0)
fields: sys_id,type,recipients,subject,body,errorCommon Issues
Notification Not Firing
Symptom: No email generated after record change Causes:
- Notification inactive
- Condition not matched
- Event not registered
- No recipients defined
Solution:
Tool: SN-Query-Table
Parameters:
table_name: sysevent_email_action
query: collection=incident^active=true
fields: name,event_name,condition,active,recipient_users,recipient_groupsRecipients Not Receiving Email
Symptom: Email shows as sent but users don't receive Causes:
- User email address invalid/missing
- User notification preferences disabled
- Email blocked by spam filter
- Incorrect recipient configuration
Solution:
Tool: SN-Query-Table
Parameters:
table_name: sys_user
query: sys_id=[user_sys_id]
fields: email,notification,activeCheck user notification preferences:
Tool: SN-Query-Table
Parameters:
table_name: cmn_notif_message
query: user=[user_sys_id]
fields: notification,device,stateEmail Shows as send-error
Symptom: Emails fail with error status Causes:
- SMTP server configuration
- Invalid email addresses
- Mail server rejection
- Attachment too large
Solution: Check the error field in sys_email record for specific error message.
Variables Not Resolving
Symptom: Email shows ${field_name} literally instead of value
Causes:
- Incorrect variable syntax
- Field doesn't exist on table
- Null/empty field value
Solution: Verify field exists:
Tool: SN-Get-Table-Schema
Parameters:
table_name: incidentTool Usage Summary
MCP Tools (Preferred)
| Tool | Purpose |
SN-Query-Table | Query notifications, events, email logs |
SN-Create-Record | Create notifications, templates, mail scripts |
SN-Update-Record | Modify notification configuration |
SN-Get-Table-Schema | Verify available fields for variables |
SN-Execute-Background-Script | Fire test events, debug |
REST API (Alternative)
| Endpoint | Method | Purpose |
/api/now/table/sysevent_email_action | GET/POST | Query/create notifications |
/api/now/table/sysevent_email_template | GET/POST | Query/create templates |
/api/now/table/sys_script_email | POST | Create mail scripts |
/api/now/table/sys_email | GET | Check email log |
/api/now/table/sysevent_register | GET/POST | Manage events |
Best Practices
- Use Events: Prefer event-based over direct notifications for decoupling
- Template Reuse: Create templates for consistent formatting across notifications
- Test in Sub-Production: Always test notifications in dev/test first
- Monitor Email Queue: Regularly check sys_email for send-error records
- User Preferences: Respect user notification opt-out settings
- Business Hours: Consider time zones and business hours for non-critical alerts
- HTML + Plain Text: Provide both for maximum compatibility
- Avoid Spam: Use digest for high-frequency events
- Watermarks: Keep watermarks enabled to prevent duplicate notifications
- Document Events: Add descriptions to custom events for maintainability
Examples
Example 1: Complete P1 Incident Notification
# 1. Register custom event
Tool: SN-Create-Record
Parameters:
table_name: sysevent_register
data:
event_name: "incident.p1.created"
table: "incident"
description: "Fired when Priority 1 incident is created"
# 2. Create notification
Tool: SN-Create-Record
Parameters:
table_name: sysevent_email_action
data:
name: "P1 Incident Alert - All Hands"
event_name: "incident.p1.created"
collection: "incident"
active: true
weight: 100
subject: "[URGENT] P1 Incident: ${number} - ${short_description}"
content_type: "text/html"
message_html: |
<h1 style="color: #d32f2f;">Priority 1 Incident Created</h1>
<p>A critical incident requires immediate attention.</p>
<table>
<tr><td><b>Number:</b></td><td>${number}</td></tr>
<tr><td><b>Description:</b></td><td>${short_description}</td></tr>
<tr><td><b>Caller:</b></td><td>${caller_id}</td></tr>
<tr><td><b>Assignment Group:</b></td><td>${assignment_group}</td></tr>
</table>
<p><a href="${URI_REF}">View Incident Now</a></p>
recipient_groups: [incident_managers_group_sys_id]
send_to_event_parm_1: true
send_to_event_parm_2: true
# 3. Create business rule to fire event
# (Create via UI or background script)Example 2: Approval Request Notification with Mail Script
# 1. Create mail script for manager chain
Tool: SN-Create-Record
Parameters:
table_name: sys_script_email
data:
name: "CC Manager Chain"
script: |
(function runMailScript(current, template, email, email_action, event) {
// Get requested_for user
var reqFor = current.document_id.requested_for;
if (reqFor) {
var user = new GlideRecord('sys_user');
user.get(reqFor);
// Add manager as CC
if (user.manager && user.manager.email) {
email.addAddress('cc', user.manager.email.toString(), user.manager.name.toString());
}
}
})(current, template, email, email_action, event);
# 2. Create notification with mail script
Tool: SN-Create-Record
Parameters:
table_name: sysevent_email_action
data:
name: "Approval Request - With Manager CC"
event_name: "approval.inserted"
collection: "sysapproval_approver"
active: true
subject: "Approval Required: ${document_id.number}"
recipient_fields: "approver"
sys_script_mail: [mail_script_sys_id]
message_html: |
<h2>Approval Request</h2>
<p>You have a pending approval request.</p>
<p><b>Request:</b> ${document_id.number}</p>
<p><b>Requested By:</b> ${document_id.requested_for}</p>
<p><a href="${URI_REF}">Approve/Reject</a></p>Example 3: SLA Breach Warning
Tool: SN-Create-Record
Parameters:
table_name: sysevent_email_action
data:
name: "SLA Warning - 75% Elapsed"
event_name: "sla.warning"
collection: "task_sla"
active: true
condition: "percentage>=75^percentage<100"
subject: "SLA Warning: ${task.number} at ${percentage}%"
recipient_fields: "task.assigned_to"
content_type: "text/html"
message_html: |
<h2 style="color: #ff9800;">SLA Warning</h2>
<p>The following task is approaching SLA breach:</p>
<table>
<tr><td><b>Task:</b></td><td>${task.number}</td></tr>
<tr><td><b>SLA:</b></td><td>${sla.name}</td></tr>
<tr><td><b>Percentage:</b></td><td>${percentage}%</td></tr>
<tr><td><b>Time Remaining:</b></td><td>${business_time_left}</td></tr>
</table>
<p><a href="${task.URI_REF}">View Task</a></p>Related Skills
admin/workflow-creation- Workflow-triggered notificationscatalog/approval-workflows- Approval notificationsitsm/incident-lifecycle- Incident notification triggersadmin/script-execution- Testing notifications via scripts
References
Other versions8 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 8
- latitude-dev/latitude-llm★ 4.7ksame name
- vellum-ai/vellum-assistant★ 1.5ksame name
- hyperlink-academy/leaflet★ 525same name
- rlajous/claude-code-commands★ 30same name
- moasq/ios-dev-agent★ 4same name
- montagao/skills★ 2same name
- hkarpinen/agent-skills★ 1same name
- jars-demo/jars-skills★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
Used alongsideProjects with it also use release.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
MicrosoftSkillrelease
Use ONLY when the user explicitly asks to cut/publish a Huabu desktop release or tag a version. Performs an outward action — bumps the version in apps/desktop/package.json, commits + annotated-tags vX.Y.Z, and pushes the branch + tag. That tag push auto-builds the macOS/Windows installers and publishes a GitHub Release. Provides `status`, `bump`, `tag-push`, and a one-command `run` (bump → tag-push).
Also in 3 projects that use this
In this repository184 other files it gives its agents.
- happy-platform-skillsSkill
- application-scopeSkill
- batch-operationsSkill
- configuration-validationSkill
- deployment-workflowSkill
- generic-crud-operationsSkill
- instance-managementSkill
- schema-discoverySkill
- script-executionSkill
- script-syncSkill
- smart-assessmentSkill
- task-analysisSkill
- task-summarizationSkill
- update-set-managementSkill
- user-provisioningSkill
- workflow-creationSkill
- workspace-insightsSkill
- approval-summarizationSkill
- approval-workflowsSkill
- catalog-builder-aiSkill
- catalog-item-generationSkill
- item-creationSkill
- multi-turn-orderingSkill
- request-fulfillmentSkill
- ui-policiesSkill
- variable-managementSkill
- ci-discoverySkill
- cmdb-search-analysisSkill
- data-qualitySkill
- impact-analysisSkill
- relationship-mappingSkill
- service-graph-diagnosisSkill
- activity-responseSkill
- csm-case-summarizationSkill
- chat-recommendationSkill
- email-recommendationSkill
- csm-kb-generationSkill
- resolution-notesSkill
- csm-sentiment-analysisSkill
- csm-sidebar-summarizationSkill
- csm-suggested-stepsSkill
- trending-topicsSkill
- automated-testingSkill
- business-rulesSkill
- client-scriptsSkill
- code-assistSkill
- code-reviewSkill
- data-importSkill
- debugging-techniquesSkill
- fluent-sdkSkill
- glide-api-referenceSkill
- mcp-server-installationSkill
- mcp-serverSkill
- performance-optimizationSkill
- scheduled-jobsSkill
- scripted-rest-apisSkill
- script-includesSkill
- servicenow-docs-mcpSkill
- test-generationSkill
- ui-actionsSkill
- The first 60 shown.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

