Name
sn_ci_analytics.CAProcessor
Description
No description available
Script
var CAProcessor = Class.create();
CAProcessor.prototype = {
initialize: function() {
this.logger = CIAnalyticsLogger.getLogger({
source: "CAProcessor",
});
this.config = new CAConfig();
this.isBroadcastAllowed = this.config.isBroadcastAllowed();
this.jobMaxConversationCount = this.config.getJobMaxConversationCount();
this.payloadSizeCalculator = new CAPayloadSizeCalculator();
this.payloadBuilder = new CAPayloadBuilder();
this.evaluator = new GlideScopedEvaluator();
this.validConversationFn = this._validationFormula();
this.isError = false;
this.logger.info("Configuration Details {0}", new global.JSON().encode(this.config.getDetails()));
this.CORRECT_INTENT = this.payloadBuilder.getIntentName(this.payloadBuilder.INTENT_CORRECT);
this.AUTO_SELECTED = this.payloadBuilder.getIntentName(this.payloadBuilder.INTENT_AUTO_SELECTED);
this.conversationIds = [];
this.UNSUPPORTED_INTENT = this.payloadBuilder.getIntentName(this.payloadBuilder.INTENT_UNSUPPORT);
},
process: function() {
try {
var batchProcessor = new CABatchProcessor();
var oobEventProcessor = new CAOOBEventProcessor();
this.clickMetricsEventProcessor = new CAClickMetricsCustomEventProcessor();
var isError = false;
var caConversationGr = this._queryCAConversation();
var lastOpenUser = "";
while (!this.isError && caConversationGr.next()) {
var conversationId = caConversationGr.conversation.sys_id;
var notificationGr = this._queryNotification(conversationId);
if (this.isBroadcastAllowed != 'true' && caConversationGr.conversation.conversation_type == 'notification'){
this.conversationIds.push(caConversationGr.conversation.sys_id);
continue;
}
if (this._canIgnoreConversation(caConversationGr, notificationGr, lastOpenUser)) {
var params = [conversationId, CABatchProcessor.batchId, caConversationGr.conversation.state, caConversationGr.conversation.consumer.name];
this.logger.info("Conversation:{0}, BatchId:{1}, Conversation State:{2}, Conversation Consumer: {3}", params);
lastOpenUser = caConversationGr.conversation.consumer;
continue;
}
this.payloadBuilder.initConversation(conversationId);
this._processOverrides(conversationId);
if (!this._processConversation(caConversationGr, notificationGr))
continue;
this._processEvents(conversationId, oobEventProcessor);
isError = !batchProcessor.queueOrSend(this.payloadBuilder.getConversation());
if (isError)
return;
}
if (!isError)
batchProcessor.sendAll();
if (this.isBroadcastAllowed != 'true')
batchProcessor._updateTableWithStatus(this.conversationIds,'ignored','Filtered out the "notification" type conversation due to system property "allow_broadcast" disabled');
} catch (err) {
var message = "CI analytics processor job failed:" + err.message;
if (err.stack)
message = message + "\n" + err.stack;
this.logger.error(message);
}
},
_validConversation: function(caConversationGr, interactionGr, notificationGr) {
if (!this.validConversationFn) {
return true;
}
this.evaluator.putVariable('convGr', caConversationGr);
this.evaluator.putVariable('interactionGr', interactionGr);
this.evaluator.putVariable('notificationGr', notificationGr);
return this.evaluator.evaluateScript(this.validConversationFn, "value_script", null);
},
_validationFormula: function() {
var gr = new GlideRecord('sn_ci_analytics_formula_override');
gr.addQuery('key', 'Active Conversation');
gr.addQuery('type', 'eligibilitycriteria');
gr.addQuery('active', true);
gr.query();
if (gr.next()) {
return gr;
}
return null;
},
_queryNotification: function(conversationId) {
var notificationGr = new GlideRecord('sys_cs_notification');
notificationGr.addQuery('conversation', conversationId);
notificationGr.query();
return notificationGr;
},
_queryCAConversation: function() {
var caConversationGr = new GlideRecord('sn_ci_analytics_conversation');
caConversationGr.addQuery('status', 'new').addOrCondition('status', 'onHold');
caConversationGr.orderBy('consumer');
caConversationGr.orderBy('sys_created_on');
if (this.jobMaxConversationCount > 0)
caConversationGr.setLimit(this.jobMaxConversationCount);
caConversationGr.query();
return caConversationGr;
},
_canIgnoreConversation: function(caConversationGr, notificationGr, lastOpenUser) {
var currentRecordUser = caConversationGr.conversation.consumer;
var conversationId = caConversationGr.conversation.sys_id;
var state = caConversationGr.conversation.state;
var status = caConversationGr.status;
while (notificationGr.next()) {
var notificationState = notificationGr.state;
if (notificationState == 'pending' || notificationState == 'sent') {
var params = [conversationId, CABatchProcessor.batchId, notificationState, caConversationGr.conversation.consumer.name];
this.logger.info("Conversation:{0}, BatchId:{1}, Notification State: {2}, Conversation Consumer: {3}", params);
return true;
}
}
if (state == 'open' || state == 'chatInProgress' || status == 'onHold')
return true;
return currentRecordUser == lastOpenUser;
},
_updateConversationStateAsIgnored: function(caConversationGr, reason) {
caConversationGr.setValue('status', 'ignored');
caConversationGr.setValue('reason', reason);
caConversationGr.update();
this.logger.info('Conversation ignored from formula override: {0}', [caConversationGr.conversation]);
},
_processConversation: function(caConversationGr, notificationGr) {
var conversationId = caConversationGr.conversation.sys_id;
var interactionGr = this._queryInteraction(conversationId);
if (!this._validConversation(caConversationGr, interactionGr, notificationGr)) {
this._updateConversationStateAsIgnored(caConversationGr, 'Filtered out from the "Active Conversation" formula override');
return false;
}
this.payloadBuilder.buildConversation(caConversationGr, interactionGr);
this.payloadBuilder.addUser(caConversationGr);
var conversationTask = this.payloadBuilder.queryConversationTask(conversationId);
var intentPrediction = {
isCorrectPrediction: false,
isAutoSelected: false,
isUnsupportedPrediction: false,
};
var nluIntents = [];
var taskIds = [];
while (conversationTask.next()) {
var topicName = conversationTask.topic_type.name;
taskIds.push(conversationTask.getValue('sys_id'));
if (this._isPreviewedConversation(topicName)) {
var params = [conversationTask.getValue('sys_id'), topicName];
this._updateConversationStateAsIgnored(caConversationGr, 'Previewed Conversation');
this._logDebug('ConversationTask: {2}, Previwed topic found {3}, conversation ignored.', conversationId, params);
return false;
}
if (this._filterInternalTopicBlock(conversationTask))
continue;
if (topicName)
this.payloadBuilder.addTopic(conversationTask);
this._processIntents(conversationTask, conversationId, nluIntents, intentPrediction);
this.payloadBuilder.addTopicNodes(conversationTask);
}
this._modifyIntentEvents(nluIntents, intentPrediction);
this.payloadBuilder.addIntentsToConversation(nluIntents);
this.payloadBuilder.updateDeflectionCount(taskIds);
return true;
},
_filterInternalTopicBlock: function(taskGr) {
if (taskGr.topic_type.type == 'TOPIC_BLOCK' && taskGr.calling_task.topic_type.type == 'SETUP_TOPIC')
return true;
return false;
},
_isPreviewedConversation: function(topicName) {
if (!gs.nil(topicName) && topicName.startsWith('_PRVW_'))
return true;
return false;
},
_queryInteraction: function(conversationId) {
var interactionGr = new GlideRecord('interaction');
interactionGr.addQuery('channel_metadata_document', conversationId);
interactionGr.addQuery('channel_metadata_table', 'sys_cs_conversation');
interactionGr.query();
interactionGr.next();
return interactionGr;
},
_processIntents: function(conversationTask, conversationId, nluIntents, intentPrediction) {
var openNluIntentFeedbackGr = new GlideRecord('open_nlu_predict_intent_feedback');
openNluIntentFeedbackGr.addQuery('app_document_table', 'sys_cs_conversation_task');
openNluIntentFeedbackGr.addQuery('app_document', conversationTask.sys_id);
//openNluIntentFeedbackGr.addQuery('mapped', true);
//openNluIntentFeedbackGr.addNotNullQuery('prediction');
openNluIntentFeedbackGr.query();
if(openNluIntentFeedbackGr.getRowCount() > 1) {
this.payloadBuilder.updateMutiplePredictionsCount();
}
while (openNluIntentFeedbackGr.next()) {
var prediction = openNluIntentFeedbackGr.prediction;
var nluIntentGr = new GlideRecord('sys_nlu_intent');
nluIntentGr.addQuery('name', prediction);
nluIntentGr.query();
if (!nluIntentGr.next())
this._logDebug("Nlu intent not found in sys_nlu_intent table for predication: {2}", conversationId, [prediction]);
var topicLangGr = new GlideRecord('sys_cs_topic_language');
topicLangGr.addQuery('nlu_intent', prediction);
topicLangGr.query();
if (!topicLangGr.next())
this._logDebug("Topic not found in sys_cs_topic_language table for nlu intent: {2}", conversationId, [prediction]);
var intentEvent = this.payloadBuilder.buildIntentEvent(openNluIntentFeedbackGr, nluIntentGr, topicLangGr);
if(intentEvent['Name'] == this.UNSUPPORTED_INTENT) {
intentPrediction.isUnsupportedPrediction = true;
}
if (intentEvent['Name'] == this.CORRECT_INTENT)
intentPrediction.isCorrectPrediction = true;
if (intentEvent['Name'] == this.AUTO_SELECTED)
intentPrediction.isAutoSelected = true;
nluIntents.push(intentEvent);
}
},
_modifyIntentEvents: function(nluIntents, intentPrediction) {
var correctName;
if (intentPrediction.isUnsupportedPrediction)
correctName = this.UNSUPPORTED_INTENT;
else if (intentPrediction.isCorrectPrediction)
correctName = this.CORRECT_INTENT;
else if (intentPrediction.isAutoSelected)
correctName = this.AUTO_SELECTED;
else
return;
nluIntents.forEach(function(event) {
event['Name'] = correctName;
});
},
_processEvents: function(conversationId, oobEventProcessor) {
oobEventProcessor.process(this.payloadBuilder);
this.clickMetricsEventProcessor.process(this.payloadBuilder);
var eventsGr = new GlideRecord('sn_ci_analytics_event');
eventsGr.addQuery('active', true);
eventsGr.query();
while (eventsGr.next()) {
var queryTable = eventsGr.source_table;
var condition = eventsGr.source_table_filter;
var conversationMappingField = eventsGr.conversation_mapping_field;
this.payloadBuilder.preProcessCustomEvent(eventsGr);
var sourceGr = new GlideRecord(queryTable);
if (sourceGr.isValid()) {
var query = conversationMappingField + "=" + conversationId;
if (!(condition == null || condition == ''))
query = query + "^" + condition;
sourceGr.addEncodedQuery(query);
sourceGr.query();
while (sourceGr.next())
this.payloadBuilder.addCustomEvent(sourceGr, eventsGr);
}
}
},
_processOverrides: function(conversationId) {
var overridesGr = new GlideRecord('sn_ci_analytics_formula_override');
overridesGr.addQuery('type', '!=', 'eligibilitycriteria');
overridesGr.addQuery('active', true);
overridesGr.query();
while (overridesGr.next())
this.payloadBuilder.processOverride(overridesGr, conversationId);
},
_logDebug: function(msg_template, conversationId, params) {
if (this.logger.isDebugEnabled()) {
var arrayUtil = new global.ArrayUtil();
var defaultParams = [conversationId, CABatchProcessor.batchId];
var argParams = arrayUtil.convertArray(params);
var mergedArray = arrayUtil.union(defaultParams, argParams);
msg_temp = "Conversation:{0}, BatchId:{1}, " + msg_template;
this.logger.debug(msg_temp, mergedArray);
}
},
type: 'CAProcessor'
};
Sys ID
854fefe4733210107d804c9885f6a7bd