One of ServiceNow’s principal strengths comes from its extensible framework. Built into the framework is the ability to retrieve information using one of a myriad of methods. If you want to get data out of any table, you can get it via direct web services, using basic auth data retrieval, having it pushed to a client, FTP server or  linux server by using the scheduled data extract, and more.  However, there are times when none of these solutions give you a logical way to achieve what you want in a simple manner.  I will give two examples: 1) adding an item to a cart, 2) fetching an attachment from a record.  For tasks such as these, the flexible Scripted Web Services is the answer.

Scripted web services are used in many integrations where a product wants to accomplish something that doesn’t have a simple solution already built-in.

How to use Scripted Web Services

This functionality requires the Web Service Provider – Scripted plugin.

There are four parts to scripted web services: WSDL (generated for you), script, input variables, output variables.  The WSDL is created for you and is what you’ll use on the client side to access your new web service.  The script is simple JavaScript and performs the required action.  Within the script you retrieve the input variables that you expect the client to send your web services.  Those variables are references using request. notation.  Once the script nears an end, you can set the output variables – the data you want to send back to the client – by using  response. notation.

This is the most flexible way to receive SOAP data and to return whatever you wish to return.  Let me explain by solving to two problems mentioned above.

Ordering a Blackberry


var cart = new Cart();
var item = cart.addItem('e2132865c0a801650010e411699');
cart.setVariable(item, 'original', request.phone_number);

// set the requested for
var gr = new GlideRecord("sys_user");
gr.addQuery("user_name", request.requested_for);
gr.query();
if (gr.next()) {
  var cartGR = cart.getCart();
  cartGR.requested_for = gr.sys_id;
  cartGR.update();
}

var rc = cart.placeOrder();
response.request_number = rc.number;

The script is a simple example of how to order a backberrry for a specific user.  Phone_number and requested_for are sent via the soap client to the script and the scripted web service returns the request_number back to the client.  Something that would be very difficult to figure out using traditional web service methodologies is quite simple to do with using this technique.

Fetching an attachment from a task record

if (typeof GlideStringUtil != 'undefined')
   var StringUtil = GlideStringUtil;
else
   var StringUtil = Packages.com.glide.util.StringUtil;

var  gr = new GlideRecord("sys_attachment");
gr.addQuery("table_sys_id", request.sys_id);
gr.query();
if (gr.next()){
   if (typeof GlideSysAttachment != 'undefined')
      var sa = new GlideSysAttachment();
   else
      var sa = new  Packages.com.glide.ui.SysAttachment();
   var binData =  sa.getBytes(gr);
   var encData =  StringUtil.base64Encode(binData);
   response.file_name = gr.file_name;
   response.table_name = gr.table_name;
   response.encodedAttachment = encData;
}
else{
   gs.log("Record not found");
}

Again, this is pretty straightforward.  What would be the alternative if direct web services were used?  Well, there would need to be a call to the sys_attachment record to find out the file_name, table_name, and associated task record.  Then there would need to be several more calls to fetch every attachment chunch (attachments are stored as chunks of data internally) only to reassemble the data client-side….not very friendly.

I created an update set for the fetch attachment record that you may download and apply to your instance: Fetch Attachment scripted web service.  Remember to enable the Web Service Provider – Scripted plugin before applying the update set.