Name
global.AutoResolutionNotificationHelper
Description
Class that has methods to help with response channels related to notifications
Script
var AutoResolutionNotificationHelper = Class.create();
// OOB response channels that we look for, for a user
AutoResolutionNotificationHelper.RESPONSE_CHANNEL = {EMAIL: 'Email', SMS: 'SMS', VA: 'Virtual Agent'};
AutoResolutionNotificationHelper.RESPONSE_CHANNEL_MODE = {ALL: 'all', FIRST_MATCH: 'first_match'};
AutoResolutionNotificationHelper.EMAIL_SYSTEM_STATUS = {READY: 'ready', NOT_READY: 'not-ready'};
AutoResolutionNotificationHelper.prototype = {
/**
* This helper is tied to a particular user and IAR config
* @param {string} userSysID - Sys ID of the user record
* @param {string} userTableName - Table where the user with userSysID can be found
* @param {string} arConfigSysID
* @param {AutoResolutionLoggingUtils} logger
*/
initialize: function(userSysID, userTableName, arConfigSysID, logger) {
this.logger = !gs.nil(logger) ? logger :
new AutoResolutionLoggingUtils().withName(this.type).withConfiguration(this.arConfigSysID).createLogger();
this.userGr = this._getUserGr(userSysID, userTableName);
this.arConfigGr = this._getARConfigGr(arConfigSysID);
this.initialRecommendationEmailSendSubflow = 'global.iar_send_initial_email_notification';
if (gs.nil(this.arConfigGr))
this.logger.debug('AutoResolutionNotificationHelper not initialized properly. Looks like invalid ar config: {0}', arConfigSysID);
this.responseChannelObjectList = this._getResponseChannelObjectList();
this.logger.debug('Response channel object for user with sys_id={0} is {1}', userSysID, JSON.stringify(this.responseChannelObjectList));
},
/**
* @typedef {Object} ResponseChannelObject
* @property {string} name - Email, Virtual Agent, or SMS
* @property {boolean} shouldSend
* @property {string} reason - Will contain the reason if shouldSend is false, else will not be present
*/
/**
*
* @return {ResponseChannelObject[]} - If first match is selected, only one of the items in the list will have shouldSend as true
* For example: If Email, SMS, Virtual Agent are of order 100, 200 and 300 and first match is found
* for SMS, the list will contain objects for Email and SMS. Object for SMS will have shouldSend as true
*
*/
getResponseChannelObjectList: function() {
return this.responseChannelObjectList;
},
/**
*
* @returns {{shouldSend: boolean, reason: String}}
*/
shouldSendEmail: function() {
return this._shouldSendNotificationToChannel(AutoResolutionNotificationHelper.RESPONSE_CHANNEL.EMAIL);
},
/**
*
* @returns {{shouldSend: boolean, reason: String}}
*/
shouldSendSMS: function() {
return this._shouldSendNotificationToChannel(AutoResolutionNotificationHelper.RESPONSE_CHANNEL.SMS);
},
/**
*
* @returns {{shouldSend: boolean, reason: String}}
*/
shouldSendVANotification: function() {
return this._shouldSendNotificationToChannel(AutoResolutionNotificationHelper.RESPONSE_CHANNEL.VA);
},
/**
* Sends an Email and SMS for the passed values. Checks if it should send before trying to send.
* @param {GlideRecord} taskGr
* @param {string} emailNotificationId
* @param {GlideRecord} smsTemplateGr
*/
sendEmailAndSMSNotificationForTask: function(taskGr, emailNotificationId, smsTemplateGr) {
// Send Email notification if needed
try {
if (this.shouldSendEmail().shouldSend)
this.sendEmail(taskGr, emailNotificationId);
else
this.logger.debug('Email not sent for user with sys ID: {0}', this.userGr.getValue('sys_id'));
} catch(error) {
this.logger.error('Error sending email to user with sys ID {0}. Error: {1}', this.userGr.getValue('sys_id'), error.getMessage());
}
// Send SMS notification if needed
try {
if (this.shouldSendSMS().shouldSend)
this.sendSMS(taskGr.getTableName(), taskGr.getUniqueValue(), smsTemplateGr);
else
this.logger.debug('SMS not sent for user with sys ID: {0}', this.userGr.getValue('sys_id'));
} catch(err) {
this.logger.error('Error sending SMS to user with sys ID {0}. Error: {1}', this.userGr.getValue('sys_id'), err);
}
},
/**
*
* @param {GlideRecord} targetGr
* @return {string} context sys id of the email flow
* @throws error
*/
sendEmail: function(targetGr, emailNotificationId) {
if (gs.nil(emailNotificationId))
throw 'No email notification to send';
var inputs = {};
inputs['target_record_sys_id'] = targetGr.getValue('sys_id'); // Sys ID (GUID)
inputs['target_table_name'] = targetGr.getTableName(); // String
inputs['notification_sys_id'] = emailNotificationId; // Sys ID (GUID)
// scriptableFlowRunResult is of type ScriptableFlowRunnerResult (java class)
var scriptableFlowRunResult = sn_fd.FlowAPI.getRunner().subflow(this.initialRecommendationEmailSendSubflow).inBackground().withInputs(inputs).run();
var contextID = gs.nil(scriptableFlowRunResult) ? null : scriptableFlowRunResult.getContextId();
this.logger.debug('Email sent to user with sys_id={0}. Flow context ID={1}', this.userGr.getValue('sys_id'), contextID);
return contextID;
},
/**
* @param {string} targetTableName table name of the target GlideRecord
* @param {string} targetSysId sys_id of the target GlideRecord
* @param {GlideRecord} notifySMSTemplateGr Template GlideRecord from notify_sms_template table
* @return {string} Unique message SID; stored in the Notify Message [notify_message] record as message_id
* @throws error
*/
sendSMS: function(targetTableName, targetSysID, notifySMSTemplateGr) {
var targetGr = new GlideRecord(targetTableName);
if (!targetGr.get(targetSysID))
throw 'Could not get target GlideRecord: table=' + targetTableName + ', sys_id=' + targetSysID;
if (gs.nil(notifySMSTemplateGr))
throw 'Notify SMS Template GlideRecord cannot be empty';
var emailFormatter = new GlideEmailFormatter(targetGr, null, null, new GlideEmailOutbound());
var smsBody = emailFormatter.substitute(notifySMSTemplateGr.getValue('template'));
smsBody = emailFormatter.evaluateTemplateScript(smsBody);
// Un escape all the HTML characters, since this is SMS
smsBody = GlideStringUtil.unEscapeHTML(smsBody);
var fromNumber = this.arConfigGr.notify_sms_phone.getRefRecord().getValue('phone_number');
var toNumber = new NotifyUtils().getSMSNumberForUser(this.userGr);
if (gs.nil(toNumber))
throw 'No active SMS device found for user with sys ID: ' + this.userGr.getValue('sys_id');
// This it the ID returned by Twilio. We can check the status of the message in the twilio console by this ID
var messageID = SNC.Notify.sendSMS(fromNumber, toNumber, smsBody, targetGr);
this.logger.debug('SMS sent to user with sys_id={0}. Message ID={1}', this.userGr.getValue('sys_id'), messageID);
return messageID;
},
/**
* Returns true if we can send notifications to any channels configured on the IAR config, for a particular user
* @returns {{shouldSend: boolean, reason: String}}
*/
shouldSendNotification: function() {
// Currently only 3 channels are supported. If more than these need to be supported, refactor this
var sendSMSResponse = this.shouldSendSMS();
var sendSMS = sendSMSResponse.shouldSend;
var reason = sendSMSResponse.reason;
var sendEmailResponse = this.shouldSendEmail();
var sendEmail = sendEmailResponse.shouldSend;
reason += sendEmailResponse.reason;
var sendVAResponse = this.shouldSendVANotification();
var sendVA = sendVAResponse.shouldSend;
reason += sendVAResponse.reason;
if (sendSMS || sendEmail || sendVA)
return {"shouldSend": true, "reason":''};
else
return {"shouldSend": false, "reason":reason};
},
anyResponseChannelActiveForUserAndConfig: function() {
var responseChannelGa = new GlideAggregate(AutoResolutionConstants.RESPONSE_CHANNEL_TABLE_NAME);
responseChannelGa.addQuery('active', 'true');
responseChannelGa.addQuery('configuration', this.arConfigGr.getValue('sys_id'));
responseChannelGa.addAggregate('COUNT');
responseChannelGa.query();
return !responseChannelGa.next() ? false : parseInt(responseChannelGa.getAggregate('COUNT')) > 0;
},
/**
* Gets the SMS template from the specified field on the passed GlideRecord, if the configuration should send SMS
* @param {GlideRecord} gr
* @param {string} field
*/
getSMSTemplateFromGR: function(gr, field) {
if (this.shouldSendSMS().shouldSend)
return gr.getElement(field).getRefRecord();
return null;
},
_getResponseChannelObjectList: function() {
var autoResResponseChannelGr = this._getResponseChannelGr();
var firstMatch = (this.arConfigGr.getValue('response_channel_selection_mode') === AutoResolutionNotificationHelper.RESPONSE_CHANNEL_MODE.FIRST_MATCH);
var responseChannel;
var responseChannelObjectList = [];
var responseChannelObject;
while (autoResResponseChannelGr.next()) {
responseChannel = autoResResponseChannelGr.getValue('response_channel');
responseChannelObject = {name: responseChannel};
switch (responseChannel) {
case AutoResolutionNotificationHelper.RESPONSE_CHANNEL.EMAIL:
var activePrimaryDvcExistsForUser = this._activePrimaryEmailDeviceExistsForUser();
this._evaluateResponseChannelObjectForEmail(responseChannelObject, activePrimaryDvcExistsForUser);
break;
case AutoResolutionNotificationHelper.RESPONSE_CHANNEL.SMS:
var activeSMSDeviceFound = this._primaryActiveSMSDeviceFoundForUser();
var notifySMSPhonePresentAndSelectedOnConfig =
AutoResolutionNotificationHelper.isNotifySMSPhonePresentAndSelectedOnConfig(this.arConfigGr);
var userOptedIn = this._isUserOptedIn();
this._evaluateResponseChannelObjectForSMS(responseChannelObject, activeSMSDeviceFound, notifySMSPhonePresentAndSelectedOnConfig, userOptedIn);
break;
case AutoResolutionNotificationHelper.RESPONSE_CHANNEL.VA:
var consumerAccountGr = this._getConsumerAccountGr();
var isUserSubscrToNotifAndChannelActive = this._isUserSubscribedToNotificationsAndChannelActive();
var conversationExistsForConsumerAccount = this._conversationExistsForConsumerAccount(consumerAccountGr);
var isVANotificationEnabledOnTheInstance = AutoResolutionNotificationHelper.isVANotificationEnabledOnTheInstance();
this._evaluateResponseChannelObjectForVirtualAgent(responseChannelObject, consumerAccountGr, conversationExistsForConsumerAccount,
isUserSubscrToNotifAndChannelActive, isVANotificationEnabledOnTheInstance);
break;
default:
responseChannelObject[responseChannel] = this._getUnknownChannelTypeObject(responseChannelObject, responseChannel);
break;
}
responseChannelObjectList.push(responseChannelObject);
// If first match is true, we break
if (firstMatch && responseChannelObject.shouldSend) {
this.logger.debug('First match found for channel {0}, for user with sys_id {1}', responseChannel, this.userGr.getValue('sys_id'));
break;
}
}
return responseChannelObjectList;
},
/**
* Returns true if system wide property is enabled to send notifications on web client for a new user who has no
* conversations
* @returns {boolean}
* @private
*/
_isNewUserWebClientPropertyEnabled: function() {
return gs.getProperty("com.glide.cs.notification_newuser_webclient", 'false') === 'true';
},
_shouldSendNotificationToChannel: function(responseChannelName) {
var shouldSendNotificationResponseObject = {};
var reason = "";
for (var objectIndex in this.responseChannelObjectList) {
responseChannelObject = this.responseChannelObjectList[objectIndex];
if (responseChannelObject.name === responseChannelName && responseChannelObject.shouldSend)
{
shouldSendNotificationResponseObject.shouldSend = true;
shouldSendNotificationResponseObject.reason = "";
return shouldSendNotificationResponseObject;
}
else if (responseChannelObject.name === responseChannelName && !gs.nil(responseChannelObject.reason))
reason = responseChannelObject.name + ":" + responseChannelObject.reason;
}
shouldSendNotificationResponseObject.shouldSend = false;
shouldSendNotificationResponseObject.reason = reason;
return shouldSendNotificationResponseObject;
},
_getConsumerAccountGr: function() {
var consumerAccountGr = new GlideRecord('sys_cs_consumer_account');
consumerAccountGr.addQuery('consumer.user_id', this.userGr.getValue('sys_id'));
consumerAccountGr.query();
return consumerAccountGr.next() ? consumerAccountGr : null;
},
/**
* @param {ResponseChannelObject} responseChannelObject
* @param {boolean} activePrimaryDeviceFound If there is an active primary_email device found for the user in this.userGr
* @private
*/
_evaluateResponseChannelObjectForEmail: function(responseChannelObject, activePrimaryDeviceFound) {
if (!activePrimaryDeviceFound) {
responseChannelObject.shouldSend = false;
responseChannelObject.reason = 'Primary email device is not found or is inactive for user with sys ID: ' + this.userGr.getValue('sys_id');
return;
}
responseChannelObject.shouldSend = true;
},
/**
* We check
* 1. If the user is subscribed to notifications and that particular channel is active
* 2. If the user has a consumer account record and has a conversation of type interactive
* 3. If VA notifications are enabled on the instance
* @param {ResponseChannelObject} responseChannelObject
* @param {GlideRecord} consumerAccountGr
* @param {boolean} conversationExistsForConsumerAccount
* @param {boolean} isUserSubscrToNotifAndChannelActive
* @param {boolean} isVANotificationEnabledOnTheInstance
* @private
*/
_evaluateResponseChannelObjectForVirtualAgent: function(responseChannelObject, consumerAccountGr, conversationExistsForConsumerAccount,
isUserSubscrToNotifAndChannelActive, isVANotificationEnabledOnTheInstance) {
var newUserWebClientEnabled = this._isNewUserWebClientPropertyEnabled();
if (gs.nil(consumerAccountGr) && !newUserWebClientEnabled) {
responseChannelObject.shouldSend = false;
responseChannelObject.reason = 'Consumer account not found for user with sys_id: ' + this.userGr.getValue('sys_id');
return;
}
// 1. If the user is subscribed to a channel and it is active
if (!isUserSubscrToNotifAndChannelActive && !newUserWebClientEnabled) {
responseChannelObject.shouldSend = false;
responseChannelObject.reason = 'User with sys_id: ' + this.userGr.getValue('sys_id') + ' is either not subscribed to the notification or the channel is inactive';
return;
}
// 2. If a consumer does not have any conversations before
if (!conversationExistsForConsumerAccount && !newUserWebClientEnabled) {
responseChannelObject.shouldSend = false;
responseChannelObject.reason = 'No interactive conversation found for user with sys_id ' + this.userGr.getValue('sys_id');
return;
}
// 3. If VA notification is enabled on the instance
if (!isVANotificationEnabledOnTheInstance) {
responseChannelObject.shouldSend = false;
responseChannelObject.reason = 'VA notification is not enabled on the instance';
return;
}
responseChannelObject.shouldSend = true;
},
/**
* We check if the user has a device of type 'SMS' in cmn_notif_device table with active=true and a notify phone number is selected on the IAR config
* @param {ResponseChannelObject} responseChannelObject
* @param {boolean} primarySMSDeviceExistsForUser
* @param {boolean} notifySMSPhoneSelectedOnConfig
* @param {boolean} userOptedIn
* @private
*/
_evaluateResponseChannelObjectForSMS: function(responseChannelObject, primarySMSDeviceExistsForUser, notifySMSPhonePresentAndSelectedOnConfig, userOptedIn) {
if (!primarySMSDeviceExistsForUser) {
responseChannelObject.shouldSend = false;
responseChannelObject.reason = 'Active SMS device not found or is inactive for user with sys ID: ' + this.userGr.getValue('sys_id');
return;
}
if (!notifySMSPhonePresentAndSelectedOnConfig) {
responseChannelObject.shouldSend = false;
responseChannelObject.reason = 'Notify SMS phone not present or selected on IAR config with sys ID: ' + this.arConfigGr.getValue('sys_id');
return;
}
if (!userOptedIn) {
responseChannelObject.shouldSend = false;
responseChannelObject.reason = 'User with sys_id: ' + this.userGr.getValue('sys_id') + ' has opted out from receiving SMS notifications for IAR with sys ID: ' + this.arConfigGr.getValue('sys_id');
return;
}
responseChannelObject.shouldSend = true;
},
_getUnknownChannelTypeObject: function(responseChannelObject, responseChannel) {
responseChannelObject.shouldSend = false;
responseChannelObject.reason = 'Unknown response channel: ' + responseChannel;
},
_conversationExistsForConsumerAccount: function(consumerAccountGr) {
if (gs.nil(consumerAccountGr)) {
this.logger.debug('Consumer account is null for user with sys_id: {0}', this.userGr.getValue('sys_id'));
return false;
}
var conversationGa = new GlideAggregate('sys_cs_conversation');
conversationGa.addQuery('consumer_account', consumerAccountGr.getValue('sys_id'));
conversationGa.addQuery('conversation_type', '!=', 'notification');
conversationGa.orderByDesc('sys_created_on');
conversationGa.addAggregate('COUNT');
conversationGa.query();
var conversationCount = conversationGa.next() ? parseInt(conversationGa.getAggregate('COUNT')) : 0;
return conversationCount > 0;
},
/**
* Returns true if the user is subscribed to a channel and the channel is active, else returns false
* @return {boolean}
*/
_isUserSubscribedToNotificationsAndChannelActive: function() {
var sysNotificationGr = new GlideRecord('sys_notification');
sysNotificationGr.addQuery('table', AutoResolutionConstants.CONTEXT_TABLE_NAME);
sysNotificationGr.addQuery('name', 'Issue Auto-Resolution');
sysNotificationGr.query();
if (!sysNotificationGr.next())
return false;
var prefs = new sn_notification.Preferences(this.userGr);
var destinations = prefs.getDestinations();
for (var i = 0; i < destinations.length; i++) {
var destination = destinations[i];
if (destination.isActive(sysNotificationGr))
return true;
}
return false;
},
_activePrimaryEmailDeviceExistsForUser: function() {
var cmnNotifDeviceGa = new GlideAggregate('cmn_notif_device');
cmnNotifDeviceGa.addActiveQuery();
cmnNotifDeviceGa.addQuery('user', this.userGr.getValue('sys_id'));
cmnNotifDeviceGa.addQuery('type', AutoResolutionNotificationHelper.RESPONSE_CHANNEL.EMAIL);
cmnNotifDeviceGa.addQuery('primary_email', 'true');
cmnNotifDeviceGa.addAggregate('COUNT');
cmnNotifDeviceGa.query();
return cmnNotifDeviceGa.next() ? (parseInt(cmnNotifDeviceGa.getAggregate('COUNT')) > 0) : false;
},
_primaryActiveSMSDeviceFoundForUser: function() {
return !gs.nil(new NotifyUtils().getSMSNumberForUser(this.userGr));
},
_isUserOptedIn: function() {
if (!this.arConfigGr.isValidField('notify_sms_phone')) {
this.logger.debug('Notify SMS phone field is not present on IAR config={0}. Probably Notify Twilio Direct Driver is not installed', this.arConfigGr.getValue('sys_id'));
return false;
}
var notifyNumberGr = !gs.nil(this.arConfigGr.getValue('notify_sms_phone')) ? this.arConfigGr.notify_sms_phone.getRefRecord() : null;
if (gs.nil(notifyNumberGr)) {
this.logger.debug('No notify SMS phone selected on IAR config with sys_id={0}', this.arConfigGr.getValue('sys_id'));
return false;
}
var notifyNumberGr = this.arConfigGr.notify_sms_phone.getRefRecord();
var fromNumber = notifyNumberGr.getValue('phone_number');
// Since we are concerned only about TWILIO, we can use the hardcoded value. If we support more drivers,
// we may have to look into NotifyUtilSNC.getProvider
var smsPreferenceHandler = new sn_sms_pref.SMSPreferenceHandler(AutoResolutionConstants.TWILIO_SMS_PROVIDER);
// Check NotifyWorkflow.runIncomingSMSWorkflow() to know how we compute fromNumberType
var fromNumberType = notifyNumberGr.getValue('short_code') === null ? 'long' : 'short';
var userPhoneNumber = new NotifyUtils().getSMSNumberForUser(this.userGr);
var optedInNumberList = smsPreferenceHandler.getOptedInNumbers(fromNumber, fromNumberType, [userPhoneNumber]);
return optedInNumberList.length === 1 && optedInNumberList[0] === userPhoneNumber;
},
_getResponseChannelGr: function() {
var autoResResponseChannelGr = new GlideRecord(AutoResolutionConstants.RESPONSE_CHANNEL_TABLE_NAME);
autoResResponseChannelGr.addQuery('configuration', this.arConfigGr.getValue('sys_id'));
autoResResponseChannelGr.addActiveQuery();
autoResResponseChannelGr.orderBy('order');
autoResResponseChannelGr.query();
return autoResResponseChannelGr;
},
_getARConfigGr: function(arConfigSysID) {
var arConfigGr = new GlideRecord(AutoResolutionConstants.CONFIG_TABLE_NAME);
if (!arConfigGr.get(arConfigSysID)) {
this.logger.info('Invalid IAR configuration with sys ID: {0}', arConfigSysID);
return null;
}
return arConfigGr;
},
_getUserGr: function(userSysID, userTableName) {
var userGr = new GlideRecord(userTableName);
if (!userGr.get(userSysID)) {
this.logger.debug('User record not found for user with sys_id {0} in table {1}', userSysID, userTableName);
return null;
}
return userGr;
},
type: 'AutoResolutionNotificationHelper'
};
AutoResolutionNotificationHelper.notifyFieldsExistOnConfig = function(arConfigGr) {
if (gs.nil(arConfigGr))
return false;
// These fields will exist only if Notify plugin is installed
return arConfigGr.isValidField('notify_sms_phone') && arConfigGr.isValidField('initial_recommendation_sms');
};
AutoResolutionNotificationHelper.isNotifySMSPhonePresentAndSelectedOnConfig = function(arConfigGr) {
return AutoResolutionNotificationHelper.notifyFieldsExistOnConfig(arConfigGr) && !gs.nil(arConfigGr.getValue('notify_sms_phone'));
};
AutoResolutionNotificationHelper.getSupportedChannelList = function() {
var supportedChannelList = new GlideChoiceList();
for (var responseChannelName in AutoResolutionNotificationHelper.RESPONSE_CHANNEL) {
supportedChannelList.add(new GlideChoice(AutoResolutionNotificationHelper.RESPONSE_CHANNEL[responseChannelName],
AutoResolutionNotificationHelper.RESPONSE_CHANNEL[responseChannelName]));
}
return supportedChannelList;
};
/**
* Check if there exists an active VA notification channel on the sys_notification_channel table
* @return {boolean}
*/
AutoResolutionNotificationHelper.isVANotificationChannelEnabled = function() {
// Use VA-related content table names to find VA notification providers
var vaNotificationContentTableNameList = ["sys_notification_va_content", "sys_notification_va_content_messaging"];
var notificationProviderGr = new GlideRecord("sys_notification_provider");
var notificationProviderQc;
vaNotificationContentTableNameList.forEach(function (contentTableName, index) {
if (index === 0) {
notificationProviderQc = notificationProviderGr.addQuery("content_table", contentTableName);
} else {
notificationProviderQc.addOrCondition("content_table", contentTableName);
}
});
notificationProviderGr.query();
var notificationProviderSysIdList = [];
while (notificationProviderGr.next()) {
notificationProviderSysIdList.push(notificationProviderGr.getUniqueValue());
}
// Use the VA notification providers to find VA notification channels
var notificationChannelGr = new GlideRecord("sys_notification_channel");
var notificationChannelQc;
notificationProviderSysIdList.forEach(function(provider, index) {
if (index === 0) {
notificationChannelQc = notificationChannelGr.addQuery("provider", provider);
} else {
notificationChannelQc.addOrCondition("provider", provider);
}
});
notificationChannelGr.addQuery("active", true);
notificationChannelGr.query();
return notificationChannelGr.next();
};
/**
* Check either web client notification or any other channel's notification is enabled before sending IAR notification
* @return {bool|boolean}
*/
AutoResolutionNotificationHelper.isVANotificationEnabledOnTheInstance = function() {
var chatSetupGr = new GlideRecord('sys_cs_live_agent_setup');
chatSetupGr.get(AutoResolutionConstants.LIVE_AGENT_CHAT_SETUP_SYSID);
if (chatSetupGr.getValue('notification_enabled') === '1') {
return true;
} else {
var channelGr = new GlideRecord('sys_cs_channel');
channelGr.addQuery('type', AutoResolutionConstants.CHAT_TYPE);
channelGr.addQuery('enable_notification', true);
channelGr.query();
return channelGr.next();
}
};
AutoResolutionNotificationHelper.isEmailFunctionalityUp = function() {
var responseObject = {status: AutoResolutionNotificationHelper.EMAIL_SYSTEM_STATUS.NOT_READY};
var isSMTPActive = _isSMTPActive();
var smtpStatusGr = _getSMTPStatusRecord();
var emailSendingInactiveMessage = 'Email sending is inactive, messages will not be sent';
var smtpAccountNotConfiguredMessage = 'There is currently no active SMTP account configured, cannot send email';
var smtpServerConnectionErrorMessage = "Cannot connect to SMTP server: mail.google.com, as: admin, message: Couldn't connect to host, port: mail.google.com, 587; timeout 20000, cause: connect timed out";
// 1. Check if SMTP active record exists
if (!isSMTPActive) {
responseObject.message = 'Email sending is not enabled or is inactive on the instance. Record not found for name glide.smtp.active in sys_status table';
return responseObject;
}
if (gs.nil(smtpStatusGr)) {
responseObject.reason = 'Cannot send email. sys_status record not found for name glide.smtp.status';
return responseObject;
}
// 2 and 3. Check for certain values and types for errors and connection issues
var value = smtpStatusGr.getValue('value');
var type = smtpStatusGr.getValue('type');
if ((value === emailSendingInactiveMessage && type === 'info') || (value === smtpAccountNotConfiguredMessage && type === 'info') ||
(value === smtpServerConnectionErrorMessage && type === 'warning')) {
responseObject.reason = value + '. Please check for name glide.smtp.status in sys_status table';
return responseObject;
}
responseObject.status = AutoResolutionNotificationHelper.EMAIL_SYSTEM_STATUS.READY;
return responseObject;
};
function _isSMTPActive() {
var sysStatusGa = new GlideAggregate('sys_status');
sysStatusGa.addQuery('name', 'glide.smtp.active');
sysStatusGa.addAggregate('COUNT');
sysStatusGa.query();
return sysStatusGa.next() ? (parseInt(sysStatusGa.getAggregate('COUNT')) !== 0) : false;
}
function _getSMTPStatusRecord() {
var sysStatusGr = new GlideRecord('sys_status');
sysStatusGr.addQuery('name', 'glide.smtp.status');
sysStatusGr.query();
return sysStatusGr.next() ? sysStatusGr : null;
}
Sys ID
583136a7b7410110635f860eee11a917