Supported Web Services

SOAP

The Snippet language supports SOAP based web services through the process of generating a proxy. Studio must be used to generate the proxy which is then saved as a .NET DLL into the CXone file system. All web service proxies must be saved to the root folder of the business unit which will use it. It is possible for a system administrator to create a proxy under business unit 3 for shared use, although this has not been done in production as of yet.

SOAP based web services are declining as RESTful web services are taking their place. Our SOAP web service proxy generation process is likely to be discontinued at some point. No new enhancements are planned for the foreseeable future.

Within the proxy generation process, certain capabilities are added to the proxy object so that it works well with CXone. One such added capability is the ability to serialize into a binary stream. All types, including the proxy, must be able to serialize in order for the VC redundancy and script marshaling capability to work. So the Studio proxy generation process is required.

In addition to the serialization capability, the proxy is also configured so that the VC execution engine will properly utilize the thread pool while waiting for a web service call to complete. Without this capability, the VC thread pool will not be used correctly and in result, customers may be affected negatively. It is critical that the proper thread pooling is used.

The final capability added by the Studio process is the ability to track web service usage. As the proxy is called to make external web service calls, counters and time trackers are utilized to record usage and impact. These metrics are saved a few times throughout the day to a database table for administrative use.

Uses

Within a Snippet, the USES command allows a Snippet to include a web service proxy DLL for use within the Snippet. The DLL file must be located either in the current business unit’s root folder on the file server, or in the business unit 3 root folder (for shared use). Syntax:

USES "<proxy>.dll"
	

Examples:

USES "sf.dll"
cStart="{now}"
sforce=new SforceService()
session=new SessionHeader()
loginResult=sforce.login("demo@ucn.net",password6")
sforce.sessionheadervalue=session
session.sessionid=loginResult.sessionid
sforce.url=loginresult.serverUrl

t=new Task()
t.ActivityDate=#"8/20/2050"
t.Description="Call placed by {first }{Last}."
t.Subject="Call @{cStart}"
t.Status="Completed"
t.CallType="Outbound"
t.OwnerId=SF_Agent_ID
t.ReminderDateTime="{cStart}"

SWITCH Type
{
   CASE "CON" { t.WhoId=SF_Obj_ID }
   CASE "LEA" { t.WhoId=SF_Obj_ID }
   CASE "ACC" { t.WhatId=SF_Obj_ID }
   CASE "OPP" { t.WhatId=SF_Obj_ID }
   CASE "CAS" { t.WhatId=SF_Obj_ID }
}
SaveResult=sforce.create(t)
	

NOTE: Before any web service proxy DLL can be used on the platform (outside of Studio testing), it must be authorized. The authorization process today involves adding the DLL name to an authorization text file located on the COR server (where the VC runs). Use the Web Admin Summary page and check the AuthorizedAssemblies configuration setting to verify the location. The format for the entry is BUS<busno>\<proxy>.dll. For example: BUS4\LCWS.dll. Each distinct DLL must be on a new line. If a DLL is updated after it has been used within a script, the only way to get the updated DLL to be used is to restart the VC.

RESTful

The Snippet language works with RESTful web services through a couple of built-in services. The first is the RestProxy service which can be used by creating a new instance in this manner:

proxy = GetRESTProxy()
	

The RestProxy provides a handful of properties and methods to interact with remote web servers. The key method for making a request is called MakeRestRequest. A complete description of all properties and methods will be provided below. When exchanging information with a RESTful web service, the RestProxy supports a dynamic structured data definition format called a DynamicData type. The DynamicData type can receive XML and JSON formatted data and provide object-oriented access patterns to read the data. It can also allow the dynamic generation of an object that can be converted into either XML or JSON.

To create a new DynamicData object, use the DYNAMIC command:

DYNAMIC <name> [FROM'<string>' | <var>]
	

The <name> is the name of a new script variable and must be compatible with the inControl scripting specification (no leading numbers or special characters except underscore ‘_’, optionally ending with a dollar sign ‘$’). If the optional FROM clause is used, the text can be an explicit JSON or XML string (enclosed in single quotes) or the name of a script variable containing JSON or XML. The initialization is provided to simplify testing only and is not provided as a general means of initializing dynamic variables. Only one line of text is permitted. If a line feed is encountered before the closing single quote, an error is raised.

Members and Sub-Members

Dynamic variables within this language are specially designed entities that have a broad range of useful capabilities. On the surface, they are objects that can have dynamically created members. For example, in a Snippet a dynamic variable can be declared and several members created:

DYNAMIC employee
	
employee.Name = "John Smith"
employee.Phone = "8005551212"
employee.Address = "1234 Clay Street

As each member is addressed, it is automatically created. So the Name, Phone, and Address members will now act as properties of the employee variable.

Dynamic variable members are case-sensitive. So employee.Name is not the same as employee.name. This is divergent from the normal behavior of the CXone platform. However, because of the need to interoperate with external systems – most of which depend on correct case – this decision was made and only applies to dynamic variables.

Sub-members may also be created on-the-fly:

employee.Department.Code = 942
employee.Department.Location = "Olive City"
	

Again, as the sub-members are addressed, they are automatically added to the structure. Now with a single expression, a reference to the structure can be assigned to another dynamic script variable:

John = employee
	

An important point to recognize is that employee and "John" will reference the same physical data. If you change a member of one, you will change both. To copy data, use the built-in function copy. The following Snippet example demonstrates this:

DYNAMIC x

x.Name = "John"
y = x
y.Name = "Sam"
	

The result of which is shown below:

Example of built-in copy function.

With the copy function, y gets a unique copy and can change it without affecting x:

DYNAMIC x

x.Name = "John"
y = copy(x)
y.Name = "Sam"
	

Image displaying example of a copy function.

You can also copy child members:

DYNAMIC x

x.Name.First = "John"
x.Name.Last = "Smith"

y = copy(x.Name)
y.First = "Sam"
	

Image displaying example of child members.

Regarding the copy function: it performs a deep copy by converting the object into a textual representation, and then back into an object. This is more expensive on platform resources than simply copying a reference. Very large objects could generate a lot of overhead and potentially slow down the executing scripts. Use it when necessary, but try not to abuse it.

Dynamic variables can also handle arrays. Either the object itself may be treated as a top level array, or a member can be treated as an array:

DYNAMIC employees
employees[1] = john

or

employees.Person[1] = john
	

Important!! All arrays begin at index 1. If you reference an array index that does not yet exist, it will create it. If the elements below the newly referenced index do not exist, they will be created also. Therefore, beware, as accidentally specifying index 100 will create empty elements for indexes 1 through 99. To obtain the number of elements in an array, use the count() function: x = count(employees.Person).

Here is the Inspector tab in Studio’s Snippet property editor. It shows a dynamic variable with a top level array:

Image displaying a dynamic variable with a top level array.

By moving the elements into a child member called Name, here is what it looks like:

Image displaying child element examples.

There is a difference between a dynamic variable that is a top level array compared to a regular script variable that is an array of dynamic variables. The following example illustrates this:

DYNAMIC a
DYNAMIC b
DYNAMIC c

a.Name = "John"
b.Name = "Sam"
c.Name = "Arnold"

x[1] = a
x[2] = b
x[3] = c

DYNAMIC y
y[1] = a
y[2] = b
y[3] = c
	

The 2 variables to examine are x and y. The first, x, is a normal script variable containing an array of dynamic variables. The second, y, is a dynamic variable that is a top level array. Both look similar in the Inspector:

Image displaying dynamic variable example.

Although they look similar, they are not the same. The next section discusses the concept of serialization for dynamic variables. The important point is that in the example above, X cannot be used for interoperating with a remote system in the same way Y can. X is not serializable, Y is.

Serialization

Before discussing serialization, it would be helpful to show how to interact with dynamic variables as compared with normal script variables. Normal variables have a long list of built-in methods to allow things like string parsing, converting to a date, sorting, and so forth. Click the following drop-down to view many examples of how to interact with dynamic variables.

One of the advantages of using dynamic variables is the power of serialization. This is the ability to convert the object into a textual format suitable for transmission over the web. 2 formats are currently supported: XML and JSON. If using the RestProxy (discussed earlier in this section), the serialization process will happen automatically. If you need to generate the serialized string manually, there are 2 string methods offered:

<var>.asjson()
<var>.asxml()
	

Use within a string context to generate the serialized version of the object:

text = "{y.asjson()}"
	

The following is what text might contain assuming the value of y resembles the previous example:

{"Name":[{"First":"Sam","Last":"Smith"},{"First":"Bill","Last":"Smith"}]}
	

Likewise, the .asxml method produces output like the following:

<?xml version="1.0" encoding="utf-16" standalone="yes"?>
<DynamicDataObject><Name><First>Sam</First<Last>Smith</Last></Name>
<Name><First>Bill</First><Last>Smith</Last></Name></DynamicDataObject>
	

RestProxy Members

The RestProxy, obtained by calling GetRestProxy(), provides the services to communicate with a remote web server using the RESTful web service conventions. When using the Studio Snippet Editor, the available properties and methods can be viewed while typing. Simply declare a new proxy instance:

proxy = GetRESTProxy()
	

Then on a new line, type proxy followed by the period (.):

Image displaying RESTProxy example.

The Intelli-Prompt system will automatically show a listbox containing the available members. Once a method is chosen, typing the opening parenthesis will again activate the Intelli-Prompt system to reveal the parameters:

Image displaying the Intelli-Prompt system showing a litbox containing available members.

Properties

Property Details
StatusCode Contains the HTTP status code following a call to MakeRestRequest().
StatusDescription Contains the HTTP status description following a call to MakeRestRequest().
ContentType Allows the overriding of the default content-type header. The default is ‘Form-urlencoded’. If sending JSON, you need to change this to ‘application/json’ for example.
ProxyTimeoutSeconds Allows changing the default request timeout. The default is 10 seconds.

Methods

Method Details
string urlencode(string value)
Description Helper method to encode a string into Url encoding format.
MakeRestRequest Performs an HTTP request to the designated URL.
ClearHeaders Clears any custom headers added with AddHeader.
AddHeader Adds a custom header to the HTTP request.
MakeTwitterOauthRequest Constructs a special request for communicating with Twitter.
GetSalesForceOAuthToken Generates a special authorization token required by SalesForce.com.