two white printer papers near macbook on brown surface

If you’ve ever worked with Virtual Agent, you probably like it and enjoy designing the topics. However, I always look for something more. And this time, I was thinking to myself: Well, the reports on the platform are nice, these are just charts with some JavaScript. Performance Analytics may be too much, but the reports? It should be doable with OOB components!

And yes, it is possible. Although it requires some advanced scripting knowledge (including HTML and CSS) and the end result may not be as pretty as you wish (but, to be honest, it only depends on your frontend skills). There are some limitations, as always – but I’m sure this kind of task will become easier and easier with time.

This article is based on build glide-utah-12-21-2022__patch1-03-01-2023.


So, how do you put reports in VA?

First, you have to ask yourself a question – What is a report? It is a set of conditions run against a table. Usually it has some graphical representation other than simple list (chart, matrix, single score, …). But there is always a requirement you have to fit in when developing topics. With that in mind, let’s take a look at our possibilities. We definitely want our bot to respond with a report of some sort. What responses we have available?

OOB bot responses in VA topic designer

From the list above there are already some options to consider, based on the report type you want:

  • Table response, for a list view report
  • Link response, when you don’t want to show the data for some reason and you can provide a link to the report
  • Script response, for a scripted report based on platform data

In this article I will focus on the 2rd option, the most complex one.

Using script to output a report

The script component is like a developer’s way around the no-code Topic Designer environmet. It allows you to use one of two undocumented APIs – sn_cs.SinglePartOutMsg and sn_cs.MultiPartOutMsg. As you can easily figure out, these APIs mimic the behaviour of other responses with the benefit of using a script. And with the script you can get data from the instance or even from the VA variables.

Simple script like that:

(function execute() {
    var singleOutMsg = new sn_cs.SinglePartOutMsg();
    singleOutMsg.setHtmlPart('<h1>Incident count</h1><div>' + vaVars.incidentCount + '</div>');
    return singleOutMsg;
})()

Gives you simple output like that:

All that you see is defined on line 3 in the setHtmlPart method. With some additional CSS it could even be just like on the platform and mimic the single score report. But how could you add CSS there? The simplest possible way is to use style attribute.

singleOutMsg.setHtmlPart(
  '<h1>Incident count</h1>' + 
  '<div style="background-color: red">' + 
  vaVars.incidentCount + 
  '</div>'
);

Improving your script to create a pie chart

OK, so now we know that this is possible. What’s next? Is it possible to create a pie chart for example? Yes, it is! Quick search on the Internet gives us multiple options for creating charts based on only HTML and CSS, like for example this simple chart.

With some additional data retrieval and formatting, your script could look like that:

(function execute() {
    var gq = new global.GlideQuery('incident')
            .where('active', true)
            .groupBy('priority') 
            .aggregate('sum', 'reassignment_count') 
            .having('sum', 'reassignment_count', '>', 1)
            .select()
            .toArray(4);
    var reassignmentSum = 0;
    var reassignmentPercents = [];
    var reassignmentLabels = [];
    var chartSum = [];

    gq.forEach(function(group){
        reassignmentSum += group.sum.reassignment_count;
        reassignmentLabels.push('Priority ' + group.group.priority);
    });
    gq.forEach(function(group){
        var sumSoFar = reassignmentPercents.reduce(function(cur, acc){ cur += Number.parseFloat(acc); return cur;}, 0);
        chartSum.push(sumSoFar);
        reassignmentPercents.push((100 * group.sum.reassignment_count / reassignmentSum).toFixed(2));
    });
    var singleOutMsg = new sn_cs.SinglePartOutMsg();
    var reportStyle = '' +
        '<style>' +
            'body{background-color:silver;display:flex;justify-content:center;align-items:center;flex-direction:column}' +
            '#my-pie-chart-container{display:flex;align-items:center}' +
            '#my-pie-chart{background:conic-gradient(' +
                'brown ' + chartSum[0] + ',' + 
                '#000 ' + chartSum[0] + '% ' + chartSum[1] + '%,' + 
                '#00f ' + chartSum[1] + '% ' + chartSum[2] + '%,' + 
                'green ' + chartSum[2] + '% ' + chartSum[3] + '%,' +
                '#ff0 ' + chartSum[3] + '%' +
            ');border-radius:50%;width:150px;height:150px}' +
            '#legenda{margin-left:20px;background-color:#fff;padding:5px}' +
            '.entry{display:flex;align-items:center}' +
            '.entry-color{height:10px;width:10px}' +
            '.entry-text{margin-left:5px}' +
            '#color-yellow{background-color:#ff0}' +
            '#color-green{background-color:green}' +
            '#color-blue{background-color:#00f}' +
            '#color-black{background-color:#000}' +
        '</style>';
    var reportTitle = '<h1>Incident reassignment by priority</h1>';
    var reportPieChart = '' +
        '<div id=my-pie-chart-container>' +
            '<div id=my-pie-chart></div>' +
            '<div id=legenda>' +
                '<div class=entry>' +
                    '<div class=entry-color id=color-black></div>' +
                    '<div class=entry-text>' + reassignmentLabels[0] + '</div>' +
                '</div>' +
                '<div class=entry>' +
                    '<div class=entry-color id=color-blue></div>' +
                    '<div class=entry-text>' + reassignmentLabels[1] + '</div>' +
                '</div>' +
                '<div class=entry>' +
                    '<div class=entry-color id=color-green></div>' +
                    '<div class=entry-text>' + reassignmentLabels[2] + '</div>' +
                '</div>' +
                '<div class=entry>' +
                    '<div class=entry-color id=color-yellow></div>' +
                    '<div class=entry-text>' + reassignmentLabels[3] + '</div>' +
                '</div>' +
            '</div>' +
        '</div>';
    singleOutMsg.setHtmlPart(reportStyle + reportTitle + reportPieChart);
    return singleOutMsg;
})()

And the resulting message from bot would look like that:

Because the HTML part of both the sn_cs.SinglePartOutMsg and sn_cs.MultiPartOutMsg APIs is added as a shadow root to the conversation window, we can provide <style> tag and be sure that CSS added there will apply only to this particular script output.

Conclusion

With some general knowledge about the requirements, understanding of basics of web development, you can really do a lot with Virtaul Agent conversation. Especially in web development, when you can use a script, you are pretty much limitless.

Related Post

Leave a Reply

Your email address will not be published. Required fields are marked *