Thursday, September 10, 2020

Make a call to the Incident Caller - How to read the Docs - Twilio Part 6

 Hi Developers,

In the last article, we have seen, how to make use of the out of the box related links on task records to make a conference call or send a message. In this article we will be creating a custom icon using UI Macro on incident form that will allow an Resolver to directly make a conference call with the Incident Caller. Seems interesting? it is!

UI macros are discrete scripted components administrators can add to the user interface. Wonder what does it mean? You might have seen little action icons next to fields on forms, for example :

This little user (Add me) icon next to the 'Assigned to' field, when clicked, adds currently logged in user to the Assigned to field.

You can visit SNGuru or check out TechNow Episode 3 video on ServiceNow Jelly Scripting by none other than @Chuck Tomasi to check the scripting logic behind this.

UI macros are typically controls that provide inputs or information not provided by existing field types. Let us understand this by means of an example :

The Show Related Incidents icon is a reference icon that appears beside the Caller field on the default incident form, when the field is populated. When clicked, it opens a browser window displaying a list of other incidents for same caller.

Now if you have got an idea about what UI Macros are and what it does, let us proceed with the development of our business requirement. Here, we will be making use of some Jelly, do not worry if you are not familiar with Jelly yet.

Step 1) Navigate to System UI > UI Macros and click 'New'

Step 2) Give it a unique name

Step 3) Replace the existing code of XML field by the following snippet :

<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
	<style>
		.hide_icon {
			visibility: hidden;
		}
		.show_icon {
			visibility: visible;
		}
	</style>
	<g2:evaluate var="jvar_show_hide_icon" object="true" jelly="true">
		var r=new myNotifyHandler().macroVisibility();
		r;
   </g2:evaluate>
	<j:set var="jvar_n" value="Make a Call ${ref}" />
	<a id="${jvar_n}" onclick="makeCall('${ref}')" class="$[jvar_show_hide_icon]">
		<span class="glyphicon glyphicon-headphones" style="font-size:25px;color:black;text-shadow:2px 2px 4px #000000;"></span>
	</a>
	
	<script>
	function makeCall(reference){
		var a=reference.split('.');
		var referenceField=a[1];
		var c=g_form.getValue(referenceField);
		 var createRes = new GlideAjax('myNotifyHandler');
                createRes.addParam('sysparm_name', 'callCaller');
                createRes.addParam('sysparm_c', c);
                createRes.getXML();
		}
	</script>
</j:jelly>

Now let us understand the above code.

<j:set var="jvar_n" value="Make a Call ${ref}" />

In the above code Jelly tag 'set' sets a variable 'jvar_n' to the value returned from value attribute. in this particular case it will be 'Make a Call ${ref}' where '${ref}' will be replaced by the referenced field as 'incident.caller_id' and the final value will become 'Make a Call incident.caller_id'.

<a id="${jvar_n}" onclick="makeCall('${ref}')" class="$[jvar_show_hide_icon]">
		<span class="glyphicon glyphicon-headphones" style="font-size:25px;color:black;text-shadow:2px 2px 4px #000000;"></span>
	</a>

In the above code 'a' tag will create a link to our bootstrap icon specified in 'span' tag. The onclick attribute onclick="makeCall('${ref}')" fires on a mouse click on the element and Execute a JavaScript code written in 'makeCall' function when an icon is clicked.

<g2:evaluate var="jvar_show_hide_icon" object="true" jelly="true">
		var r=new myNotifyHandler().macroVisibility();
		r;
   </g2:evaluate>

The evaluate tag evaluates JavaScript code (server side), and makes variables visible to future code. Unlike other tags, the evaluate tag evaluates the content that is inside the tag as server side JavaScript. In the above code we will be calling a script include named 'myNotifyHandler' and it's function 'macroVisibility' to check whether macro should be visible to the currently logged in user or not. We will see how to write this Script Include in later steps. This function will return a class value to be set in our anchor tag later.

<style>
		.hide_icon {
			visibility: hidden;
		}
		.show_icon {
			visibility: visible;
		}
	</style>

The 'style' tag specifies styles to be applied to an element for a specified class. In our case. it will hide the icon if class is be hide_icon or will display the icon if it is show_icon.

<script>
	function makeCall(reference){
		var a=reference.split('.');
		var referenceField=a[1];
		var c=g_form.getValue(referenceField);
		 var createRes = new GlideAjax('myNotifyHandler');
                createRes.addParam('sysparm_name', 'callCaller');
                createRes.addParam('sysparm_c', c);
                createRes.getXML();
		}
	</script>

The 'script' tag is used to embed a client-side script (JavaScript). Whenever the icon is clicked this script will be executed. The parameter 'reference', in this case, will have field name as 'incident.caller_id'. Our code will retrieve the field name 'caller_id' by splitting the value and then it will call g_form method to retrieve field Caller's sys_id. Then we are calling 'callCaller' function and passing the caller sys_id to it for further processing.

I would suggest you to go through ServiceNow documentation for learning more about Jelly Tags and https://www.w3schools.com/ for HTML, CSS, Bootstrap or XML.

Step 4) Click 'Submit'

Step 5) Navigate to System UI > Script Includes and click 'New'

Step 6) Give it a (unique) name as 'myNotifyHandler' (Since, we have used the same script include name to be called in our macro).

Step 7) Make it accessible from 'All application scopes'

Step 8) Make it 'Client callable'

Step 9) Replace the existing 'Script' by the following code snippet :

var myNotifyHandler = Class.create();
myNotifyHandler.prototype = Object.extendsObject(AbstractAjaxProcessor, {
    callCaller: function() {
        var c = this.getParameter('sysparm_c');
        var gc = new GlideRecord('sys_user');
        gc.get(c);
        var cm = gc.getValue('mobile_phone');

        var r = gs.getUserID();
        var gr = new GlideRecord('sys_user');
        gr.get(r);
        var rm = gr.getValue('mobile_phone');

        var notify = new SNC.Notify();
        var from = gs.getProperty('glide.notify.task.phone_number');
        var participants = [cm.toString(), rm.toString()];

        // set up a conference call
        var conferenceCall = notify.conferenceCall();

        // set up the outbound calls for all conference call participants
        for (var i in participants) {
            var to = participants[i];
            notify.call(from, to, conferenceCall);
        }

    },
	macroVisibility: function() {
		if(gs.hasRole('itil')){
			return 'show_icon';
		}else{
			return 'hide_icon';
		}
    },
    type: 'myNotifyHandler'
});

Let us understand what this script does. let us first look at the function 'macroVisibility' :

macroVisibility: function() {
		if(gs.hasRole('itil')){
			return 'show_icon';
		}else{
			return 'hide_icon';
		}
    },

here, gs.hasRole('itil') will return true only if currently logged in user will have an role 'itil', in which case it will return 'show_icon' and tell our macro to be visible. If user doesn't have the role we will be returning 'hide_icon' and will hide the macro. Thereby we will be controlling the icon to be visible to only Resolvers or users having ITIL role in other words. 

The GlideSystem (referred to by the variable name 'gs' in any server-side JavaScript) API provides a number of convenient methods to get information about the system, the current logged in user, etc. hasRole(String roleName) method determines if the current user has at least one of the passed-in roles.  You can read more about it here.

Now let us take a look at our other function 'callCaller' :

callCaller: function() {
        var c = this.getParameter('sysparm_c');
        var gc = new GlideRecord('sys_user');
        gc.get(c);
        var cm = gc.getValue('mobile_phone');

        var r = gs.getUserID();
        var gr = new GlideRecord('sys_user');
        gr.get(r);
        var rm = gr.getValue('mobile_phone');

        var notify = new SNC.Notify();
        var from = gs.getProperty('glide.notify.task.phone_number');
        var participants = [cm.toString(), rm.toString()];

        // set up a conference call
        var conferenceCall = notify.conferenceCall();

        // set up the outbound calls for all conference call participants
        for (var i in participants) {
            var to = participants[i];
            notify.call(from, to, conferenceCall);
        }

    },

here, In the following lines of code we will be getting mobile numbers of caller of the incident and the resolver who clicked the icon :

var c = this.getParameter('sysparm_c');
        var gc = new GlideRecord('sys_user');
        gc.get(c);
        var cm = gc.getValue('mobile_phone');

        var r = gs.getUserID();
        var gr = new GlideRecord('sys_user');
        gr.get(r);
        var rm = gr.getValue('mobile_phone');

In the ServiceNow documentation here, you will find all the scripts that you can use with Notify to interact with calls and SMS messages, or to provide a custom client interface.

Notify - conferenceCall() Creates a new conference call. We have copied the code snippet available here and modified it for our purpose :

If you compare both the codes, you will realize,

var from = '+14041234567';
var participants = ['+31612345678', '+31623456789', '+31687654321'];

the above code from example snippet has been changed in our code to :

var from = gs.getProperty('glide.notify.task.phone_number');
        var participants = [cm.toString(), rm.toString()];

The system property 'glide.notify.task.phone_number' stores Notify phone number used for sending SMS-s and starting conference calls from any record that belongs to the task table (or table that extends task table).

Step 10) Click 'Submit'

Step 11) Navigate to Incident > All and open any incident record

Step 12) Right click the 'Caller' field and select 'Configure Dictionary'

Step 13) Add the attribute ref_contributions=ui_macro_name to the Attributes field and click 'Update'

Dictionary attributes alter the behavior of the table or element that the dictionary record describes.

Dictionary attribute ref_contributions displays an icon for a reference field and when the field renders on a form, it invokes the named UI macro. If there are more than one macro like in this case, they are separated by semicolons (;).

Step 14) Navigate back to your incident form and you'll see an icon next to Caller field if you will have 'itil' role.

Step 15) Click the new icon we added and you'll be added to the conference call with the caller of the current incident.

So we have created an icon next to caller that, when clicked, will allow a user with ITIL role to connect with the incident caller directly in conference call.

In next article, we will solve another business requirement. Till the time, I would recommend you to visit the sources that I have mentioned in the article to have better idea about UI Macros :

Also there is an awesome and short similar community article 'Integrating ServiceNow with Twilio Services with the help of Notify API' written by @Abhishek Gardade that would help you to picture the scenerio in one shot and it will provide the ready-made update set that you can directly download and import.

If you have any queries regarding, UI Page, UI Macro, Jelly, or Twilio, Please mention in the comments or post a question to the ServiceNow Community. We would love to help.

Thank you.

Vishal Ingle

ServiceNow Certified System Administrator

DxSherpa Technologies Pvt. Ltd.

Pune, MH, IN.

 

Monday, September 7, 2020

Using Notify with tasks - How to read the Docs - Twilio Part 5

Hello Developers,

Till now, in this series of articles, we had setup Twilio, integrated it with Notify and tested our configurations. Now it's time for fun and using the Twilio functionality in ServiceNow to make calls, send messages, using it to reduce the time of incident resolution and what not?

In next few articles we will be trying our hands on actual development, though I will not be able to cover all the business scenerios as well as the Premium features available to only Twilio users with PAID accounts. I'll recommend you to go through both Twilio ServiceNow official documentations to learn more and use it in your projects.

In this article we will get an idea about Using Notify with tasks.

Notify allows you to initiate conference calls and send SMS alerts from task records.

Step 1) Navigate to any task record, such as an incident or change request. In this example we will navigate to an Incident record.

Navigate to Incident Open and open any of the Incident.

Now the screen will be somewhat like this :

Step 2) Scroll down a bit to find 'Related Links' section and click the 'Start conference call' related link.

You'll get a pop-up :

Step 3) Select one or more Recipients to participate in the conference call.

The Caller (Opened by) of the incident will be added as a participant by default. You can add Resolver (Assigned to) from Recommended list to Selected list of participants.

More participants can be added manually by search :

Step 4) Include a brief message for participants and Click Start.

The Conference call will start and the selected participants will receive a conference call :

and a text message with conference details :

You will receive an Info message on console with Conference number :

And the information will also be captured in activity stream/ work notes of an incident.

Any conference call records created from a task are associated with that task. You can view associated conference calls from the task record in the Conference calls related list. You may need to configure the form to add the related list.

Step 5) Navigate to the form view you want to add a related list to. Right-click the form header and click Configure > Related Lists.

Step 6) Select Conference calls from slush bucket and click 'Save'.

Now you will be able to see the related list and conference details on incident form :

So, we have used Notify to start conference calls from an incident record. This functionality is available for all tables that extend the Task table, such as incident, problem, or change request.

All calls and messages made from tasks are initiated using a single Notify phone number (E.164 or short code). You can configure which phone number is used by setting the property glide.notify.task.phone_number.

Notify must be set up before you can use Notify on task. We already made the following configurations in our previous steps mentioned in earlier articles in this series, so you don't need to worry about it.

Ensure there are Notify phone numbers (E.164 or short code) in number groups with phone call workflow.

Use glide.enable.notify_on_task property to enable Notify integration for Task table and its extensions. Entering phone number in glide.notify.task.phone_number property is equivalent to setting glide.enable.notify_on_task to true.

Read more about Manage conference calls on task & Send an SMS alert from a task at ServiceNow Docs, those are similar concepts.

In the next article we will create a custom Macro that will allow the resolver to directly make a conference call to the caller of the incident.

Please ping me your queries here in the comments or post a question in the community, we would love to help.

Thank you.

Vishal Ingle

ServiceNow Certified System Administrator

DxSherpa Technologies Pvt. Ltd.

Pune, MH, IN.

Sunday, September 6, 2020

Testing Notify-Twilio Integration - How to read the Docs - Twilio Part 4

 Hi Developers,

In last few articles in this series we have learnt how to setup the Twiliohow to configure Twilio with ServiceNow Notify and how to setup NotifyAnd as we have already discussed, it's always better and equally important to test your integration and configurations before proceeding forward with the development.

All the information for Twilio-Direct callback testing is available at ServiceNow Docs.

We will be making an outgoing call & will be sending an SMS using Twilio and trigger callbacks to ServiceNow to test whether Twilio can reach the instance.

Step 1) Navigate to Notify > Administration > Twilio Direct Configuration.

Step 2) Click 'here' in the Info Message 'This record is in the Twilio Direct Driver application, but Global is the current application. To edit this record click here.' to change the application scope.

The screen will look somewhat like below :

Step 3) Click 'Test Callbacks'

Step 4) Fill the 'To' field with your mobile number, let the Test type as 'Call' and leave the Message field as is. Click Initiate Test Call.

Your screen will now look somewhat like this :

And you will recieve a voice call from Twilio number on your mobile number specified in 'To' field :

Step 5) You can also view when the last callback test was run, its status, and the test logs. Click 'View logs' in the success message 'Callback test successful. View logs for more details.'

Your screen will look somewhat like this :

Step 6) Open the recent test record and observe the details.

Step 7) Now let us test the SMS, In Step 4, Change the Test type as 'SMS', fill the 'To' field with your mobile number and leave the Message field as is. Click Initiate Test SMS.

Now your window will look somewhat like this :

And you will receive a text message from from Twilio :

Step 8) Click 'View logs' in the success message 'Callback test successful. View logs for more details.'  and open the recent test record.

Step 9) Observe the callback test results.

If our tests are successful, that means we are good to proceed. If you get any kind of error, please mention it in comments or post a question to community, we would love to help.

An important points to remember here is, The callbacks can be tested only after a connection is established with Twilio.

So far we have everything we need to start development. In the next post we will be discussing how to make use of Twilio functionality on Tasks.

Thank you.

Vishal Ingle

DxSherpa Technologies Pvt. Ltd.

Pune, MH, IN.