Paul Kunze
Tera Guru

Hello community,

here I will share some of my learnings about creating a custom CTI (Computer Telephony Integration) script for the HR Case form.

When this is successfully implemented, it means that an HR employee who gets a phone call will automatically be redirected to an HR Case form pre-filled with the calling user.

 

First let me explain the basics to set this up:

By default when you open a url like https://yourinstance.service-now.com/cti.do an empty incident form will open. By passing some parameters in the URL you can also specify which incident to open or which user to select. The official documentation from ServiceNow can be found here.

There is also a comment about defining your own CTI script but it is very short and even a bit confusing, that is why I am creating this more detailed explanation here. I had to go through some trial and error myself and want to share my learnings.

 

Creating the Business Rule

If you do not want to open the incident form but another link in the instance then you need to define your own CTI script. You could overwrite the existing script (which can be found in the Business Rule "CTI Processing") but that is not recommended. Instead, you should create a new Business Rule for your own usecase.

I know that it is a bit confusing that you have to write the script in a Business Rule. But that is how the architects at ServiceNow decided to do it. The trick is to create the Business Rule for the table "Global" and to make it client callable (you need to display that field in the list layout and set the value to true there). For my example the Business Rule is created as follows:

  • Name: CTI for HR Case
  • Scope: Global
  • Table: Global [global]
  • Accessible from: This application scope only
  • Active: true
  • Advanced: true
  • Client callable: true

find_real_file.png

 

Writing the Script

What comes next is your script in the advanced tab of the Business Rule. What you definitely need in there is a function that at least assigns a value to the answer variable and returns the same value. The simplest example would be this:

function createHrCase() {
  var url = 'sn_hr_core_case_creation.do';
  answer = url;
  return url;
}

 

When you have come this far you can already start your first test: Open the URL https://yourinstance.service-now.com/cti.do?sysparm_cti_rule=createHrCase and you will be redirected to the HR Case form.

The parameter “sysparm_cti_rule” tells the CTI processor which function to execute. If it is the name of the function in your Business Rule then this will be called. If the name you provided is unknown it will default to opening an incident form.

 

Now that we can open an HR Case form we can take the next step and pre-populate a user. Let’s extend our script to the following:

function createHrCase() {
  var userSysId = '';

  // get url parameter
  if(typeof sysparm_user_id != 'undefined'){
    userSysId = sysparm_user_id.toString();
  }
 
  // build url to redirect to
  var url = 'sn_hr_core_case_creation.do?sysparm_user=' + userSysId;
  answer = url;
  return url;
}

 

After saving this you can for example open the URL https://yourinstance.service-now.com/cti.do?sysparm_cti_rule=createHrCase&sysparm_user_id=62826bf03710200044e0bfc8bcbe5df1. If you provide a valid sys_id for a user, it will pre-populate that user in your HR Case form. That is because the page https://yourinstance.service-now.com/sn_hr_core_case_creation.do is also listening for certain parameters.

Please note the following points:

  • Your parameter must start with sysparm_ otherwise it will not work
  • You need to check if the parameter is really provided, otherwise if not an error will be thrown and the whole script will abort (defaulting to the incident form)
    • Do this with typeof ... != 'undefined'
  • You need to convert the parameter to a String, otherwise it will be an object and might not behave as you want (this caused me some headache)

 

In most cases you will not know the sys_id and want to provide a different parameter. That is no problem either because you are completely free to use anything you have access to in the script. For example if you only know the username of the user why not find the sys_id using a GlideRecord? The script would then look as follows:

function createHrCase() {
  var username = '';
  var userSysId = '';
 
  // get url parameter
  if(typeof sysparm_user_name != 'undefined'){
    username = sysparm_user_name.toString();
  }
             
  // get user record
  var grUser = new GlideRecord('sys_user');
  if(username != '' && grUser.get('user_name', username)){
    userSysId = grUser.getValue('sys_id');
  }
 
  // build url to redirect to
  var url = 'sn_hr_core_case_creation.do?sysparm_user=' + userSysId;
  answer = url;
  return url;
}

 

This example can be tried out by opening the URL https://yourinstance.service-now.com/cti.do?sysparm_cti_rule=createHrCase&sysparm_user_name=abel.tuter

find_real_file.png

 

This is already it. Not too complicated but you need to know how to do it. I hope my little tutorial will help some people.

Comments
Ryan126
Tera Contributor

Thanks for the post. 

Do you know of a way to always open the new ServiceNow form in a new tab by controlling this behavior *ONLY* in ServiceNow?  Thus, whenever a new form is created via this integration, we always want the form to open in a new tab, even if there already is a ServiceNow tab open (because otherwise it just overwrites the existing tab). 

Thanks, interested in people's thoughts on this.    

Paul Kunze
Tera Guru

That is a good question. I don't think that this is possible because when the script is running the page needs to be already open.

What you can try as a workaround is to open additional tabs with window.open(yourUrl, '_blank'); and navigate back on the main page by calling window.history.back();

kurtbell1
Giga Expert

This is REALLY helpful.  Thanks for this.

 

Quick followup question - in your implementation how does the Agent interact between the IVR system and ServiceNow?   Do they pick up the call in the IVR agent panel and then click a link that invokes the CTI.do url?  Just curious how their click-by-click goes in your environment.

Paul Kunze
Tera Guru

Thank you, I'm glad that it helped 🙂

In the implementation for my client the telephony system automatically opened a new browser tab with the correct link for ServiceNow as soon as the agent picked up the call. So no manual click was needed.
This was achieved by making the ServiceNow link known to the telephony system which only had to dynamically add the correct parameter to the URL (like the user name or phone number).

JJ1
Kilo Guru

Hello Paul,

 

Just curious to know if you considered the possibility of using agentworkspace to route the calls to agent through the workspace ? I saw some documentation but not exactly sure if anyone has done it with the openFramework they have mentioned in it. 

 

Thanks,

Jeevan

Jagmeet SIngh1
Tera Contributor

Any possibility of using agentworkspace to route the calls to agent through the workspace ? In this implementation?? 

Syed Multhazim1
Tera Contributor

Hey Paul Kunze,

Greetings.

Scenario:
Need to open a case record whenever an incoming call is attended from the open frame window.

Current Situation:
A new IMS record is getting displayed upon answering the call.

I've created a new Client Callable Business Rule, now could you please let me know where I should be calling this business rule? Is it in the screenpop_url system property or should I configure it in my client application ( Cisco Contact Center )? I've added images of the system property and the Business rule.

Below is the image of the system property:

image.png

Below is the image of Business Rule:

SyedMulthazim1_1-1679508967772.png

 


Thank you!

 

Paul Kunze
Tera Guru

Hello @Syed Multhazim1,

your URL is correct (/cti.do?sysparm_cti_rule=createCaseRecord), assuming that the function name in your Business Rule is also named "createCaseRecord" (that's not visible in your screenshot).

It's important that exactly this URL is getting opened when you want to initiate your CTI call. If you are utilizing the system property screenpop_url for fetching the correct URL then this looks correct.
In my case the external CTI system already opened the right URL in the user's browser. You could also do this from external or open the link from within ServiceNow, for example by executing "gs.setRedirect(url);".

Best regards,
Paul

brianbeauchamp
Tera Guru

Thanks for a very helpful article on how to use CTI to generate HR cases using sn_hr_core_case_creation.

 

Adding to the question others above have asked, Paul, have you had any experience with this opening in HR Agent workspace?

brianbeauchamp
Tera Guru

With the help of Support I was given the URL to populate the employee verification in HR Agent Workspace.

 

https://<instance>.service-now.com/now/workspace/hr/new_record/sn_hr_core_case/0/params/user-id/<sys_id>/subject-person-id-on-case/<sys_id>

Michael O J
Tera Expert

Great article. 

 

Here is my URL for opening an Interaction in the CSM workspace using the above recipe:

 

https://xxx.service-now.com/cti.do?sysparm_cti_rule=createInteraction&sysparm_caller_customerid=<ID>&sysparm_caller_phone=<phone>
 
The URL build in the BR:
   

 

    var url = 'now/cwf/agent/record/interaction/-1_uid_1/params/query/type=phone';

    // Add Contact if callerSysid is not empty
    if (callerSysId != null) {
        url += "^contact=" + callerSysId;
    }

    //Add Account if callerCustomersysId is not empty
    if (callerCustomerSysId != null) {
        url += "^account=" + callerCustomerSysId;
    }

 

lawrencemgann
Tera Guru

Thank you for this excellent thread @Paul Kunze !  Question for others using CTI for HR --

 

I'm encountering an issue where the URL to create a new Interaction in HR Agent Workspace is always opening in a new browser tab entirely, rather than within a new IMS tab in HR Agent Workspace.

 

I've tried window.open(url, "_self"); and top.window.open(url, "_self"); to attempt to force the link to open in the same tab, but no luck so far.

 

Any thoughts on what might be misconfigured?

 

Link arrives like: 

https://company.service-now.com/cti.do?sysparm_cti_rule=hrCTI&sysparm_caller_id=

 

hrCTI script builds the url like:

if (url == null) {
        url = "now/workspace/hr/new_record/interaction/11/params/user-id/" + profileID + "/subject-person-id-on-case/" + profileID;
        answer = url;
        return url;
    }

 

 Appreciate any thoughts or guidance!

steveo2
Tera Contributor

Hi Lawrence, did you ever find a solution to this in Workspace?  We are looking to implement the same.

Thanks

 

Evaldas Mikelio
Tera Explorer

Hello,

 

Here is the script for workspace. I also tried multiple ways of adding more parameters but according to my consultancy case reply its not possible to prefill more fields from url. 

 

https://<instance>/cti.do?sysparm_cti_rule=createHrCase&sysparm_user_name=<username>

 

 

 

function createHrCase() {
  var username = '';
  var userSysId = '';
 
  // get url parameter
  if(typeof sysparm_user_name != 'undefined'){
    username = sysparm_user_name.toString();
  }
             
  // get user record
  var grUser = new GlideRecord('sys_user');
  if(username != '' && grUser.get('user_name', username)){
    userSysId = grUser.getValue('sys_id');
  }
 
  // build url to redirect to
  var url = 'now/workspace/hr/new_record/sn_hr_core_case/0/params/user-id/' + userSysId + '/subject-person-id-on-case/' + userSysId;
  answer = url;
  return url;
}

 

 

 

Version history
Last update:
‎08-28-2020 08:45 AM
Updated by: