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:
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"
You can also copy child members:
DYNAMIC x x.Name.First = "John" x.Name.Last = "Smith" y = copy(x.Name) y.First = "Sam"
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:
By moving the elements into a child member called Name, here is what it looks like:
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:
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.

Syntax:
<variable>.method(<parameters>) Examples: name = " sam " g = name.length() h = name.trim() i = name.mid(2,3) j = name.contains("sam") k = name.indexof("sam")
When dynamic variables are used, simply referencing a member automatically creates that member if it doesn’t exist. If Y is a dynamic variable, the expression y.length would reference a member named “length” and automatically create it (since it doesn’t already exist), thus preventing you from using the length method. To manage this, a special dynamic variable member called $value is used. The $value member will not create a new dynamic member. Instead, it will return the literal string value of the member upon which $value is being used. From $value, you can then use the normal set of methods, illustrated in the following:
DYNAMIC name name.First = "sam " g = name.First.$value.length() h = name.First.$value.trim() i = name.First.$value.mid(2,3) j = name.First.$value.contains("sam") k = name.First.$value.indexof("sam")
Note that you can’t have a dynamic variable that only contains a simple value (name = “ sam “ will turn name into a regular script variable). Also, you cannot assign the $value member. It is a read-only property of a dynamic variable. If you attempt to assign name.$value = “sam”, you will get an error. The $value member also serves another important purpose. When copying dynamic variable members to regular script variables, without using $value, you will simply create a new dynamic variable:
DYNAMIC name name.First = "Sam" x = name.First
Because First is a member of a dynamic variable, x automatically becomes a dynamic variable (this can be useful if you plan to extend x with additional members, or more common, if the member you’re assigning from has sub-members of its own). The following example illustrates the issue:
c = x.indexof("a") // Fails to compile! c = x.$value.indexof("a") // works
But if name.First.$value is used instead, the new variable will be normal:
DYNAMIC name name.First = "Sam" x = name.First.$value c = x.indexof("a") // Works! c = x.$value.indexof("a") // Fails to compile
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 (.):
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:
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. |