06-24-2014 06:03 AM - edited 03-14-2019 01:33 PM
Hi,
I am trying to get UCCX to contact a SOAP web service so that I can make routing decisions based on the SOAP response. But as I have virtually no experience with SOAP/XML I am struggling a bit.
below is the SOAP command that I am trying to send to the web service to query if an ANI has called recently
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<FindInteraction xmlns="http://www.something.com/v4">
<data>
<Tenant>Test</Tenant>
<Options>
<Contact>000000000</Contact>
<DataValues />
</Options>
</data>
</FindInteraction>
</soap12:Body>
</soap12:Envelope>
the response should be something like the below, the "Code" value is what I will base my routing on.
<Response>
<Header>
<ClientID></ClientID>
<Id>038793f2-5b11-4ead-a05b-aa77ff76430f</Id>
<Status>
<Code>109021</Code>
<Description>The contact that you submitted does not exist.</Description>
<ErrorMessage></ErrorMessage>
<Result>ContactNotFound</Result>
</Status>
</Header>
<Data>
</Data>
</Response>
I have had a look at https://supportforums.cisco.com/docs/DOC-23899 but I am still struggling to understand SOAP.
is the above simple to do, or do I need to find a "programming friend"
any help appreciated.
Darren
06-25-2014 03:03 AM
Hi,
I can be your "programming friend" if you want. It's relatively simple.
Can you tell me the UCCX license level (Premium, Enhanced or Standard, or perhaps IP IVR). Plus do you have the WSDL (so I can create a mock SOAP server).
G.
06-25-2014 05:23 AM
06-25-2014 05:59 AM
Hi, yep, that's it, the WSDL file. I already created a simple SOAP server.
Two more things: the "FindInteraction" method is actually expecting a number of other parameters, too. They are all marked as "optional", indeed, and your original post contains one parameter only ("Contact") too, but I just thought asking this won't hurt. So this is the actual "FindInteraction":
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:plat="http://www.virtualhold.com/Toolkit/Platform-v4">
<soap:Header/>
<soap:Body>
<plat:FindInteraction>
<!--Optional:-->
<plat:data>
<!--Optional:-->
<plat:Tenant>?</plat:Tenant>
<!--Optional:-->
<plat:Options>
<!--Optional:-->
<plat:ClientId>?</plat:ClientId>
<!--Optional:-->
<plat:Contact>?</plat:Contact>
<!--Optional:-->
<plat:Segment>?</plat:Segment>
<!--Optional:-->
<plat:InteractionId>?</plat:InteractionId>
<!--Optional:-->
<plat:DataValues>
<!--Zero or more repetitions:-->
<plat:PublicCallInfoType>?</plat:PublicCallInfoType>
</plat:DataValues>
</plat:Options>
</plat:data>
</plat:FindInteraction>
</soap:Body>
</soap:Envelope>
The second question: how are we going to handle errors? I see the response to the FindInteraction method contains //Header/Status/ErrorMessage or //Header/Status/Code - I assume this is something we would like to be read by UCCX as well.
Thanks for clarifying this.
G.
06-25-2014 04:38 PM
Gergely,
yes there are other optional parameters, but Contact is the one I need to use as i will be using the ANI of the caller as a variable to use as the contact for the look-up.
Regarding error handling, I dont really know what to do here. the <Code>109021</Code> field is the important one to me as the code value changes depending on the outcome of the findinteraction request, and I will make a routing decision based on the code value.
thanks for you help..
Darren
06-26-2014 01:02 AM
OK, understood.
I will try to find a working UCCX in my lab, test the solution and get back to you. G.
06-26-2014 04:21 AM
Hi,
I have written and tested a code fragment.
Let's do this with the "template" way.
First, we create a simple XML template:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:plat="http://www.virtualhold.com/Toolkit/Platform-v4">
<soapenv:Header/>
<soapenv:Body>
<plat:FindInteraction>
<plat:data>
<plat:Tenant>__TENANT__</plat:Tenant>
<plat:Options>
<plat:Contact>__CONTACT__</plat:Contact>
<plat:DataValues />
</plat:Options>
</plat:data>
</plat:FindInteraction>
</soapenv:Body>
</soapenv:Envelope>
Notice the __TENANT__ and __CODE__ strings. We will replace them with something useful within the script.
Save this as vht_request.xml and upload it to the Document Management page to your UCCX.
Next, add the following five new variables to your script:
code - type String, initial value: "" - this variable will hold the "Code" sent by our SOAP server;
doc - type Document, initial value: DOC[] - this is just a utility variable, reused many times as we will see;
soapResponseString - type String, initial value: "" - another utility variable, for storing the response sent by the SOAP server;
soapServerURL - type String, initial value: well, this is the endpoint URL of your SOAP server. The WSDL file you sent me the other day already contains a reference to it, "http://172.16.202.59/VHTPlatformWS-v4/VHTPlatformWS.asmx" but you might want to double check with the person administering this SOAP server. My mock SOAP server was available at "http://10.232.128.68:8090/mockIVHTPlatformWS", I am using it in my script;
xpathResultSelectCode - type String, initial value: this is the XPath expression to filter out the value of the Code XML element encapsulated within other elements. You probably want to use this: "//*[local-name()='FindInteractionResult']/*[local-name()='Header']/*[local-name()='Status']/*[local-name()='Code']"
Next, we are going to use the following steps:
1. doc = Keyword Transform Document.
The Keyword Template: DOC[vht_request.xml] - this essentially tells UCCX to take the XML file we uploaded previously, convert it to a Document type variable.
Keywords: this is where the magic happens. I mapped "__TENANT__" to "Test" and "__CONTACT__" to "5556363". You will probably want to map these to something legal, like the ANI of the caller.
Document: doc. This just assigns the document we transformed at this step to this variable.
2. Create XML Document. Source Document: doc. Document: doc. Do not write anything into the Source ID box. This step tells UCCX to look at the transformed document as an XML document.
3. Set. The Variable would be soapResponseString, and the Value - well, this code block:
{
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
String content = doc;
int readTimeout = 5000;
try {
java.net.URL url = new java.net.URL(soapServerURL);
java.net.HttpURLConnection urlCon = (java.net.HttpURLConnection) url.openConnection();
urlCon.setFixedLengthStreamingMode(content.length());
urlCon.setReadTimeout(readTimeout);
urlCon.setDoInput (true);
urlCon.setDoOutput (true);
urlCon.setUseCaches (false);
urlCon.setRequestMethod("POST");
urlCon.setRequestProperty("Content-Type","text/xml;charset=UTF-8");
java.io.DataOutputStream output = new java.io.DataOutputStream(urlCon.getOutputStream());
output.writeBytes(content);
output.flush();
output.close();
java.io.DataInputStream input = new java.io.DataInputStream(urlCon.getInputStream());
int bufSize = 4096; // buffer size, bytes
byte[] bytesRead = new byte[bufSize];
int bytesReadLength = 0;
while(( bytesReadLength = input.read( bytesRead )) > 0 ) {
baos.write(bytesRead,0,bytesReadLength);
}
input.close();
baos.close();
} catch (Exception e) {
e.printStackTrace();
return null;
}
return baos.toString();
}
I took this from my other document, https://supportforums.cisco.com/document/97736/uccx-8x-really-simple-soap-client-no-custom-jar
Again, if anything bad happens, this code block would return null. Nothing. Nada. Nil. Semmit. If everything goes fine, this code block issues a SOAP HTTP request and the response would appear as a String as the value of the soapResponseString variable.
4. doc = Create XML Document. Source Document: (Document) soapResponseString. Document: doc. This tells UCCX to cast the value of the soapResponseString into a Document type variable, and, create an XML document out of it.
5. code = Get XML Document Data. Document: doc. XML path: xpathResultSelectCode. Result Data: code. This is where the other magic happens, the system would filter out the value of the Code element and assign this value to the code variable.
I will try and upload screenshots after I posted this.
G.
06-26-2014 05:31 AM
Gergely,
that looks great, think I can actually understand it. I will be onsite tomorrow, hopefully I will have some time to try it out in the non-prod environment.
thanks heaps,
Darren
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide