Archive for September, 2011

Writing and Deploying a Tropo App with an iPad

Tuesday, September 27th, 2011

I recently found myself at a conference without WIFI and i wanted to write and deploy a new Tropo voice application to the cloud. Armed with my 3g iPad, this task was a snap! See for yourself…

Tropo at Baltimore BetaScape

Monday, September 26th, 2011

This past weekend in Baltimore, I got a chance to take part in one of the most interesting hackathons I’ve been to in a while (and I go to a lot of hackathons).

BetaScape was an event held on September 23rd through the 25th in the Station North section of Baltimore. It’s goal was to bring together artists and technologists to work together, innovate and build cool things.

BetaScape Bot

I had the privilege to take part in what was billed as CreateCamp – a hacking event held on the second day of BetaScape.

CreateCamp was meant to feed off of the ideas and energy of a series of lectures, discussions and workshops from the first day of BetaScape, and inform the creative energies of it’s attendees.

I was asked to be one of the facilitators at CreateCamp – to help others experiment and build interesting things. I love mashing up things with telephone-based apps and playing with realtime web technologies, and it turned out that CreateCamp was a fertile ground for my interests.

The group of attendees that came together for CreateCamp was – based on my previous experience at hackathons – a bit unusual and also really exciting. The groups that attend hackathons can sometimes be pretty homogenous.

CreateCamp was completely different. The group of people that came to the event was as diverse as it’s interests.

Ultimately, I think the makeup of the group that came to Station North this past Sunday to create things was a direct result of the awesome array of projects that were worked on throughout the day – everything from robots, to clothing, to realtime web and SMS apps.

In my opinion, BetaScape and CreateCamp were a huge success and I sincerely hope to see this event again next year, and to be able to attend and help out. Congratulations to the organizers of the event!

I also think the organizers of other hacking events could learn a lot from what happened at CreateCamp in Baltmore.

Note – photo courtesy of BetaScape

Tropo at Apache Barcamp Spain 2011, Seville, Oct 8

Monday, September 26th, 2011

If you are in Spain next week then you may be interested in stopping by the ETSII University in Seville, where it will take place one of the most exciting events in Europe this year, the Apache Barcamp Spain. An event created by developers for developers. It promises to be a great event with lots of fun.

We are proud sponsors of this event and we will be there speaking about Tropo and Phono and helping anyone interested to learn more about these awesome platforms.

By the way, the event sold out pretty quickly but we still have some spare tickets for anyone planning to attend. So if you happen to be at the sunny Spain next week and you are interested then in attending then do not hesitate to contact us.

Tropo at GigaOm Mobilize 2011 San Fran Sept 26-27

Saturday, September 24th, 2011

If you’re in San Francisco Monday and Tuesday (September 26-27), stop by the Mission Bay Conference Center for GigaOm’s Mobilize conference.  Voxeo Labs will be there demoing with some of the gear used to run the free wireless network & Tropo apps that debuted at this year’s Burning Man festival.  From the Mobilize website:

Opportunity. Everywhere. That’s the theme of Mobilize 2011, and why, this year, our Mobilize event is doubling in scope, providing you two days of insight and analysis. The conjunction of mobile computing and cloud-based services will unleash an entire new wave of product and market growth. At this year’s Mobilize 2011, we’ll show you how Cloud Computing and Mobile Web creates the beginning of further opportunity.

I also snagged quite a few of the limited edition RINGER Tropo Invader shirts from Orlando before I left so make sure to stop by our table, see a demo and get a free shirt (they’re all the rage).

Receiving & Sending Texts Using Tropo & the Python Framework Django

Thursday, September 22nd, 2011

Django is a high-level Python Web framework that encourages rapid development and clean, pragmatic design. This blog will discuss how to implement Django with Python to receive and reply to a text message – note that installation instructions will be Mac oriented, if you use Windows you can find some alternate install instructions here.

Requirements:
    1)Tunnlr - used to simulate a web server, so you can test from a desktop
        -signup to Tunnlr here
        -detailed instructions on setup can be found here
    2)Python Library
        -Download in the terminal:
              $git clone https://github.com/tropo/tropo-webapi-python.git
        -Or download directly from github.com here             
    3)Django
        -Download Django-1.3.1.tar.gz
          Next, in the terminal, execute the following
              $cd Django-1.3.1
              $sudo python setup.py install

Follow the above instructions to install/setup Tunnlr and Django; once they’re ready, go into whatever directory you want the Django/Tropo app to reside in (Sites/Django_Apps, for example. Once you’re in your chosen directory, go ahead and download the Python library mentioned above. With everything installed and downloaded, enter this in the terminal:

    $django-admin.py startproject mysite

This will create a directory that looks like this:

    mysite/
        __init__.py
        manage.py
        settings.py
        urls.py

The file “urls.py” is the only one that needs to be edited in this directory. Open this file and insert this:

from django.conf.urls.defaults import * 
from hello.views import hello

urlpatterns = patterns('',
('^hello/$', hello)
)

This sets the URL that calls the app to something like this http://server_example.com/hello/, and sets it to specifically call the method “hello” in the actual Tropo app.

On to the meat – while in the mysite directory, enter the following in the terminal:

    $python manage.py startapp hello

This will open another directory with four more files as shown below:

    hello/
        __init__.py
        models.py
        tests.py
        views.py

The Tropo application will be stored in the “views.py” file, shown below, which receives a text and replies back to the same number:

# Create your views here.
# sends information back to Tropo
from django.http import HttpResponse  
# This will allow you to call Tropo functions
from tropo import Tropo 
# This will bypass authorization
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt

# hello is the method name called by urls.py 
# Also, request is where all of the text's information lies
def hello(request): 
  t = Tropo()
  # This is the initial text that you want to extract
  msg = request.POST['msg'] 
  # This sends a text reply back
  json = t.say("you just said: " + msg) 
  # This renders the reply into JSON so Tropo can read it
  json = t.RenderJson(json) 
  # This sends the JSON to Tropo
  return HttpResponse(json) 

Now that this is complete, go to Tropo and create a new WebAPI app. Define the URL that powers this app as your Tunnlr address (which can be set up and located using the Tunnlr instructions mentioned earlier), followed by the app name. In our case, it would be :

    http://web1.tunnlr.com:XXXXX/hello/

Hit Create, then once the screen refreshes with your application, add a U.S. number (needed to send an SMS) and hit Update.

You now want to launch Tunnlr under port 8000, in order for the app to be accessible – instructions on the manual launch of Tunnlr can be found on the same instructions page mentioned earlier. Django comes with its own webserver, which is mostly used for development, and we’re going to use it to access the app. Navigate to the directory mysite, which we were in previously, and enter:

    $python manage.py runserver

With the Django webserver running and Tunnlr open and ready, you can now send a text to the phone number you added to your Tropo app earlier – shortly after sending, you should receive a text message back saying “You just said: …..”

That pretty much sums everything up – it’s a basic example without a lot of real world functionality, but we received enough questions on how to implement Django with Tropo that we felt a quick example would be beneficial. You can view both of the created directories on github here.

Note that all of the Tunnlr bits are unnecessary if you have an actual webserver – you would just be running Django there, instead, and using the URL to your server and the “hello” resource.

New Fax Library for Pythonistas

Thursday, September 22nd, 2011

Remember the post we did earlier this year with the Ruby gem written by Jason Goecke called pamfaxr for sending and receiving faxes? Well we are excited to announce that there is a new Python library by Jonathan Sweemer to do the same thing! Here’s the source code on GitHub too!

Jailbreaking OpenVBX

Wednesday, September 21st, 2011

Remember when the iPhone was only available on AT&T?   That was true until October 11, 2009 when a young coder named geohot (and friends) released the first iPhone/iPod jailbreak.  Suddenly iPhones weren’t tied to to just AT&T…now you could give AT&T the boot and choose Verizon or T-Mobile as your service provider.  Score!

In the spirit of geohot’s jailbreaking efforts, the rapscallions at Disruptive Technologies took on the the task of “jailbreaking” OpenVBX.

OpenVBX is a web-based open source phone system. It’s essentially a virtual PHP/MySQL PBX  and it’s available for download from GitHub.   Users of OpenVBX can make phone calls, send text messages…all very cool.

The catch is…you’re locked into one service provider: Twilio.  There’s no way to choose to use another cloud telephony provider…until now.

Today we’re pleased to announce a new fork of OpenVBX that adds support for Tropo.  For the first time, users of OpenVBX will have a choice of multiple platforms on which to run it, making it REALLY OpenVBX.

The coders at Disruptive Technologies added full support for the the Tropo API and Phono SIP-based VoIP web phone to the communications layer of the OpenVBX project. Of course, when selecting the Tropo API, users will now get access to all of the more advanced features of the Tropo network: speech recognition and text-to-speech in 24 languages, phone numbers in over 40 countries, international SMS, in/outbound SIP VoIP support, inbound Skype support, multiple phone numbers per callflow script, improved conferencing.

Disruptive Technologies also extended OpenVBX with the VoiceVault API to support Voice Biometrics in password resets. After adding VoiceVault credentials on the API Accounts Tab, the password reset dialog will provide an option to request a phone call to reset your OpenVBX account password.

The OpenVBX fork with Tropo can be found on GitHub.  We have sent the maintainer of the OpenVBX project a pull request to merge these updates into the project. The following features and bugfixes have been added to the OpenVBX package:

  • Fixed a redirect bug. OpenVBX no longer incorrectly redirects users to 404 pages.
  • Fixed bug in Twilio client. 60 seconds after the user has been “inactive”, the client is no longer able to be called for that user. This prevents calling the client if the user has closed their browser. (This also works for the Phono Client)
  • Added support for the Tropo API. You can now add a “Tropo API account” on the system settings page, and from the installer. Either a Tropo or Twilio account is required. Included in the new Tropo API additions are:
    1. Support for Tropo domestic and international phone numbers, on the “numbers” page.
    2. All applets in the “flows” page now support Tropo JSON as well as TwiML. Any number can be assigned any flow – so a tropo number and a twilio number can both be assigned the same flow.
    3. Support for existing Tropo numbers & applications. If the user prefers to set up their numbers initially in Tropo.com, the application will see these numbers and they can be assigned a flow within the application.
    4. Recordings, and Voicemail, as well as outbound dialing with Tropo.
  • Several theme changes. The OpenVBX logo has been modified to include both the Tropo and Twilio logo. If only one of the accounts is active, only that logo will show in the VBX logo – so if a user only has a Twilio account, only the Twilio logo will show, and vice versa. Other minor theme changes:
    1. Several pages in the System Settings tabs have been reworked.  Notibly the API accounts page, which now has each API accounts logos.
    2. Step 3 of the installation has been reworked.
    3. Several Twilio-specific content has been changed to be more ambiguous.
  • Added support for “Phono” browser phone, in addition to the Twilio Client. Any non-Twilio based numbers will use the new Phono browser phone.

This project has since been renamed to TropoVBX. Please refer to the updated blog post and new source code repository on GitHub.

Creating an internationalized Restaurants Finder application in minutes with Grails and Tropo

Wednesday, September 21st, 2011

Grails Logo In a previous blog post I already showed how we could pretty quickly create applications in Grails with the Tropo Grails Plugin and host them in Cloud Foundry with almost no effort. In this blog post I’m going to show a more ellaborated example. But, hey! In Tropo and Grails ellaborated examples don’t take more than 100 lines of code :)

One of the advantages of Tropo against its competitors is speech recognition and several internationalization features. Tropo understands 24 languages, so I thought that it would be pretty cool to create an application to find restaurants in a non-English speaking country as most of our blog posts are commonly focused on English. To implement my restaurants finder application I used the 11870 API service which is a Spanish web service that gives you the names, phone numbers and reviews of many services across any city in Spain (pretty cool).

So whats the idea around this restaurant finder? Basically imagine that you are on holidays with your wife in a city that you don’t know. And back in the hotel you made a reservation to a nice restaurant. Then you go through the day to visit the city and when it is time to go to the restaurant you realize that you don’t know where it is. Damn, you forgot the map! You don’t have any tourist service nearby, locals don’t know the restaurant location and you don’t have internet connection or an smartphone at hand. And of course your wife is starving! What do you do? Your marriage and peaceful holidays are at risk! Hopefully my restaurants finder could help you here :) Basically you dial a phone number, say the name of the city you are in, say the name of the restaurant and the application will tell you the phone number of the restaurant (it would be a one-liner change in the application to actually transfer your call to the restaurant’s phone).

But let’s look to some of the code. A first Grails action loads the name of all the cities with population bigger than 10.000. I’ve got a list from the Internet and just built a comma-separated list of cities. I use that list to create my choices statement that instructs Tropo to only accept one of those cities:


def index = {

    def citiesFile = applicationContext.getResource(
                            'classpath:cities.txt').file
    def citiesString = new String(IOUtils.toByteArray(
                            new FileInputStream(citiesFile)))
    def cities = citiesString.tokenize(',')

    def tropo = new TropoBuilder()
        tropo.tropo {
            say(value:"Bienvenido al servicio de información...", 
                  voice:"carmen")
            ask(name:'city',mode:"speech",
                         recognizer:"es-es", voice:"carmen") {
                say(value:"Diga el nombre de una ciudad")
                choices(value:citiesString)
            }
            on(event:'continue',next:'/tropo/restaurant')
        }
        tropo.render(response)	
}

That will prompt the user for the name of the city. Once the user says the name of a city a second Grails action will be triggered. In that action we call the 11870 API to fetch the list of available restaurants in that city. With that list I create another choices attribute that will instruct Tropo to only accept restaurants with a name in that list.

def restaurant = {

    def tropoRequest = request.JSON
    def place = tropoRequest.result.actions.value

    def map = restaurantMap(place)
    session["restaurants"] = map
    def restaurants = restaurantList(map)

    def tropo = new TropoBuilder()
    tropo.tropo {
        ask(name:'restaurante', mode:'speech', 
                      recognizer:'es-es', voice:'carmen') {
	    say(value:"Diganos el nombre de un restaurante en ${place}")
	    choices(value:restaurants)
	}
	on(event:'continue',next:'/tropo/info')
    }
    tropo.render(response)
}

In the code above, the method restaurantMap takes the name of the place and returns a map with all the restaurants in that place and their phone numbers. That map is stored in the HTTP session so later can be used to retrieve the phone number for the restaurant that the user has told. This is the actual code that invokes 11870 API and builds the map:

def restaurantMap(def place) {

    def query = "http://api.11870.com/api/v2/search?appToken=..."

    def feed = new XmlParser().parse(query)

    def restaurants = []
    def map=[:]
    feed.entry.each {
        restaurants << it.title.text()
        map.put(it.title.text(),it.'oos:telephone'.text())
    }
    map
}

Finally, once the user says the name of a restaurant, one last action will take the input and will use it to find the phone number of the restaurant:

def info = {

    def tropoRequest = request.JSON
    def restaurant = tropoRequest.result.actions.value

    def map = session["restaurants"]
    def phone = map.get(restaurant)

    def tropo = new TropoBuilder()
    tropo.tropo {
        say(value:"El teléfono de ${restaurant} es ${phone}...", 
              voice:"carmen")
        hangup()
    }
    tropo.render(response)		
}

That was pretty easy, wasn’t it? In very few lines of code we get a quite useful application. Provided you have an API to fetch restaurants from and a list of cities of a country then it would be fairly simple to add support for extra countries to this little example. There is many other things that could be done like handling nomatches and timeouts to make the application more reliable and user friendly, or dial the phone number of the restaurant and transfer the call. I hope you don’t mind if I leave these as exercises to the reader.

But wait, do you want to see the app in action? I’ve recorded a short video that goes through the source code and also shows the application working.

And that is it. I hope you liked it!

Unlocked & Loaded: Voxeo’s Upcoming Customer Summit

Tuesday, September 20th, 2011

In mid-October in Orlando, Florida, Voxeo (the company behind Tropo, Phono and SMSified) is bringing together customers, partners and developers for a summit to discuss the future of unlocked communications.

Voxeo Customer Summit 2011

On October 10th-12th, the Voxeo Customer Summit will take place at the JW Marriott Orlando Great Lakes. This conference will be packed with great speakers and cutting edge presentations providing details on the future of Voxeo’s product offerings.

We’ll be doing deep dives into the awesomeness that is Tropo, Phono and SMSified. If you’re already a user of these platforms, you’ll glean new details of how they can benefit your business and get to pick the brains of the engineers and technologists behind them.

If you’re just starting out with one of these platforms, you’ll quickly build your knowledge of how to use them, how they can benefit you and how you can build cutting edge communication apps.

You’ll be rubbing elbows with other Voxeo customers, large and small and hanging out with other developers who are using our platforms and APIs to run their businesses.

The event will be MC’d by the always engaging Chris Pirillo, of Lockergnome fame.

It’s like getting a front row seat for a show about the future of telephony and unified communications. And you’re invited!

To register to attend, just click here. The event is also on Lanyard.

Hope to see you there!

Speaking in Whispers: Creating a “Whisper” Dialog Using a Tropo Conference

Friday, September 16th, 2011

We often get a common request to create a “whisper” dialog, where an inbound call is transferred to a second contact, and that contact has the option to decline the call or accept it. While our transfer doesn’t have that level of functionality, there is a relatively straightforward method using a conference to mimic it.

The following app is written in PHP and intended for Tropo Scripting; it also utilizes our REST API to submit an interrupt signal, which we’ll get into in more detail shortly.

We’ll need to initially describe what the app does, as it loops back on itself, making code breakouts difficult to explain linearly. Essentially, the app has if/else logic built into to handle an inbound call and an outbound call. When an inbound call comes in, Tropo drops the user into a conference and lets them sit for a few moments. While they wait, Tropo relaunches the same app using the curl REST client for PHP and makes an outbound call to a second contact. When this contact picks up, they’re prompted to accept or decline a call – if they say yes, they’re dropped into the same conference as the inbound caller. If they say no, Tropo disconnects the original conference with the inbound caller using a signal and then disconnects the outbound call as well.

With the general explanation out of the way, we’ll move on to the code. First, we define a couple of functions:

<?php

function choiceFCN($event) {
    global $session;
    if ($event->value == "yes") {
        conference("1337");
    }
    else {
        $curl_handle=curl_init(); 
        curl_setopt($curl_handle,CURLOPT_URL,'https://api.tropo.com
/1.0/sessions/'.$session.'/signals?action=signal&value=exit'); 
        curl_setopt($curl_handle,CURLOPT_CONNECTTIMEOUT,2); 
        curl_exec($curl_handle); 
        curl_close($curl_handle);
        say("You declined, disconnecting");
    }
}

function badChoiceFCN($event) {
    say("I’m sorry,  I didn’t understand that. You can say yes or no");
}

These functions determine what to do when the outbound call recipient says yes or no, or something completely different like “okay”. choiceFCN is the more complicated of the two – if the recipient says ‘yes’, then you can see where the conference is connected. If they say ‘no’, curl is utilized to submit a signal to the inbound caller’s conference to disconnect it, and then disconnects the outbound call as well.

Next, we have the if/else functionality, which is the bulk of the app:

if ($currentCall->callerID == null) {
    call("+14075550100");
    ask("Do you want to connect to ".$caller."?", array(
        "choices" => "yes, no",
        "timeout" => 10.0,
        "attempts" => 3,
        "onChoice" => "choiceFCN",
        "onBadChoice" => "badChoiceFCN"
        )
    );
}
else {
    $token = 'your_token';
    $callerID = $currentCall->callerID;
    $sessionID = $currentCall->sessionId; 
    $curl_handle=curl_init(); 

    curl_setopt($curl_handle,CURLOPT_URL,'http://api.tropo.com/1.0/
sessions?action=create&token='.$token.'&caller='.$callerID.'
&session='.$sessionID); 
    curl_setopt($curl_handle,CURLOPT_CONNECTTIMEOUT,2); 
    curl_exec($curl_handle); 
    curl_close($curl_handle); 

    say("please hold while we connect your call");
    conference("1337", array(
        "allowSignals" => "exit"
        ));
    say("The recipient declined the call.  Goodbye.");
    }
?>

The inbound/outbound detection is done through the use of “callerID” – no callerID means the app was launched using a token, and therefore outbound. So if callerID is null, trigger the outbound portion of the app; if there is a callerID, launch the inbound portion.

The outbound portion is relatively straightforward – call out to a number, ask the user if they want to connect, use the onChoice and onBadChoice handlers to define which function to use in each case. The inbound, on the other hand, is a little more complex. There’s several variables to start:

$token = 'your_token'; $callerID = $currentCall->callerID; $sessionID = $currentCall->sessionId;

First variable is the token for your app, which is found beneath the URLs when you’re looking at your app in the Tropo UI. Second is saving the callerID of the inbound user for use during the outbound session, and then the sessionID as well for use in the signaling.

Once the variables are locked in, the curl to relaunch the app for the outbound call is started, and then the inbound caller is dropped into the conference. Note in the URL for the curl we add in the variable from earlier – this passes them into the outbound portion of the app as variables that we can then use. Also note in the actual conference the inbound caller is added to, there’s an extra variable in there called “allowSignals”. This is where you define a keyword (or “signal”) that can be used by the REST API to interrupt the conference, dropping the caller back to the application. If the outbound user says “no” and the signal is sent (defined in the URL

https://api.tropo.com/1.0/sessions/'.$session.'/signals?action=signal&value=exit

shown in the earlier portion of code), the conference will disconnect and the inbound user will hear “The recipient declined the call. Goodbye.”

That’s the extent of it; hope it helps someone! You can find the complete app on my Github, feel free to use it and abuse it as you see fit.