Redial: Interactive Telephony : Week 5
Programming Asterisk: More AGI, More PHP and perhaps more more
More PHP and AGI
Variable Scope
One thing that we neglected to cover last week was the scope of variables in PHP.
Consider the following PHP:
<?PHP
function myFunction()
{
$bVariable = "world";
}
$aVariable = "hello";
echo($aVariable . " " . $bVariable);
?>
It will only print "hello" and will not show "hello world" as we are intending. This is an example of variable scope, since the $bVariable is defined within myFunction() it is not accessible from outside the function. We could remedy this by "returning" $bVariable and assigning or echoing it out from there.
<?PHP
function myFunction()
{
$bVariable = "world";
return $bVariable;
}
$aVariable = "hello";
$cVariable = myFunction();
echo($aVariable . " " . $cVariable);
?>
Another thing that should be known is that "global" variables, those defined outside of functions, are not automatically accessible inside functions and have to be declared first.
This won't work as intended.
<?PHP
function myFunction()
{
$bVariable = "world";
echo($aVariable . " " . $bVariable);
}
$aVariable = "hello";
myFunction();
?>
By declaring the "global" variable inside the function we can use it. This will work as intended.
<?PHP
function myFunction()
{
GLOBAL $aVariable;
$bVariable = "world";
echo($aVariable . " " . $bVariable);
}
$aVariable = "hello";
myFunction();
?>
Yet another way of doing the same thing would be to pass in the variable that you want access to.
<?PHP
function myFunction($cVariable)
{
$bVariable = "world";
echo($cVariable . " " . $bVariable);
}
$aVariable = "hello";
myFunction($aVariable);
?>
More Information:
PHP: Functions - Manual
Emailing Files
While the Asterisk Voicemail system is nice and gives us an easy means to get messages recorded and emailed for other uses it isn't terribly flexible.
If perchance you are using the "parseMailScript" that we covered early on and you want to develop your own messaging system within Asterisk but still want to recieve messages that are left on the server via email you can use the PHP Mail function.
Unfortunately, the Mail function is a bit difficult to work with when sending attachments. With this in mind I put together a function that can be included in your plain PHP or AGI scripts for sending mail with attachments.
To use it first "include" it into your script (AGI or straight PHP) and then call the function. Here is an example.
#!/usr/bin/php -qc /var/lib/asterisk/agi-bin/useragi/php_agi.ini
<?PHP
require('/var/lib/asterisk/agi-bin/useragi/phpagi.php'); // only if doing AGI
include("/var/lib/asterisk/agi-bin/useragi/mailer.php"); // Includes the mailAttachment function
$success = mailAttachment("Shawn.Van.Every@nyu.edu", "vanevery@walking-productions.com", "Test", "Here is a message body\nblah blah\n", "/home/sve204/phonelist.gsm");
?>
As you can see, mailAttachment takes the to address, from address, subject subject, message body and attachment file as arguments.
If you want it to work exactly how the parseMailScript is setup you should structure the body of the message in the same manner that our voicemail is sent (which is as follows).
/*
The format that voicemail messages are sent:
${VM_NAME}\n${VM_DUR}\n${VM_MSGNUM}\n${VM_MAILBOX}\n${VM_CALLERID}\n${VM_DATE}
*/
$to = "somebody@somewhere.com";
$from = "somebody@somewhere.com";
$subject = "The Title";
$body = "Some Name\nSome Duration\nSome Mailbox\nSome Caller ID\nSome Date";
$attachment = "/home/sve204/phonelist.gsm";
$success = mailAttachment($to, $from, $subject, $body, $attachment);
Call Files with Variables
You can set variables to be used in Asterisk when generating call files. In order to do this you simply add the following line to the call file.
SetVar: VARNAME=VARVALUE
The PHP script that we started working with to make generating call files easy has been updated to allow the passing of a variable.
It is the fourth argument and is optional. You pass in the variable as NAME=VALUE.
/var/lib/asterisk/agi-bin/useragi/gencallfile.php 17188096659 somecontext 10 MYVAR=something
Call Files for use in the future
If you change the modified date of a call file (using the touch command as shown below) you can have asterisk make the call at that point.
touch -t YYYYMMDDHHMM.SS filename
touch -t 200610041320.15 callfile.call
PHP for Web Development
Of course, PHP is very good for web development.
<html> <!-- Required for all HTML pages -->
<head>
<title>The Top Bar Title</title>
</head>
<body>
Some information
<br> <!-- A line break -->
<!-- A Comment Tag -->
<? // Denotes the start of PHP processing
echo "The Date and Time is: "; // print a string, end with a semicolon
$mydata = "July 29, 2004"; // Assign a variable
echo $mydata; // print the string variable
?>
</body>
</html> <!-- Closing tag, required -->
Example
PHP can occur anywhere in the page within "<? ?>" tags
<?
function printDate()
{
echo "The Date and Time is: ";
$mydata = "July 29, 2004";
echo $mydata;
}
?>
<html>
<head>
<title>The Top Bar Title</title>
</head>
<body>
<?
printDate();
?>
</body>
</html>
Example
PHP with Forms
PHP is ideal for generating HTML forms and even more so for dealing with data that comes back from forms.
A Basic HTML Form
<html>
<head>
<title>A Basic HTML Form</title>
</head>
<body>
<form action="form_example.php" type="get">
First Name:<input type="text" name="first_name"><br>
Last Name:
<select name="last_name">
<option value="Smith">Smith</option>
<option value="Doe">Doe</option>
</select>
<br>
<input type="submit" value="Submit Me">
</form>
</body>
</html>
HTML Form Example
Form Processing with PHP
Dealing with data submitted via a form
<?
/*
Description: Helper function to get values from a form post (type="post" or query string (type="get")
Returns: value of key or null on failure
*/
function getPOSTorGETValue($key)
{
if (isset($_POST[$key]))
{
$value = $_POST[$key];
}
else if (isset($_GET[$key]))
{
$value = $_GET[$key];
}
else
{
$value = null;
}
return $value;
}
?>
<html>
<head>
<title>The Form Output</title>
</head>
<body>
<?
$first_name = getPOSTorGETValue("first_name");
$last_name = getPOSTorGETValue("last_name");
echo "Your First Name is: " . $first_name . "<br>";
echo "Your Last Name is: " . $last_name . "<br>";
?>
</body>
</html>
Example Form Output
Database Interaction
PHP has a pretty straight forward method to working with MySQL databases. I am not going to go into SQL which is the language used to put data in and get data out of a database so if you would like to learn it this provides a good starting point: http://www.webdevelopersnotes.com/tutorials/sql/
There is one caveat to working with Asterisk on Social and MySQL on ITP's webserver, the port to connect to MySQL on ITP's webserver is not open. If you plan to connect with an AGI script or PHP script from Social, you can request that Nancy open the port for your user to Social.
// Some Variables used for connecting
$hostname = "itp.nyu.edu"; // Hostname of the MySQL server
$dbname = "sve204"; // Database name, this is your net-id if using ITP's server
$username = "sve204"; // MySQL username, this is probably your net-id
$password = "xxxxxx"; // MySQL password, this is NOT your net-id password
// Create a connection to the database server
$mySql = mysql_connect($hostname, $username, $password) or die (mysql_error());
// Tell mysql that you want to use your database
mysql_select_db($dbname, $mySql) or die(mysql_error());
// A string for our SQL statement
$query = "insert into callers (caller_id) values ('17188096659')";
// Execute the query, actually inserts the data
$result = mysql_query($query, $mySql);
The above inserts one row into the database table callers and sets the caller_id equal to 17188096659.
Here is an example that pulls all of the caller_id values out of the table
// Here is a query function that I like to use to make my life easier
function sqlQuery($query)
{
global $mySql;
$data = null;
$result = mysql_query($query, $mySql);
# This set's up an associative array (key->value pair) for all of the data returned
if (sizeof($result) > 0)
{
$num_fields = mysql_num_fields($result);
$row_cnt = 0;
while ($row_data = mysql_fetch_array($result)) {
for ($cnt = 0; $cnt < $num_fields; $cnt++) {
$field_name = mysql_field_name($result, $cnt);
$data[$row_cnt][$field_name] = $row_data[$cnt];
}
$row_cnt++;
}
}
return $data;
}
// Some Variables used for connecting
$hostname = "itp.nyu.edu"; // Hostname of the MySQL server
$dbname = "sve204"; // Database name, this is your net-id if using ITP's server
$username = "sve204"; // MySQL username, this is probably your net-id
$password = "xxxxxx"; // MySQL password, this is NOT your net-id password
// Create a connection to the database server
$mySql = mysql_connect($hostname, $username, $password) or die (mysql_error());
// Tell mysql that you want to use your database
mysql_select_db($dbname, $mySql) or die(mysql_error());
// A string for our SQL statement
$query = "select caller_id from callers";
// Execute the query, actually inserts the data
//$result = mysql_query($query, $mySql);
// Using my function above
$result = sqlQuery($query);
for ($i = 0; $i < sizeof($result); $i++)
{
echo("Row: " . $i . " value: " . $result[$i]['caller_id'] . "\n");
}
More AGI
Predefined Variables
// Predefined AGI Variables, send them to the Asterisk console for debugging
$agi->conlog($agi->request["agi_request"]);
$agi->conlog($agi->request["agi_channel"]);
$agi->conlog($agi->request["agi_language"]);
$agi->conlog($agi->request["agi_uniqueid"]);
$agi->conlog($agi->request["agi_callerid"]);
$agi->conlog($agi->request["agi_dnid"]);
$agi->conlog($agi->request["agi_rdnis"]);
$agi->conlog($agi->request["agi_context"]);
$agi->conlog($agi->request["agi_extension"]);
$agi->conlog($agi->request["agi_priority"]);
$agi->conlog($agi->request["agi_enhanced"]);
$agi->conlog($agi->request["agi_accountcode"]);
$agi->conlog($agi->request["agi_network"]);
$agi->conlog($agi->request["agi_network_script"]);
A Full Example
AGI Portion
Web Portion
Midterm Thoughts
Voice 2.0
Telephony Examples
Nerd Vitties
Get Your Email By Telephone: Introducing MailCall for Asterisk
NewsClips for Asterisk
Wakeup System
Weather System
As Easy As 1-2-3: A Telephone Reminder System for Asterisk