Change SOAP message activity success variable to reference the SOAP response rather than the HTTP code recieved.

dbrennan
Kilo Contributor

I wasn't really sure how to word this in the question section.  

Anyways, what I want to do is change when the SOAP message activity outputs success and failure.   By default it appears to just output success as long as it made a connection and got a response.   I am making a SOAP call to a 3rd party services API to add new users to our companies organization within that 3rd party services application.   The response received from this API call has a variable called responseStatus and responseMsg.   I would like to have the activity output success only if the responseStatus variable is Success. Else if it fails I will output the responseMsg stating why it failed.

Is there any way to do this using the SOAP message activity or will I have to run a separate script?   If I must use a separate script for the error handling, how do I make that script reference the response received from the SOAP message activity?   I am fairly new to ServiceNow and am unsure of how to go about this.   Any advice would be much appreciated.

Thank you

7 REPLIES 7

Joe McCarty1
ServiceNow Employee
ServiceNow Employee

The sensor script on the SOAP activity will give you access to the output via activity.output and you can set the result via activity.result.   So you should be able to set activity.result to fail even if the http status code is 200.   But the value should be 'success' or 'failure' for the activity to work.   There is also activity.fault_description that you can set with the error details assuming you wanted to reflect it on the workflow context.   There is an example here (http://www.john-james-andersen.com/blog/service-now/example-soap-within-a-servicenow-workflow.html   )   He's using the XMLHelper vs. XMLDocument.   You can use either to parse, but the latter gives you some more xPath flexibility.



Otherwise, in the sensor script you can write the output to work notes or write it to workflow.scratchpad and output it in a future activity.


Hey Joe!



This is a great start.   I have tried playing with the sensor script and came up with this:



var responseXML = new XMLDocument(activity.output, true);


var status = responseXML.getNodeText("//ns:responseStatus");


var respMsg = responseXML.getNodeText("//ns:responseMsg");


if(status != 'Successful'){


      activity.result = 'error';      


      activity.fault_description = respMsg;


      workflow.error(respMsg); // Logs the error message against the workflow context


}


else {


workflow.info('Successfully added user to organization');


}



The XML response should look something like this:



<ns:addUser_Response xmlns:ns="http://team.webservices.kanban.app.digite.com/">


      <ns:addUserDetails>


            <ns:loginId>sam</ns:loginId>


            <ns:responseStatus>Successful</ns:responseStatus>


            <ns:responseMsg>User Added Successfully</ns:responseMsg>


      </ns:addUserDetails>


      <ns:addUserDetails>


            <ns:loginId>ron.parab</ns:loginId>


            <ns:responseStatus>Successful</ns:responseStatus>


            <ns:responseMsg>User Added Successfully</ns:responseMsg>


      </ns:addUserDetails>


</ns:addUser_Response>



However when running the above sensor script, the SOAP message activity fails everytime due to a null pointer exception.



I have tried entering informaiton for the xml response's status to report false and successful and in both occasions the activity reports that it failed.   From other forum posts as well as the wiki for XMLDocument, it looks like the way I am supposed to reference the elements for responseStatus and responseMsg should be as I have in my script above but it still seems to be returning null.



Any ideas on why this is?



Thanks and sorry for the long post.


Joe McCarty1
ServiceNow Employee
ServiceNow Employee

This worked for me as a background script in the global scope (are you in the global scope?, I think some of the APIs may be different in a scope).   Also, have you verified the XML payload on the ECC Queue (if using a mid server) or by writing activity.output to a log:



var xml = '<ns:addUser_Response xmlns:ns="http://team.webservices.kanban.app.digite.com/"><ns:addUserDetails><ns:loginId>sam</ns:loginId><ns:responseStatus>Successful</ns:responseStatus><ns:responseMsg>User Added Successfully</ns:responseMsg></ns:addUserDetails><ns:addUserDetails><ns:loginId>ron.parab</ns:loginId><ns:responseStatus>Successful</ns:responseStatus><ns:responseMsg>User Added Successfully</ns:responseMsg></ns:addUserDetails></ns:addUser_Response>';



var responseXML = new XMLDocument(xml, true);


var status = responseXML.getNodeText("//ns:responseStatus");


var respMsg = responseXML.getNodeText("//ns:responseMsg");




gs.print(status);


gs.print(respMsg);



Output:


[0:00:00.002] Script completed in scope global: script



*** Script: Successful
*** Script: User Added Successfully

Hey Joe,



I am in the global scope.



yeah, I ran a test and printed it to the global log and here is what I got as a response:


<?xml version='1.0' encoding='UTF-8'?>


<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">


        <soapenv:Body>


                  <ns:addUser_Response xmlns:ns="http://team.webservices.kanban.app.digite.com/">


                            <ns:addUserDetails>


                                      <ns:loginId>test@email.com</ns:loginId>


                                      <ns:responseStatus>Failed</ns:responseStatus>


                                      <ns:responseMsg>1.Role 're' is not present in the workspace '1044284'. </ns:responseMsg>


                            </ns:addUserDetails>


                  </ns:addUser_Response>


        </soapenv:Body>


</soapenv:Envelope>



So it appears to be working but I just can't seem to gain access to those response details.



Any other ideas?   Sorry to keep bothering you.  



Thank you