- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-30-2025 08:32 AM
With ATT getting rid of their SMS gateway, I've been working through sending notifications through a 3rd party SMS gateway. Most were related to incidents up until this point, and now I'm working on sending a notification to users indicating that an emergency change requires approval.
The problem I'm running into is that the SMS message sends correctly, I can validate that the worknote is being put together properly in the system logs, but the worknote never posts to the change. I can't for the life of me figure out why. The method I'm using in this script has worked for incidents in 9 other script actions I've created, so I'm very confused about why this one doesn't work.
(function execute() {
// Param 1 is set in the workflow and just returns the change record"
var record = new GlideRecord('change_request');
if (!record.get(event.parm1)) {
gs.error('Record not found. SMS not sent.');
return;
}
// Get the list of recipients' sms addresses from the system property
var recipientsProperty = gs.getProperty('sms.emergency.change.approvers', '');
var recipients = recipientsProperty.split(',').map(function(r) {
return r.trim().toLowerCase();
});
if (recipients.length === 0) {
gs.info('No recipients found. SMS not sent.');
return;
}
// Get the list of allowed providers from the system property property
var allowedProvidersProperty = gs.getProperty('SMS - Providers', '');
var allowedProviders = allowedProvidersProperty.split(',').map(function(p) {
return p.trim();
});
if (allowedProviders.length === 0) {
gs.info('No allowed providers configured. SMS not sent.');
return;
}
// Query the notification devices to make sure the provider is valid
var deviceGR = new GlideRecord('cmn_notif_device');
deviceGR.addEncodedQuery('type=SMS^email_addressIN' + recipients.join(','));
deviceGR.query();
// Message to send
var message = 'Emergency ' + record.number + ' has been submitted and is awaiting your approval';
var workNoteLog = '';
while (deviceGR.next()) {
var provider = deviceGR.service_provider + '';
if (allowedProviders.indexOf(provider) === -1) {
gs.info('Skipping device for ' + deviceGR.email_address + ' due to disallowed provider.');
continue;
}
var phoneNumber = '1' + deviceGR.phone_number + '';
// Call the REST Message
var r = new sn_ws.RESTMessageV2('SMS Notifications', 'POST Encoded');
r.setStringParameterNoEscape('to', phoneNumber);
r.setStringParameterNoEscape('text', encodeURIComponent(message));
try {
var response = r.execute();
var responseBody = response.getBody();
var httpStatus = response.getStatusCode();
gs.info('SMS sent to ' + phoneNumber + '. Response: ' + responseBody + ' | Status: ' + httpStatus);
// Determine message based on status code
var resultMessage = '';
if (httpStatus === 200) {
resultMessage = 'SMS message sent to carrier successfully. Please contact carrier if you didn\'t receive a message.';
} else {
resultMessage = httpStatus;
}
// Add a work note for tracking purposes
workNoteLog += '\nSMS sent to ' + phoneNumber + ' (User: ' + deviceGR.name + ')' +
'\nResponse: ' + responseBody +
'\nStatus: ' + resultMessage;
gs.error('WORKNOTELOG: ' + workNoteLog);
} catch (ex) {
gs.error('Error sending SMS to: ' + phoneNumber + ': ' + ex.message);
}
}
if (workNoteLog) {
record.work_notes = workNoteLog;
record.update();
}
})();
In the system log, I see:
"WORKNOTELOG:
SMS sent to 5555555555 (User: First Last)
Response: ID: 1b15e5446e97c573b91016ce55d2c7ea
Status: SMS message sent to carrier successfully. Please contact carrier if you didn't receive a message.: no thrown error"
I've tried using setJournalEntry to no avail, as well as a few different variations of how the worknote is setup and ultimately tries to post to the change request, but haven't had any luck. Since this is working just fine on other script actions, I feel like I'm missing something easy here and just need another set of eyes.
TIA!
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-02-2025 09:36 AM - edited 06-03-2025 06:54 AM
Also see the edit at the bottom of this post.
I ended up starting over and mimicking another script I had working in the instance. The big difference in this one is using a group to get the numbers instead of a system property. The worknotes are seemingly compiled and posted the same way though, so I'm not really sure why this one works and the previous didn't. Here's what I ended up doing though:
(function execute() {
// Param 1 is set in the workflow and just returns the change record"
var record = new GlideRecord('change_request');
if (!record.get(event.parm1)) {
gs.error('Record not found. SMS not sent.');
return;
}
var allowedProvidersProperty = gs.getProperty('SMS - Providers', '');
var allowedProviders = allowedProvidersProperty.split(',').map(function(p) {
return p.trim();
});
var workNoteLog = '';
var notifiedUsers = {}; // Track notified users by sys_id
// Function to send SMS
function sendSMS(user) {
var userId = user.sys_id + '';
if (notifiedUsers[userId]) return; // Skip if already notified
notifiedUsers[userId] = true; // Mark as notified
var deviceGR = new GlideRecord('cmn_notif_device');
deviceGR.addQuery('user', userId);
deviceGR.addQuery('type', 'SMS');
deviceGR.query();
var foundValidDevice = false;
while (deviceGR.next()) {
var providerId = deviceGR.service_provider + '';
if (allowedProviders.indexOf(providerId) > -1) {
var phoneNumber = '1' + deviceGR.phone_number;
// Message to send
var message = 'Normal - Urgent ' + record.number + ' has been submitted and is awaiting your approval';
// Call the REST Message
var r = new sn_ws.RESTMessageV2('SMS Notifications', 'POST Encoded');
r.setStringParameterNoEscape('to', phoneNumber);
r.setStringParameterNoEscape('text', encodeURIComponent(message));
try {
var response = r.execute();
var responseBody = response.getBody();
var httpStatus = response.getStatusCode();
gs.info('SMS sent to ' + user.getDisplayValue() + ': ' + responseBody + ' | Status: ' + httpStatus);
// Determine message based on status code
var resultMessage = '';
if (httpStatus === 200) {
resultMessage = 'SMS message sent to carrier successfully. Please contact carrier if you didn\'t receive a message.';
} else {
resultMessage = httpStatus;
}
// Add a work note for tracking purposes
workNoteLog += 'SMS sent to ' + phoneNumber + ' (User: ' + user.getDisplayValue() + ')\nResponse: ' +
responseBody + '\nStatus: ' + resultMessage + '\n\n';
foundValidDevice = true;
} catch (ex) {
gs.error('Error sending SMS to: ' + user.getDisplayValue() + ': ' + ex.message);
}
}
}
if (!foundValidDevice) {
gs.info('No valid SMS device found for user: ' + user.getDisplayValue());
}
}
// Notify CAB Approver group
var execGroupGR = new GlideRecord('sys_user_grmember');
execGroupGR.addQuery('group', <sys_id here>>);
execGroupGR.query();
while (execGroupGR.next()) {
sendSMS(execGroupGR.user);
}
// Add a single work note if anything was logged
if (workNoteLog) {
record.work_notes = workNoteLog;
record.update();
}
})();
EDIT: During testing of different change workflows, I noticed that the way I was triggering the event was more likely the cause of the issue since the worknotes portions of the script worked in some workflows and not others. In legacy workflows, I had a "Notification" activity that is setup to message numbers directly. However, I also added the event trigger like this: gs.eventQueue('emergency.change.waiting.for.approval', current, current.task.sys_id);
When I triggered the event that way, for whatever reason, worknotes weren't being added. What I ended up doing is adding a "Create Event" activity that simply pointed to the event to trigger and used the parameter of: current.sys_id
Once I made that change the workflow, everything was all good.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-30-2025 09:31 AM
That doesn't appear to have worked. In fact, I actually didn't get the SMS message this time either. For what it's worth param1 is returning the sys_id in the event call:
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-02-2025 09:36 AM - edited 06-03-2025 06:54 AM
Also see the edit at the bottom of this post.
I ended up starting over and mimicking another script I had working in the instance. The big difference in this one is using a group to get the numbers instead of a system property. The worknotes are seemingly compiled and posted the same way though, so I'm not really sure why this one works and the previous didn't. Here's what I ended up doing though:
(function execute() {
// Param 1 is set in the workflow and just returns the change record"
var record = new GlideRecord('change_request');
if (!record.get(event.parm1)) {
gs.error('Record not found. SMS not sent.');
return;
}
var allowedProvidersProperty = gs.getProperty('SMS - Providers', '');
var allowedProviders = allowedProvidersProperty.split(',').map(function(p) {
return p.trim();
});
var workNoteLog = '';
var notifiedUsers = {}; // Track notified users by sys_id
// Function to send SMS
function sendSMS(user) {
var userId = user.sys_id + '';
if (notifiedUsers[userId]) return; // Skip if already notified
notifiedUsers[userId] = true; // Mark as notified
var deviceGR = new GlideRecord('cmn_notif_device');
deviceGR.addQuery('user', userId);
deviceGR.addQuery('type', 'SMS');
deviceGR.query();
var foundValidDevice = false;
while (deviceGR.next()) {
var providerId = deviceGR.service_provider + '';
if (allowedProviders.indexOf(providerId) > -1) {
var phoneNumber = '1' + deviceGR.phone_number;
// Message to send
var message = 'Normal - Urgent ' + record.number + ' has been submitted and is awaiting your approval';
// Call the REST Message
var r = new sn_ws.RESTMessageV2('SMS Notifications', 'POST Encoded');
r.setStringParameterNoEscape('to', phoneNumber);
r.setStringParameterNoEscape('text', encodeURIComponent(message));
try {
var response = r.execute();
var responseBody = response.getBody();
var httpStatus = response.getStatusCode();
gs.info('SMS sent to ' + user.getDisplayValue() + ': ' + responseBody + ' | Status: ' + httpStatus);
// Determine message based on status code
var resultMessage = '';
if (httpStatus === 200) {
resultMessage = 'SMS message sent to carrier successfully. Please contact carrier if you didn\'t receive a message.';
} else {
resultMessage = httpStatus;
}
// Add a work note for tracking purposes
workNoteLog += 'SMS sent to ' + phoneNumber + ' (User: ' + user.getDisplayValue() + ')\nResponse: ' +
responseBody + '\nStatus: ' + resultMessage + '\n\n';
foundValidDevice = true;
} catch (ex) {
gs.error('Error sending SMS to: ' + user.getDisplayValue() + ': ' + ex.message);
}
}
}
if (!foundValidDevice) {
gs.info('No valid SMS device found for user: ' + user.getDisplayValue());
}
}
// Notify CAB Approver group
var execGroupGR = new GlideRecord('sys_user_grmember');
execGroupGR.addQuery('group', <sys_id here>>);
execGroupGR.query();
while (execGroupGR.next()) {
sendSMS(execGroupGR.user);
}
// Add a single work note if anything was logged
if (workNoteLog) {
record.work_notes = workNoteLog;
record.update();
}
})();
EDIT: During testing of different change workflows, I noticed that the way I was triggering the event was more likely the cause of the issue since the worknotes portions of the script worked in some workflows and not others. In legacy workflows, I had a "Notification" activity that is setup to message numbers directly. However, I also added the event trigger like this: gs.eventQueue('emergency.change.waiting.for.approval', current, current.task.sys_id);
When I triggered the event that way, for whatever reason, worknotes weren't being added. What I ended up doing is adding a "Create Event" activity that simply pointed to the event to trigger and used the parameter of: current.sys_id
Once I made that change the workflow, everything was all good.