Issues with MySQL and ODBC on Centos 5
I run a server with Centos 5.6. For a number of reasons I need to have a newer version of MySQL running on it than what Centos 5 comes with stock. So I used IUS to install MySQL 5.1. Great. It works, I have a somewhat recent version of MySQL. Problem was I’m running FreeSwitch (FS) on this box as well. And I’ve linked up FS to MySQL via ODBC. For some reason that connection went wonkers at some point during an upgrade (I suspect). So the problem was that FS was in a limbo mode where it couldn’t start because MySQL ODBC didn’t work.
The error I got was something along the lines of:
isql: relocation error: /usr/lib64/libmyodbc3.so: symbol strmov, version libmysqlclient_15 not defined in file libmysqlclient.so.15 with link time reference
Starting FreeSwitch gave me the same error.
You can use isql to test that the connection is indeed there, so I had a good baseline test for figuring out when this would actually work again. Googling the error was of no help. Upgrading packages via Yum back and forth was no help either. The solution for me ended up being very simple. Install a new version of the MySQL ODBC Connector and update my ODBC DSN to use this new driver.
- Get the newer ODBC package for your platform here.
- Install it using “rpm -i mysql-connector-odbc-5.1.10-1.rhel5.x86_64.rpm” – that was the version I used.
The RPM will automatically add the new driver to /etc/odbcinst.ini, so you need to update your /etc/odbc.ini to use this new driver instead.
/etc/odbcinst.ini
[MySQL]
Description = ODBC for MySQL
Driver = /usr/lib64/libmyodbc3.so
Setup = /usr/lib/libodbcmyS.so
FileUsage = 1
UsageCount = 2
[MySQL ODBC 5.1 Driver]
Driver = /usr/lib64/libmyodbc5.so
UsageCount = 1
/etc/odbc.ini
[MyDSN]
Driver = MySQL ODBC 5.1 Driver
My old DSN used “MySQL” as the driver but with the new package installed I had to change that to “MySQL ODBC 5.1 Driver”. That’s of course re-nameable.
After this running isql gave me a connection to the database and everything was back to normal. Posting it here in case someone has the same issue and can’t fidn a solution.
If you like my writing you should subscribe to my RSS feed.
Sencha Touch Cookbook Published
During the fall of 2011 I was a technical reviewer of the now published book on Sencha Touch by Packt Publishing. The books goes through a number of different scenarios for building apps with Sencha Touch.
Reviewing a book has been an interesting experience. The process is fairly simple. You receive a number of chapters on a fixed schedule. You then have to comment on it, suggest improvements, fact check what’s written as well as make sure the code is reasonable. This then has to be sent back to the editor.
The bonus of being a reviewer is that you get your name in the book. So if you go to the Amazon Look Inside feature and flip through the first few pages you’ll find a little blurb about me.
You can find and buy the book online at Packt Publishing or on Amazon.
If you like my writing you should subscribe to my RSS feed.
Running Erlang Webmachine on Heroku
When Heroku released their new stack Cedar they opened the door for a whole new set of components to run on their platform. To support running other components on Heroku you need a build pack that tells Heroku how to build and run your app. Heroku’s published a build pack for Erlang as well as a demo app. This demo app uses straight up Mochiweb as a web server.
MochiWeb is an Erlang library for building lightweight HTTP servers.
Webmachine runs on top of Mochiweb and is
A REST-based system for building web applications.
In this blog post I’ll show how to get a Webmachine app running on Heroku.
Let’s get to it
So here are the steps to get a vanilla Webmachine app up and running on Heroku.
$ git clone git://github.com/basho/webmachine $ cd webmachine $ make $ ./scripts/new_webmachine.sh my-erlang-app /tmp $ cd /tmp/my-erlang-app $ make
You can now run “./start.sh” and open your browser on http://localhost:8000 and see your new awesome Hello World Webmachine app. Now we want to deploy it to Heroku.
Make sure you have Ruby and the Heroku gem installed. If not run:
$ gem install heroku
Then setup our app:
$ git init $ heroku create my-erlang-app -s cedar $ heroku config:add BUILDPACK_URL=http://github.com/heroku/heroku-buildpack-erlang.git
This initializes a new Git repository in our app directory, creates the heroku app. The final line setups the build pack that cedar should use when deploying the app.
Let’s add the source files to the Git repo and start hammering out some code.
$ git add Makefile README rebar rebar.config start.sh src/* priv/dispatch.conf
Next we want to update our rebar.config:
%%-*- mode: erlang -*-
{sub_dirs, ["rel"]}.
{deps_dir, ["deps"]}.
{erl_opts, [debug_info]}.
{deps, [{webmachine, "1.9.*", {git, "git://github.com/basho/webmachine", "HEAD"}}]}.
Create the Procfile which Foreman will use to control our app:
web: erl -pa ebin deps/*/ebin -noshell -boot start_sasl -s reloader -s my-erlang-app
You know have the major components in place for Heroku deployment. If you want to test it out run:
$ ./rebar get-deps compile $ foreman start
Of course this requires that you’ve Foreman in your path. If not install Ruby and run “gem install foreman”. If all goes well your app will start up and you’ll be able to point your browser to http://localhost:8000 and see the output.
Before we can push to Heroku we need to update the application start up code for the generated Webmachine app. When Cedar attempts to start your application it’ll define the port on which your app should listen/bind. Hence we need to read out this value and tell Webmachine to use it. Also we want to update the logging, basically turning it off (more about this later) and we want to just bind to the default catch all ip of 0.0.0.0.
Open up my_erlang_app_sup.erl in the src/ directory.
Change the init method so it looks like this:
init([]) ->
{ok, Dispatch} = file:consult(filename:join(
[filename:dirname(code:which(?MODULE)),
"..", "priv", "dispatch.conf"])),
Port = list_to_integer(os:getenv("PORT")),
io:format("start web server on port ~p~n", [Port]),
WebConfig = [
{ip, "0.0.0.0"},
{port, Port},
% {log_dir, "priv/log"},
{dispatch, Dispatch}],
Web = {webmachine_mochiweb,
{webmachine_mochiweb, start, [WebConfig]},
permanent, 5000, worker, dynamic},
Processes = [Web],
{ok, { {one_for_one, 10, 10}, Processes} }.
This reads out the port number that Cedar has assigned to our app in line 6 and passes it to the Webmachine config. Also it binds to the right IP in line 9 and disables the log dir in line 11.
Make sure it compiles by running the rebar command again:
$ ./rebar get-deps compile
Before we push to Heroku you might want to change the output message of your app. Open “src/my_erlang_app_ressource.erl” and change the “to_html” function.
Now do the add and commit dance to git:
git add <input-changed-file-list-here> git commit -m "initial commit before push to Heroku"
Next run
$ git push heroku master
Point your browser to http://my-erlang-app.heroku.com and you should see your output message as defined in “src/my_erlang_app_ressource.erl”.
To see what’s going on when Cedar boots up your app run “heroku logs”. This will spit out the same output you see when you run foreman locally. This is a great (and the) way to debug why your app isn’t starting up.
I’ve pushed my repository to Gibhub and deployed the app to Heroku. It’s called Erloku and you can check it out here
Next steps
Here are a couple of things that I’d like to continue to work on.
- By default Webmachine comes with a logger that outputs to tiles. Since this doesn’t go well with Heroku which expects and redirects output from Standard Output and Standard Error to its logs. Therefore it would be nice to implement a logger for Webmachine that outputs to StdOut and StdErr. Doing this shouldn’t be too hard.
- Get two dynos running an Erlang Node to talk with each other. Cedar probably has walls in place that won’t allow this, but if possible it would be mighty cool.
If you like my writing you should subscribe to my RSS feed.
ErlChat – A Simple Chat Server Written In Chicago Boss, A Web Framework For Erlang
Recently I’ve been exploring Erlang and its web frameworks. As part of this exploration I found Chicago Boss. This blog post is a pointer into the simple chat server I built using Erlang and Chicago Boss.
Jordan Orelli and Seth Murphy from Hacker School built Chatify as a demo application for Brubeck:
Brubeck is a flexible Python web framework that aims to make the process of building scalable web services easy.
Chatify is a simple chat application built with Brubeck as the backend and HTML and Javascript as the front end.
I decided to reimplement the backend in Chicago Boss and reuse the front-end. The result is Erlchat.
Here’s the main page of Erlchat, where you enter your nickname before logging into the chat:
Bert and Ernie chat’s away:
They’re loving it!
The code is really simple. Mostly because the required parts for building a chat server is built into Chicago Boss in the form of a message queue abstraction. However, the reason it works is because of Erlangs ability to scale out. Each call to retrieve messages is a long polling HTTP call, and hence blocks a connection. Since Erlang scales to many thousands of processes and Chicago Boss takes advantage of that, it really isn’t a problem.
The following function gets called by the client when he wishes to retrieve the messages that have occurred in Channel since his last retrieveal (LastTimestamp). It blocks on the call to boss_mq:pull.
receive_chat('GET', [Channel, LastTimestamp]) ->
{ok, Timestamp, Messages} = boss_mq:pull(Channel, list_to_integer(LastTimestamp)),
{json, [{timestamp, Timestamp}, {messages, Messages}]}.
Sending a message is a simple HTTP POST that creates a new message and pushes it on to the Channel message queue. It uses the utility method seen below.
send_message('POST', [Channel]) ->
create_and_push_message(Channel, list_to_binary(Req:post_param("message")), Req:post_param("nickname")),
{output, "ok"}.
create_and_push_message(Channel, Message, Username) ->
NewMessage = message:new(id, Message, Username, erlang:localtime()),
boss_mq:push(Channel, NewMessage).
Check out the README as well as the source. It’s all up on Github.
If you like my writing you should subscribe to my RSS feed.
Giving EM-Smsified Some Server Love
I just pushed the next release of my EM-SMSified gem to Github and Rubygems. This release (0.3.0) adds an EventMachine HTTP server to make it easy to react to SMSified callbacks.
Installing is easy as always:
gem install em-smsified
Using it is equally easy. Here’s an example of a “pong” server that sends a pong back to any received text message:
require 'rubygems'
require 'yaml'
require 'em-smsified'
require 'eventmachine'
require 'evma_httpserver'
smsified = EventMachine::Smsified::OneAPI.new('username', 'password')
EM.run do
Signal.trap("INT") { EM.stop }
Signal.trap("TRAP") { EM.stop }
puts "Hit CTRL-C to stop"
puts "=================="
puts "Server started at " + Time.now.to_s
puts "Starting incoming SMSified callback server"
EM.start_server '0.0.0.0', 8080, EventMachine::Smsified::Server do |s|
s.on_incoming_message do |msg|
puts "Message received " + Time.now.to_s
puts "#{msg.sender_address} says '#{msg.message}' to #{msg.destination_address}"
smsified.send_sms( :message => 'Pong',
:address => msg.sender_address,
:sender_address => msg.destination_address) do |result|
puts "Pong sent " + Time.now.to_s
end
end
end
end
A more elaborate example is up on Github (examples/pong_server.rb).
The server supports incoming messages on which you need to set a subscription (SMSified – Receiving Messages) and delivery notifications. The latter is set up when you send an sms message by adding the :notify_url parameter.
Use cases
Having a server that’s easy to use from EventMachine makes it easy to implement more advanced text message scenarios:
- You could couple this with the em-websocket gem and add easy websocket callbacks from received text messages.
Source on Github as usual, and gem on Rubygems.
If you like my writing you should subscribe to my RSS feed.
Putting EventMachine In the SMSified Gem
I wanted to utilize EventMachine for something and real and since I’ve been tinkering with telephony stuff recently I thought something that sends text messages might be a good candidate. Instead of rewriting everything from scratch I started with the SMSified Ruby gem instead. SMSified is a service by Tropo that makes it really easy to send text messages. Since the service is still in beta sending text messages is free. Pretty neat. SMSified has a Ruby gem that comes with a test suite. Hence I thought it would be a good starting point.
Installing the new gem is easy
gem install em-smsified
Here’s some example code showing how to send an SMS via SMSified:
require 'rubygems'
require 'eventmachine'
require 'em-smsified'
oneapi = EventMachine::Smsified::OneAPI.new(:username => 'user', :password => 'password')
EM.run do
oneapi.send_sms(:address => '14155551212', :message => 'Hi there!', :sender_address => '13035551212') do |result|
puts result.inspect
end
end
The original gem uses HTTParty to do HTTP requests. To mock these in the spec suite the gem used FakeWeb. FakeWeb doesn’t work with EventMachine and therefore my first step was to replace FakeWeb with WebMock, which works with a number of Ruby HTTP frameworks. After that I DRY’ed up the code a bit to contain where HTTP requests were being made. Then I added EventMachine via the EM-HTTP-Request gem. To EM’ify the new library I had to modify the original interface to take an anonymous block. This block gets called when the request to SMSified returns. This is where you can check what was returned and perform any updates. This is shown in the code sample above.
There are more examples in the source tree and there’s also some YARD documentation.
Jason Goecke and John Dyer wrote the original SMSified gem making my job so much easier.
em-smsified on RubyGems.
Source on Github.
If you like my writing you should subscribe to my RSS feed.
TweetHose Released as a Gem
I’ve just released a gem called TweetHose to RubyGems. Here’s the short description of what it is:
TweetHose lets you easily generate a daemon that listens to the Twitter firehose. When keywords you’re interested in appears, you can set up a callback. Should make it easy to create that Justin Bieber tracking app you’ve always wanted.
Install it via a quick:
gem install tweethose
Source is up on Github.
If you like my writing you should subscribe to my RSS feed.
The Simple Way to Generate One File MSDN Style Documentation for Your .NET Projects
I was recently tasked with generating code documentation. The last time I had to do that I used NDoc and the XML Comments that the C# compiler (csc.exe) spits out. Turns out that NDoc is no longer, or at least it’s not being maintained. Instead the new kid on the block is Sandcastle.
It might be my memory failing, but I seem to remember that setting up NDoc to generate MSDN style documentation was pretty easy. My initial foray into using Sandcastle was not. This post describes a super simple way to generate MSDN style documentation that’s contained in a single CHM file.
We’ll need some software. So go ahead and download and install the following:
- Sandcastle – http://sandcastle.codeplex.com
- Sandcastle Help File Builder – http://shfb.codeplex.com
This includes a guide that installs and sets up the required software. It’s important to download and set up HTML Help Workshop v.1 as part of this process.
Optional:
- GhostDoc – http://submain.com/products/ghostdoc.aspx
Not required, but it makes it super easy to generate XML documentation from within Visual Studio. It’ll even auto generate some of the text. The free version is fine, but obviously the paid version includes more features.
With all of the software installed and in place, it’s time to generate some documentation.
- Open Sandcastle Help File Builder GUI and start a new project.
- Right click Documentation Sources on the right and select “Add Documentation Source”.
- Find and select your solution file (*.sln).
- Select “HtmlHelp1″ under HelpFileFormat under the “Build”-category.
- Fill out whatever other properties you want. HelpTitle and HtmlHelpName are obviously good for putting in the name of your project. The “Show Missing Tags”-category is good for fine tuning what’s added if you haven’t explicityly documented everything.
- Hit CTRL+SHIFT+B or select “Build Project” from the “Documentation”-menu.
- Wait.
- You should now have a .chm file in your output folder.
Remember if your distribute the CHM file by putting it on the internet and allowing people to download that they need to Unblock the file first, before opening it. Otherwise all of the links inside will fail. You can see my post on X.509 Certificates and Downloads Via Internet Explorer for a description of the troubles that can occur when downloading files and they’re marked as being unsafe.
If you like my writing you should subscribe to my RSS feed.
JSON Proxy Using IIS Reverse Proxy for Fun and Profit
Developing mobile applications using Sencha Touch that will be packaged up using PhoneGap to run as a “native” app on a phone can be a bit of a pain. Especially if you’re accessing some kind of API. Because of restrictions in the browser, you’re not allowed to do cross site requests, meaning it’s difficult to call external API’s during development. You’re likely to run your new shiny mobile app from a file on your hard drive or served up by a locally running web server. But the API’s you need to access are probably running on a another external server. Hitting that API will give you a sad message from Chrome, because of the “Same Origin Policy”. Safari will just return nothing, and ignore you. IE9 and Firefox are not even options, because they don’t run WebKit. You can of course do all of your development in PhoneGap, deploying to an emulator or a real device and always test on that. But it adds quite a bit of time to the feedback loop and for prototyping it’s especially nice to have the fast feedback loop afforded by the browser, the console and the inspector. So how do we get around this annoyance. One way is to use JSON-P and the ScriptTagProxy. Another is to utilize a reverse proxy server, which is what I’ll describe in this post.
I’m developing on Windows 7, so this is a description on how to set it up using IIS. This guide on the IIS.net website explains things in more detail. If you’re running on Mac or Linux you could setup nginx, Apache or another web server. Most web server software include proxy rewrite and reverse proxy capabilities.
Before we get started here’s a quick and simple diagram of what we’re trying to achieve:
Browser < => Local Web Server (IIS) Proxy To => External Server with API
First you’ll want to install the Application Request Routing module. This module works with the URL Rewrite module to proxy requests back and forth between your web server and some other back end server. Next step is to enable the ARR module on your IIS Root.
Then on your web site that hosts your mobile application code (basically just a virtual directory to your web root of your Sencha Touch application) you want to configure the URL Rewrite module. There are a couple of options for doing this, one is through the IIS Management GUI, the other is by adding the appropriate configuration in your web.config file. I’ll list the configuration settings in the following, but you can just as well set this up using the GUI and the guide. Another options is to copy in the following configuration settings, and then tinker with it using the GUI afterwards. The IIS Manager GUI is basically a nice way of manipulating web.config files.
If your virtual directory doesn’t have a web.config (it probably doesn’t since it’s serving up plain HTML and JS) create a new file called web.config and fill in the following:
<?xml version="1.0" encoding="UTF-8"?> <configuration> </configuration>
Then add the following in between the configuration-tags, so your entire file looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Proxy To External server" stopProcessing="true">
<match url="^services/(.*)" />
<conditions>
</conditions>
<action type="Rewrite" url="http://my-external-server.com/{R:0}" logRewrittenUrl="false" />
</rule>
</rules>
<outboundRules>
<rule name="Add Application prefix" preCondition="IsHTML">
<match filterByTags="A" pattern="^/(.*)" />
<conditions>
<add input="{URL}" pattern="^/(appName)/.*" />
</conditions>
<action type="Rewrite" value="/{C:1}/{R:1}" />
</rule>
<preConditions>
<preCondition name="IsHTML">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
<urlCompression doStaticCompression="false" />
</system.webServer>
</configuration>
This configuration says to rewrite all requests coming into the virtual directory at http://localhost/appName/services/ to http://my-external-server.com/services/. The outbound rule looks at the returned HTML and rewrites that too, so links and hrefs will continue to work. If you don’t do this step, links won’t be rewritten and when you follow them you’ll get an error because the links point to the server you’re trying to mask.
With this in place you can configure your Sencha Touch data classes to use http://localhost/appName/services/ as the server prefix, and service calls will be proxied back and forth to your external data server. To make it easier to transition from development to production, wrap the server prefix in a configuration object.
I’ve found this proces to be of tremendous value when developing. It’s so much easier to debug things when they run in the browser and you can use the full browser stack.
One thing I’ve found is that sometimes IIS will barf and throw an internal server error related to request compression and GZip’ping. I’ve disabled Static Compression in the hope that that would help, which it does. The error still shows up though. I’ve found that a quick “iisreset” does the trick and puts everything back on the track. This minor annoyance is worth it compared to the added benefit of running everything in the browser and skipping an emulator.
If you like my writing you should subscribe to my RSS feed.
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 

