Twilio: Rolling My Wife’s Eyes in 31 Lines of PHP

And then she gives you that look
The Look - Flickr user Nabo, used under CC license

For some reason a certain number of my little side projects result in “The Look”, that rolled-eyes expression that let’s me know I’m such a nerd. Given that Valentine’s Day fell on a weekend this year and I had a little free time this Sunday morning, the look was inevitable.

Today I finally had a few minutes to try out Twilio, a new web services provider that helps to telephone-enable applications through an easy REST API. In the case of PHP it is made even easier through a helper library provided by Twilio on their developer site.

Twilio is free to sign up and they provide a generous starting credit to begin exploring their service in a sandbox environment (they let you use their sandbox number for incoming call tests and put a watermark message on the front of all your outgoing communications). You can send and receive calls, add interactive menus to the calls, use recorded voice clips or text-to-speech and even send and receive text messages, all through their APIs and XML formatted speech scripts.

My Hello World test for the morning was simple; I wanted to call my home number and deliver a Valentine’s Day greeting. To do so I first signed up with Twilio, then went to my Twilio dashboard for my API key and to download the twilio.php helper library.

I then created helloworld.php with the following:

<?php
require "twilio.php";
 
/* Twilio REST API version */
$ApiVersion = "2008-08-01";
 
/* Set our AccountSid and AuthToken */
$AccountSid = "ACxxxxxxxxxxxxxx";
$AuthToken = "xxxxxxxxxxxx";
 
/* Outgoing Caller ID you have previously validated with Twilio */
$CallerID = '2223334444';
 
/* Instantiate a new Twilio Rest Client */
$client = new TwilioRestClient($AccountSid, $AuthToken);
 
/* make Twilio REST request to initiate outgoing call */
$response = $client->request("/$ApiVersion/Accounts/$AccountSid/Calls",
    "POST", array(
        "Caller" => $CallerID,
        "Called" => '4445556666',
        "Url" => "http://mysite.com/helloworld.xml"
    ));
    if($response->IsError)
        echo "Error: {$response->ErrorMessage}";
    else
        echo "Started call: {$response->ResponseXml->Call->Sid}";
?>

Initiating a call just requires a number to “call from” (in reality it’s just the number the Twilio system presents as caller ID), a number to call to, and the Account ID and token. The URL specified in the request to call out is an XML document that defines what happens during the call, using a format referred to as TwiML:

<Response>
        <Say>Happy Valentine's Day!</Say>
</Response>

In this case things are pretty straightforward, the system also has the ability to play mp3 files, take responses and branch based on keypresses and perform a number of additional actions. It looks like one could easily build a menu system or a survey system.

All in all an interesting offering that I’ll be tinkering with more in the future.

Resolving PHP-MySQL Connection Issues

I ran into an interesting issue when installing WordPress on my re-installed server, I could not get a database connection during installation. I added some debugging and discovered that I had a “Can’t connect to MySQL server on” error returned after the call to mysql_connect() in PHP.

To check the source of the issue I then tried to connect on the command-line using the mysql client, which occurred successfully, confirming that I was using the correct credentials and host address (this was a remote MySQL server).

I next created a test PHP script with a simple mysql_connect() call, and executed it with “php test.php” from the command-line, which was also successful.

Finally I accessed test.php through a browser, where again the connection failed.

So I was dealing with a situation where it was Apache in particular that was unable to connect to the remote MySQL server. Thanks to Wez Furlong‘s ideas I was able to narrow this down to SELinux blocking outgoing communications by Apache.

So, if you’re having issues with Apache and specifically connecting out, you may want to disable SELinux for Apache.