Variables block in click_to_call API does not inject custom channel variables into dialplan

VitalPBX Version: 4.5.3 R1 (Asterisk 20.18.2, Debian 12)

Summary:
The variables object in the POST /api/v2/core/click_to_call endpoint is documented as passing variables to the generated call channels, but custom variables never appear in the dialplan.


Steps to Reproduce:

Send the following API request (JSON format as required by docs):

curl --location 'https://callcenter.example.com/api/v2/core/click_to_call' \
--header 'app-key: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
    "caller": "10013",
    "callee": "0123456789",
    "cos_id": 1,
    "cid_name": "Test Call",
    "cid_number": "0123456789",
    "variables": {
        "X-APP": "Postman",
        "X-CAMPAIGN": "sales"
    }
}'

The API echoes the variables back in the response confirming they were received:

{
    "status": "success",
    "message": "Call queued",
    "data": {
        "caller": "10013",
        "callee": "0123456789",
        "variables": {
            "X-APP": "Postman",
            "X-CAMPAIGN": "sales"
        }
    }
}

Expected Behavior:
X-APP and X-CAMPAIGN should be available as channel variables in the dialplan, accessible via ${X-APP} and ${X-CAMPAIGN}.


Actual Behavior:
The variables are completely empty in the dialplan. Verified using NoOp debug statements inside [before-bridging-call-hook] which runs on the real PJSIP channel (not the Local/ wrapper):

-- Executing [s@before-bridging-call-hook:5] NoOp("PJSIP/10013-00000011", "X-APP=") in new stack
-- Executing [s@before-bridging-call-hook:6] NoOp("PJSIP/10013-00000011", "X-CAMPAIGN=") in new stack

Both empty. Tested across 5+ calls with multiple variable name formats (X-APP, X_APP, XAPP). None appear.


Variables confirmed available on the same channel for reference:

FROM_QUEUE_CALLBACK=yes
CTC_EXECUTED=yes
CALLID=1780570501.42
CALLER=0123456789
CALLEE=10013

These are VitalPBX-set variables, confirming the hook fires correctly and the channel is accessible.


Root Cause Analysis:
The click-to-call API generates an Asterisk .call file in /var/spool/asterisk/outgoing/. The variables block is presumably written as SetVar: lines in that file. However, because the call originates via a Local/ channel pair (Local/AGENT@click-to-call/n), the SetVar: variables from the call file are set on the originating spool wrapper — they do not propagate into the Local/ channel ;2 leg where the dialplan actually executes. This is a known Asterisk behavior with Local/ channels and call file variable propagation.


Workaround:
The reserved variable CONTEXT works correctly (it changes the Context: directive in the .call file, not a channel variable). VitalPBX-native variables like FROM_QUEUE_CALLBACK=yes are also available and can be used to identify click-to-call originated calls.

For integrations requiring call correlation without custom variables, the CALLID variable (set by VitalPBX itself) is available and reliable.


Request:
Please investigate why SetVar: lines from the click-to-call .call file are not propagating into the Local/ channel dialplan execution. A fix could involve either:

  1. Using AMI Originate with Variable: instead of call file SetVar:, which properly injects variables into originated channels.
  2. Documenting clearly that the variables block only supports the reserved CONTEXT variable and that custom variables are not functional.

Happy to share full Asterisk verbose logs if needed.


References:

  • VitalPBX Changelog: “API: The click-to-call endpoint now supports passing variables for the generated channels. Nonetheless, the request has to be in JSON format.” (VitalPBX 3.x changelog)
  • VitalPBX 4 API Postman docs: https://documenter.getpostman.com/view/5481262/2s935hQmgP
1 Like