Skip to content

Commit 592287e

Browse files
Create code.js
1 parent e575064 commit 592287e

File tree

1 file changed

+72
-0
lines changed
  • Server-Side Components/Script Includes/Sends Slack/Teams notifications when specific fields change on configured tables

1 file changed

+72
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/**
2+
* Script Include: AuditFieldChangeNotifier
3+
* Description: Sends Slack/Teams notifications when specific fields change on configured tables.
4+
* Usable in: Business Rule (after update)
5+
*/
6+
var AuditFieldChangeNotifier = Class.create();
7+
AuditFieldChangeNotifier.prototype = {
8+
initialize: function () {
9+
// Slack or Teams webhook URL (store in sys_properties for security)
10+
this.webhookUrl = gs.getProperty('x_custom.audit_notifier.webhook_url', '');
11+
// Default app name
12+
this.appName = gs.getProperty('x_custom.audit_notifier.app_name', 'ServiceNow');
13+
},
14+
/**
15+
* Send notification if the specified fields have changed
16+
* @param {GlideRecord} current - Current record
17+
* @param {GlideRecord} previous - Previous record
18+
* @param {Array} fieldsToWatch - Array of field names to monitor
19+
*/
20+
notifyOnFieldChange: function (current, previous, fieldsToWatch) {
21+
try {
22+
if (!this.webhookUrl) {
23+
gs.warn('[AuditFieldChangeNotifier] Webhook URL not configured.');
24+
return;
25+
}
26+
var changes = [];
27+
fieldsToWatch.forEach(function (field) {
28+
if (current[field] + '' !== previous[field] + '') {
29+
changes.push({
30+
field: field,
31+
oldValue: previous[field] + '',
32+
newValue: current[field] + ''
33+
});
34+
}
35+
});
36+
if (changes.length === 0)
37+
return; // No relevant field changed
38+
var payload = this._buildPayload(current, changes);
39+
this._sendWebhook(payload);
40+
} catch (e) {
41+
gs.error('[AuditFieldChangeNotifier] Error: ' + e.message);
42+
}
43+
},
44+
/**
45+
* Build payload for Slack/Teams message
46+
*/
47+
_buildPayload: function (current, changes) {
48+
var shortDesc = current.short_description ? current.short_description + '' : '(No short description)';
49+
var tableName = current.getTableName();
50+
var recordUrl = gs.getProperty('glide.servlet.uri') + tableName + '.do?sys_id=' + current.sys_id;
51+
var changeLines = changes.map(function (c) {
52+
return `• *${c.field}* changed from _${c.oldValue}_ → *${c.newValue}*`;
53+
}).join('\n');
54+
return JSON.stringify({
55+
text: `🛠️ *${this.appName}* — Field Update Notification\n\n*Record:* <${recordUrl}|${tableName}> \n*Description:* ${shortDesc}\n\n${changeLines}\n\n_Updated by ${gs.getUserDisplayName()}_`
56+
});
57+
},
58+
/**
59+
* Send payload to webhook
60+
*/
61+
_sendWebhook: function (payload) {
62+
var r = new sn_ws.RESTMessageV2();
63+
r.setEndpoint(this.webhookUrl);
64+
r.setHttpMethod('POST');
65+
r.setRequestHeader('Content-Type', 'application/json');
66+
r.setRequestBody(payload);
67+
var response = r.execute();
68+
if (response.getStatusCode() >= 400)
69+
gs.error('[AuditFieldChangeNotifier] Webhook error: ' + response.getBody());
70+
},
71+
type: 'AuditFieldChangeNotifier'
72+
};

0 commit comments

Comments
 (0)