Voximal VoiceXML Browser
========================

Voximal integrates a VoiceXML 2.1 interpreter with Asterisk. The distribution
contains the Asterisk application module (app_voximal.so), the voximald
interpreter process, speech and prompt connectors, configuration examples and
installation scripts.

Main features
-------------

- VoiceXML 2.1 execution from an Asterisk dialplan.
- Local and HTTP audio prompts, SSML and cloud Text-to-Speech connectors.
- Speech recognition through Asterisk res_speech, MRCP and cloud providers.
- Google Speech v1 and v2 support and Google Dialogflow v2 integration.
- DTMF, speech, hotword, continuous and AMD barge-in modes.
- Answering Machine Detection and noise detection.
- Record, monitor, transfer, fax and optional video operations.
- Integrated HTTP dialer with accounts, schedules and result callbacks.
- HTTP billing, reports, statistics and Prometheus metrics.
- AAI and SIP/IAX User-to-User processing, including RFC743x hexadecimal data.
- JavaScript execution with SpiderMonkey and extensible VoiceXML objects.

Core resources
--------------

The current Voximal 18 build configuration uses these main resources:

- OpenVXI, maintained by Voximal for the VoiceXML interpreter.
- Asterisk 22.9.0 as the default build target, with separately packaged
  modules for other supported Asterisk branches.
- Mozilla SpiderMonkey from Firefox 149 (`MOZJS_VERSION=149`).
- Xerces-C 3.3.0 for XML and VoiceXML parsing.
- libcurl 8.20.0 for HTTP and HTTPS connectors.
- json-c 0.18 for JSON processing.
- gRPC 1.80.0 and protobuf 31.1 for Google speech services.
- Abseil 20250512.2, RE2 2024-07-02 and c-ares 1.34.5 as gRPC
  dependencies.
- Google APIs snapshot 20251003-2193a2b, including Google Speech and
  Dialogflow generated protobuf/gRPC interfaces.
- UniMRCP 1.8.0 for optional MRCP speech resources.

Exact dependency versions are selected by the project `.config` file and can
change independently of the Voximal application version.

Installation
------------

Extract the binary distribution and run its installer as root:

    tar xzf voximal_Vx.x_date-distrib.tar.gz
    cd voximal_Vx.x_date-distrib
    ./install.sh

Useful installer options are:

    ./install.sh -g             # Do not install GUI modules
    ./install.sh -u             # Do not generate uid.txt
    ./install.sh -U asterisk    # Select the runtime owner
    ./install.sh -d /target     # Stage files below another root

The installer detects the installed Asterisk version and selects the matching
app_voximal module. Asterisk must be restarted or the module loaded after the
installation.

Configuration
-------------

The main Asterisk configuration is normally installed as:

    /etc/asterisk/voximal.conf

The interpreter configuration is normally installed as:

    /etc/voximald.conf

A complete reference for voximal.conf is provided in CONFIGURATION.md. The
distribution also contains voximal.conf.sample.

A minimal dialplan entry is:

    [voximal]
    exten => 1000,1,Answer()
     same => n,Voximal(http://127.0.0.1/vxml/index.vxml)
     same => n,Hangup()

AAI and User-to-User
--------------------

Set the following option to read and decode RFC743x User-to-User headers before
passing the value to the VoiceXML session:

    [general]
    useuserinfo=rfc743x

The decoded value is available to VoiceXML through telephone.aai and
connection.aai. Semicolon-separated key/value contents can also be inspected
from the Asterisk dialplan:

    same => n,Set(IDC=${VOXIMAL(parse,${SIPREC_AAI},IDC)})

Rich AAI contents can be transported through a temporary file. JSON objects
and arrays received from the HTTP billing or dialer connectors are always
serialized as:

    file:///tmp/voximal-aai-<session-index>.json

The interpreter resolves this reference and exposes the parsed content through
the VoiceXML AAI context. Short, non-JSON User-to-User strings remain inline.

HTTP billing
------------

The billing endpoint can override the effective VoiceXML URL, parameter and
AAI when it accepts an `action=open` request:

    {
      "url": "voice.example.net/vxml/customer.vxml",
      "param": "customer:agent@database",
      "aai": {
        "customerId": 88200,
        "language": "fr-FR"
      },
      "max": 3
    }

An URL without a scheme receives `https://` for a domain or `http://` for an
IP address. `max` limits concurrent sessions sharing the exact effective
`param + URL` pair. JSON AAI objects and arrays are passed through a temporary
file; strings retain the legacy AAI behavior.

HTTP dialer
-----------

Polling responses may carry either `context`, `aai`, or both:

    {
      "jobs": [{
        "id": "call-123",
        "number": "+33123456789",
        "url": "https://voice.example.net/vxml/customer.vxml",
        "context": {"campaign": "reminder"},
        "aai": {"customerId": 88200, "language": "fr-FR"}
      }]
    }

When both fields are present, `aai` is sent to VoiceXML and `context` is kept
for the final `action=report` callback. With `context` alone, it is also used
as the VoiceXML AAI. JSON objects and arrays always use the temporary-file
transport, independently of their serialized length.

Prometheus exposes separate dialer counters:

    asterisk_voximal_dialer_originates
    asterisk_voximal_dialer_originates_error

Calls that successfully open VoiceXML also increment the normal Voximal
session counters. Enable Voximal debug logging to display billing/dialer HTTP
request URLs, response codes, content types, response bodies and decisions.

Command-line interface
----------------------

Important Asterisk CLI commands include:

    voximal show version
    voximal show configuration
    voximal show accounts
    voximal show sessions
    voximal show statistics
    voximal set logger on
    voximal set logger off
    voximal set logger interpreter
    voximal reload

The integrated dialer is controlled with:

    voximal dialer start
    voximal dialer stop
    voximal dialer kill
    voximal dialer status
    voximal dialer call <number-or-channel> <account>

SELinux
-------

Keep SELinux enabled on supported distributions. Voximal reuses the native
Asterisk process domain and file types instead of creating a separate process
domain:

- app_voximal and voximald run under asterisk_t;
- /usr/sbin/voximald uses asterisk_exec_t;
- /var/cache/voximal uses asterisk_var_lib_t.

The package always contains voximal_base.te and normally also contains the
compiled voximal_base.pp module. voximal_base is a minimal extension that adds
the System V message queue permissions used by app_voximal and voximald, plus
the missing permission to create cache subdirectories.

The installer loads voximal_base.pp and applies persistent file-context rules
with semanage and restorecon. If the compiled module is absent, install.sh can
build it from voximal_base.te.

Required SELinux management commands are semodule, semanage and restorecon.
Building the policy on the target additionally requires checkmodule and
semodule_package.

Diagnostics
-----------

Check the installation with:

    asterisk -rx "module show like app_voximal"
    asterisk -rx "voximal show version"
    asterisk -rx "voximal show configuration"

On SELinux systems, verify the runtime contexts with:

    ps -eZ | grep -E 'asterisk|voximald'
    ls -Zd /usr/sbin/voximald /var/cache/voximal
    semodule -l | grep voximal_base

Additional changes and compatibility notes are recorded in ChangeLog.
