N2IVR (VXML) Lua Application
N2IVR (VXML) Lua Application Configuration
The N-Squared IVR (Interactive Voice Response) solution supports various distinct control mechanisms.
This page contains information specifically related to the N2IVR when configured to offer VXML-controlled interactions. In this mode:
- SIP/RTP is used for audio stream control.
- The VoiceXML interpreter controls the announcements played and interaction requests made to the caller.
Note that the N2IVR (INAP) Lua Application is only an end-point for RTP streams. It does not proxy/transcode RTP packets and does not support the establishment of any B-Legs.
The logic for the N2IVR operating in this mode is defined by a purpose-specific run-time script written in the Lua scripting language, and this page describes the configuration parameters specifically for the Lua Logic script. There is also a general N2IVR (VXML) Deployment Guide page which defines all of the components which are required to implement the N2IVR (VXML) solution in a typical deployment model.
Here is a N2IVR (VXML) Lua Application config example showing the specific configuration within the LogicApp.
<application name="VXML-IVR" module="LogicApp" admin_alloc="1m" user_alloc="64m">
<include>
<lib>../apps/logic/lib</lib>
<lib>../../n2sip/lib</lib>
<lib>../apps/rest_c/lib</lib>
</include>
<parameters>
<parameter name="edr_enabled" value="1"/>
<parameter name="default_edr_app_name" value="EDR"/>
<parameter name="default_edr_stream_key" value="vxmlivr"/>
<parameter name="trace_level" value="0"/>
<parameter name="max_trace_level" value="3"/>
<parameter name="trace_per_second" value="20"/>
<parameter name="default_lua_lib_path" value="../lua/lib/?.lua;../lua/lib/3rdparty/?.lua;../../n2sip/lua/lib/?.lua"/>
<parameter name="default_rest_app_name" value="VXML-REST-Client"/>
</parameters>
<config>
<services>
<service module="LhoSipApp::LhoSipIncallLuaService"
libs="../../n2sip/apps/lho_sip/lib"
script_dir="../../n2sip/lua/svc"
>
<globals>
<!-- section for custom configuration for the VXML IVR service -->
</globals>
<script_check_secs>5</script_check_secs>
<triggers>
<!-- section for explicitly defining the called party numbers which trigger the IVR VXML interpreter -->
<trigger called_prefix="64" script_key="n2ivr_vxml"/>
</triggers>
</service>
</services>
<agents>
<agent module="LhoSipApp::LhoSipOutcallLuaAgent" libs="../../n2sip/apps/lho_sip/lib"/>
<agent module="RestClientApp::VxmlLuaAgent" libs="../../n2sip/apps/rest_c/lib"/>
</agents>
</config>
</application>
Configuration Details
Parameters
The default_lua_lib_path must include the n2svcd and n2sip default lua/lib paths.
The default_rest_app_name must point to a REST Client app which will be used to request VoiceXML documents from a VoiceXML server.
Service
The LhoSipIncallLuaService service must be configured as per the LhoSipIncallLuaService Configuration page.
It should have a service-level edr_stream_key attribute present which defines the default stream key to which the N2IVR (VXML) EDRs will be written.
The service-level script_dir should be configured as “../../n2sip/lua/svc” which is typically the relative path from the n2svcd/bin directory to the n2sip/lua/svc directory which contains the required service script n2ivr_vxml.lua.
Agents
The VXML service requires the use of the RestClientApp::VxmlLuaAgent for querying VoiceXML servers.
Triggers
At least one trigger must be defined which points to the script with script_key configured as n2ivr_vxml.
Refer to the LhoSipIncallLuaService configuration page for possible trigger-matching parameters.
Globals
Refer to the Logic App Configuration page for a description of how to define global constants such as those listed in this section.
IMMEDIATE_200_OK_RESPONSE
This global parameter determines whether the IVR will accept the inbound SIP call from the A-Party immediately, or defer a response until a VoiceXML action requires a response to be made.
If set to false (the default), the IVR will not immediately accept
any inbound call. Instead it will defer the decision until the
IVR must either:
- Accept the call to play audio or interact with the caller, or
- Transfer the call to another B-party, or
- Reject the call.
If set to true, the IVR will send a 200 OK and set up the RTP
path between the A-Party and the IVR prior to sending the first
request to the VoiceXML server.
Individual mappings in the SERVICE_IDENTIFICATION configuration can override this
global configuration value.
Note that if an inbound call does not match any SERVICE_IDENTIFICATION
then the inbound call is rejected regardless of the configuration of this
parameter.
IGNORE_TTS_ERROR_EVENTS
In a VoiceXML document, text-to-speech can be requested with a prompt such as:
<prompt> Hello, this is a TTS request </prompt>
In this version of the N2IVR VoiceXML engine, TTS is not available and encountering
an prompt of this nature would generate an error.unsupported.builtin.tts event.
This would generally be handled by the default error handler, resulting in
the call being ended immediately.
However, if this global is set to true then VoiceXML engine will enable a default
event handler for the error.unsupported.builtin.tts event that will suppress
the event and continue processing the VoiceXML document as if the prompt did
not exist.
By default the value of this global is set to false. I.e. text-to-speech requests are not ignored.
Individual mappings in the SERVICE_IDENTIFICATION configuration can override this
global configuration value.
SERVICE_IDENTIFICATION
The SERVICE_IDENTIFICATION global parameter must be defined for the service.
This array of mappings will define which VoiceXML document URI should be used
to retrieve the initial VoiceXML document for each possible inbound called party
prefix or pattern match.
The SERVICE_IDENTIFICATION must be an array of hashes. The format is as follows:
<global name="SERVICE_IDENTIFICATION" type="array">
<!-- more mappings as required can be defined -->
<mapping type="hash"> <called_prefix>64918</called_prefix> <uri>https://voicexml.nsquared.nz/care.jsp</uri> </mapping>
<mapping type="hash">
<called_pattern>64%d+</called_pattern>
<immediate_200_ok_response>true</immediate_200_ok_response>
<uri>https://voicexml.nsquared.nz/info.jsp</uri>
</mapping>
<mapping type="hash"> <called_prefix></called_prefix> <uri>https://voicexml.nsquared.nz/default.jsp</uri> </mapping>
</global>
The order of the mappings list is important. All mappings are processed in the
order written in the configuration. Each <mapping> may have the following
elements defined, which become key/value pairs of the mapping itself:
| Property | Description |
|---|---|
called_prefix
|
The prefix of the called party number (taken from the To: SIP header)
to match against a mapping. More specific mappings must be defined before
less specific mappings.
An empty called prefix can be provided as a default service to trigger for all inbound requests not matched by other rules. Unlike other rules, an empty called_prefix mapping is always selected only if all other rules fail to match. Either called_prefix or called_pattern must be specified. |
called_pattern
|
A Lua pattern that is tested against the called party of an inbound call. |
ignore_tts_error_events
|
Determines whether calls that are captured by this service identification should ignore text-to-speech requests. If not specified the global value of the IGNORE_TTS_ERROR_EVENTS will be used to determine behaviour for calls to this service. |
immediate_200_ok_response
|
Overrides the value of the IMMEDIATE_200_OK_RESPONSE option
defined at the global level for the IVR engine.
|
uri
|
The HTTP(S) URI to retrieve the first VoiceXML document from, for the
call interaction. If the host & port are not defined, then the default
host and port of the associated RestClientApp will be used.
Note that any SSL/TLS connectivity required must be defined on the RestClientApp itself.
|
HANGUP_CODES
If the VXML IVR service enters a state in which the VXML interpreter no longer has control of the call, yet the A-party is connected to the IVR, the VXML IVR service must hang up the call.
If the caller is connected to the IVR then this will be a normal BYE. Otherwise the call will be declined with a SIP response code. In error scenarios a SIP code can be added to a header sent with the BYE.
The SIP code used to hang up the call is determined by the scenario. The service supports separate hangup codes for the following scenarios. The exact SIP message flow used by the hangup depends on the current state of the SIP call control model. See the LhoSipIncallLuaService.hangup() method for more information.
| Scenario | Default Code | Description |
|---|---|---|
no_service_error
|
603
|
If the IVR cannot determine the VXML service endpoint to contact based on the
SERVICE_IDENTIFICATION list, the A-party will be disconnected
with the SIP code defined by the no_service_error configuration
option.This scenario also generates a SETUP-ERR EDR.
|
setup_error
|
500
|
If there is an error in retrieving or parsing the first VXML response from
the VoiceXML server, or there is a problem in establishing the RTP
channel to the A-party when immediate_200_ok_response is set to true,
the IVR service will disconnect the A-party with the
setup_error code. This scenario also generates a SETUP-ERR EDR.
|
engine_error
|
500
|
If there is an error during the interpretation of a VoiceXML document,
the VoiceXML server will disconnect the A-party with the engine_error code.
Note that this scenario captures abnormal VoiceXML engine errors, not those captured by the VoiceXML <catch> element.
This scenario triggers a normal VXML service EDR with a CODE
tag with a value between 5000 and 5999.
|
force_decline
|
603
|
If a VoiceXML document ends call control with a VXML <exit>
element, but a 200 OK has not yet been sent to the A-party, the call will
be declined with this SIP code.
This scenario is an otherwise normal call end scenario with the VXML service EDR including a tag FORCE_HANGUP set to 1
and SIP_DECLINE_CODE set to the SIP code used.
|
vxml_error
|
500
|
If the VXML interpreter exits due to a VXML <throw>, the
event thrown can be used to generate a specific SIP response code.
The format for the associated hangup code of a VXML thrown event is
vxml_ as a prefix, and then the event value as the suffix.
The most generic VXML event is error, and the
associated hangup code is defined by vxml_error. More
specific hangup codes can be defined in addition to this.
Note that there is no regex applied. If a specific VXML error is not defined exactly as used by the VXML document, then the vxml_error hangup code is used.
This scenario is an otherwise normal call end scenario with the VXML service EDR including a tag FORCE_HANGUP set to 1,
the tag SIP_DECLINE_CODE is set to the SIP code used,
and the VXML event is stored in the EVENT EDR tag.
|
To override a hangup code, define the HANGUP_CODES global parameter.
This parameter is optional, as is each scenario. If a scenario isn’t defined, the
service will use the default.
A HANGUP_CODES global parameter defined with the defaults would be:
<global name="HANGUP_CODES" type="hash">
<no_service_error>603</no_service_error>
<setup_error>500</setup_error>
<engine_error>500</engine_error>
<force_decline>603</force_decline>
<vxml_error>500</vxml_error>
</global>
Note that the VXML <disconnect> element does not use a hangup code defined by this
global parameter. Instead, the VXML <disconnect> element will not hang up with
a code as a disconnect would normally be a call end with a BYE.
However if a disconnect should send a code, one can be set by setting the
VXML session variable connection.protocol.sip.disconnect_code
which can be defined using the VXML_SESSION_VARIABLES global parameter, and/or
overridden by individual VXML documents.
VXML_SESSION_VARIABLES
The VXML_SESSION_VARIABLES global parameter may be defined for the service. This
table of session variables will be made available as session variables to the VoiceXML
interpreter and can be accessed within VoiceXML documents using:
<var name="myvar" expr="session.connection.aai"/>
All listed properties will become session variables.
The VXML_SESSION_VARIABLES value if declared
must be a hash, with the element names as the session variable name, and
element values as the session variable values.
For example, VXML_SESSION_VARIABLES might be defined as:
<global name="VXML_SESSION_VARIABLES" type="hash">
<connection.aai>VXML Application (N2IVR)</connection.aai>
</global>
The session variable connection.protocol.sip.disconnect_code is special.
This session variable will determine the SIP hangup code used when
the <disconnect> VXML element is encountered.
VXML_PROPERTIES
The VXML_PROPERTIES global parameter may be defined for the service. This
table of properties will define the initial value of VoiceXML properties, i.e.
those document in Section 6.3 of the VoiceXML 2.0
specification. Properties not
listed in this table are ignored by the N2IVR VXML interpreter and need not be
defined. If defined, they will be ignored.
The VXML_PROPERTIES value if declared must be an object. Any of the following properties
may be defined. If a property is not defined, the default as described will be used.
| Property | Default | Description |
|---|---|---|
interdigittimeout
|
4s | The inter-digit timeout value to use when recognizing DTMF input. Defined as a Time Designation value. |
termtimeout
|
0s | The terminating timeout to use when recognizing DTMF input. Defined as a Time Designation value. |
termchar
|
# |
This is the termination digit to use to determine input termination
by the user during an IVR interaction. This must be defined as one of:
0,1,2,3,4,5,6,7,8,9,*,#. The termination digit may be undefined. When undefined, the default termination digit for the IVR RTP application will be used. |
bargein
|
true | Whether to allow users to interrupt announcements being played with DTMF digits. Default is true. May be set to "true" or "false". |
bargeintype
|
speech | Type of announcement interrupt analysis to use. The N2IVR only supports "speech" interrupts (i.e. DTMF detection). When "hotword" is defined, the IVR will raise an error during call processing. |
timeout
|
8s | The timeout waiting for the user to input a DTMF tone before a noinput event is generated by the VXML interpreter. Defined as a Time Designation value. |
documentmaxstale
|
The maximum 'staleness' to allow for cached documents. Set to an empty
value by default, which causes the VXML HTTP request engine to not define
the Cache-Control max-stale header value.
When specified, must be specified as a number indicating the number of seconds to allow stale cache value to be used. Note that the VXML IVR does not cache documents. This value is only relevant if a downstream HTTP proxy is caching VXML documents. |
|
documentmaxage
|
The maximum age a downstream HTTP cache should allow when providing
cached documents in response to a HTTP request by the VXML IVR.
When set to an empty value (the default), the HTTP request engine will
not set the the Cache-Control max-age
header value.
When specified, must be specified as a number indicating the maximum age (in seconds) a reqested document may be before a fresh document must be retrieved. Note that the VXML IVR does not cache documents. This value is only relevant if a downstream HTTP proxy is caching VXML documents. |
|
documentfetchhint
|
safe |
When set to safe all requests for documents by the VXML IVR
will be made at the time the document is required. A value of prefech
is ignored (all HTTP requests for documents are performed in safe mode)
|
audiomaxstale
|
Ignored. All audio is read at the moment it is required from the IVR's local audio storage - whether from disk, or local database. | |
audiomaxage
|
Ignored. All audio is read at the moment it is required from the IVR's local audio storage - whether from disk, or local database. | |
audiofetchhint
|
prefech | Ignored. All audio is read at the moment it is required from the IVR's local audio storage - whether from disk, or local database. |
fetchaudio
|
When audio should be played to the caller during the retrieval of
documents from a VoiceXML server, the audio file to play must be
defined by this property.
The value of this property must be a valid audio file name as stored by the IVR. |
|
fetchaudiodelay
|
2s | The delay before initiating playback to the caller of the audio defined by the fetchaudio parameter. Defined as a Time Designation value. |
fetchaudiominimum
|
5s | The minimum time to play the audio defined by fetchaudio once started. If the VXML IVR receives the VXML document prior to this minimum timeframe completing, then execution of the document is delayed until the minimum timeframe is complete. |
fetchtimeout
|
0s | Ignored. All audio is read at the moment it is required from the IVR's local audio storage - whether from disk, or local database. Defined as a Time Designation value. |
maxnbest
|
1 | Ignored. In this N2IVR VXML service release, `maxnbest` is always limited to 1. |
MERGE_EDRS
The MERGE_EDRS global parameter may be defined for the service. This
boolean defines whether the VXML IVR will generate a single EDR per call handled,
or an EDR per document processed.
The default approach is for the service to generate an EDR for each document
processed. Set this variable to true to generate a single EDR for each handled
SIP call.
<global name="MERGE_EDRS" type="boolean">true</global>
MAX_REENTRIES
The MAX_REENTRIES global parameter may be defined for the service. This
variable defines the maximum number of times a transition from one code
block in a VXML document can be made to another code block within thes same
VXML document. This occurs with <goto> commands using hash references to
blocks in the same VXML document. It also occurs when formitems are iterated
through.
This variable ensures infinite loops do not occur. The default is set to 1000.
<global name="MAX_REENTRIES" type="integer">800</global>
MAX_TRANSITIONS
The MAX_TRANSITIONS global parameter may be defined for the service. This
variable defines the maximum number of transitions allowed between VoiceXML
documents (whether triggered via <goto> requires or <submit>).
This variable ensures infinite loops do not occur. The default is set to 10.
<global name="MAX_TRANSITIONS" type="integer">20</global>
DEFAULT_LANGUAGE
The DEFAULT_LANGUAGE global parameter may be defined for the service. This
variable defines the name, as known in N2IVR’s UI configuration and in the
N2IVR database, of the language to treat as the default to use for audio
announcements.
<global name="DEFAULT_LANGUAGE">English</global>
LANGUAGE_MAPPING
The LANGUAGE_MAPPING global parameter may be defined for the service. This
hash defines the mapping of xml:lang attributes that may be present in
VoiceXML documents to named languages in the N2IVR configuration. Where
a VoiceXML document language is defined without a mapping, or where
a VoiceXML document does not have a xml:lang attribute, the default langauge
will be used.
<global name="LANGUAGE_MAPPING" type="hash">
<en-EN>English</en-EN>
</global>
AUDIO_SOURCE_INTERPRETATION
The AUDIO_SOURCE_INTERPRETATION global parameter may be defined for the service.
This string defines the approach the VXML service will take to interpreting
the <audio> element’s src attribute.
By default, the internal N2IVR method is used. This method can also
be explicitly defined by setting AUDIO_SOURCE_INTERPRETATION to Internal.
The internal method applies the following rules:
- If
srcattribute is of the formbuiltin://messageidthen the givenmessageid(a numeric value) is used as a message ID as configured in the N2IVR. - If
srcattribute is of the formfile://.../v/filenamethen the given filename is used as a variable part name. The final directory path segment can also be set tovariable_partsinstead of justv. - If
srcattribute is otherwise afile://URI, the filename is interpreted as a file uploaded and named in the N2IVR with the given name (without prefix). - Any other URI formats are treated as an error.
This configuration option can be set to FermaSynthesis in which case the
audio source is decoded as per the following rules:
- The file name without suffix is determined.
- If the file name matches a numeric value as might be returned by the FermaSynthesis REST API provided by N2IVR then the audio file is played as the identified variable part.
- If the file name does not match a known variable part, the file name is used as a lookup into the named annoucement files stored by the IVR.
This configuration option can be set to Hook in which case a hook
file must also be given, with a method that implements this Lua signature:
--- @param src string The string which defines the source audio
--- @return boolean # On parse failure, return false. Otherwise returns true
--- @return string? # The error string, on failure, or on success the filename
--- @return integer? # On parse success, if a message ID, return the message ID as the third value, and true as the first.
---
function interpret_audio_source (src)
return false, "Unknown source URI format."
end
Example:
<global name="AUDIO_SOURCE_INTERPRETATION">FermaSynthesis</global>
Time Designation Values
VoiceXML time designation values
are supported as configuration values for variables and properties where
appropriate. A time designation value is a number, such as 250 or 1.1 or +0.5
followed by either ms (indicating milliseconds) or s (seconds).
Example values:
1s250ms+3.0s