Manage Your Call Recordings with the REST API

Credit: http://www.flickr.com/photos/usnavy/

When we talk about our API, sometimes we use the term “REST” without describing what it actually means. When we look under the hood, we find a lots of moving pieces that fit together to make everything work as described.

Realistically, to people who just use Twilio on a day to day basis, those details are not important. The key part developers should understand is “nouns and verbs.”

Four HTTP Verbs Drive REST APIs

The four HTTP verbs that drive REST APIs are POST, GET, PUT, and DELETE. The POST and GET verbs and are well-understood by modern web developers because we use them to create and retrieve our nouns. Less common but just as important is PUT. Ideally, we use it to update our nouns. The fourth verb – DELETE – will delete our noun but is rarely used. Within the Twilio API, we use DELETE in one place: call recordings.

Depending on how you use Twilio, you could easily collect call recordings which you don’t want to store long term. You could delete these via the Dashboard on the site but programmatically using the REST API is more powerful and flexible. It’s even easy if you use our Helper Libraries.

Warning: If you just copy and paste the following code, it will delete all the Recordings within the specified date ranges. Please customize this code before you use it.

In PHP, it’s as simple as authenticating with our Account Sid and AuthToken and then calling the delete method on each Recording. In this sample, I use getIterator to get a specific date range of recordings, display some information, and delete them one by one using their Recording Sid:
Not surpisingly, the equivalent using our Python module is quite similar:

Of course, you can still go with raw cURL from the command line:

Delete Specific Call Recordings

Realistically, we probably don’t want to blindly delete Recordings by date range. We could have important customer calls, voice mail greetings, or other important Recordings. To ensure that the delete focuses exactly on the Recordings we want, we’ll combine a few pieces to make something more useful. In this particular case, first we get a list of Calls filtered by the To phone number and the StartTime. Next, we only delete the call recordings if they are less than 20 seconds. In my account, this To number is used exclusively for testing and development of voice apps, so deleting the shortest call recordings makes sense:

In general, keeping your account “clean” is useful. While everything else within the REST API is text, Recordings are files and large by comparison. If you regularly delete the unimportant files, your processing will be easier and faster.

Posted by Keith Casey on February 22, 2012 Tagged , , , , ,

Twilio for .NET Developers Part 7: SMS & Voice Application Flows using ASP.NET MVC

This is a series of blog posts that introduce and walk you through using the different .NET Helper Libraries that Twilio provides.

These libraries simplify using the Twilio REST API for .NET developers, and provide as set of utilities that make it easy to work with TwiML and Twilio Client. Take a look at part one, twothree, four, five and six of the series.

Creating SMS & Voice Application Flows using ASP.NET MVC

In the last post we looked at how you can build an Interactive Voice Response (IVR) system that includes a multi-step voice call work flow by using an HTTP Handler in an ASP.NET Web Application.  In this post we will look at how you can create the same IVR system using the ASP.NET MVC Framework.

Multi-step Voice Call Work Flows

Before we get started building the application, as a reminder, lets take a look at the call flow that our application needs to be able to handle.  The diagram below shows the different paths that the user can take through the call flow:

Because the call flow is the same as the one we used in the previous post, the bulk of the logic can be reused as we create the application using the ASP.NET MVC framework.

There are of course some differences.  The first and probably most noticeable difference you will see in the MVC-based application is how we handle tracking our position in the call flow.  In the ASP.NET Web Application we were using a single HTTP handler as our endpoint, therefore we had to use request parameters to track our location in the call flow.

ASP.NET MVC however includes a powerful routing engine that we can leverage in our application.  Instead of directing each request to a single endpoint, we use the routing engine to expose different parts of the call flow logic through different URL’s.  For example, we can isolate different logical steps of the call flow in multiple Action Methods, each exposed as a unique URL.

Setting up the Application

As in the last post, lets get started building the application by creating a new ASP.NET MVC Website and then configuring a Twilio number to know about the applications endpoint.

In Visual Studio create a new ASP.NET MVC 3 website.  Once you have the base application created, add the Twilio REST, Twilio TwiML and Twilio MVC libraries from NuGet as was described in the Nth post of this series.

Next, right click on the projects controllers folder and add a new Controller named IvrController to the project:

We will use this Controller to handle all of the incoming requests from Twilio, process the requests based on our application logic and then return TwiML responses to Twilio.

Additionally, because we know that Action Methods in this controller will return TwiML, we can go ahead and change the class that the controller derives from to TwilioController:

public class IvrController : TwilioController
{
    //
    // GET: /Ivr/
    public ActionResult Index()
    {
    }
}

By deriving from the TwilioController class we can take advantage of the TwiML method inside of our Action Methods.  The TwiML method simplifies returning a TwiML result from an Action Method by converting a TwilioResponse object to an ActionResult and setting the response Content-Type to application/xml.

Now that we have our Controller created, lets configure the default route in the MVC application to use it as the default controller value:

routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{source}", // URL with parameters
    new { controller = "Ivr", action = "Index", source = UrlParameter.Optional } // Parameter defaults
);

Configuring the Routing Engine to use our Controller as the default means that we won’t have to explicitly specify the controller name in the URL’s we use to access the application.  Instead the Routing engine will simply insert the default value we’ve set.

Once you have basic website set up, deploy the site to a public location on the Internet, like Windows Azure or AppHarbor.

Setting up Twilio

Now that we have a public endpoint created, let’s configure a Twilio phone number to point to that endpoint.  As we showed in the last post, you can configure a Twilio number by logging into your twilio.com account, opening the account dashboard and selecting a number to configure.  The figure below shows that I’ve configured my number to point to my domain.

Remember that because we set up the default route to use the IvrController controller class and Index action method by default, we don’t have to specify the URL explicitly when I configure the number.

Also remember that as was explained in the previous post, instead of purchasing and using a Twilio number, you can use the free sandbox number that is included with every Twilio account.  If you decide to use the sandbox number, then callers would need to know and enter the sandbox PIN code after dialing the sandbox number.  Additionally in order to send text messages you will need to verify an outgoing number with Twilio, which you can do from your account dashboard.

Call Greeting

Once we have the basic infrastructure set up we can get to work adding the work flow logic to our application.  Remember that when a call is made to our number, Twilio will answer and tell our application about it by making an HTTP request to the Voice Handler URL.

Because we’ve configured our ASP.NET MVC application with default route values, that means that when Twilio makes this request, it will be routed to the IvrController class and then the Index action method.

Since we know that in our application the first thing we want users to hear when the call is answered is a greeting sound file, we can return a set of TwiML instructions from the Index action method that tell Twilio to play that sound file.  Using the Twilio TwiML Library as shown below we can response with a <Play> verb which instructs Twilio to play the provided sound file:

public ActionResult Index()
{
    UrlHelper helper = new UrlHelper(HttpContext.Request.RequestContext);

    var twiml = new TwilioResponse();
    twiml.Play(helper.ContentAbsolute("~/Content/Audio/greeting.mp3"));
    return TwiML(twiml);
}

Once we’ve created the TwiML response we need, we can call the TwiML method and pass the response to it.  The TwiML method will set the HTTP response content type to “application/xml” and convert the TwilioResponse into an ActionResult which is returned as the result of the Index action method.

One additional interesting part of the Index action method is the use of the UrlHelper object.  Normally you would use the UrlHelper in a MVC View to generate links to other views, but in this case, since we do not have a View, we are using the helper and a custom extension method called ContentAbsolute to resolve the location of the greeting audio file in the Controller.

Once you’ve got the Index method set up you can test the application by calling the number you configured earlier.  You should hear the greeting play, then the call will end.

Main Menu

Next we want to add a menu to our application that allows users to select what they want to do.  We want the menu to be separate from the greeting so that later we can allow users can return to the main menu without having to hear the greeting repeated.

Adding the menu will create a new branch in the applications work flow.  Once the greeting plays, we want the application to immediately redirect to the main menu branch.  To do this we can use the Redirect method to add a <Redirect> verb to the greeting TwiML response.  The <Redirect> verb directs Twilio to continue processing the call using a new URL.  In this case the URL we’ve provided includes the value “mainmenu” as its action parameter.

public ActionResult Index()
{
    UrlHelper helper = new UrlHelper(HttpContext.Request.RequestContext);

    var twiml = new TwilioResponse();
    twiml.Play(helper.ContentAbsolute(&quot;~/Content/Audio/hello.mp3&quot;));
    twiml.Redirect("http://example.com/Ivr/mainmenu");
    return TwiML(twiml);
}

When Twilio calls the redirect URL, the MVC Routing engine will evaluate the URL and determine that it needs to execute the MainMenu method in the IvrController class.  This method is shown below:

public ActionResult MainMenu()
{
    var response = new TwilioResponse();

    response.Say("To check the status of an order, press one");
    response.Say("To receive automated status updates via text message, press two");
    response.Say("To speak with a customer service representative, press three");

    return TwiML(response);
}

You can test the modifications to the app by dialing the phone number again.  This time you should hear the greeting play, followed immediately by the main menu content.

Accepting Menu Input

Once we’ve added the main menu we need to add a way to listen for the selection that the user makes.  In IVR applications users make selections by pressing the keys on their phones, which causes the device to emit a DTMF tone.  By including the <Gather> verb in our TwiML we can instruct Twilio to listen for DTMF tones and tell us when the user enters them.  The code below shows how we can add the <Gather> verb to our main menu:

public ActionResult MainMenu()
{
    var response = new TwilioResponse();

    response.BeginGather(new {
    action = "http://example/Ivr/MenuOptions", numDigits = "1" });
    response.Say("To check the status of an order, press one");
    response.Say("To receive automated status updates via text message, press two");
    response.Say("To speak with a customer service representative, press three");
    response.EndGather();
    response.Hangup();

    return TwiML(response);
}

Notice how we start the gather before the first call to the Say method by using the BeginGather method, then end it after the last Say using the EndGather method.  By surrounding the <Say> verbs with a <Gather> verb, we are telling Twilio to listen for input while each Say is executed, allowing someone to press a key to move on before the prompt finishes.

Also notice that we are using an anonymous type to set two attributes on the Gather verb.  The first, the action attribute, tells Twilio what URL to request once the Gather completes.  This URL is called the action handler.  The second attribute tells Twilio how many digits to gather from the user before making a request to the action handler.

Based on the TwiML we are returning to Twilio, during the call if DTMF tones are detected during a <Gather>, Twilio will convert the tones into the corresponding numeric values and call the action handler, passing the converted values as a request parameter named ‘Digits’.  If no input is detected, then Twilio will continue to execute the remaining TwiML, in our case executing the remaining <Say> and <Hangup> verbs.

The URL thats been set for the Gather verbs action handler changes the action parameter to “MenuOptions” which is a new action parameter whose job it is to determine which menu option the user selected and which branch in the apps work flow to use.

The code below shows the MenuOptions action method:

public ActionResult MenuOptions(string Digits)
{
    var response = new TwilioResponse();

    if (Digits == "1") { /* menu option one */ }
    if (Digits == "2") { /* menu option two */ }
    if (Digits == "3") { /* menu option three */ }

    return TwiML(response);
}

Notice how the action method has a single method parameter named Digits.  This parameter maps to an HTTP request parameter that Twilio sends which contains the value that Twilio gathered from the end user.  Using the Digits parameter we determine which work flow branch the app should follow.

Menu Option One – Package Status

The first option in the menu allows the user to check on the status of a package.  In our application, this will be implemented as a two step process.  First, we need to allow the user to enter in a package ID number to get status information for.  Second, we need to look up the package using the ID and tell the status to the end user.

The first step is handled by the MenuOptions action handler, which as was shown in the previous section evaluates which menu option the user selected from the main menu.  If the first menu option was selected prompts the user to enter a package ID:

if (digits == "1")
{
    twiml.BeginGather(new {
        action = "http://example.com/Ivr/Lookup",
        numDigits = "9" });
    twiml.Say("To retrieve status information, please enter your 9 digit package ID");
    twiml.EndGather();
    twiml.Say("I'm sorry, I didn't hear the ID.");
    twiml.Redirect(
    string.Format(
        "http://example.com/Ivr/MenuOptions?Digits={0}",
        Digits)
    );
}

As before, we are defining an action handler for the Gather verb, however this time we are specifying a new action parameter value: ‘lookup’.  We can now add to our Controller a new Action Method to process the package ID entered by the end user:

public ActionResult Lookup(string Digits)
{
    var response = new TwilioResponse();

    var order = Orders.FindById(Digits);
    if (order != null)
    {
        response.Say(string.Format("Your package is currently {0}.", order.Status));
    }
    else
    {
        response.Say("I'm sorry.  We were unable to find a package with that ID.");
    }
    return TwiML(response);
}

The Lookup action method is responsible for locating the package and returning its status to the user and executes after the user has entered their package ID.

As with the MenuOptions action method, the Lookup action method accepts a single method parameter Digits, which contains the value of the <Gather> entered by the end user.

At this point our application should now allow user to hear the menu options, select the option to check the status of their package and then hear the status.  You can test the application by dialing your number and pressing “1” when the main menu plays.

Menu Option Two – Package Notification

The next major option available to users in our application is to register to receive notifications via SMS when their package status changes.  If you look at the application flow diagram that was shown at the beginning of this post you can probably tell that the work flow for this branch is virtually identical to the branch for checking package status, and therefore the code to add this part of the application is virtually identical to the code to check a package status.

To start we again need to add the code that handles the user selecting the option from the main menu to the MenuOptions action handler:

if (Digits == "2")
{
    twilio.BeginGather(new {
        action = "http://example/Ivr/register",
        numDigits = "9" });
    twilio.Say("To register to retrieve status information, please enter a package ID");
    twilio.EndGather();
    twilio.Say("I'm sorry, I didn't hear the ID.");
    twilio.Redirect(
        string.Format(
            "http://asp.devinrader.info/orders/Options?digits={0}",
            Digits));
}

The verb above defines a new Register action handler, which is shown below:

public ActionResult Register(string Digits, string From)
{
    var response = new TwilioResponse();

    var order = Orders.FindById(Digits);
    if (order != null)
    {
        //save the registration
        Notifications.Create(Digits, From);

        response.Say("Thank you for registering to receive notifications. " +
            "To disable notifications you can send the word Stop to " +
            "555-555-5555 at any time."));
    }
    else
    {
        response.Say("I'm sorry.  We were unable to find a package with that ID.");
    }

    return TwiML(response);
}

As an example of how this might work in a real application, our sample uses the static Create method on the mock Notifications object to create a new notification using the package ID entered by the user and their phone number (from the ‘From’ request parameter).  In a real application this notification could be saved to a database to be used by a separate monitoring application.

As with the previous sections you can test the application by calling your number.  You should now be able to both check the status of an package as well as select the second menu option and register to receive status updates.

Menu Option Three – Connect to Customer Service

The last option that we are giving the users of our application is to connect to a customer service representative.  To do this we want our application to call out to our customer service center and bridge the customer and agent together.

To do that our application detects the selection of the third option in the MainMenu action handler and simply returns the TwiML instructing Twilio to connect to another call

if (Digits == "3")
{
    response.Say("One moment while we connect");
    response.Dial("+15555555555");
}

Here we are using the Dial verb to tell Twilio to create a new call to the provided number.  Twilio will automatically bridge the existing call with the new call, allowing the customer to speak with an agent.

Submenus and Flow Redirects

If you look at the call flow diagram from the beginning of this post you will see that there are several places where the caller can double back on themselves to either re-enter a package ID, or to return to the main menu.  The logic to do this is basically the same for both flow branches.

Lets add the menu options to the lookup branch first.

public ActionResult Lookup(string Digits)
{
    var response = new TwilioResponse();

    //using the digits entered by the end user, look up the status
    var order = Orders.FindById(digits);
    if (order != null)
    {
        twiml.Say(string.Format("Your package is currently, {0}.", order.Status));
    }
    else
    {
        twiml.Say("I'm sorry.  We were unable to find a package with that ID.");
    }

    twiml.BeginGather(new {
        action = "http://example.com/Ivr/MenuRedirect/lookup",
        numDigits = "1" });
    twiml.Say("To look up another package, press one");
    twiml.Say("To return to the main menu, press two");
    twiml.EndGather();
    twiml.Say("Goodbye");
    twiml.Hangup();

    return TwiML(response);
}

You can see that we’ve added the code to create our menu to the end of the lookup block.   Again using the <Gather> verb, we let the user tell us what they want to do once the lookup completes, which in this case is to either lookup another package or to return to the main menu.

In order to process their input we need to create another logic branch that will be run when the Gather completes.  We indicate this new branch as we have done before, by creating a new action method named MenuRedirect, which you can see as part of the action handler URL.

Also notice that there is another segment in the action handler URL after the MenuRedirect.  If you remember back at the beginning of the beginning of this post we registered a default route that looked like this:

The additional parameter in the action handler URL will get mapped to the source segment of our route.  We can use this in the redirect action method in order to determine if the user is coming from the lookup branch or the register branch.

The code below shows the code we use for the redirect action method:

public ActionResult MenuRedirect(string Digits)
{
    if (digits == "1")
    {
        if (RouteData.Values["source"].ToString() == "lookup")
        {
            return RedirectToAction("Options", new { digits = "1" });
        }
        if (RouteData.Values["source"].ToString() == "register")
        {
            return RedirectToAction("Options", new { digits = "2" });
        }
    }
    if (digits == "2")
    {
        return RedirectToAction("MainMenu");
    }
}

The logic is fairly straight forward.  If the user indicates enters “1”, we determine if they are coming from the lookup branch or the register branch and use MVC’s RedirectToAction helper method to redirect the request to the appropriate action method.

If the user enters “2”, we redirect them back to the main menu action method.

Summary

As we’ve shown in this post, creating complex call flows using ASP.NET MVC is easy, but does require a bit of planning up front in order to design and implement the work flow.  Once you understand the call flow, implementing the code is quite simple using the basic capabilities of ASP.NET MVC.

In the next and final post in this series we will look at some tools and techniques you can use when you run into a problem and need to debug an app that integrates with Twilio.

Catch up on the rest of the .NET Series:
Twilio for .NET Developers Part 1: Introducing the Helper Libraries
Twilio for .NET Developer Part 2: Adding Twilio Helper Libraries to your Project
Twilio for .NET Developers Part 3: Using the Twilio REST API Helper Library
Twilio for .NET Developers Part 4: Using the Twilio.TwiML Helper Library
Twilio for .NET Developers Part 5: Twilio Client, MVC and WebMatrix Helper Libraries
Twilio for .NET Developers Part 6: Creating SMS & Voice App Flows Using ASP.NET Web Forms 

This series is written by Twilio Developer Evangelist Devin Rader. As a co-founder of the St. Louis .NET User Group, a current board member of the Central New Jersey .NET User Group and a former INETA board member, he’s an active supporter of the .NET developer community. He’s also the co-author or technical editor of numerous books on .NET including Wrox’s Professional Silverlight 4 and Wrox’s Professional ASP.NET 4. Follow Devin on Twitter @devinrader

Posted by Devin Rader on February 21, 2012 Tagged , ,

Join Twilio for Picture Perfect Hacking at Photo Hack Day 2

Following a stellar showing from the previous Photo Hack Day, Aviary is back with an even bigger agenda for their next photo-centric hackathon.

This weekend, Photo Hack Day 2 will kick off with two days of photo-friendly hacking and a special emphasis on mobile apps. As an added bonus, attendees will enjoy a fireside chat with some amazing NYC entrepreneurs, including the co-founder of Reddit Alexis Ohanian, CEO of the Cheezburger Network Ben Huh and the founder of Tumblr David Karp.

Join us on February 25-26 at the General Assembly in New York City for this epic event. Register for the event here, and make sure to reach out to Frank Denbow, who will be there to help with any Twilio questions during the hackathon.

Looking for some inspiration? Take a walk down memory lane and check out the rad hacks from last year below.

Honey Badger

Created by Abe Stanway and Misha Ponizil, an app called Honey Badger uses Face.com’s recognition API to determine if someone other than you is using your computer. An alert is sent to you via SMS powered by Twilio.

PhotoJabber

Developed by Michael Schonefield, PhotoJabber lets multiple users select a photo on any webpage and chat via Twilio Client with other PhotoJabber users looking at the same photo. 


Slideboard

Slideboard, developed by Brian Yang, creates a web interface for mobile devices to browse photography and send to friends via SMS.


Zone Minder

Remember to update your time zone on your camera during travels with Zone Minder, an app by Jesse Chan-Norris that sends SMSnotifications using Foursquare check-ins.

Tag Fight

Tag Fight, developed by David Huerta, is an SMS messaging game where users compete for screensaver images by texting in tags.

See the ful list of the apps built during the last Photo Hack Day here. We can’t wait to see what you come up with this year! To reward your awesomeness, we’re giving the team with the best overall Twilio hack a Kindle Fire and $50 in Twilio credit.

If you have any questions about the event, you can visit the Photo Hack Day website or tweet at @photohacknyc.

Posted by Tony Mataya on February 20, 2012 Tagged , ,

Seattle Entreprenuers Descend on The Startup Conference

Yesterday I attended The Startup Conference in downtown Seattle, organized by the Founder Institute. This was the Institutes’s first go in Seattle after putting on the conference in Silicon Valley, Los Angeles and Paris.  Being relatively new to the Seattle startup scene, I was looking for a solid litmus test of the local entrepreneurial energy as we kick-off 2012.

This conference was a single-day event that featured CEOs from Seattle’s most interesting startups, including Rich Barton (Zillow), Rand Fishkin (SEOMoz), Neil Patel (KISSmetrics) and Glenn Kelman (Redfin).  These awesome speakers were rounded out with a Pitch Session featuring over a dozen startups with the top-3 advancing to go for the gold in front of a VC and Angel-staffed panel.

Transparency Software and Power to the People

A veteran founder with multiple companies under his belt, Rich Barton had very interesting and inspirational message to share. Listing all the companies he’s founded or been a part of is challenging, but a few to name include Microsoft, Expedia, Zillow, and Glassdoor. The common thread between all of them was powerful: they remove gatekeepers, democratize information and empower people to make decisions.  They turn closed silos into free and open markets where customers are in charge and not companies.

It’s hard to believe that it wasn’t that long ago that a travel agent was required to book a flight.  Rich calls these applications “transparency software” and challenged the audience think about other ways to empower people with information that they don’t have access to today.  Cool trivia nugget: Expedia started-out as an idea for a CD-ROM, sort of the travel version of Encarta.

No, Pitching a 20 year-old Isn’t Easy

About halfway through the day, it was time for a dozen local startups to try out their pitches in front of a live audience and get instant feedback from Brian Wong, the founder and CEO of Kiip.  You’d like to think pitching someone who can’t order a beer yet would be easy, especially if you’re a multi-decade industry veteran. Wrong!  Brian provided razor-sharp feedback that managed to be both hilarious and highly insightful.

Humor aside, Brian did a great job of helping these founders hone their pitches.  Often times a founder is just way too close to their product and they need help to articulate the concept to a person who’s seeing this for the first time.  What problem are you solving?  Who are the people that care about this?  How big is the opportunity?

Kudos to the brave founders who got up front of hundreds of people to make their pitch: LocalBlox, Blab, Soccer Buddies, myCommunityPlace, Teammatez, Like Bright, Discoverful and Mobmix.

2012 is Looking Up for Startups in Seattle

Overall, this was a great event.  Much thanks to the Founder Institute, Geekwire and Redmond Startup Weekendfor organizing.  When one of the speakers asked the audience “how many of you are in your first year of running your startup?” a startling number of hands went up.  There’s a tangible electricity in the air and strong sense of optimism in the people that I got a chance to talk to at the event.

Shalendra Chhabra, Product Manager at Clipboard.com

Feel free to ping me at any time to talk about what you’re building at carter@twilio.com or @CarterRabasa on Twitter.

Posted by Carter Rabasa on February 17, 2012 Tagged , ,

QuickPay sets out to transform parking, with a little help from Twilio

We’d like to congratulate QuickPay, a Twilio customer that just closed a new round of funding.

QuickPay’s mission is to make parking easier. Instead of fumbling with parking machines, cash boxes and meters, people with the QuickPay smart phone app will be able to pay by touching their phones.

While we’ll never be able to get those hours back that we’ve already spent hunting for all the tickets that got misplaced in our messy cars, we are looking forward to an enhanced parking experience in the future. And we are proud that QuickPay chose to use the Twilio API to power its pay-by-voice and pay-by-text features.

This morning, QuickPay announced a strategic investment by Fontinalis Partners, an investment firm focused on transportation infrastructure. Chris Thomas, a co-founder of Fontinalis Partners, will join QuickPay’s board.

Barney Pell, QuickPay’s executive chairman, said the team sought out Fontinalis Partners, QuickPay’s first institutional investor, for their transportation expertise and their shared belief that the $26 billion parking industry is about to be transformed by new technologies.

Pell, who previously co-founded Powerset, a natural language search engine that was bought by Microsoft, said the same forces that upended Internet search—local, social, mobile, personal, and contextual technologies—are also poised to fundamentally alter parking.

At Twilio, we think one more transformative technology belongs on that list: cloud communications, which is making it easy for companies like QuickPay to add voice, VoIP and text messaging capabilities to their apps.

In a statement, William Clay Ford, Jr., a founding partner of Fontinalis Partners and the executive chairman of Ford Motor Company, said he was excited by the opportunity that QuickPay presents to “build value and create social good.”

We couldn’t agree more.

Posted by Annie McGee on February 16, 2012 Tagged ,

A Twilio-Powered Valentine’s Day

Today is a day to celebrate love and friendship. Share it with the ones special to you, preferably through an awesome hack. Developers are building really cool Twilio apps to kick Valentine’s Day off right, and below we picked a few of our favorites.

Secretly SMS Your Crush with UMake.me

Secret crushes are hard, but luckily there’s a way to share your feelings without revealing your true identity. With UMake.me, users are able to anonymously text someone and let them know how they feel. You can even check and see if your secret admirer read your text message and replied. Go ahead, do it, what’s a better time than Valentine’s Day?

UMake

Pick Your Date Night with Jars of Love

An entry from last year’s contest, developer Geoff Sinfield created an app to connect couples through sharing ideas that are turned into date nights. Jars of Love let’s you add thoughts and date night ideas into a virtual “jar” via SMS. Once a week the jar will randomly select a suggestion and send it to both partners.

Jars of Love

Chat with Potential Dates on Match.com

For many of us, Valentine’s Day is about finding new love, which is where Match.com comes into play. The popular online dating service integrated a line of communication powered by Twilio that lets users talk to potential dates via call or SMS, and listen to personal voicemails, without revealing their numbers. It’s a great way to kick start a new relationship without having to give out your digits to the world wide web.

Anonymous

Call your Lover Anonymously

Sticking with the anonymous secret admirer theme, CloudSpokes launched their very own Valentine’s Day app challenge. First place winner Kenji776’s app utilized Twilio by allowing participants to call one another without revealing their phone numbers. Check out a video of his app in motion.

Parisian Love, Twilio Style

Parisian Love, Twilio style is a video inspired by the Google search of a man in love. We created our interpretation through programming a Twilio app. Take a look, and maybe you’ll be inspired to create your own Valentine’s app today.

Hacky Valentine’s Day and if you built something cool this year, share it with us!

Posted by Ladan Mahini on February 14, 2012 Tagged , , ,

Using SQL to Build a Voice Broadcast Application with Twilio

Austin Henderson is a developer and DOer, with a passion about designing for efficiency, redundancy and integrity in every feasible situation. Below is a detailed description on how to build a voice broadcast app using SQL and powered by Twilio.

Austin is the developer behind the projects twiSQL and twiCLI, the post below was originally posted on his blog here.

Using SQL Server to Conduct Telephone Campaigns

To make the use of the services that Twilio offers easier I have built two special use projects that are free for download and use. twiCLI is a command line tool for the Windows environments designed to place phone calls and send text messages, and twiSQL is a set of SQL user defined functions to enable telephone calls and text messaging from TSQL code.

In this entry I am speaking to the project twiSQL – and the goal is to communicate how to build a complete call campaign system using nothing by SQL, Twilio and the library functions of twiSQL. For portability the documentation file has been updated with this sample project added to the end.

Sometimes the best way to understand an idea is to see it in action in the form of a working project. In this sample project we will illustrate the idea of a list of prospects that need to be contacted with a telephone campaign.

First we build some tables to hold the details of these transactions.

CREATE TABLE [dbo].[myProspects](

      [ProspectID] [int] IDENTITY(1,1) NOT NULL,

      [ProspectName] [varchar](max) NULL,

      [ProspectPhone] [varchar](25) NULL

) ON [PRIMARY]

CREATE TABLE [dbo].[myProspectCalls](

      [CallID] [int] IDENTITY(1,1) NOT NULL,

      [ProspectID] [int] NULL,

      [CallDate] [datetime] NULL,

      [CallSID] [varchar](255) NULL,

      [CallStatus] [int] NULL,

      [CallDetails] [varchar](max) NULL

) ON [PRIMARY]

In the example code below we will insert a few records into our myProspects table and then loop through those records placing telephone calls and playing the predefined greeting.

-- CLEANING OUT THE TABLE FOR PROSPECTS - THIS IS JUST FOR TEST RUN

truncate table myProspects

-- BUILDING THE PROSPECT RECORDS - NORMALLY THIS WOULD BE LOADED FROM A FILE

insert into myProspects (ProspectName, ProspectPhone)

select 'John Doe','18005551212'

insert into myProspects (ProspectName, ProspectPhone)

select 'Bill Smith', '18005551212'

-- THIS SECTION HANDLES PLACING THE CALLS

declare @prospectID int

declare @callingPhoneNumber varchar(11)

declare @prospectPhone varchar(25)

declare @prospectName varchar(255)

declare @CallSID varchar(255)

declare @authID varchar(255)

declare @token varchar(255)

declare @whatToSay varchar(max)

declare @whatToSayTemplate varchar(max)

-- HERE YOU WOULD USE YOUR CUSTOM MESSAGE TO SPEAK

select @whatToSayTemplate = 'Hello %NAME%. As a representative of We Make Stuff company I would like to thank you for reaching out to our agent for your needs. If you should need to reach us at any time please feel free to call 888-555-1212 for prompt assistance. We sincerly appreciate your time, and please remember to look us up on Facebook. Have a fantastic day!'

-- YOU WILL NEED TO FILL IN YOUR AUTHID AND TOKEN VALUES FROM TWILIO

select @authID = 'XXXXXXXXXXXXXXXXXXXXXXXX'

select @token = 'XXXXXXXXXXXXXXXXXXXXXXXXX'

-- YOU HAVE TO HAVE A PHONE NUMBER WITH TWILIO – REPLACE THE NUMBER BELOW

select @callingPhoneNumber = '16158008999'

-- CHECKING TO GET THE FIRST PROSPECT

select @prospectID =

(select top 1 ProspectID from myProspects order by ProspectID asc)

-- WE HAVE CALLS TO MAKE HERE PEOPLE - LETS GET TO WORK

while isnull(@prospectID,0) > 0

begin

      -- GETTING THE VARIABLES TO USE FOR OUR CALL

      select @prospectPhone = ProspectPhone, @prospectName = prospectName

      from myProspects where ProspectID = @prospectID

      -- NUMBER MUST BE 11 DIGITS

      if isnumeric(@prospectPhone) = 1 and len(@prospectPhone) = 11

      begin

            select @prospectPhone

            -- REPLACING THE NAME IN OUR STRING TO SAY - NICE TOUCH

            select @whatToSay = replace(@whatToSayTemplate,'%NAME%',@prospectName)

            -- HERE WE MAKE THE CALL THROUGH OUR UDF

            SELECT @CallSID = dbo.msgTwilioMakeCall(@prospectPhone,@callingPhoneNumber,@whatToSay,'m',@authID,@token)

            if charindex('|',@CallSID) > 0

            begin

                  SELECT @CallSID =

right(@CallSID,len(@CallSID) - charindex('|',@CallSID))

                  insert myProspectCalls (ProspectID,CallDate,CallSID,CallStatus)

                  values (@prospectID,getdate(),@CallSID,0)

            end

            else

            begin

                  insert myProspectCalls (ProspectID,CallDate,CallSID,CallStatus)

                  values (@prospectID,getdate(),@CallSID,-1)

            end

            -- GETTING THE NEXT PROSPECT

            select @prospectID = (select top 1 prospectID from myProspects

            where prospectID > @prospectID order by prospectID asc)

      end

end

Now that we have placed the telephone calls at some point in the future you may want to know that the call was actually completed. The code below is used to illustrate how you can use the provided functions to check the details of a specific call.

-- THIS LOGIC WILL CHECK THE STATUS OF THE CALLS

declare @authID varchar(255)

declare @token varchar(255)

-- YOU NEED TO REPLACE YOUR AUTHID AND TOKEN

select @authID = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'

select @token = 'XXXXXXXXXXXXXXXXXXXXXXXXXXX'

declare @callSID varchar(255)

declare @callID int

declare @callDetails varchar(max)

declare @callStatus int

-- WE WILL BE SETTING UP A LOOP HERE TO GO THROUGH THE RECORDS

select @callID =

(select top 1 CallID from myProspectCalls where CallStatus = 0 order by callID asc)

while isnull(@callID,0) > 0

begin

      select @callSID = callSID from myProspectCalls where callID = @callID

      select @callDetails = dbo.msgTwilioViewCall(@callSID,@authID,@token)

      -- THE FULL XML IS RETURNED IN THE @callDetails VARIABLE

      -- YOU CAN PROCESS THAT XML HOWEVER YOU NEED AS THERE IS GOOD

      -- INFO CONTAINED IN IT - FOR THIS CASE WE JUST CHECK TO SEE THE STATUS

      if charindex('|completed|',@callDetails) > 0

      begin

            select @callStatus = 1

      end

      else

      begin

            select @callStatus = 0

      end

      -- UPDATING THE STATUS OF THE CALL RECORD

      update myProspectCalls

set callDetails = @callDetails, callStatus = @callStatus

      where callID = @callID

      -- GETTING THE NEXT CALL ID RECORD

      select @callID =

(select top 1 CallID from myProspectCalls

where CallStatus = 0 and callID > @callID

      order by callID asc)

end

One other option to consider is that as opposed to using the text to speech engine you can alternatively record an mp3 file, host it on a public URL and pass the URL to the file as the text of the call. This option provides for a very personalized campaign with a small modification to the process.

When we make the call to msgTwilioMakeCall() we just replace the variable @whatToSay with the URL to the file. A simple way to pull this off will be to host a file using the shared link functionality of Dropbox – or any other public URL. In the example below we are using Dropbox.

SELECT @CallSID = dbo.msgTwilioMakeCall(@prospectPhone,@callingPhoneNumber, 'http://dl.dropbox.com/u/1541272/recorded.mp3','m',@authID,@token)

Using the above method you could easily pull of the familiar telephone call campaign component of running for public office or perhaps the reminder of your dentist appointment, and all for almost nothing in expense.

Hopefully this sample project helps give you a vision for what is possible in a very few simple steps with very limited impact on the wallet.

Posted by Ladan Mahini on February 13, 2012 Tagged ,

Twilio for .NET Developers Part 6: Creating SMS & Voice Application Flows using ASP.NET Web Forms

This is a series of blog posts that introduce and walk you through using the different.NET Helper Libraries that Twilio provides.

These libraries simplify using the Twilio REST API for .NET developers, and provide as set of utilities that make it easy to work with TwiML and Twilio Client. Take a look at part one,twothree,  four, and five of the series.

Creating SMS and Voice Application Flows using ASP.NET Web Forms

So far in this series we’ve looked at the tools that Twilio provides .NET developers to make integrating Twilio services into .NET easy.   In the next two posts we will look at some ways to use these tools to create multi-step flows for both SMS and voice applications.

In this first post we will look at how you can create this application using an ASP.NET Web Application, including how you can divide up the logic of the application based on the required call flow.  In the next post we’ll look at creating the same application using ASP.NET MVC 3.

Multi-step Voice Call Work Flows

While it is easy to set up applications that accept respond to a single incoming SMS message or Voice call, most applications require a more complex work flow where your Twilio and your application work together to create more complex application work flows.

One way to think about work flows between your application and Twilio is in terms of a conversation between two parties who do not speak the same language.  The first party is the caller and the second party is your application.  In order to be able to talk to each other, the parties need a translator, which is where Twilio fits in.  Twilio takes the signals from a carrier (like Verizon) and translates that into information your application can use to make decision.  Your application then tells Twilio what to do, and Twilio translates that into actions which are passed back to the carrier.  Below is a flow diagram that shows a simple flow for a voice call using Twilio:

To see how this conversation works in more complex applications, lets create a simple order status application.  This application, known as an Interactive Voice Response (IVR) system allows users to perform a number of different actions including check the status of a package, set up automatic status notifications or speak to customer service agents.   Below is flow chart that shows the different paths the user can take through the system:

On the surface the flow looks fairly complex, but if you break it down there are three main flows through the application:

  • Status Check – Allows the user to look up the status information for a specific package
  • Notification Signup – Allows a user to register to recive text messages when the status of their package changes
  • Customer Service – Allows the user to be connected to a customer service agent.

In this post we will look at how you can create this application using an ASP.NET Web Application, including how you can divide up the logic of the application based on the required call flow.

Setting up the ASP.NET Web Application
Lets get started building the application by creating a new ASP.NET Web Application in Visual Studio.  Once you have the base application created, add the Twilio REST and Twilio TwiML libraries from NuGet as was described in the Nth post of this series.

Next, open the Add New Item dialog and add a new Generic Handler to the project:

The Generic Handler template adds a new generic HTTP handler class to the project.  We’ll use this handler to receive requests from Twilio, process the requests based on our application logic and then return TwiML responses to Twilio.

Creating a HTTP Handler endpoint is a good approach to follow when using an ASP.NET Web Application to build an IVR system.  It provides a way to handle incoming request without the processing overhead required by an ASPX webpage, and simplifies the programming model because you only have to deal with one method: the handler’s ProcessRequest method.

It also provides a way to group related areas of a complex IVR application into a smaller number of endpoints.  For example, in our sample application we will use a single HTTP handler that contains the work flow for our entire IVR.  Another option would be to create a handler for each branch of the call flow.

Of course one problem with combining multiple parts of a call flow into single endpoint is that it requires the application to understand which branch of of the call flow a given request needs to execute.  As you will see as we work through creating the sample application, a common way indicate to the application which part of the call flow to execute is to append parameters to the URLs that we tell Twilio to request as the caller works their way through the call flow.  By evaluating the parameter values, we can change the logic that gets executed by the handler in order to return different TwiML instructions to Twilio.

Now that you have the base project set up you need to deploy it out to a publicly accessible location on the Internet.  For example you could deploy the application to a traditional hosting provider, or a cloud hosting provider like Windows Azure or AppHarbor.

Finally, once you have the project deployed, you configure Twilio to know about the application endpoint.

Setting up Twilio

Before we get started writing the application, lets go set up a phone number for your users to call and tell Twilio about the endpoint you created in the previous section.

In this post we walk you through purchasing and and configuring a new 10 digit phone number, however buying a number is not a requirement to utilize Twilio.  Instead of purchasing a new number, you can use the free sandbox number that is included with every Twilio account.  If you decide to use the sandbox number, then users of this system would need to know and enter the sandbox PIN code after dialing the sandbox number.  Additionally in order to send text messages you will need to verify an outgoing number with Twilio, which you can do from your account dashboard.

Start by loading twilio.com in your browser and logging into your account.  Once you are logged in, load the account dashboard and open the Numbers tab and click the Buy Number button:

Locate a number and click the Buy button.  Twilio will let you know that it costs 1$ per month for a standard long number and ask you to confirm your purchase.  Once you confirm, Twilio will let you configure your new number:

To configure the number you need to enter a URL into the Voice URL text box.  This URL represents the point in your application that Twilio can talk to when it needs to know how to handle an incoming phone call.

Enter the URL that points to the deployed HTTP Handler you created in the previous section and click the Save button.  When Twilio receives an incoming call it will make an HTTP call to this URL with the call details.

Call Greeting

Now that we have the basic infrastructure set up we can get to work adding the work flow logic to our application.  When a call is made to our number, Twilio will answer and tell our application about it by making an HTTP request to the Voice Handler URL.  When that request is made we want to tell Twilio to play a greeting sound file, which we will do using the Twilio TwiML Library as shown below:

 public void ProcessRequest(HttpContext context)
{
     context.Response.ContentType = "application/xml";

     TwilioResponse twiml = new TwilioResponse();
     twiml.Play("http://example.com/greeting.mp3");

     context.Response.Write(twiml.ToString());
}

In the ProcessRequest method we set the Response.ContentType property to application/xml to tell Twilio that the response is in an XML format.  Next we call the Play method which adds a <Play> TwiML verb to the response and provide the sound file we want to play.  Finally we output the string value of the TwilioResponse object to the Response stream.

You can test the app by calling the phone number we bought earlier.  You should hear the audio file play, then the call will disconnect.

Main Menu

Next we want to add a menu to our application that allows users to select what they want to do.  We want the menu to be separate from the greeting so that later we can allow users can return to the main menu without having to hear the greeting repeated.

Adding the menu will create a new branch in the applications work flow, so in order to know what TwiML to return we need to add logic to the ProcessRequest method that looks for a request parameter named src.  We will use the value (or lack thereof) of the src parameter to help tell us what branch of the logic should handle the request.

The code below shows how the ProcessRequest method has been modified to include the menu logic:

context.Response.ContentType = "application/xml";

TwilioResponse twiml = new TwilioResponse();

string source = context.Request["src"] ?? String.Empty;

if (source)
{
     twiml.Play("http://example.com/greeting.mp3");
     twiml.Redirect("http://example.com/status.ashx?scr=mainmenu");
}
else
{
     twiml.Say("To check the status of an order, press one");
     twiml.Say("To receive automated status updates via text message, press two");
     twiml.Say("To speak with a customer service representative, press three");
}

context.Response.Write(twiml.ToString());

The first modification we made is to add conditional logic to check to see if the src request parameter exists.  When a call is initially made, that parameter won’t be in the request from Twilio, so the conditional will evaluate to true and the TwiML used to play the greeting will be returned.

Also notice that now, in addition to the <Play> verb being used, we are using the Redirect method to add a <Redirect> verb to the greeting TwiML response.  The <Redirect> verb directs Twilio to continue processing the call using a new URL.  In this case the URL we’ve provided appends the src parameter with the value ‘mainmenu’.

When Twilio calls the redirect URL, the conditional logic will now fail and the app will fall into the else block.  In that block we are using the Say method to add the main menu text.

You can test the modifications to the app by dialing the phone number again.  This time you should hear the greeting play, followed immediately by the main menu content.

Accepting Menu Input

Once we’ve added the main menu we need to add a way to listen for the selection that the user makes.  In IVR applications users make selections by pressing the keys on their phones, which causes the device to emit a DTMF tone.  By including the <Gather> verb in our TwiML we can instruct Twilio to listen for DTMF tones and tell us when the user enters them.  The code below shows how we can add the <Gather> verb to our main menu:

twiml.BeginGather(new {
     action = "http://example.com/status.ashx?src=mainmenu",
     numDigits = "1" });
twiml.Say("To check the status of an order, press one");
twiml.Say("To receive automated status updates via text message, press two");
twiml.Say("To speak with a customer service representative, press three");
twiml.EndGather();
twiml.Say("Goodbye");
twiml.Hangup();

Notice how we start the gather before the first call to the Say method by using the BeginGather method, then end it after the last Say using the EndGather method.  By surrounding the <Say> verbs with a <Gather> verb, we are telling Twilio to listen for input while each Say is executed, allowing someone to press a key to move on before the prompt finishes.

Also notice that we are using an anonymous type to set two attributes on the Gather verb.  The first, the action attribute, tells Twilio what URL to request once the Gather completes.  This URL is called the action handler.  The second attribute tells Twilio how many digits to gather from the user before making a request to the action handler.

Based on the TwiML we are returning to Twilio, during the call if DTMF tones are detected during a <Gather>, Twilio will convert the tones into the corresponding numeric values and call the action handler, passing the converted values as a request parameter named ‘Digits’.  If no input is detected, then Twilio will continue to execute the remaining TwiML, in our case executing the remaining <Say> and <Hangup> verbs.

The URL thats been set for the Gather verbs action handler is the same URL as the one used for the redirect earlier, but this time when Twilio makes the request to that URL, the request will also include the Digits request a parameter which we can use to determine which branch in the apps work flow to use.

The code below shows how we can modify the code to leverage the Digits parameter to change the flow of our app:

string source = context.Request["src"] ?? String.Empty;
string digits = context.Request["Digits"] ?? String.Empty;

if (digits == String.Empty)
{
     twiml.BeginGather(new {
        action = "http://example.com/status.ashx?src=mainmenu",
        numDigits = "1" });
     twiml.Say("To check the status of an order, press one");
     twiml.Say("To receive automated status updates via text messa     ge, press two");
     twiml.Say("To speak with a customer service representative, p     ress three");
     twiml.EndGather();
     twiml.Say("Goodbye");
     twiml.Hangup();
}
if (digits == "1") { /* menu option one */ }
if (digits == "2") { /* menu option two */ }
if (digits == "3") { /* menu option three */ }

Using this logic if the Digits parameter is empty, we follow the mainmenu logic branch.  If the Digits parameter exists we use its value to determine which work flow branch the app should follow.

Menu Option One – Package Status

The first option in the menu allows the user to check on the status of a package.  In our application, this will be implemented as a two step process.  First, we need to allow the user to enter in a package ID number to get status information for.  Second, we need to look up the package using the ID and tell the status to the end user.

As we discussed previously, the <Gather> verb lets us tell Twilio to listen for user input, so we are going to use it to let the user input their package ID.

 if (digits == "1")
{
     twiml.BeginGather(new {
       action = "http://example.com/status.ashx?src=lookup",
       numDigits = "9" });
     twiml.Say("To retrieve status information, please enter your      9 digit package ID");
     twiml.EndGather();
     twiml.Say("I'm sorry, I didn't hear the ID.");
     twiml.Redirect(
       string.Format(
         "http://example.com/status.ashx?src={0}&Digits={1}",
         source, digits)
);
}


As before, we are defining an action handler value for the Gather verb, however this time we are using a new value for the src parameter: ‘lookup’.  We can now add to our application logic that checks the value of the src parameter and changes the logic flow based on its value:

 string source = context.Request["src"] ?? String.Empty;
string digits = context.Request["Digits"] ?? String.Empty;

if (source == "mainmenu")
 {
     /* main menu logic ... removed for clarity */
 }

if (source == "lookup")
 {
     var order = Orders.FindById(digits);
     if (order != null)
     {
     twiml.Say(string.Format("Your package is currently, {0}.", or     der.Status));
     }
     else
     {
     twiml.Say("I'm sorry.  We were unable to find a package with      that ID.");
     }
 }

You can see in the code above that we’ve added two blocks of logic that will execute based on the value if the source variable.  The first executes when the source value is ‘mainmenu’, the second when the value is ‘lookup’.  Later we will add more logic blocks based on other values later. The Lookup block is responsible for locating the package and returning its status to the user and executes after the user has entered their package ID. At this point our application should now allow user to hear the menu options, select the option to check the status of their package and then hear the status.  You can test the application by dialing your number and pressing “1” when the main menu plays.

Menu Option Two – Package Notifications

The next major option available to users in our application is to register to receive notifications via SMS when their package status changes.  If you look at the application flow diagram that was shown at the beginning of this post you can probably tell that the work flow for this branch is virtually identical to the branch for checking package status, and therefore the code to add this part of the application is virtually identical to the code to check a package status. The primary difference is that we will add anew value for the src parameter which tells our application to use the Package Notification logic branch.  A trimmed down version of the code for the Package Notification branch is shown below:


string source = context.Request["src"] ?? String.Empty;
string digits = context.Request["Digits"] ?? String.Empty;

if (source == "mainmenu")
{
    if (digits == String.Empty) { /* menu option one */ }
    if (digits == "1") { /* menu option one */ }

    if (digits == "2")
    {
        twiml.BeginGather(new {
             action = "http://example.com/status.ashx?src=register             ",
             numDigits = "9" });
        twiml.Say("To register to retrieve status information, " +
             "please enter your 9 digit package ID");
        twiml.EndGather();
        twiml.Say("I'm sorry, I didn't hear the ID.");
        twiml.Redirect(
             string.Format(
                  "http://example.com/status.ashx?src={0}&Digits={                  1}",
                  source, digits)
             );
    }

    if (digits == "3") { /* menu option three */ }
}

if (source=="register") {

    var order = Orders.FindById(digits);
    if (order!=null)
    {
        //save the registration
        Notifications.Create(digits, context.Request["From"]);

        twiml.Say("Thank you for registering to receive notificati        ons.");
        twiml.Say("To disable notifications you can send the word         Stop to " + "555-555-5555 at any time.");
    }
    else
    {
        twiml.Say("I'm sorry.  We were unable to find a package wit        h that ID.");
    }
}

As you can see, instead of the lookup value used to get the package status, we are now checking for the value ‘register’ which tells the application that the user wants to register to receive status information via text messages.

As an example of how this might work in a real application, our sample uses the static Create method on the mock Notifications object to create a new notification using the package ID entered by the user and their phone number (from the ‘From’ request parameter).  In a real application this notification could be saved to a database to be used by a separate monitoring application.

As with the previous sections you can test the application by calling your number.  You should now be able to both check the status of an package as well as select the second menu option and register to receive status updates.

Menu Option Three – Connect to Customer Service

The last option that we are giving the users of our application is to connect to a customer service representative.  To do this we want our application to call out to our customer service center and bridge the customer and agent together.

To do that our application detects the selection of the third option, and returns the TwiML instructing Twilio to connect to another call

string source = context.Request["src"] ?? String.Empty;
string digits = context.Request["Digits"] ?? String.Empty;

if (source == "mainmenu")
{
    if (digits == String.Empty) { /* menu option one */ }
    if (digits == "1") { /* menu option one */ }
    if (digits == "2") { /* menu option two */ }

    if (digits=="3") {
        twiml.Say("One moment while we connect you");
        twiml.Dial("+15555555555");
   }
}

Here we are using the Dial verb to tell Twilio to create a new call to the provided number.  Twilio will automatically bridge the existing call with the new call, allowing the customer to speak with an agent.

Submenus and Flow Redirects

If you look at the call flow diagram from the beginning of this post you will see that there are several places where the caller can double back on themselves to either re-enter a package ID, or to return to the main menu.  The logic to do this is basically the same for both flow branches.

Lets add the menu options to the lookup branch first.

if (source=="lookup") {

     //using the digits entered by the end user, look up the statu     s
     var order = Orders.FindById(digits);
     if (order != null)
     {
          twiml.Say(string.Format("Your package is currently, {0}.          ", order.Status));
     }
     else
     {
          twiml.Say("I'm sorry.  We were unable to find a package           with that ID.");
     }

twiml.BeginGather(new {
      action = "http://example.com/status.ashx?src=redirect&action      =lookup", numDigits = "1" });
twiml.Say("To look up another package, press one");
twiml.Say("To return to the main menu, press two");
twiml.EndGather();
twiml.Say("Goodbye");
twiml.Hangup();
}

You can see that we’ve added the code to create our menu to the end of the lookup block. Again using the <Gather> verb, we let the user tell us what they want to do once the lookup completes, which in this case is to either lookup another package or to return to the main menu.

In order to process their input we need to create another logic branch that will be run when the Gather completes.  We indicate this new branch as we have done before, by using a new value for the src parameter called ‘redirect’.

Additionally we are sending another parameter called ‘action’.  We’ll use this additional parameter in the redirect branch in order to determine if the user is coming from the lookup branch or the register branch.

The code below shows the code we use for the redirect branch:

if (source=="redirect")
{
     if (digits=="1")
     {
         if (context.Request["action"] == "lookup")
         {
            twiml.Redirect(
                "http://example.com/status.ashx?src=mainmenu&Digit                s=1");
         }
         if (context.Request["action"] == "register")
         {
            twiml.Redirect(
                "http://example.com/status.ashx?src=mainmenu&Digit                s=2");
         }
     }
     if (digits=="2")
     {
            twiml.Redirect("http://example.com/status.ashx?src=mai            nmenu");
     }
}

The logic is fairly straight forward.  If the user indicates enters “1”, we determine if they are coming from the lookup branch or the register branch and simply redirect the call to the correct place in the app.

If the user enters “2”, we redirect them back to the main menu.

Summary

As you can see, creating more complex call flows using an  HTTP Handler in and ASP.NET Web Application is easy, but does require a bit of planning up front in order to design and implement the work flow.  Once you understand the call flow, implementing the code is quite simple.

In the next post we will look at how you can implement the same application using the ASP.NET MVC 3 Framework.

Read more of the .NET series:
Twilio for .NET Developers Part 1: Introducing the Helper Libraries 
Twilio for .NET Developers Part 2: Adding Twilio Helper Libraries to your Project
Twilio for .NET Developers Part 3: Using the Twilio REST API Helper Library
Twilio for .NET Developers Part 4: Using the Twilio.TwiML Helper Library
Twilio for .NET Developers Part 5: Twilio Client, MVC and WebMatrix Helper Libraries

This series is written by Twilio Developer Evangelist Devin Rader. As a co-founder of the St. Louis .NET User Group, a current board member of the Central New Jersey .NET User Group and a former INETA board member, he’s an active supporter of the .NET developer community. He’s also the co-author or technical editor of numerous books on .NET including Wrox’s Professional Silverlight 4 and Wrox’s Professional ASP.NET 4. Follow Devin on Twitter @devinrader

Posted by Devin Rader on February 10, 2012 Tagged , ,

Add Twilio SMS Messaging to your Rails App

Below is a detailed walk through of adding SMS messaging to your Rails app written by Chris Rittersdorf of Mutally Human. Chris is an experienced developer who enjoysbuilding excellent web applications and in his spare time maintains manlyco.de.

This content was originally posted on the Mutually Human blog found here.  

Introduction

The use of smart phones is on the rise, however SMS text messaging is still the best way to reach the broadest customer base, especially in developing countries. If you have a Ruby on Rails application that needs to reach this broad customer base, Twilio is an excellent tool to have in your toolbox.

It’s easy to add Twilio to a Rails application. This post will walk you through the process of integrating Rails with Twilio, including:

  • Signing Up for a Twilio Account
  • Testing with Twilio’s Sandbox App
  • Integrating Twilio with a Rails Application
  • Configuring your Twilio enabled Rails application for Production

Let’s get started!

Signing Up for Twilio

Signing up for Twilio is as simple as providing your name, email and password. After you sign up and log in for the first time, you are taken to the Dashboard. This will give you plenty of information to get started. Upon signing up, you are given $30 in credits to get started. These credits are spent every time a text message is sent or received by Twilio.

In the bottom left section of your dashboard, you’ll see a box called Sandbox App. The Twilio Sandbox is where you want to do development work with Twilio. The Sandbox not only lets you test out your SMS enabled application, but it also lets you lock down which mobile phones can send text messages to it and which mobile phones it can send text messages to. This is in contrast to the live account that can send and receive text messages to and from any mobile phone. Now that you know what the Sandbox is, let’s try it out.

Testing Your Account Using the Sandbox

To test the SMS sandbox, send a text message from your phone to the sandbox number. The content doesn’t matter, it can be anything. Try texting “hello twilio”. You’ll then see a reply similar to this:

Sent from the Twilio Sandbox Number - Error: No PIN.
Make sure you begin your message with the Sandbox PIN from your Twilio Dashboard.

Any time you interact with the Twilio Sandbox, you must provide a PIN along with all communications (whether SMS or Voice). This PIN is located below the Sandbox number on your dashboard. Enter the pin at the beginning of your text message, for example:

28910293 hello twilio

You’ll then get a reply from the default Twilio Service located at:

http://demo.twilio.com/welcome/sms

Now that you’ve confirmed that your account is in working order, let’s see how was can leverage service in a Ruby on Rails application.

Integrating Twilio with Your Rails Application

Web applications communicate with Twilio using an XML variant called TwiML. For example:

This section of TwiML describes how to respond to a user calling a phone number. It speaks a message during the phone call, then sends the user an SMS message. But, it’s no fun writing TwiML. And since we’re using Ruby, there’s a gem for that! The twiliio-ruby gem abstracts TwiML into an easy to use Ruby API. In your Rails application, simply add the twilio-ruby gem to your Gemfile:

Now you have the necessary library to start sending text messages. So now let’s use it!

Sending a Text Message Using Twilio

Sending a text message with your Rails application is simple. But before doing so, there is one configuration we have to make. To test your application using the Twilio Sandbox, you’ll need to white-list any phone numbers you plan to send SMS messages to. You can do this by going to the Numbers tab and clicking the Verify Number button. There is a series of steps you’ll have to complete to verify your number.

After you’ve verified the phone number, your application can now send text messages. The following code example show you how:

In this example, the send_text_message action receives a phone number from a form post, then relays a hard-coded message to that phone number via SMS. The twilio_sid, twilio_token, and twilio_phone_number variables contain the configuration information for authentication using the twilio-ruby gem. Generally, you’d want to pull this into a configuration file that gets loaded when your application loads, but I’ve put them into local variables for simplicity.

Receiving a Text Message Using Twilio

In order to receive a text message from a mobile device, you’ll have to expose an endpoint that is reachable by Twilio. Here is an example:

In this example, the index action receives a POST from Twilio. It grabs the message body, and the phone number of the sender and logs it. Retrieving the information from the Twilio POST is as simple as looking at the params hash:

In order for text messages to reach your application you have to tell Twilio where to send requests. This is again done in the Sandbox App section of the Twilio Dashboard. Specify your publicly facing endpoint in the SMS URL field and click “Save”.

If you’re running your server locally and have no publicly facing endpoint, you can use a service like tunnlr to create one. This creates a publicly accessible URL with an SSH tunnel back to your local machine.

So the publicly facing endpoint for your application would look something like:

http://web1.tunnlr.com:89530/sms

Configuring Twilio for Production

To deploy your SMS enabled application in a production environment, there are three things you’ll need to do: buy a Twilio phone number, configure that phone number in your application, and then configure the production end-point in Twilio.

Purchasing a phone number requires you to enter payment information and decide on a phone number to provision. Twilio will guide you through the process. At the time of writing, Twilio’s pricing is set at $1.00 a month plus an additional 1¢ charge per text.

Also, you will need to update the Twilio phone number in your application to the new number that you’ve provisioned. The examples above contained a variable with the value for a Twilio phone number. Change this value to the new phone number you provisioned.

Finally, you’ll now have to configure the SMS endpoint much like how we did for the Sandbox. Click on the “Numbers > Twilio Numbers” tab. Then click on the phone number you provisioned. Finally, in the “SMS Request URL” field, specify your publicly facing production endpoint URL, then click “Save Changes”.

Conclusion

Whether it be for those on-the-go, or those who otherwise are not able to use a computer or smart phone, SMS provides excellent alternative interface for the users of your web application. For those looking for a simple and affordable way to get started, Twilio is an outstanding option. So now that you know how to get started, what will you build using Twilio?

Posted by Meghan Murphy on February 8, 2012 Tagged , , , ,