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:

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:

  1. Accept the call to play audio or interact with the caller, or
  2. Transfer the call to another B-party, or
  3. 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:

PropertyDescription
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.

ScenarioDefault CodeDescription
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.

PropertyDefaultDescription
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:

  1. If src attribute is of the form builtin://messageid then the given messageid (a numeric value) is used as a message ID as configured in the N2IVR.
  2. If src attribute is of the form file://.../v/filename then the given filename is used as a variable part name. The final directory path segment can also be set to variable_parts instead of just v.
  3. If src attribute is otherwise a file:// URI, the filename is interpreted as a file uploaded and named in the N2IVR with the given name (without prefix).
  4. 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:

  1. The file name without suffix is determined.
  2. 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.
  3. 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:

  • 1s
  • 250ms
  • +3.0s