Name

global.TopicControlUsageUtil

Description

Processes and saves analytics about the published topic for LUA

Script

var TopicControlUsageUtil = Class.create();
  TopicControlUsageUtil.prototype = {
      initialize: function() {
  		this.logger = new GlideChatbotLoggerSetupUtil("com.glide.cs").setup();
  },

  _hasExistingUsageData: function(cs_topic_id) {
      var gr = new GlideRecord('sys_cs_topic_control_usage');
      gr.addQuery('cs_topic_id', cs_topic_id);
      gr.query();
      return gr.hasNext();
  },

  _deleteExistingUsageData: function(cs_topic_id) {
      var gr = new GlideRecord('sys_cs_topic_control_usage');
      gr.addQuery('cs_topic_id', cs_topic_id);
      gr.query();
      gr.deleteMultiple();
  },

  _stringifyUsage: function(usage) {
      if (!usage || JSON.stringify(usage) === '{}') {
          return null;
      }
      return JSON.stringify(usage);
  },

  _saveNodeData: function(cs_topic_id, version, node, subtype, usage) {
      var gr = new GlideRecord('sys_cs_topic_control_usage');
      gr.initialize();
      gr.cs_topic_id = cs_topic_id;
      gr.node_id = node.id;
      gr.node_name = node.name;
      gr.step_type = node.stepType;
      gr.subtype = subtype;
      gr.graph_version = version;
      gr.usage = this._stringifyUsage(usage);
      gr.insert();
  },

  processGraph: function(graphJson, cs_topic_id, overwrite) {
      try {
          if (!overwrite && this._hasExistingUsageData(cs_topic_id)) return;

          if (!graphJson) return;

          var graph = JSON.parse(graphJson);

          // before adding new node data
          this._deleteExistingUsageData(cs_topic_id);

          // get the first and only goal either 'primary' or some UUID for older topics
          var goalId = Object.keys(graph.goals)[0];
          var version = graph.graph_api_version;
          var nodes = graph.goals[goalId].nodes || [];
          var variables = graph.variables;
          for (var nodeId in nodes) {
              var node = nodes[nodeId];
              var stepType = node.stepType;
              switch(stepType) {
                  case 'Start':
                      // ignore
                      break;
                  case 'TerminateGoal':
                      // ignore
                      break;
                  case 'ImplicitEnd':
                      // ignore
                      break;
                  case 'Prompt':
                      this._processPrompt(cs_topic_id, version, node, variables);
                      break;
                  case 'GroupedChoicePrompt':
                      this._processGroupedChoicePrompt(cs_topic_id, version, node);
                      break;
                  case 'TextOutput':
                      this._processTextOutput(cs_topic_id, version, node);
                      break;
                  case 'RecordOutput':
                      this._processRecordOutput(cs_topic_id, version, node);
                      break;
                  case 'ReusableTopic':
                      this._processReusableTopic(cs_topic_id, version, node);
                      break;
                  case 'CustomControl':
                      this._saveNodeData(cs_topic_id, version, node, node.reusableTopicChoice);
                      break;
                  case 'OneExtendCapability':
                      this._processOneExtendCapability(cs_topic_id, version, node);
                      break;
                  default:
                      this._saveNodeData(cs_topic_id, version, node);
              }
          }
      } catch (e) {
          this.logger.error('Error occured while processing topic control usage for cs_topic_id: ' + cs_topic_id + ' ' + e.toString());
      }
  },

  _processPrompt: function(cs_topic_id, version, node, variables) {
      var variable = variables[node.variableId];
      var usage = {};
      var varType = '';
      if (variable.secure) {
          usage.secure = true;
      }
      if (variable.varType === 'string') {
          varType = 'string';
      }
      else if (variable.varType === 'boolean') {
          varType = 'boolean';
      }
      else if (variable.varType === 'date_time') {
          varType = 'datetime';
      }
      else if (variable.varType === 'image') {
          varType = 'image';
      }
      else if (variable.varType === 'file') {
          varType = 'file';
      }
      this._saveNodeData(cs_topic_id, version, node, varType, usage);
  },

  _processGroupedChoicePrompt: function(cs_topic_id, version, node) {
  	var usage = {};
  	var varType = 'array.string';
  	var groups = node.groups;
  	usage.multipleGroups = groups.length > 1;
  	groups.forEach(function(group) {
  		if (!group.isMultipleSelect) {
  			usage.singleSelectGroup = true;
  		}

  		if (group.isMultipleSelect) {
  			usage.multiSelectGroup = true;
  		}

  		group.choices.forEach(function(choice) {
  			if (choice.meta.image.value) {
  				usage.imageInChoiceItem = true;
  			}
  		});
  	});

  	usage.singleSelectGroup = usage.singleSelectGroup || false;
  	usage.multiSelectGroup = usage.multiSelectGroup || false;
  	usage.imageInChoiceItem = usage.imageInChoiceItem || false;
  	this._saveNodeData(cs_topic_id, version, node, varType, usage);
  },


  _processTextOutput: function(cs_topic_id, version, node) {
      var usage = {};

      if (node.secure) {
          usage.secure = true;
      }
      var value = node.value.value;
      if (value) {
          findRichTextUsage(value);
      } else {
          value = node.value;
          if (value.length > 1) {
              usage.alternateMessage = true;
          }
          value.forEach(function(variation) {
              findRichTextUsage(variation.value);
          });
      }

      function findRichTextUsage(value) {
          if (value.type === 'emoji') {
              usage.emoji = true;
          }
          if (value.type === 'link') {
              usage.link = true;
          }
          if (value.type === 'bulleted-list') {
              usage.bulletedList = true;
          }
          if (value.type === 'numbered-list') {
              usage.numberedList = true;
          }
          if (value.bold) {
              usage.bold = true;
          }
          if (value.italic) {
              usage.italic = true;
          }

          if (value.children) {
              findRichTextUsage(value.children);
          }

          if (Array.isArray(value)) {
              value.forEach(function(child) {
                  findRichTextUsage(child);
              });
          }
      }
      this._saveNodeData(cs_topic_id, version, node, node.value.mode, usage);
  },

  _processRecordOutput: function(cs_topic_id, version, node) {
      this._saveNodeData(cs_topic_id, version, node, node.cardTemplate);
  },

  _processReusableTopic: function(cs_topic_id, version, node) {
        var usage = {};

        if (node.useTemplateTopic) {
           usage.dynamicTopicBlock = true;
         }

         this._saveNodeData(cs_topic_id, version, node, node.reusableTopicChoice, usage);
   },

  _getCapabilityName: function(definitionId) {
      var gr = new GlideRecord('sys_one_extend_capability_definition');
      var capabilityName = '';
      if (gr.get(definitionId))
          capabilityName = gr.capability.name.toString();

      return capabilityName;
  },

  _processOneExtendCapability: function(cs_topic_id, version, node) {
      var capabilityName = this._getCapabilityName(node.definitionId);
      this._saveNodeData(cs_topic_id, version, node, capabilityName);
  },

  type: 'TopicControlUsageUtil'
};

Sys ID

471672c6b7948110d033d76cde11a9e0

Offical Documentation

Official Docs: