How to run a script, asynchronous from dialplan

Hello Guys, I’m almost a beginner in asterisk.

I wanted to know if it is possible for me to run a script separately from asterisk.
So that would basically be asynchronous.

My goal is to make connections with the database and send information to a remote API, while dialplan continues to do its job normally.

It is possible? I’ve been trying to do this for a while, but without success.

Sure you could - possibly odbc functions tied to something like:

https://marcelog.github.io/articles/asterisk_json_curl_dialplan.html

And continue executing the next prio.

Dial in parallel to your regular dialplan and a local channel, use the local channel for the curl request and save the result in global variable

1 Like

We need more info :slight_smile:

Do you need to take any action on the success or failure of your API request? Do you need to return any values from your API request?

If your API call just logs some data and you don’t care what happens (‘message in a bottle’), you could just use the SHELL function, kick off a script, ending the command line with an ampersand (‘&’) and the script will execute in the background.

Apologies for the delay.

But from the way you mentioned, I understood that it is possible to send information, but this information does not run asynchronously to the dialplan, right?

Apologies for the delay.

Please Can you show me more of what this would look like, if it’s not too much to ask?

Apologies for the delay.

What I really need is to run a curl, or some other way I can send a json to a remote API.

I have to send the following data:

Call start:
-callerid(num)
-callerid(dnid)

Call handling:
-Callerid(num)
-Number that answered

End of call:
-callerid(num)
-end of call api code.

There’s more I need to submit… but I’m summarizing too much.

My difficulty is running these 3 scripts asynchronously during the call. So that the call doesn’t get stuck when having to run an AGI and having to wait to finish its execution to go to the next step.

Another difficulty I’m having is knowing who answered the call and sending it at the moment the call was answered. Because today the call is forwarded to a queue, and as far as I know, after the call enters the queue, it is not possible to perform many things within the queue. So if I wanted to run a script, it would have to be on the next line in the dialplan, which is when I exit the queue.

But I need the service in the queue, to send this event.

I believe that all this is possible, creating a script that connects to the AMI, and is forever reading the events, but this is something very laborious and must be well controlled/detailed so as not to cause call bugs.

In summary:

I would need to send events to a remote API asynchronously so as not to “hang the dialplan”, these events must contain:

  • Call initiation
  • Answer
  • End of call.

I greatly appreciate the help of all of you;

Below is a piece of my dialplan. I would have to fit this sending to the api, in my dialplan when dialing 94.

#include /etc/asterisk/global_features.conf

[ecoville] ;condominio ligando entre si e para portaria
exten => 94,1,NoOp(### LIGANDO PARA  TECNOCONTROL PORTARIA ###)
exten => 94,n,Set(CONDOMINIO=ecoville)
exten => 94,n,Macro(gravacao)
exten => 94,n,Set(QUEUE=tecnocontrol)
exten => 94,n,Playback(/var/lib/asterisk/sounds/custom/beep)
exten => 94,n,Queue(${QUEUE})
exten => 94,n,Hangup

Maybe something like:

        exten = 94,1,                   verbose(1,[${EXTEN}@${CONTEXT}])
        same = n,                       system(/scripts/log-my-data.sh --state=call-start --caller-id=${cid} --dialed-number=${did} &)
        same = n,                       // continue with your dialplan //
  1. Using ‘same = n’ will make your dialplan easier to write, read, maintain, and debug.
  2. You should use verbose() instead of noop().
  3. The ampersand at the end of the arguments to the system function gives you the asynchronicity
  4. Whatever language you choose to write your script, you should use '‘getopt_long’ to parse the command line options.

Welcome!

Riffing off of suggestion from @ambiorixg12 for parallel Local channels, and this previous post, and assuming four-digit PJSIP extensions, you could try adding something like this below your [ecoville] context in extensions.conf - not sure on specifics (didn’t test it) but it might help get you a little closer to your desired outcome:

[ecoville-agent]
exten = _XXXX,1,Set(par=Local/${EXTEN}@ecoville-parallel)
 same =       n,Set(opt=G(ecoville-answered^${EXTEN}^1))
 same =       n,Set(__OG_CALLER_CHANNEL=${CHANNEL})
 same =       n,Dial(${PJSIP_DIAL_CONTACTS(${EXTEN})}&${par},60,${opt})

[ecoville-parallel]
exten = _XXXX,1,Set(res=${CURL(url-initiated)})

[ecoville-answered]
exten = _XXXX,1,Wait(10)
 same =       n,Set(res=${CURL(url-answered)})
 same =       n,Bridge(${OG_CALLER_CHANNEL})
exten = h,1,Set(res=${CURL(url-ended)})

And also modify your queues.conf like so - and possibly preload pbx_config and chan_local (see bottom of the queues.conf sample file):

[ecoville]
member => Local/5007@ecoville-agent,0,Agent 007,PJSIP/5007
member => Local/5008@ecoville-agent,0,Agent 008,PJSIP/5008

[tecnocontrol]
member => Local/5006@ecoville-agent,0,Agent 006,PJSIP/5006
member => Local/5007@ecoville-agent,0,Agent 007,PJSIP/5007

Please do let us know how it went for you and what your eventual dial plan morphed into, in order to help the next beginner. Thank you!

Edited: to add that the (url-answered) part could hang – look at the Originate() application’s async ‘a’ option to solve that part, or, another parallel Local Dial(), or, forked System() per post from @sedwards . And given all this dial plan complexity, you may find that AMI or similar is better/easier for your situation.

The answers so far all assume you want/need to do this from the dialplan. What about an external (python/c/etc) app that connects via the ARI? I can monitor the state of the call and initiate actions within Asterisk or externally (SQL, fork applications, etc)

ARI cannot take actions on an arbitrary call; it only has control whilst the call dialplan is running Stasis, for that application.

AGI is likely to be more appropriate if you just want to trigger asynchronous processing, and AMI if you want to track the call and do processing without affecting the dialplan execution.

My feeling is that ARI is least likely to be appropriate in this case, as it is intended for very low level control of the call not for on the side processing.

ARI can be used as a way to listen for events.

FastAGI would be the other obvious way. Since your server process can continue running after the connection from Asterisk is closed, you can perform whatever asynchronous operations you like.

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