What is AGI?
The Asterisk Gateway Interface (AGI) is a way to interface with Asterisk much like CGI is for Apache. It is language agnostic, and there are example scripts in PHP, Perl, and Python to name a few. The reason for this versatility is that AGI uses standard streams that are connected with modern UNIX operating systems. The streams used are STDIN, STDOUT, and STDERR.
Because of its flexibility, AGI can be used to create a range of different applications. Some examples that I have seen are applications that tell you the current temperature, pushing caller ID information to a MythTV system, writing CDR data to different backend databases, and the list goes on.
A small disclaimer, I wrote this guide as a learning tool for myself. I’ve attempted to present the information here in a clear, concise manner, and to be as accurate as possible. If you find any errors or have suggestions please post your suggestions.
Getting started
Asterisk has a standard location for AGI scripts when installed from source. If you’ve installed from a vendor’s package they might have changed the location to fit their standards. The location by default is /var/lib/asterisk/agi-bin/.
Looking in that directory you can see that there are already several programs provided by the developers to give you a head start.
/var/lib/asterisk/agi-bin/
agi-test.agi
eagi-test
eagi-sphinx-test
jukebox.agi
Go ahead and test that you can call the AGI files by adding something like the following to
your dialplan:
exten => 300,1,Answer
exten => 300,n,AGI(agi-test.agi)
exten => 300,n,Hangup
Now dial 300 (or whatever extension you chose) and see if you hear a voice read off an ex-tremely long number. If you do then you’ve successfully called an agi-test script.
All that this section did in the dialplain is calling the AGI application with the agi script to run.
AGI Internals
As mentioned previously, AGI works through the standard UNIX pipes of STDIN, STDOUT, and STDERR. Asterisk will pass variable information from the call to the AGI script. Please see the list of agi variables below.
AGI Variables
agi request Name of the agi script that is being called
agi channel Channel that the call is coming from, e.g. Zap/1-1
agi language Language that is configured on the server
agi type Call type, e.g. Zap
agi uniqueid A unique identifier for this session
agi callerid Caller ID number
agi calleridname Caller ID name
agi callingpres PRI Call ID presentation variable
agi callingani2 Caller ANI2 (PRI channels)
agi callington Caller type of number (PRI channels)
agi callingtns ransit Network Selector (PRI channels)
agi dnid Dialed Number Identifier
agi rdnis Redirected Dial Number ID Service
agi context Current Context (e.g. outbound)
agi extension Extension that was called (e.g. 300)
agi priority Current priority in the dialplan
agi enhanced 0.0
agi accountcode Accound code (if specified)
Your AGI script will get all of this information dumped to it from STDIN when it is initially called. It will then return any results or operations through STDOUT. During this process Asterisk essentially turns over control of the dialplan to the AGI script. A list of commands that you can send back to Asterisk is on page
Program overview
This program is a simple example of using the AGI variables that get passed to it and acting on
them. This program grabs the callerid variable passed to it via STDIN from Asterisk. Remember
that when discussing internals we said that Asterisk would pass that information as agi callerid. It
then reads back that callerid information to the person who called. This is a great tool to have on
hand when you’re trying to figure out what number you’re calling from.
1 #!/usr/bin/python
2 #
3 # Import module required.
4 import sys
5 # Read and ignore AGI environment (read until blank line)
6 env = {}
7 tests = 0
8 # Get a dump of all the environment variables passed to the AGI script
9 while 1:
10 line = sys.stdin.readline().strip()
11 if line == ”:
12 break
13 key,data = line.split(�:�)
14 if key[:4] <> ‘agi_’:
15 #skip input that doesn’t begin with agi_
16 sys.stderr.write(“Did not work!\n”)
17 sys.stderr.flush()
18 continue
19 key = key.strip()
20 data = data.strip()
21 if key <> ”:
22 env[key] = data
23 sys.stderr.write(“AGI Environment Dump:\n”)
24 sys.stderr.flush()
25 for key in env.keys():
26 if key == “agi_callerid”:
27 callerid = env[key]
28 sys.stderr.write(” — %s = %s\n” % (key, env[key]))
29 sys.stderr.flush()
30 sys.stdout.write(“SAY DIGITS ” + callerid + ” \”\”\n”)
31 sys.stdout.flush()
32 # Need to grab a result for this to work
33 result = sys.stdin.readline()
The keys to this script are lines 27 and 30. In line 27 we store the callerid information that
Asterisk has passed to STDIN. Then, we take this number and play it back to the caller on line
30. This is a simple program but gives us our foundation of dealing with information coming from
Asterisk
Debugging programs
There are several useful tricks you can use when debugging AGI programs. The “agi debug”
command dumps the raw transmit and receive commands going through the Asterisk system. You
can enable it by typing agi debug at the asterisk console interface.
Additionally, AGI scripts dump error messages to the Asterisk “console” session. If you started
your session using normal init scripts, just attaching to it normally won’t show you these messages.
You need to launch asterisk with the command “asterisk -cr”.
AGI Commands
answer Asserts answer
channel status Returns status of the connected channel
control stream file Send the given file, allowing playback to be controlled by the given dig-
its, if any. (Asterisk 1.2)
database del Removes database key/value
database deltree Removes database keytree/value
database get Gets database value
database put Adds/updates database value
exec Executes a given Application. (Applications are the functions you use
to create a dial plan in extensions.conf ).
get data Gets data on a channel
get full variable Gets a channel variable, but understands complex variable names and
builtin variables. (Asterisk 1.2)
get option Behaves similar to STREAM FILE but used with a timeout option.
(As-terisk 1.2)
get variable Gets a channel variable
hangup Hangup the current channel
noop Does nothing
receive char receives one character from channels supporting it
receive text Receives text from channels supporting it
record file Records to a given file
say alpha Says a given character string (Asterisk 1.2)
say date Say a date (Asterisk 1.2)
say datetime Say a formatted date and time (Asterisk 1.2)
say digits Says a given digit string
say number Says a given number
say phonetic Say the given character string.
say time Say a time
send image Sends images to channels supporting it
send text Sends text to channels supporting it
set autohangup Autohangup channel in some time
set callerid Sets callerid for the current channel
set context Sets channel context
set extension Changes channel extension
set music Enable/Disable Music on hold generator, example “SET MUSIC ON
default”
set priority Prioritizes the channel
set variable Sets a channel variable
stream file Sends audio file on channel
tdd mode Activates TDD mode on channels supporting it, to enable communica-
tion with TDDs.
verbose Logs a message to the asterisk verbose log
wait for digit Waits for a digit to be pressed



hello,first i want thank you very mush for this subject, it was usefull for me.
second i ask you for help me in create script ogi file,if you agree i will send the details.
i hope you agree becouse it is very important for me and i will be thankfull for you.
I’m waiting.. good bye
Yasmin, sure, send us the detail for the AGI script you want. If i couldn’t help, there are many volunteers around who may help in better way.
hello sir,i’m very very happy you accept help me, i hope you help me as fast as you can becouse this will be spesific my life..
this is the datiels:
Commercial :
This system will be used for push call every where in the world from our server throw VoIP to the mobile or land lines
We will use it for all the world countries, so we have to control the duration of the ring per country (it will be different each time we change the pushing destination)
So the duration of ringing will be between (5 Second to 1 Minute)
And we have to change the message that the subscriber will hear when he answering our call ,
We have to control the caller ID that the subscriber received on mobile or land line phone , we will use our numbers or extensions as a caller ID ,
my System specification:
I want use on the server:
- Asterisk version 1.4.17
- Operating system is Linux
-E1 Lines or another system.
sir , this is my email if you want contant me any time:
power.grils2000@gmail.com
helloooooooo,sir why you don’t answer me.
plz plz sir answer i really need your help,
i don’t know how can i start to work in this
i’m waiting you…
Thanks the “agi debug” command really turned this day around!
Now im going to check out fast agi.
If you have any helpful links on the fast agi topic plz post them.
I have problem. I am using Asterisk 1.4 version and running agi scripts but for some reason my asterisk server gets stuck and I see the following errors on the asterisk console:
[May 18 13:56:38] WARNING[10949]: rtp.c:1873 ast_rtcp_new: Unable to allocate RTCP socket: Too many open files
[May 18 13:56:38] WARNING[10949]: channel.c:762 ast_channel_alloc: Channel allocation failed: Can’t create alert pipe!
[May 18 13:56:38] WARNING[10949]: chan_sip.c:4062 sip_new: Unable to allocate AST channel structure for SIP channel
[May 18 13:56:38] NOTICE[10949]: chan_sip.c:14721 handle_request_invite: Unable to create/find SIP channel for this INVITE
[May 18 14:03:53] WARNING[13436]: res_agi.c:259 launch_script: Unable to create toast pipe: Too many open files
[May 18 14:15:17] WARNING[14914] app_dial.c: Unable to create channel of type ‘SIP’ (cause 42 – Switching equipment congestion
In result my customer calls are dropping and get the get dead air. Anybody can quick help what is going wrong pleae?
Alesbi,
I’m not exactly sure, but I guess this is logs issue, your AGI application is trying to dump log in the logs file but maybe the space is full. Please verify if that is the case. First thing i’d see is /var/log/asterisk
Hello;
We are a Canadian registered charity and we are trying to develop a community Voip line. The content will be placed in a mysql database. Users can dial in a number, select a particular masjid and access the prayer times and other announcements. Would appreciate a snippet of code for AGI preferably in PHP. Thanks
Alesbi,
Here is the exact solution for the errors/warnings you are getting. Basically it is your system issue but not Asterisk issue. You should tune your system limit by applying the following steps.
open /etc/security/limits.conf and add the following at the end:
user soft nofile 65536user hard nofile 65536
Also run the following command on Linux command prompt or put it in the Asterisk init script in start.
ulimit -n 65536Hope this helps
Hi,
We need a AGI script to accept last 4 digits and zip code of a customer to
look into a MS Sql database and handle renewal or cancellation of their
account. Please let us know if such a script can be created.
Hi Digvijay,
Yeah, Everything can be done in AGI, your card holders can login to their account, verify last 4 digit etc as you mentioned in your question BUT we have done this with MySQL database, i’m not sure about MSQL DB. However programaticly it should be easy. Let me know if you need more info regarding your question.
Hi,
I just started to study asterisk AGI. So this artical was very helpful to me. I have no problem with sending asterisk values to a AGI. We can easily use php arguments for that. But I want to know how to get some input to dialplan from AGI file. Can you please help me with this problem.
Thank you!
First of all thank you a lot of this technical introduction to asterisk agi, I have been searching a lot but did not find any good stuff as this artical is very well explained. Actually i have been trying to build a prepaid application for asterisk, so that when ever a caller calls, the dial plan will pass in to the agi script, AGI- script will check the first few dialed digits (lets say 3), on the basis of these digital will pull out information from the database(mysql), if the credit is negative or zero the calls will not pass through and it will be rejected and if there is credit then the call will pass through. please i need help in this regard..
and one more thing can i link this database with phpmyadmin……..
your help in this regard will be highly appreciated
wating for your responce
Best Regards
Harry
Harry, what language you are using with Asterisk AGI? Perl or PHP?
Hi-
I need some one who can help to write PHP agi script very simple – asterisk —->E1——–>1E—–PBX-GSM
I want agi to look Phpmyadmin database ——>incoming DID—–>send to——>ext