Shell cURL+JSON in the dialplan

Asterisk 13.7.2

Dialplan:

exten => s,1,GotoIf($["${CHANNEL(state)}" = "Up"]?begin)
exten => s,n,Answer
exten => s,n,Wait(1)
exten => s,n(begin),Noop(Playing announcement howdy)
exten => s,n,Playback(custom/howdyhowdyhowdy)
exten => s,n,Set(result=${SHELL(curl -s 'https://somewebsite.com/bcms' |     python -c "import sys, json; print json.load(sys.stdin)['AUX']")})
exten => s,n,SayDigits(${result})
exten => s,n,Hangup

when I curl -s 'https://somewebsite.com/bcms' I get a JSON response with multiple fields. I need the value of only one field.

In the Linux command line, when I run:
curl -s 'https://somewebsite.com/bcms' | python -c "import sys, json; print json.load(sys.stdin)['AUX']")})
It works. Linux returns a number result (e.g. 10)

When I try to bake that into the dial plan I get an error:

[2016-10-26 15:40:36] WARNING[13399][C-00002c77]: pbx.c:4771 pbx_substitute_variables_helper_full: Error in extension logic (missing '}')
[2016-10-26 15:40:36] WARNING[13399][C-00002c77]: pbx.c:4274 func_args: Can't find trailing parenthesis for function 'SHELL(curl -s 'https://somewebsite.com/bcms' | python -c "import sys, jso'?

I think this is related to the new line clause. I read the example on the wiki, but I am not sure how to string this together. Can anyone help me by providing an example using the info above? Thanks for your help!

The ; is being treated as a comment indicator. You will need to escape it by putting \ in front of it.

2 Likes

I’m using curl module to run a request from an external API (res_curl)

1- Check if CURL function is installed or not by running this command in your Asterisk CLI :

sip*CLI> core show function CURL

If you have already this function defined, you can move directly to step 6.
If you get an output message error like :

No function by that name registered.
Command 'core show function CURL' failed.

-> you can follow these instructions to install/enable it
2- Install Asterisk CURL package in your command line :

$ yum install asterisk16-curl

You can replace 16 with your Asterisk version.

3- Install jq command :

$ yum install jq

4- You have to add this line into modules.conf (if you use an PBX UI platform like FreePBX or Issabel …, you should work with modules_custom.conf file) :

...
load => res_curl.so
...

5- Reload your asterisk :

$ systemctl restart asterisk

6- You should found CURL function installed and worked. Then you can call your API like this to go through this json output example :

{
  "result": {
      "data": {
        "name": "Hello world",
        "id": 882983
      },
      "message": "messages.info.get_success",
      "code":200
  },
  "errors":[]
}
exten => s,n,Set(CURL_RESULT=${CURL("https://apilink.co/test")})
exten => s,n,Set(curl_status=${SHELL(echo '${CURL_RESULT}' | jq '.result.code' | tr '\n' ' ')})

Hope its help !

Why not do the following?


exten => s,n,Set(CURL_RESULT=${SHELL(curl -s 'https://apilink.co/test' | jq '.result.code' | tr '\n' ' ')})

Does anyone know a reason why jq would not work from within dialplan ? It is installed and working fine if I call the curl from the command line outside of asterisk. Curl is working fine from within the dial plan but if I use the jq part to set a Variable or just display it it is always empty. There is no error in SYS log etc so I am a bit lost. I want to avoid using the agi route to parse json datA

Not sure how you installed Asterisk, but I would check if you can run jq as the Asterisk user.

The ‘PATH’ environment variable can also play a role. I pass a limited environment when I start Asterisk like:

                nice --adjustment=-20\
                        env --ignore-environment\
                                HOSTNAME=${HOSTNAME}\
                                PATH=${PATH}\
                                        ${ASTERISK} ${START_OPTIONS}

so if ‘jq’ was not on the path I passed, it would not be found.