Even he, to whom most things that most people would think were pretty smart were pretty dumb, thought it was pretty smart.
—Douglas Adams, The Salmon of Doubt
The Asterisk Gateway Interface, or AGI, provides a standard interface by which external programs may control the Asterisk dialplan. Usually, AGI scripts are used to do advanced logic, communicate with relational databases (such as PostgreSQL or MySQL), and access other external resources. Turning over control of the dialplan to an external AGI script enables Asterisk to easily perform tasks that would otherwise be difficult or impossible.
This chapter covers the fundamentals of AGI communication. It will not teach you how to be a programmer—rather, we'll assume that you're already a competent programmer, so that we can show you how to write AGI programs. If you don't know how to do computer programming, this chapter probably isn't for you, and you should skip ahead to the next chapter.
Over the course of this chapter, we'll write a sample AGI program in each of the Perl, PHP, and Python programming languages. Note, however, that because Asterisk provides a standard interface for AGI scripts, these scripts can be written in almost any modern programming language. We've chosen to highlight Perl, PHP, and Python because they're the languages most commonly used for AGI programming.
Instead of releasing an API for programming, AGI scripts
communicate with Asterisk over communications channels (file
pointers , in programming parlance) known as
STDIN, STDOUT, and
STDERR. Most computer programmers will recognize
these channels, but just in case you're not familiar with them we'll
cover them here.
STDIN , STDOUT , and STDERR are channels by which programs in Unix-like
environments receive information from and send information to external
programs. STDIN, or "standard input," is the
information that is sent to the program, either from the keyboard or
from another program. In our case, information coming from Asterisk
itself comes in on the program's STDIN file handle.
STDOUT, or "standard output," is the file handle
that the AGI script uses to pass information back to Asterisk.
Finally, the AGI script can use the STDERR
("standard error") file handle to write error messages to the Asterisk
console.
Let's sum up these three communications concepts:
An AGI script reads from STDIN to get
information from Asterisk.
An AGI script writes data to STDOUT to
send information to Asterisk.
An AGI script may write data to STDERR to
send debug information to the Asterisk console.
The communication between Asterisk and an AGI script follows a predefined pattern. Let's enumerate the steps, and then we'll walk through one of the sample AGI scripts that come with Asterisk.
When an AGI script starts, Asterisk sends a list of variables and their values to the AGI script. The variables might look something like this:
agi_request: test.py
agi_channel: Zap/1-1
agi_language: en
agi_callerid:
agi_context: default
agi_extension: 123
agi_priority: 2
After sending these variables, Asterisk sends a blank line. This is the signal that Asterisk is done sending the variables and it is time for the AGI script to control the dialplan.
At this point, the AGI script sends commands to Asterisk by
writing to STDOUT. After the script sends each
command, Asterisk sends a response that the AGI script should read.
This action (sending commands to Asterisk and reading the responses)
can continue for the duration of the AGI script.
You may be asking yourself what commands you can use from within your AGI script. Good question—we'll cover the basic commands shortly.[126]
In order to work properly, your AGI script must be executable.
To use an AGI script inside your dialplan, simply call the
AGI() application, with the name of the AGI script
as the argument, like this:
exten => 123,1,Answer()
exten => 123,2,AGI(agi-test.agi)
AGI scripts often reside in the AGI directory (usually located in /var/lib/asterisk/agi-bin), but you can specify the complete path to the AGI script.
In this chapter, we'll first cover the sample agi-test.agi script that comes with Asterisk (which was written in Perl), then write a weather report AGI program in PHP, and then finish up by writing an AGI program in Python to play a math game.
[126] To get a list of available AGI commands, type
show agi at the Asterisk command-line
interface. You can also refer to Appendix C for an AGI command
reference.