Asterisk JSON_DECODE function

In very recent versions of Asterisk 16,18 and 19 (now available for the Distro) there is a new function called JSON_DECODE. There is no JSON_ENCODE counterpart. It was contributed by the the asterisk community forum user interlinked (I don’t know if they have a sign-in here).

It provides basic JSON parsing, a typical use case would be doing a curl of an API, getting a result back in JSON, and pulling whatever info you need to continue. It will parse a 1D array of key/value pairs, and there is a technique here that may allow you to work with more complex arrays.

To use this, confirm you asterisk version is new enough with this from the asterisk console:

*CLI> core show function JSON_DECODE

  -= Info about function 'JSON_DECODE' =-

[Synopsis]
Returns the string value of a JSON object key from a string containing a JSON
array.

[Description]
The JSON_DECODE function retrieves the value of the given variable name and
parses it as JSON, returning the value at a specified key. If the key cannot be
found, an empty string is returned.

[Syntax]
JSON_DECODE(varname,item)

boredapi.com hosts a free API that returns JSON, from the bash prompt you can see it in action

# curl https://www.boredapi.com/api/activity
{"activity":"Find a charity and donate to it","type":"charity","participants":1,"price":0.4,"link":"","key":"1488053","accessibility":0.1}[[email protected] modules]#

Here is some simple dialplan you can use with FreePBX:

[from-internal-custom]               ; edit 4500 if necessary to avoid conflict with anything else
exten => 4500,1,NooP(Entering user defined context from-internal-custom in extensions_custom.conf)
exten => 4500,n,set(result=${CURL(https://www.boredapi.com/api/activity)})
exten => 4500,n,FLITE(${JSON_DECODE(result,activity)})
exten => 4500,n,Hangup

With the above in extensions_custom.conf and the diaplan reloaded, you can call 4500 from a local extension and have a random activity read back to you. Different one for each call.

    -- Executing [[email protected]:1] NoOp("PJSIP/6006-00000039", "Entering user defined context from-internal-custom in extensions_custom.conf") in new stack
    -- Executing [[email protected]:2] Set("PJSIP/6006-00000039", "result={"activity":"Listen to your favorite album","type":"music","participants":1,"price":0.08,"link":"","key":"3136729","accessibility":0.2}") in new stack
    -- Executing [[email protected]:3] Flite("PJSIP/6006-00000039", "Listen to your favorite album") in new stack
    -- <PJSIP/6006-00000039> Playing '/tmp/flite_2xOr9u.slin' (language 'en')
    -- Executing [[email protected]:4] Hangup("PJSIP/6006-00000039", "") in new stack
  == Spawn extension (from-internal, 4500, 4) exited non-zero on 'PJSIP/6006-00000039'

So what is a practical application of this? Storing an array of data in places that are designed to accept only a single value. One place is with the CDR userfield, or in the GUI as the extension account code.

I’ve been trying to use it with Dynamic Routes, but the dialplan generated for dynroutes does an ExecIf against the returned JSON string, and the quote characters causes it throw an error. A task for some future rainy weekend.

4 Likes

This topic was automatically closed 31 days after the last reply. New replies are no longer allowed.