Hi everyone,
I am writing dynamic form elements and am having an issue in my DTMF application in CVP 10.5.1.
The issue is that the optional return value isn't returning. If I sent an option to "1 [cars]" or "1[cars]" the form is returning just 1 as the value.
When I debug, the app uses the return value but when I deploy to the server it's not working. I suspect this is due to the VXML Gateway Adapter on the application being Cisco DTMF and the Debugger using its own adapter, but either way, I need to get the deployed app to use the Optional Ret Value.
Can someone suggest a way to get the Form element to return the Optional Return Value instead of just the DTMF as I really need that functionality to avoid having to do a whole lot of hoop jumping with the underlying data?
I have confirmed the same behavior for both my dynamic form and a form element configured with DTMF Keypresses statically.
Thanks in advance!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
With cisco DTMF only gateway, the form element only returns the keypress
that the caller entered. It doesn't return the value in the square
brackets. You'd need Nuance to have the value in the square brackets
returned.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The DTMF-Only gateway doesn't return the value in the square brackets
when you use the Form element, you'd need to purchase Nuance for that
functionality.
If you know Java, you can 'extend' the Form element's java class
MFoundationForm. In the method named addXMLBody() you can execute the
super.addXMLBody method to execute the original Form element; and when
it returns the string 'done', then retrieve the settings and assign the
value in the square brackets into Element (or Sesson) data yourself.
The only other option using the out of the box Studio elements is to use
the N_Option_Menu elements. They're coded to return the configured value
rather than the DTMF key pressed.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
After doing the extension I can dive into a whole slew of the common VoiceElementConfig and ElementData items - where is the selected DTMF 'value' stored?
Thanks!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
It's stored as element data named "value" for the current element.
So you'll use the method of the session api named
getElementData(this.getElementName(), "value")
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Thanks for all the replies.
Here's where I am at.
My addXmlBody() is firing but there are some issues.
Here's the code I currently am testing:
@Override
public String addXmlBody(VMain vxml, Hashtable reqParameters, VoiceElementData data){
try{
String result = super.addXmlBody(vxml, reqParameters, data);
data.addToLog("Super addXMLBody result", result);
VoiceElementConfig vec = data.getVoiceElementConfig();
String[] values = vec.getSettingValues("dtmf_keypress", data);
for (String value : values){
data.addToLog("dtmf_keypress",value);
}
data.addToLog("dtmf_keypress value count", ""+values.length);
ElementData[] ed = super.getElementData();
for(ElementData edv : ed){
data.addToLog(edv.getName(), "" + edv.VALUE);
}
data.addToLog("This Value", data.getElementData(this.getElementName(), "value"));
} catch (Exception ex){
data.addToLog("error", "Exception: " + ex);
return "done";
}
return "done";
}
There are two issues though, the super.addXmlBody() result is null and the element "value" is also null.
I am seeing my dtmf_keypress configurations appropriately logged so I am sure that the method is firing properly and no Exception is being caught.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
the addXMLBody method is called multiple times.
The first time, result equals null because the code is sending vxml to
the gateway and needs vxmlserver to return to the addXMLBody with the
caller's response in the reqParameters.
So, you need to check and do your stuff ONLY if the result is equal to
"done":
And you always want to return the value of the 'result' variable that
came back from the super.addXMLBody at the end.
if( result.equals("done")) {
**
//this is when you want to loop through the settings and see which
one matches the caller's selection. And do your stuff here. **
*
**
*} **
*
**
return result;
**
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Hi,
See below - I modified your code a little.
I don't know why the getElementData() method returns null even though
the exit state is 'done', but if you retrieve the info being sent back
from the gateway using *reqParameters.get("foundation_fld") *then you'll
get back the DTMF entered by the caller. I'm printing it to the Activity
Log below.
You can then modify this code to find that dtmf in the vec array you
have and proceed from there.
public String addXmlBody(VMain vxml, Hashtable reqParameters,
VoiceElementData data){
String result="";
try{
result = super.addXmlBody(vxml, reqParameters, data);
data.addToLog("Super addXMLBody result", result);
if("done".equalsIgnoreCase(result)){*
VoiceElementConfig vec = data.getVoiceElementConfig();
String[] values =
vec.getSettingValues("dtmf_keypress", data);
for (String value : values){
data.addToLog("dtmf_keypress",value);
}
data.addToLog("dtmf_keypress value count",
""+values.length);
data.addToLog("This Value", ""+reqParameters.get("foundation_fld"));*
}
return result;
} catch (Exception ex) {
data.addToLog("error", "Exception: " + ex);
return result;
}
}
--
Janine Graves
Cisco Designated VIP
Training the Experts, LLC
Expert Training in CVP, IVR, VoiceXML, and Speech Technologies
617-549-8585
1 Roundys Hill, Marblehead, MA 01945
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I think I have it sorted out now - really appreciate the input and pointers.
The method getElementName() actually returns the Studio Elements Pane name - not the application element name - so I used getCurrentElement instead - which solved the element data problems. Not sure how long it was working but that cleared up that piece.
The code that's currently working to solve the issue is (Ignore Case is a good addition too but I think the return is always lower, but ya know... things change.
if("done".equals(result)){ | |||
try{ | |||
data.addToLog("Super addXMLBody result", result); | |||
VoiceElementConfig vec = data.getVoiceElementConfig(); |
String elementValue = data.getElementData(data.getCurrentElement(), "value"); | |||||
data.addToLog("This Data Element Value", elementValue); | |||||
String[] values = vec.getSettingValues("dtmf_keypress", data); | |||||
for (String value : values){ | |||||
data.addToLog("dtmf_keypress",value); | |||||
String retValue = value.substring(value.indexOf("[")+1); | |||||
retValue = retValue.substring(0,retValue.indexOf("]")); | |||||
data.addToLog("retValue",retValue); | |||||
data.addToLog("Compare", "Value: " + value + ", Element Value: " + elementValue); | |||||
if(elementValue.equals(value.substring(0,value.indexOf("[")))){ | |||||
data.addToLog("Matched", "Value: " + value + ", Element Value: " + elementValue); | |||||
data.setElementData("result", retValue); | |||||
} | |||||
} | |||||
} catch (Exception ex){ | |||||
data.addToLog("error", "Exception: " + ex); | |||||
} finally{ | |||||
return result; | |||||
} | |||||
} else { | |||||
return result; | |||||
} |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
good job! You're right about using data.getCurrentElement() for the
element name.
In doAction and doDecision, the element name is passed as a parameter,
but I never need it.
Here, where we need it, it's not passed as a parameter.
Go figure.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Thanks for the replies, that's what I was assuming to be the case - it's a bummer that the debugger doesn't emulate the actual Gateway Adapter that will be utilized. Feature Request forthcoming.
I will try out extending the Form element, that's a slick approach that might save me some time jockeying data between elements manually.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Yes, I agree. The Debugger is great for a lot of things now but it
doesn't simulate the gateway's Voice Browser too well. Maybe once the
voice browser is virtualized it'll be easier for Cisco to match its
behavior in the Debugger.
It would also be nice if Cisco documented these little 'features' so we
don't have to find out the hard way!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Comments
0 comments
Please sign in to leave a comment.