How to create a parent REQ with child RITM (w/ executing WF) from a RESTful POST

GoBucks
Mega Sage

We have begun development for an external website to be able to submit data from one of its web forms into our ServiceNow instance.   We have our prototype working to create an Incident:

RESTful POST > import set table > transform map creates Incident record

For Incident, this is fairly straight forward.

However, this is trickier when it comes to creating a Service Request.   Realizing that a transform map needs a single target table defined makes me wonder how this best can be achieved.   How could a RESTful submission to an import set table best be transferred into a Service Catalog Request (So, it's as if someone just submitted via a service catalog item form & populated all the form variables)?

Thanks in advance for any help!

7 REPLIES 7

Brad Tilton
ServiceNow Employee
ServiceNow Employee

Hi Jeff,



You can do the same thing with an import table and in your transform map you could run a transform script that uses the catalog api to populate variables and submit an item. When you create an ite min this way it will automatically create the request and run the workflows.


Thanks for the quick response, Brad.   We started with this approach, but our result was just a Request record (Transform map's Target table: sc_request) without any child RITM.   We then tried setting target table to: sc_req_item.   This resulted in no Request (no surprise there) but the standalone RITM that was created had no associated workflow.   Although these first very preliminary tests are being done manually with spreadsheet, not a REST http POST yet.   We're just manually transforming a spreadsheet w/ one record to test.   I can always try with a REST client, but I think the issue is most like with our script.



This is very rough, but was our first draft, based on a business rule (that transfers a 'ticket' to incidents and service requests).



// establish a cart adding in the Catalog Item chosen in the Ticket's 'Request Item' field


var cartId = GlideGuid.generate(null);


var cart = new Cart(cartId);


var item = cart.addItem(current.request_item);



// set variables


cart.setVariable(item, 'olk_comments', current.olk_comments);


cart.setVariable(item, 'olk_ostaff_actions', current.olk_ostaff_actions);


cart.setVariable(item, 'olk_ostaff_username', current.olk_ostaff_username);



var request = cart.placeOrder();




// get the created child RITM record


var ritm = new GlideRecord('sc_req_item');


ritm.addQuery("request", request.sys_id);


ritm.query();



// update the RITM's fields accordingly


while (ritm.next()) {


      ritm.opened_by = current.opened_by;


      ritm.watch_list = current.watch_list;



      // Update our RITM record


      ritm.update();


}









The above is set to onBefore.   There are no other transform scripts or field maps associated with this transform map at the moment.


dline
Giga Contributor

Brad,


Thanks for the quick response. What you are suggesting is what we originally thought, we've created a temp table for the restful API to drop their data into, and created a transform map with the following on Before script-



var ctype = current.u_call_type;




// If call type is SERVICE CATALOG REQUEST...


  // establish a cart adding in the Catalog Item chosen in the Ticket's 'Request Item' field


  var cartId = GlideGuid.generate(null);


  var cart = new Cart(cartId);


  var item = cart.addItem(current.request_item);




  // set variables


  cart.setVariable(item, 'ohiolink_comments', ticket_data); // variable name must be set to 'ohiolink_comments'


  cart.setVariable(item, 'ohiolink_comments', current.ohiolink_comments);


  cart.setVariable(item, 'ohiolink_ip_range', current.ohiolink_ip_range);


  cart.setVariable(item, 'ohiolink_ip_services', current.ohiolink_ip_services);


  cart.setVariable(item, 'ohiolink_ip_range_description', current.ohiolink_ip_range_description);


  cart.setVariable(item, 'ohiolink_listserv_action', current.ohiolink_listserv_action);


  cart.setVariable(item, 'ohiolink_listserv_list_names', current.ohiolink_listserv_list_names);


  cart.setVariable(item, 'ohiolink_listserv_member_emails', current.ohiolink_listserv_member_emails);


  cart.setVariable(item, 'ohiolink_ostaff_actions', current.ohiolink_ostaff_actions);


  cart.setVariable(item, 'ohiolink_ostaff_username', current.ohiolink_ostaff_username);


  cart.setVariable(item, 'watch_list', current.watch_list);



  var request = cart.placeOrder();






  var ritm_sysID = "";


  // get the created child RITM record


  var ritm = new GlideRecord('sc_req_item');


  ritm.addQuery("request", request.sys_id);


  ritm.query();




  // update the RITM's fields accordingly


  while (ritm.next()) {


  ritm.opened_by = current.opened_by;


  ritm.watch_list = current.watch_list;




  // Update our RITM record and capture its sys_id


  ritm_sysID = ritm.update();


  }



We have tried setting the destination table as Request[sc_request] and Request Item[sc_req_item] both ways the transform reports back that it was successful with no errors, but when you go to REQ items it does generate a REQ or an RITM but none of the data for the variables, or the workflow that should have kicked off are identified. It creates in essence a blank REQ or RITM.



Any ideas?


Doug Line


Brad Tilton
ServiceNow Employee
ServiceNow Employee

Hi Doug,



If you're using a transform map you can't use current, the correct syntax to use is source.columnname



You should be able to transform to any table really, as the script is what is populating the records. I would make sure you set ignore = true; at the end of the before script so it doesn't create blank records.



Your other option here is instead of using the import process, just have your temp table and run an after create business rule on it so that it processes every record after the rest call creates it. That may be a little simpler for you than a transform map.