Creating Podio Voicemail Using Tropo, Podio and PHP
On Wednesday June 1st I went to the Podio World Tour NYC App Camp. I didn’t really plan on making anything, I mainly showed up to check it out and say hello to the Podio peeps. However, I got into a small chat with @fabianmu and @froda about how to augment Podio, so you could call a phone number and have a message be posted into Podio. I thought: that’s pretty easy! I’ll just whip up Tropo and add some PHP to glue it all together and I’ll be golden. Basically yes, however it took a bit longer than the time I had that evening. This post explains what I did and how it works.
Scenario
You have a phone number that anyone can call. Once connected the user is asked to leave a voicemail for you. The recording is transcribed to text and both the recorded audio file and the text is uploaded to special app on Podio. That way you have a central voice mailbox for your company/organization integrated into your Podio space.
Podio Setup
Here’s how it looks in Podio.
When a new message has been placed in the voice mailbox, it’ll be included in the Activity Stream of the space. In the top navigation bar we see the “Calls”-app which holds all of the individual calls.

Clicking a single item reveals the following picture. Here we see all of the details of the call including a transcription of the voice mail.

The “Calls”-app is simple and was configured using the Podio App Builder. It just has a single text field for the transcription, as well as the default title. The audio file is attached using the standard attachment feature.

Tropo Setup
In this scenario Podio works as a receiver of information and hence we’ll use the API to add this information. In order to record the I used Tropo which is a service like Twilio. It allows you to create voice and text message communication solutions and have your own code executed when certain things happen. Here we want something to happen when a user calls us up over the phone. The following image shows the configuration of my Podio Tropo app.

I utilize the Hosted option on Tropo, and have assigned a local US number to it. This means that whenever someone calls this number, the code in the hosted file Podio.rb will be executed. That file contains the following code.
say "Welcome to the Podio Voice Mail."
callerID = $currentCall.callerID
sessionId = $currentCall.sessionId
record "Please leave a voicemail for us. When you are finished recording, press the pound key.", {
:beep => true,
:maxTime => 60,
:terminator => '#',
:recordURI => "http://server.com/hook.php?callerId=" + callerID + "&sessionId=" + sessionId,
:transcriptionOutURI => "http://server.com/hook.php?callerId=" + callerID + "&sessionId=" + sessionId,
:transcriptionID => sessionId
}
say "Thank you!"
hangup
- First we greet the user.
- Then we extract some information about the call, caller id is the number the user is calling from, session id is an internal id we can use as an identifier.
- We ask the user to leave a voicemail for us, and press # when done. When he/she has done this we ask Tropo to post the recording to a server and passing along some information in the query string. We also request transcription to be done, and the result of that should be posted to the specified URL. Again we utilize the query string to pass some information.
- Then we thank the user and finally hangup.
Custom PHP Glue
The receiving code running on a server is where we glue the output of Tropo together with Podio. I had some trouble getting PEAR to work when I first hacked on it. However, googling around helped me get it up and running. The trick to install the required PEAR packages for the Podio PHP helper was to run
pear install HTTP_Request2-beta
Also I had to modify my “open_basedir” to allow PHP to include files from the PEAR directory. Once that was done, the Podio PHP library worked like a charm.
The PHP script that receives data from Tropo and uploads it to Podio has a number of elements to it. First we setup the required information to access Podio:
<?php
require_once('podio-php/PodioAPI.php');
$client_id = 'YOUR_CLIENT_ID';
$client_secret = 'YOUR_API_SECRET';
$oauth = PodioOAuth::instance();
$baseAPI = PodioBaseAPI::instance($client_id, $client_secret);
$baseAPI->setLogHandler('file', 'podio_log.log', 'podio');
//log base info
$baseAPI->log(serialize($_GET));
$file_name = 'audio-' . $_GET['sessionId'] . '.wav';
$target_path = '/var/www/' . $file_name;
We set up the basic API Client information. You can create this by going to the API Keys page on your profile. Also we setup a log file to make it easier to see what’s going on. We setup the file name and the target path, which will be where the audio file will be stored locally. We use the session identifier as part of the name to be able to retrieve it later, when the transcription result comes in.
To save the audio file received from Tropo the following code goes into effect:
if (is_uploaded_file($_FILES['filename']['tmp_name'])) {
if(move_uploaded_file($_FILES['filename']['tmp_name'], $target_path)) {
$baseAPI->log("$target_path [{$_FILES['filename']['size']} bytes] was saved");
} else {
$baseAPI->log("$target_path could not be saved.");
}
}
Here we utilize the variables set up previously.
Once the transcription result is posted to our PHP code, we execute the following.
// Obtain access token
$username = 'YOUR_USER_ID';
$password = 'YOUR_PASSWORD';
$oauth->getAccessToken('password', array('username' => $username, 'password' => $password));
$api = new PodioAPI();
$transcription_input = @file_get_contents('php://input');
$obj = json_decode($transcription_input);
$baseAPI->log('Transcription input: ' . $transcription_input);
$file = $api->api->upload($target_path, $file_name);
First we log in to the Podio API and get an object reference to it. Then we read the posted JSON transcription result from Tropo into a temporary variable and JSON decode it. We upload the audio file posted previously and hold on to the reference returned from Podio.
Next is the actual code that posts the item into the “Calls”-app in Podio. @fabianmu’s shodio project was of great help in figuring out how to construct the field and value arrays.
$app_id = YOUR_APP_ID;
//create fields array
$newItem = array();
$newItem['appId'] = $app_id;
$newItem['external_id'] = $_GET['sessionId'];
$newItem['tags'] = array();
//Title field
$newField = array();
$newField['field_id'] = 1817081;
$newField['values'][]['value'] = 'New voicemail from ' . $_GET['callerId'];
$newItem['fields'][] = $newField;
//Transcription field
$newField = array();
$newField['field_id'] = 1817083;
$newField['values'][]['value'] = $transcription_input;
$newItem['fields'][] = $newField;
$item = $api->item->create($app_id, $newItem['fields'], array((int)$file['result']['file_id']), $newItem['tags'], $newItem['external_id']);
$baseAPI->log("new item posted to podio: " . serialize($item));
We basically construct the required fields, putting in “New voice mail from $CALLER_ID” and adding the transcribed result to the transcription field. Then we create a new item for our app identified by $appId, associate the file we uploaded earlier to the item and put in the session identifier from Tropo as the external_id. To verify that something happens, we log out the returned item from Podio.
Conclusion
Tinkering with Podio’s API was really fun. As always there was a bit of a learning curve in getting the API helpers up and running. Getting the right versions of PEAR and related libraries, and making sure that everything connects together took most of the time. Also figuring out where and how Tropo posts the audio file and the transcription result, took a bit of tinkering.
It’s amazing how quickly you can built something with these new API’s and services out there. Voice enabling an app in less than a 100 lines of code is pretty neat.
If you like my writing you should subscribe to my RSS feed.
I am a self employed independent software development consultant at