June 23, 2016

Today, three developers said hello to an entirely new coding environment — the NYSE. Right after Jeff Lawson rang the bell, welcoming $TWLO into the world, David Huerta, Leah Culver, and Rob Spectre started slinging code.

Check out all their apps and try them out right here: http://www.twlo.codes/

In a matter of hours the team of developers built three Twilio-powered apps that let you do anything from contacting your congressional representative via SMS, to checking stock prices via text, to spreading the word of Hodor through a hotline. It wasn’t just the team of 3 that shipped code. Kenny Polcari, a 35 year veteran of the NYSE who had never coded in his life, built a Twilio app in 6 minutes.

Here are the apps the crew built:

The code you write makes phones ring. But it does far more than that. It unites a community of developers, reduces the distance between a citizen and their congressperson, and sparks Hodor-sized belly laughs. Today, that code brought us — the whole community — to the NYSE where, for the first time, we made a bell ring. We can’t thank you enough for being an integral part of that and we can’t wait to see what you build.

3 Developers Walk Into The NYSE: Apps From The Trading Floor Code Jam

Bookmark this post:
Ma.gnolia DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google


Earlier this month, you heard about Ian Webster, who built an app to call your federal representatives. Communication can be a powerful force for change. Today we’ll learn how to empower others by building an app similar to Ian’s with SMS.

Using C#, ASP.NET, and Azure, we will build a messaging application that responds to a ZIP code with a list of federal representatives for that area:

SMS (text) conversation showing the house representative and senators for ZIP code 95219

Tools

The tools we’ll be using are the staples of the Microsoft stack along with the Twilio API and Sunlight Foundation’s Congress API. Here’s what you’ll need to get right now:

  1. A Twilio Account
  2. Visual Studio 2015 – Free Community Edition is fine
  3. An Azure Account
  4. An API Key for Sunlight Foundation congress API

We’ll also be using ASP.NET MVC 5 and the Twilio C# Helper Library.

Getting Started

First, create a new, empty ASP.NET MVC project that can handle incoming SMS text messages from Twilio. For step-by-step instructions, please see our documentation on how to setup a new project.

Name your project

TwilioCongressBot.Web
  and the solution
TwilioCongressBot
 . Once you see that your Azure Web App is ready, you can proceed.

zFQvq36cEm1jfDah69PweSGterrUmgowyPswbx_xR4ug_R69bEjRACok3aiCwDtwjJjDbnc8jzuBA6KtCqCe3g4i-jg_5q2y0Itk2yKIbK-BYhbfGO07un8_yMRVPB_NPgdEIHMj-2

NuGet Packages

To finish off the framing for our project, we need to install a couple dependencies via the NuGet Package Manager. In the menu, choose Tools > NuGet Package Manager > Package Manager Console. Then, run the following commands:

Install-Package Twilio.Mvc -DependencyVersion HighestMinor
Install-Package Newtonsoft.Json

Creating a Legislator Controller

When Twilio receives a SMS message at a phone number that you own it will call a special URL called a Webhook. Let’s create an empty MVC 5 Controller and name it

LegislatorController
 . Our previously mentioned walkthrough has details on creating a new controller.

Update the namespaces that you import into your controller to be as follows:

using Newtonsoft.Json;
using RestSharp;
using System.Collections.Generic;
using System.Configuration;
using System.Text.RegularExpressions;
using System.Web.Mvc;
using Twilio.Mvc;
using Twilio.TwiML;
using Twilio.TwiML.Mvc;
using TwilioCongressBot.Web.Models;

And then make sure your

LegislatorController
  inherits from
TwilioController
 :

public class LegislatorController : TwilioController

Using the Congress API

If you don’t have your API key yet, head over to the Sunlight Foundation and register for a free one. Their website also contains documentation for the API.

Storing the API Key

We need somewhere to keep track of this API key, and the typical place for doing that in an ASP.NET app is the Web.config file, specifically the appSettings section:

<appSettings>
  <add key="webpages:Version" value="3.0.0.0" />
  <add key="webpages:Enabled" value="false" />
  <add key="ClientValidationEnabled" value="true" />
  <add key="UnobtrusiveJavaScriptEnabled" value="true" />
  <add key="CongressApiKey" value="PASTE KEY HERE"/>
</appSettings>

Add the highlighted line to your web.config file and use the API key you obtained during the registration process.

Calling the API

We will be calling the

/legislators/locate
endpoint, passing it a ZIP code as well as our API key. The template for the URL we’ll be calling can be assigned to a private field on our controller like so:

private string _congressApiUrlTemplate = "https://congress.api.sunlightfoundation.com/legislators/locate?zip={0}&apikey={1}";

We’ll use C#’s String.Format() function to replace {0} with the ZIP code and {1} with our API key from the web.config file. Once we’ve built the URL, we can use RestSharp (already included as a dependency of the Twilio helper library) to make the call and Json.Net to parse the result:

private CongressApiResult getLegislators(string zip)
{
   var url = string.Format(_congressApiUrlTemplate, zip, ConfigurationManager.AppSettings["CongressApiKey"]);
   var client = new RestClient(url);
   var request = new RestRequest(Method.GET);
   var response = client.Execute(request);
   if (response.ResponseStatus != ResponseStatus.Completed || 
       response.StatusCode != System.Net.HttpStatusCode.OK)
   {
       return null;
   }
   return JsonConvert.DeserializeObject<CongressApiResult>(response.Content);
}

The

CongressApiResult
  class defines all of the expected properties of the API result. We need to create a source file to hold this class and dependent classes. Place it in the “Models” folder of our solution.

Pro-tip: This class was auto-generated by Visual Studio by copying the expected JSON result (obtained here) from the congress API and using: Edit… Paste Special… Paste JSON as Classes. The generated Result class was then manually renamed to Legislator:

public class CongressApiResult
{
   public Legislator[] results { get; set; }
   public int count { get; set; }
   public Page page { get; set; }
}

public class Page
{
   public int count { get; set; }
   public int per_page { get; set; }
   public int page { get; set; }
}

public class Legislator
{
   public string bioguide_id { get; set; }
   public string birthday { get; set; }
   public string chamber { get; set; }
   public string contact_form { get; set; }
   public string crp_id { get; set; }
   public int? district { get; set; }
   public string facebook_id { get; set; }
   public string fax { get; set; }
   public string[] fec_ids { get; set; }
   public string first_name { get; set; }
   public string gender { get; set; }
   public string govtrack_id { get; set; }
   public int icpsr_id { get; set; }
   public bool in_office { get; set; }
   public string last_name { get; set; }
   public object middle_name { get; set; }
   public object name_suffix { get; set; }
   public object nickname { get; set; }
   public string oc_email { get; set; }
   public string ocd_id { get; set; }
   public string office { get; set; }
   public string party { get; set; }
   public string phone { get; set; }
   public string state { get; set; }
   public string state_name { get; set; }
   public string term_end { get; set; }
   public string term_start { get; set; }
   public string thomas_id { get; set; }
   public string title { get; set; }
   public string twitter_id { get; set; }
   public int votesmart_id { get; set; }
   public string website { get; set; }
   public string youtube_id { get; set; }
   public string lis_id { get; set; }
   public int senate_class { get; set; }
   public string state_rank { get; set; }
}

Determining a ZIP Code

As you can see here, Twilio will pass us a

Body
parameter containing the contents of whatever was sent to us as a text message. It also may send us a
FromZip
parameter if it can identify geographic data based on the source phone number (not geolocation). For example if the text message was sent from the 415 area code, Twilio can tell you that area code is located in San Francisco, CA.

Let’s check the

Body
first, to see if the user specified a ZIP code and fallback to the
FromZip
:

private string getValidZip(SmsRequest request, TwilioResponse response)
{
    if (containsValidZip(request.Body)) return parseZip(request.Body);
    if (containsValidZip(request.FromZip))
    {
        var fromZip = parseZip(request.FromZip);
        response.Message("Text your ZIP code for more accurate results. We're guessing " + fromZip);
        return fromZip;
    }
    return null;
}

private Regex _zipValidator = new Regex(@"\d{5}");
private bool containsValidZip(string input)
{
    return _zipValidator.IsMatch(input ?? "");
}

private string parseZip(string input)
{
    return _zipValidator.Match(input).Value;
}

Notice we’re adding a help message if we fallback to the

FromZip
letting them know they may need to text us their specific ZIP code if the one associated with their phone number isn’t where they reside.

Putting it Together

Now we just need our controller action to use the code we’ve written to get the ZIP code, pass it to the congress API, and format the results:

[HttpPost]
public ActionResult Index(SmsRequest request)
{
   var response = new TwilioResponse();

   var zip = getValidZip(request, response);
   if (zip == null)
   {
       response.Message("Please text your ZIP code.");
   }
   else
   {
       var legislators = getLegislators(zip);
       if (legislators == null)
       {
         response.Message("Error getting results for " + zip);
       }
       else if(legislators.count == 0)
       {
         response.Message("Could not find results for " + zip);
       }
       else
       {
           foreach (var legislator in legislators.results)
           {
               response.Message("Your " + labelDict[legislator.chamber] + ": " +
                 getFullName(legislator) + " - " + legislator.phone + " - " +
                 legislator.oc_email);
           }
       }
   }

   return TwiML(response);
}

There’s two things in the formatting code above we haven’t covered yet. First, we create the following dictionary as a private field:

private IDictionary<string, string> labelDict = new Dictionary<string, string>()
{
    { "house", "House Representative" },
    { "senate", "Senator" }
};

This helps us translate the “chamber” property from the API to a more friendly text description. Also, we have a simple helper function to concatenate the first, middle, and last name of the representative:

private string getFullName(Legislator legislator)
{
    return (legislator.first_name + " " +
            legislator.middle_name + " " +
            legislator.last_name).Replace(" ", " ");
}

You can find the full source code for the controller and model on GitHub.

Testing and Debugging Locally

Run your application from within Visual Studio to view your application in the browser. In the case of an empty ASP.NET project, we don’t have a default home page for our app:

IgKsiyuDVjAaEYXHToPOSMsLu_tggXebmjhN8tPimkVbbcMS8zrCPepZW43uDOdr7cIZkkLBchhUI22OLTS11iT34FJEh1x5gR3BgQSU7POR5QAcMOYq6NeGgwSc2-vOrFylYr3O-2

Instead of using the browser to test, open a new PowerShell window and run the following command:

Invoke-WebRequest http://localhost:XXXXX/Legislator -Method POST -Body @{Body="Hello World 95219-4444";FromZip="95209"}

Replace the XXXXX with the random port number that Visual Studio assigned to your web app. You can see this in the browser URL when Visual Studio first launched your app.

This will return a PowerShell object with the response from your controller:

StatusCode : 200
StatusDescription : OK
Content : <?xml version="1.0" encoding="utf-8"?>
          <Response>
            <Message>Your House Representative: Jerry McNerney - 202-225-1947 - Rep.Mcnerney@opencongress.org</Message>
            <Message>Your Senator: Barbara Boxe...
RawContent : ...

You should be able to see the raw XML response we are returning in the Content property. Pro-tip: you can see just the Content property with a single command:

(Invoke-WebRequest http://localhost:XXXXX/Legislator -Method POST -Body @{Body="Hello World 95219-4444";FromZip="95209"}).Content

Deploying and Configuring the App

Publish to Azure

To publish your app to Azure, find the “Azure App Service Activity” tab in Visual Studio and click the Publish button:

yFSmmSC2uNboRCcMhmt1hDQmNnOcGsMqXLfRG-KhHv6JJ1RbsPQTcCwHVOmd-Vvezp4cTFI0zYw1hDul8eRCjZRtQ2BP4qFUY6SAGPx9zo-BHM5imgtt07IrjcRI5sRtz0zCdUIb-2

Once the publish is complete, you can test your app from PowerShell again:

Invoke-WebRequest https://congressbot01.azurewebsites.net/Legislator -Method POST -Body @{Body="Hello World 95219-4444";FromZip="95209"}

Replace

congressbot01
  with the name you selected for your Azure Web App.

Assuming that works, we can move on to attaching your Webhook to a phone number in Twilio.

Configure a Twilio Number

If you haven’t already purchased a Twilio phone number, do so now. Once that is done, you can configure the Messaging Webhook as follows:

P7H6PI1sQraynbnZSlDGDWyGvqen-Wx37dPHnMHZJtAznKxM6L8N1nTwkmj-pKbjGEYapqZ7QV0etnh5AW5AJTdQs3z2ZT0SPww_BsB-4HCLIT5J6eOqq-QBtIEtBC8dHWhl8tSF-2

Use the same URL for your Azure Web App that you tested in PowerShell earlier. Be sure to click the SAVE button to save your configuration for the phone number.

Taking the Final Test Drive

With your Twilio phone number confirmed, you can simply send a text to test it out:

65RvKADoXAwig_u9ulklhCpix2gGUcRn9pywsNfG7oh6x7he_6fkDZurZPnTrM-CLsj31KJDBW9-3an3b6r0-gjOHKfNEtO_ReMcFmM27eKtmJPL4TLpSGO4f4BOP6cIKqA0ypsD-1

Wrapping Up

You can download the entire solution from GitHub. If you want to publish this completed app to Azure, right-click on the CongressBot web app in the Solution Explorer and choose “Publish.”

Now all you need to do is give your Twilio phone number to your colleagues, friends, family, etc. and allow their voices to be heard! Or, have them text (646) 8USA-REP (+1-646-887-2737), which is powered by this app.

I’m David Prothero and I work on the Twilio Developer Education team. If you have any questions or feedback on this hack, let me know in the comments below, hit me up on Twitter at @dprothero or shoot me an email at dprothero at twilio.com.

Using C# and Azure to Build a SMS Representative Directory

Bookmark this post:
Ma.gnolia DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google


Hodor is not man of many words. In fact, he’s just got one: “Hodor.” And while communication may not be his forte, one wonders how his adventures with Brandon Stark might have turned out if they had the mobile communication technology we all take for granted today.

Thanks to the recent release of TwiML Bins we don’t have to wonder any longer. To get in contact with Hodor, you need only call or text our Hodor Hotline at (917) 722-6264. Ask him anything you like, and digest the wisdom of his reply.

text-hodor

Even if you’ve never written a line of code before, you can build a hotline like this yourself in just five minutes with TwiML Bins. It’s easier than falling out the moon door. You’ll need to sign up for a free Twilio account to get started. Then there’s just three steps: 

  1. Write the three lines of code to respond to a text message
  2. Write the three lines of code to respond to a phone call
  3. Buy a Twilio programmable phone number

Write the Code

TwiML is a simple set of instructions used to program your Twilio number. TwiML Bins let you host static TwiML without setting up a server of your own. We’ll create two TwiML Bins – one for the instructions on what to do when a text message comes in, and one for phone calls.

  1. Go to your Twilio Console.
  2. Scroll down and click Developer Center.
  3. Click TwiML Bins.
  4. Click Create a New TwiML Bin.
  5. Name your TwiML Bin “Hodor SMS”.

Valid TwiML starts with a 

<Response>
 tag, ends with a 
</Response>
 tag, and has instructions in-between. Here we’ll use the
<Message>
  tag to reply to an incoming message. Paste the following code to respond to an incoming text message, then save your TwiML Bin:

<Response>
  <Message>Hodor.</Message>
</Response>

Now create a second TwiML Bin and name it “Hodor Voice.” Here we’ll

<Play>
 a WAV file that’s hosted on Dropbox (of course, you can swap in the URL of any publicly accessible MP3 or WAV if you’d like). Paste this code in, then save your TwiML Bin. 

<Response>
  <Play>https://www.dropbox.com/s/dn5as27x5anez0t/hodor.wav?dl=1</Play>
</Response>

hodor-twiml-bin

Buy your programmable phone number

Congrats! You just wrote some TwiML. Now you just need a phone number.

  • Go to your Twilio Phone Numbers.
  • Click Buy a Phone Number.
  • Search for a number that suits you. 
  • Click Buy

Confirm your purchase and click Setup Number. Now we need to tell Twilio where to find instructions on what to do when someone calls or texts this number. 

  • Under Voice, look for the line that says “A call comes in.” Change the first box to “TwiML” and the second to “Hodor Voice”.
  • Under Messaging, look for the line that says “A message comes in.” Change the first box to TwiML and the second to “Hodor SMS.”

Ensure your settings look like this, then hit Save.

hodor-phone-number

 

That’s it! Text your shiny new Twilio phone number. Then, give it a call.

What’s Next?

There’s so much more you can do with TwiML Bins and a programmable phone number. For instance, go back to your “Hodor Voice” TwiML bin and replaced the 

<Play></Play>
 line with these variations: 

Talk in a robot voice:

<Say loop="10">Hodor</Say>

Forward the call to you cellphone, giving you a temporary phone number: 

<Dial>1-312-XXX-XXXX</Dial>

Create a conference line:

<Dial>
  <Conference>My Conference Line</Conference>
</Dial>

To learn more, check out: 

If you build something cool with TwiML Bins, hit us up at @twilio. And if you have any questions, drop me a line at @greggyb or gb@twilio.com

How to Text with Hodor

Bookmark this post:
Ma.gnolia DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google


In the movie Wall Street, one dimension of the main character Gordon Gecko that the film disappointingly fails to explore is his love of the outdoors.  That’s right, he loves to go camping.  Unexpected, right?

Gordon’s never going to get a data connection out there, but with a bit of Python and Twilio SMS he can still check his stock prices with only a few of those precious reception bars.  Let’s find out how.

Setup and Build

For this simple app all you need is a Twilio account and a Python development environment.  If you are new to Python it’s easy to set up sign up for a free trial.

Start by opening a terminal or command line and create a new virtual environment named ‘twilio-ticker’:

virtualenv twilio-ticker

Activate the virtualenv:

source twilio-ticker/bin/activate

The dependencies we need are requests, an HTTP client, Flask, a Python microframework and the Twilio helper library:

pip install requests flask twilio

Awesome, let’s dig into some code. Create a new file named app.py, open it in your favorite code editor and import the dependencies we just installed:

import requests

from flask import Flask, request
from twilio import twiml

Now add the code needed to create and run a new Flask app:

import requests

from flask import Flask, request
from twilio import twiml

app = Flask(__name__)

if __name__ == "__main__":
    app.debug = True
    app.run()

Next define a new route that Twilio can request via an HTTP POST when it receives an inbound text message.  That route creates a response that containing the TwiML <Message> verb which tells Twilio to send an SMS message back to the sender.

app = Flask(__name__)


@app.route('/sms', methods=['POST'])
def sms():
    response = twiml.Response()
    response.message("Hello World")
    return str(response)

if __name__ == "__main__":
    app.debug = True
    app.run()

This is a good place to make sure the basics of our app are set up and run.  Start the app by running:

python app.py

The app will start and expose the sms route on http://localhost:5000.

Test the route using an HTTP client like cURL or Postman to make a request to the sms route. The response should contain the generated TwiML.

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Message>Hello World</Message>
</Response>

High five! With the route generating TwiML let’s modify it to let someone request the the price of a specific listing by texting in a stock symbol.

Start by grabbing the text of the incoming SMS message which Twilio includes its HTTP request as a form-encoded value named Body.  Using that symbol craft a URL for the Yahoo Finance API that we’ll request to the to get information about the listing:

@app.route('/sms', methods=['POST'])
def sms():
    symbol = request.values.get('Body')
    path = "http://finance.yahoo.com/webservice/v1/symbols/{0}/quote?format=json"
    path = path.format(symbol)

    response = twiml.Response()
    response.message("Hello World")
    return str(response)

Using requests make an HTTP GET request to the Yahoo URL.  From the response parse the price and replace the original TwiML message with a new message that contains the stock symbol and price:

@app.route('/sms', methods=['POST'])
def sms():
    symbol = request.values.get('Body')
    path = "http://finance.yahoo.com/webservice/v1/symbols/{0}/quote?format=json"
    path = path.format(symbol)
 
    response = twiml.Response()
    try:
        result = requests.get(path)
        price = result.json()['list']['resources'][0]['resource']['fields']['price']
        response.message("Current price of {0} is: {1}".format(symbol, price))
    except:
        response.message("Whoopsie doodle - could not find the information.")
  return str(response)

Restart the app and head back to your HTTP client to make a request to the sms route again this time including the form-encoded Body parameter.

<Response>
    <Message>Current price of GOOG is: 695.94</Message>
</Response>

With the app running the final step is to connect a Twilio phone number to it.  Twilio uses an HTTP request to a public URL to tell us that it has received an incoming SMS message.  We can expose the Python app running in own local environment via a public URL by using ngrok.

ngrok http 5000

Once ngrok starts grab the public URL that it assigned:

Next, head over to the Phone Numbers section of the Twilio Console to select an existing number in your account buy a new number.

Configure the phone number so that when Twilio receives an incoming SMS message Twilio will make an HTTP, or “webhook”, request to your ngrok URL:

Save the phone number and give your app a try by texting your favorite stock symbol to your Twilio phone number.

Boom!  Quick stock symbol info on your phone via single simple SMS message.

Wrapup

By combining a few bits of Python and Twilio, in just a few minutes we were able to build a really fun and useful SMS app.  But the fun does not have to stop there.

The app could be made even more useful by allowing the user to request prices of multiple stocks or by using a task queue library like Celery to allow the user to set up SMS notifications for when a symbol hits a price threshold.

Let me know what you’re building with Python or Twilio.  Shoot me a tweet @devinrader.

Check Stock Prices with Python and Twilio SMS

Bookmark this post:
Ma.gnolia DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google


“Test, commit, push, deploy” – You’ll hear a lot of new words getting shouted over the din of the trading floor at the NYSE tomorrow.

Tomorrow, three developers set up shop in a place far from the port 80 they call home. David Huerta, Leah Culver and Rob Spectre will sling code straight from the floor of the New York Stock Exchange live on Twitch

Starting at 9:00 AM EDT / 6:00 AM PT / 1:00 PM GT they’ll design, develop and deploy as many Twilio apps as they can. Watch them in action live on Twitch.tv. We’ll be breaking down what powers their apps, how you can build them, and a few special surprises.

See you tomorrow on Twitch.

 

The offering of Twilio’s Class A common stock is being made only by means of a prospectus. A copy of the final prospectus may be obtained from Goldman, Sachs & Co., Attention: Prospectus Department, 200 West Street, New York, NY 10282, telephone: 1-866-471-2526, or email: prospectus-ny@ny.email.gs.com; and from J.P. Morgan Securities LLC, c/o Broadridge Financial Solutions, 1155 Long Island Avenue, Edgewood, NY 11717.

A registration statement relating to these securities has been filed with, and declared effective by, the Securities and Exchange Commission. This communication shall not constitute an offer to sell or the solicitation of an offer to buy, nor shall there be any sale of these securities in any state or jurisdiction in which such offer, solicitation or sale would be unlawful prior to registration or qualification under the securities laws of any such state or jurisdiction.

Tune Into The NYSE Code Jam Tomorrow On Twitch

Bookmark this post:
Ma.gnolia DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google


June 22, 2016

One of the appealing aspects of the bar Cheers was that it was a place where everyone knew your name. A friendly face that knows your preferences doesn’t just make you feel appreciated, it’s also more efficient. Forget the formality, this type of personal attention lets you cut right to the heart of the matter and get things done quickly.... Read More

The post Personalization Basics in Voice-Based Customer Service appeared first on Plum Voice.

Bookmark this post:
Ma.gnolia DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google


Not everyone is a telecom nerd like we are. When you send or receive a text message using Twilio, we go to great lengths to ensure that the nerdiness and complexity of the telecom world stays well hidden.

While you might not care how the sausage is made, sometimes that process can reveal a great deal of useful information. In this case, the process reveals information that can help you improve the reliability and readability of your messages.

That’s why we’re excited to announce Twilio Messaging Insights.

Messaging Insights is a gradual roll-out of new messaging features that provide you detailed information about how your messages are performing out in the wild. The first phase of Messaging Insights is exposed through a completely redesigned Message Details page in your Twilio Console. This gives you a drill-down view into a single message sent through Twilio.

messagingdetails

The new page includes the following:

API Endpoint

The first thing you’ll notice is a designation of the Twilio API endpoint you sent the message with.
message details api endpoint

 

Why is this important? Overall this can help you understand the feature set of the API endpoint you’re using and compare it to the latest available from Twilio. For instance, if you see the API Endpoint /SMS/Messages, you’re using our now deprecated messaging endpoint and it’s time to upgrade!

Character Encoding

Next, the Messaging Detail page will show you how each message is encoded by Twilio. We show you the number of segments used for each message and whether a message was encoded using GSM or UCS-2.
Character Encoding
This information can come in really handy for understanding how a message will display to an end user and because character encoding affects concatenation length. Messages encoded in UCS-2 are concatenated into 70 character segments as opposed to 160 for GSM.

If you include Unicode characters in a message, Twilio automatically encodes your message as UCS-2 so it can be sent successfully. However sometimes Unicode dash or space can accidentally be added to an otherwise GSM compatible message. This could double the number of message segments sent because of the shorter UCS-2 concatenation and now you know where to look!

Delivery Steps

Scroll down the Message Details page and you’ll find a new section: Delivery Steps.
Delivery Steps
Delivery Steps shows the steps a message goes through when transiting the Twilio infrastructure and how long it took for each step before it goes out to the carrier network. This level of visibility is extremely helpful in troubleshooting any message latency, for example with queuing. Again, if you’re using the deprecated endpoint, Delivery Steps will not be available to them (another reason why you should move onto the new endpoint!).

For the keen eyed- you’ll notice that my status callbacks (deliberately) failed in the first screenshot. That’s because I wanted to illustrate we actually send you two status callbacks for each message- one for when the message was sent to the carrier network and another when the carrier reports it as delivered. Messaging Insights are stored for seven days.

Give It A Try

We’re particularly proud of these additions to the Message Details page because no one else in the industry gives you this level of real-time logging or transparency into their infrastructure. It’s especially useful when debugging your app (as I can attest!).

Try it yourself. Go into your messaging log, select a message and you’ll see all the information associated with that message. Or sign up for Twilio and check it out.

Introducing Messaging Insights

Bookmark this post:
Ma.gnolia DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google


June 21, 2016

Did you know that Node.js has a built in debugger? I didn’t until a few months ago. Check out how it can make debugging your code a breeze.

To follow along at home you’ll need:

First let’s write some code to debug. We’re going to sum the contents of an array with a for loop.

Paste the following into a file named index.js.

'use strict'

const list = [1, 2]
let total = 0

for (let i = 0; i <= list.length; i++) {
  total += list[i]
}

console.log(total)

Running this with node index.js you’ll see NaN printed out.

wat

Instead of smashing our faces against the keyboard let’s run the file through the Node.js debugger by passing node the debug keyword.

node debug index.js

The debugger will load up the file and enter in a paused state or rather reach an initial breakpoint. If you’ve ever used GDB before you should feel right at home and if you haven’t you’re about to see how powerful debuggers can be.

Screen Shot 2016-06-15 at 2.37.54 PM

Set a breakpoint inside the loop on line 7.

setBreakpoint(7)

Since our breakpoint is inside a loop our program will pause on each pass. Let’s set some watchers on the variables we care about. Watchers will print out the variable each time a breakpoint is reached.

watch('total')
watch('i')
watch('list[i]')
watch('total + list[i]')

Now we tell the debugger to continue with execution.

continue

We hit our breakpoint and see the values of our watched variables printed out.

break in array.js:7
Watchers:
  0: total = 0
  1: i = 0
  2: list[i] = 1
  3: total + list[i] = 1

  5
  6 for (let i = 0; i <= list.length; i++) {
> 7   total += list[i]
  8 }
  9

The values appear to be correct. Let’s continue forward with the shortcut c.

debug> c
break in array.js:7
Watchers:
  0: total = 1
  1: i = 1
  2: list[i] = 2
  3: total + list[i] = 3

  5
  6 for (let i = 0; i <= list.length; i++) {
> 7   total += list[i]
  8 }
  9

This is still correct. We should now leave the loop and print the total. Let’s continue.

debug> c
break in array.js:7
Watchers:
  0: total = 3
  1: i = 2
  2: list[i] = undefined
  3: total + list[i] = "NaN"

  5
  6 for (let i = 0; i <= list.length; i++) {
> 7   total += list[i]
  8 }
  9

Woah hold on a second. There’s our NaN and what is that undefined there. Also, why did we run this loop again? Let’s print out the length of the list. We can use exec to execute a string of JavaScript while in the debugger.

debug> exec('list.length')
2

Oops! We made the mistake of using <= instead of <. There might not be a lot of code here but I bet you can recall a bug that you’ve dealt with where stepping through and looking at the variables would have caught it.

In The Real World

Next let’s look at a real world example. Say you are using Twilio to receive an SMS for the first time and haven’t yet looked at our beautiful new docs to see what the payload will look like.
Instead of inspecting things with iterative console.log statements, we can set a breakpoint and drop into a magical REPL in the middle of our executing program.

Replace the contents of index.js with the following basic Express app that receives a POST request from Twilio. We can set a breakpoint via our code by adding debugger where we’d like – this will be ignored when not using the debugger.

'use strict'

const express = require('express')
const bodyParser = require('body-parser')

const app = express()

app.use(bodyParser.urlencoded({ extended: false }))

app.post('/sms', (req, res) => {
  res.set('Content-Type', 'text/plain')
  debugger
})

app.listen(3000)

Next install the dependencies.

npm install express body-parser

Start Ngrok on port 3000 and configure your Twilio phone number to POST incoming messages to http://YOUR_NGROK_URL.ngrok.io/sms. If you haven’t used Ngrok before my buddy Phil has a great post about why you’ll love using it to test webhooks.

ngrok http 3000

ngrok-url

ngrok-config

Fire up the app in debug mode and tell the debugger to continue past its initial breakpoint.

node debug index.js
< Debugger listening on port 5858
connecting to 127.0.0.1:5858 ... ok
> 1 'use strict'
  2
  3 const express = require('express')
debug> c

Send a text message to your Twilio phone number and watch as the breakpoint gets triggered. We’ll actually be paused with an open HTTP connection. Type repl to drop into a REPL of your paused application.

break in index.js:12
 10 app.post('/sms', (req, res) => {
 11   res.set('Content-Type', 'text/plain')
>12   debugger
 13 })
 14
debug> repl

Press Ctrl + C to leave debug repl
> req.body
{ ToCountry: 'US',
  ToState: 'NY',
  SmsMessageSid: '***************************************',
  NumMedia: '0',
  ToCity: 'GARDEN CITY',
  FromZip: '08899',
  SmsSid: '**************************************',
  FromState: 'NY',
  SmsStatus: 'received',
  FromCity: 'BROOKLYN',
  Body: 'Hi',
  FromCountry: 'US',
  To: '+1**********',
  ToZip: '11215',
  NumSegments: '1',
  MessageSid: '*********************************************',
  AccountSid: '********************************************',
  From: '+1*********',
  ApiVersion: '2010-04-01' }
>

The request will stay open for about 15 seconds so if you’re quick enough you can actually send a reply text by responding to Twilio. Since we set the Content-Type header to text/plain any text we send back will automatically be sent as an SMS.

You might need to trigger the request again if you receive an error. Don’t forget the initial continue.

> res.send('What up?')
{ domain: null,
  _events: { finish: [Function] },
  _eventsCount: 1,
  _maxListeners: undefined,
...
}

Wrap Up

Using the built in Node.js debugger gives you absurd control and introspection into your code.

Before I learned about the debugger I was running my code several times with different console.log statements. Now I drop into it often to test webhooks or the response bodies of API requests.

Being able to just poke around and write lines of your application in a REPL is extremely productive.

Let me know if you find a creative use for the debugger in your own code.

Using The Node.js Debugger For Fun And Profit

Bookmark this post:
Ma.gnolia DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google


June 20, 2016

Many of you have adopted Twilio Conference to create complex call flows for multi-party scenarios. Over the last few months, the Conference team has been looking at how our API should be improved to make your job easier. Today, we are excited to announce the addition of a dedicated Hold API for Conference. You will be able to put a call leg on hold while keeping the participant in the conference. Before, you had to remove a call leg from the conference and transferring it to a new one. It’s quite a tedious sequence, especially when you had to do it at scale and keep track of a load of call SIDs.

Many multi-party use cases rely on the ability to manipulate participant resources while the call is ongoing. Think, for example, when an agent needs to put you on hold to pass your request to a more experienced colleague. This why we think that Conference Hold will significantly simplify your life in a lot of scenarios.

How Does It Work

You can now update the properties of a participant resource by POSTing the following parameters to the participant SID. This keeps the participant in the conference but redirects the participant’s media stream to a specified TwiML document or audio file.

Here’s are the optional parameters and a description of what they do.

Hold
– Specifying true will hold the participant, while false will un-hold.
 
HoldUrl
– The ‘HoldUrl’ attribute lets you specify a URL for music that plays when a participant is held. The URL may be an MP3, a WAV or a TwiML document that uses or . If omitted, Twilio will play default hold music.
 
HoldMethod
– Specify GET or POST, defaults to POST
 

The request would look like this:

$POST /Conference/CFbbe46ff1274e283f7e3ac1df0097ab39/Participants/CA386025c9bf5d6052a1d1ea42b4d16662
    -d "Hold=True" \
    -d "HoldUrl=https://myapp.com/hold" \
    -u 'AC123:{AuthToken}'

To better understand how it works, let’s have a look to one of the most common Contact Center scenarios.

Contact Center Cold Transfer – Before and After

Before

In Contact Center terminology, a “cold transfer” is the situation where a customer is put on hold while transferred to a different department or agent. Until now, you had to do the following.

1. When Customer calls Twilio number CA123:

  • persist the callSid CA123 received from the webhook, as you will have to modify that call leg later on.
  • place Customer into Conference_A

$ POST /Calls/CA123 \
    -d "Url=https://myapp.com/holdconference" \
    -u 'AC123:{AuthToken}'

And serving the associated TwiML.

Conference_B

3. Once the Customer have been moved to Conference_B, Agent_1 can add Agent_2 to Conference_B. You can create a TwiML flow to do it.

Conference_B

ConferenceHold1

Now

Let’s have a look at how this would be simplified with the new hold capability in the same scenario.

1. When Customer calls Twilio number CA123, Place Customer into Conference_A as before.

$POST /Conference/CFbbe46ff1274e283f7e3ac1df0055ab39/Participants/CA386025c9bf5d6052a1d1ea42b4d16662
    -d "Hold=True" \
    -d "HoldUrl=https://myapp.com/hold" \
    -u 'AC123:{AuthToken}'

3. Finally, it’s time to bring in the second agent. You can create a TwiML flow to add Agent_2 into the conference.

$POST /Conference/CFbbe46ff1274e283f7e3ac1df0012ab39/Participants/CA386025c9bf5d6052a1d1ea42b4d16662
    -d "Hold=False" \
    -u 'AC123:{AuthToken}'

4. At this point Agent_1 can un-hold the customer and can disconnect. Customer and Agent_2 will remain chatting in the conference room.

Et voila! We have done everything by just using “Conference_A”.
Conference2

How To Enable It

Conference Hold is in Public Beta and you can start experimenting with it right now. Have a look the new documentation here and let us know if you have any questions.

Introducing Conference Hold

Bookmark this post:
Ma.gnolia DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google


June 19, 2016

Did you hear the preamble joke the guy told before showing you how to build a SMS Dadjoke Slackbot in Python?

A phone is lost in the jungle, and gets tangled in a thicket of vines. It sees a python and says “Hey can you cut me some Slack?”

[I’ll pause while you mentally prepare yourself for an onslaught of Dad jokes]

Our Dadbot will text you terribly awesome jokes when you @ mention it in its Slack channel. Dadbot will also drop a quality Dad joke in a Slack channel when you text a Twilio number. This is the power of the Slack API combined with the Twilio SMS API — Dad jokes abound.

What We’ll Need

My dad doesn’t go anywhere without cargo pants, extra napkins stuffed in his pocket, and a map. We will also need a few precious items before heading out to build Dadbot.

Twilio Developer Evangelist and lover of all things Python, Matt Makai has a step-by-step guide on setting up your virtual environment right here on his blog.

For the Slack side of things you’ll need the following:

For all things Twilio, you’ll need these two things:

 

Setting The Stage For Dad Jokes: Your Development Environment

Using Terminal, create a proverbial cargo pant pocket in which you’ll store your Dadbot project. Once you create that directory, create a new virtualenv to separate our application’s dependencies from any other projects you’ve got in the works.

virtualenv dadbot

Activate that environment with the following command.

Source dadbot/bin/activate

Awesome. You should see something like this.
VirtualEnvActivated

It’s time to get the slackclient API helper library installed so we can send and recieve messages from our #dadbot Slack channel. Here’s the pip command you run to install the slackclient, Twilio helper libraries, and Flask.

pip install slackclient twilio flask

Next, we’ll need to get an access token for our Slack team as well as our Twilio API credentials. Get ready to export some tokens.

Cutting Dad Jokes Some Slack: Using The Slack Web API

What’s the good of telling a great Dad joke if there’s no one around to hear it? Slack’s chat app will serve as our vessel for Dad jokes. They offer programmatic access to their chat app through a simple to use WebAPI.

Click here to sign up for a Slack account, create a team, or sign in to your trusty old Slack account. Once you’re all set up, scroll down the API page to Authentication and click “Generate Test Tokens.”

Pro Tip – You’ll need administrative privileges in the Slack team you generate test tokens for.
SlackGenerateTokens

We’ll have to check that our Python code has the green light to call the Slack API. To test that it’s authorized, we need to export our secret tokens (from both Slack and Twilio) as enviornment variables. We’ll export the token with the name

SLACK_TOKEN

export SLACK_TOKEN='your slack token pasted here'

Sending Texts To Your Dadbot

If you don’t have a Twilio account, now would be a good time to sign up for a free account. We need to access the Twilio API to send and receive texts. If you’ve already got a Twilio account, go ahead and sign in. You’ll need to purchase a number you’ll use to send text to and from Dadbot. If you have an existing number you want to use, that works as well.

Buyanumber
Twilio is going to ask for a URL it can hit to send an HTTP POST request once an SMS reaches our Dadbot Twilio number. We have to solve what I call the “Zoolander Problem — our code is only accessible to our local machine. To provide Twilio a URL and solve the Zoolander Problem, we’ll use ngrok to expose our local web server through an accessible domain.

After you download ngrok, get it up and running with this command in terminal.

./ngrok http 5000

You should see something like this.
ngrok
Grab the forwarding URL, go to your Twilio Console, and paste the forwarding url plus “/twilio” in the “A message comes in” field. Keep that Forwarding URL handy because we’ll need it to handle some Slack details shortly.
dropngrokinforwarding

Next, we’re going to export our Twilio Account SID and Auth Token as environment variables. Head into your Twilio Console and copy down these two variables.
accountsidauthtoken

Make sure you’re not still in the Python REPL. Enter CTRL + d if you still are. Once you’re out of REPL, use the following command to export the variables.

import os
from flask import Flask, request, Response
from slackclient import SlackClient
from twilio import twiml
from twilio.rest import TwilioRestClient

Remember all those environment variables we exported earlier? The os module will pull the

TWILIO_ACCOUNT_SID
,
TWILIO_AUTH_TOKEN
and other variables we exported from the command line. The Flask class will instantiate our app, while request Response will give us the HTTP inputs and responses we need.

Let’s grab those environment variables and instantiate the Flask app alongside the Slack and Twilio clients.

@app.route('/twilio', methods=['POST'])
def twilio_post():
    response = twiml.Response()
    if request.form['From'] == USER_NUMBER:
        message = request.form['Body']
        slack_client.api_call("chat.postMessage", channel="#dadbot",
                              text=message, username=dadbot,
                              icon_emoji=':robot_face:')
    return Response(response.toxml(), mimetype="text/xml"), 200

We’ll be using the

python
command to test that our Dadbot is running smoothly, and to start a Flask server. To make this possible, add the following function:

* Running on http://127.0.0.1:5000/ (Press CTRL C to quit)
* Restarting with stat
* Debugger is active!
* Debugger pin code: 144-609-426

It’s that time. Text your Twilio phone number. You should see that your message has posted in the Slack Channel like so.
dadbotsayshi

That simple “hai” is a confirmation that your SMS has hit Twilio, triggered an HTTP Post request to your ngrok URL, ngrok forwarded the POST request to your local machine, and hit the dadbot.py file that’s running on your Flask server. This is the journey of a Dad joke.

Importing Your Favorite Jokes, Exporting Random Dad Jokes

No one wants to hear the same joke over and over again. Use the import random module to allow our app to make a random Dad joke selection from our list of Dad jokes that we’ll contain in myList. We need to edit some code so Twilio knows to print the selected random Dad joke in Slack.

Go back into your Dadbot.py file and add the following lines of code.

# -*- coding: utf-8 -*-

import os
from flask import Flask, request, Response
from slackclient import SlackClient
from twilio import twiml
from twilio.rest import TwilioRestClient

SLACK_WEBHOOK_SECRET = os.environ.get('SLACK_WEBHOOK_SECRET', None)
TWILIO_NUMBER = os.environ.get('TWILIO_NUMBER', None)
USER_NUMBER = os.environ.get('USER_NUMBER', None)
 
app = Flask(__name__)
slack_client = SlackClient(os.environ.get('SLACK_TOKEN', None))
twilio_client = TwilioRestClient()

import random
import random
myList = [“Your dad jokes here”, “even more dad jokes,”] 
random.choice(myList)


@app.route('/twilio', methods=['POST'])
def twilio_post():
    response = twiml.Response()
    if request.form['From'] == USER_NUMBER:
        message = random.choice(myList)
        print message
        slack_client.api_call("chat.postMessage", channel="#dadbot",
                              text=message, username='dadbot',
                              icon_emoji=':robot_face:')
    return Response(response.toxml(), mimetype="text/xml"), 200

We’re using the random.choice module to select a joke from

myList
and telling Twilio to print that joke in our Slack channel.

Save the

dadbot.py
file and try texting your Twilio number. It should print a random joke in your Slack channel.

Dadbotmakesajoke

My Dad thinks slack refers to rope and types emails in blue comic sans. It’s safe to say he’s not logging into Slack on a regular basis. Let’s open up the enjoyment of Dad jokes to him by triggering texts when you @mention dadbot in a Slack channel.

Receiving Slack Messages via SMS

In order to trigger a text when someone summons the dadbot, we need to use Slack’s outgoing webhooks. The outgoing webhook will alert our Python app through an HTTP POST Request.

CTRL+C that Flask server you’ve got up and running. We’re going to modify our dadbot.py file by adding the following highlighted bits of code.

# -*- coding: utf-8 -*-

import os
from flask import Flask, request, Response
from slackclient import SlackClient
from twilio import twiml
from twilio.rest import TwilioRestClient
 
SLACK_WEBHOOK_SECRET = os.environ.get('SLACK_WEBHOOK_SECRET', None)
TWILIO_NUMBER = os.environ.get('TWILIO_NUMBER', None)
USER_NUMBER = os.environ.get('USER_NUMBER', None)
 
app = Flask(__name__)
slack_client = SlackClient(os.environ.get('SLACK_TOKEN', None))
twilio_client = TwilioRestClient()
 
@app.route('/twilio', methods=['POST'])
def twilio_post():
    response = twiml.Response()
    if request.form['From'] == USER_NUMBER:
        message = random.choice(myList)
        print message
        slack_client.api_call("chat.postMessage", channel="#dadbot",
                              text=message, username='dadbot',
                              icon_emoji=':robot_face:')
    return Response(response.toxml(), mimetype="text/xml"), 200

@app.route('/slack', methods=['POST'])
def slack_post():
    if request.form['token'] == SLACK_WEBHOOK_SECRET:
        channel = request.form['channel_name']
        username = request.form['user_name']
        response_message = username + " in " +  channel + " says: " + random.choice(myList)
        twilio_client.messages.create(to=USER_NUMBER, from_=TWILIO_NUMBER,
                                      body=response_message)
    return Response(), 200

@app.route('/', methods=['GET'])
def test():
   return Response('It works!')
 
 
if __name__ == '__main__':
    app.run(debug=True)

Notice that random.choice(myList) addition in the response_message? We’ll be using that function again to trigger random Dad jokes via SMS.

Go to the Slack Outgoing Webhooks page then click the “outgoing webhook integration” link as shown below.
outgoingwebhooksclick

Head down to the Integration Settings section. Click “#dadbot” as the channel to listen on. Type “@dadbot” in the “Trigger Word(s)” value. Copy and paste your ngrok Forwarding URL plus “/slack” into the URL(s) text box.

generatedtoken
After you copy your Slack token, click “Save Settings”. I regenerated the token in the picture so it won’t work if you accidentally copy it. Export your Slack token as an environment variable using this command.

(dadbot)$ export SLACK_WEBHOOK_SECRET = 'generated outgoing webhook token here'

Restart your Flask server and prepare for awful jokes. We’re going to test out receiving messages from Slack via SMS. Head on over to the #dadbot channel you created. You should see the prompt that an outgoing webhook integration has been added to the channel.
outgoingwebhookadded

Try @mentioning dadbot. The message has to start with that @mention. My message to dadbot won’t work because I pre-empted it with “what’s up”. Try saying “@dadbot tell me a joke!” You should get a joke sent to your phone.
thedadjoke

Awesome! Our Dadbot lives and is telling a whole host of random, terrible jokes. Let us know what Dadjokes you equip your Dadbot with. My personal favorite is “What’s a vampire’s favorite fruit? A necktarine.” Yep. It’s awful. Don’t blame me, blame my Dad. It’s his joke. If you’ve lost your appetite for adding more jokes to your app, here are a few things you can do to expand on your Slackbot.

Happy Father’s Day everybody!

Building A Dad Joke SMS Slack Bot In Python

Bookmark this post:
Ma.gnolia DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google


June 16, 2016

FacebookTwitterGoogle+LinkedIn

(This blog originally appeared on ptpinc.com on Thursday, May 19, 2016. It has been reposted in its original version with permission from the author.)

In a recent series of radio ads that feature a bereft and primitive attempt at a telephone customer experience, Ruby Receptionist entreats us to “rediscover the lost art of human interaction.”  Have our automated voice systems and digital interfaces become too impersonal?  These ads succinctly call out the challenge faced by customer service user interfaces: “Making your customers feel special, while making you look good.”

Another popular trend is to think of customer service interactions along the lines of effort.  Matthew Dixon claims that the best path to customer loyalty should not be the often sought after goal of a special experience, but rather the more mundane, but no less critical, effortless experience.

Whether we are trying to make our customers feel special, or to reduce their effort, the emotional toll on the user seems to be front and center.  At the end of the day, a customer who is saved from excess emotional effort and strain, it would seem, is the customer who will remain loyal and happy.  But surely the multitude of best practices we have learned in the last generation of voice and digital interface design, can still be exploited to achieve this goal?

Having begun to study Emotional Intelligence (EI) (see, for example, Replacing Bad Habits and Bringing EI to PTP) and how embracing EI competencies and techniques allows one to manage emotions and relate more effectively to co-workers and clients, I, along with a few of my PTP colleagues, started to notice some interesting connections between EI principles and Voice User Interface (VUI) best practices.  Perhaps by viewing VUI design through an EI lens, we can wrap best practices in the cocoon of emotional intelligence to simultaneously eliminate friction and make the customer feel good.

The essence of EI is the ability to identify and manage your own emotions and the emotions of others. User Interface (UI) design can benefit from a similar approach.  By recognizing, understanding and managing our own emotions and thereby influencing the emotions of others, we can improve our ability to relate to clients, win sales, and garner repeat business – so why not use these same ideas to improve our IVR and digital interface systems and improve our users’ engagement and satisfaction with our UIs?

Taking this line of reasoning one logical step further, it is possible, at least roughly, to map the established best practices in UI design for digital and voice channels to the standard set of EI principles, such as the one laid out by Daniel Goleman in Working with Emotional Intelligence (see Figure 1).

Emotional_Intelligence_1
CAN A USER INTERFACE EXHIBIT EMOTIONAL INTELLIGENCE?

While there may certainly be some VUI design best practices that have little to do with EI (e.g. making questions clear and unambiguous, avoiding phonetic similarities in response options, etc.), there are many that directly correlate to and complement EI precepts.  The list of best practices is readily available to anyone searching the internet (for example Jason Brome’s Commandments of VUI DesignPaul Seibert’s VUI Design best practices, and Vicki Broman’s 10 Best Practices for Making the IVR a Desirable Destination, to name a few).   When you read these, the connection to EI jumps out at you.  So much so, in fact, that one begins to realize that most techniques we use to engage the user, not overburden the user, treat the user in as human a way as possible – and even manage the user’s emotions – draw directly from the (until now, implicit) objective of imbuing the system with Emotional Intelligence. I’ll walk you through several ways emotional intelligence informs user interface design.

EMPATHY

Examples abound. Take empathy, the grand-daddy of EI competencies.  How does a VUI express empathy for the caller?  The machine should be sensitive to the user’s answers.  It could:

  • Adjust subsequent options it offers the user based on choices and answers the user gives
  • Anticipate and address possible anger triggers, such as when a user response does not match the grammar, or when the identification number he provides is off by one digit
  • Offer to give the user extra time to answer when she might need to find a document or look something up (e.g. finding her checkbook to find a routing number)
  • Acknowledge difficult sections of the call flow and encourage the user to be patient and persevere

SELF AWARENESS

Anthropomorphically, the UI can manifest the very human attribute of self awareness by keeping menus short, keeping prompts simple and to the point, and providing easy access to an agent.

Every list of best practices emphasizes the importance of an iterative approach – tuning an application incrementally until it is optimized.  This too can be seen as the hallmark of a self-aware application: one that is constantly reflecting on its own behavior and making adjustments based on the feedback it receives.

Likewise, a good application is designed to recognize how a user wants to use the UI.  It will adapt to the user, in the same way that a good customer service representative (“CSR” or “agent”) may realize, based on a caller’s reaction, that the CSR is not meeting this particular caller’s needs.  By realizing that he is thwarting the user’s goals, the self-aware agent (or UI) changes course and assists the user in a more perspicuous manner.

Most techniques we use to engage the user, not overburden the user, treat the user in as human a way as possible – and even manage the user’s emotions – draw directly from the (until now, implicit) objective of imbuing the system with Emotional Intelligence.

AUTHENTICITY

A big part of EI is building trust with your counterpart, thereby earning credibility and respect, and establishing a bond.  A good user interface should do the same thing with the user by consistently representing the company’s brand, being an authority, and acting respectfully.

Authenticity can also be achieved by setting realistic expectations with the user – and not giving the user the impression that the system can do more than its actual capabilities will allow.  For example, open-ended questions like, “What can I do for you today?” should be avoided unless the designer has a well-defined grammar and some great back-tracking logic to support it.

Similarly, when a utility company IVR system “knows” (by querying the back end) that the caller’s area (based on caller ID) is currently experiencing a power outage, the application will gain the user’s trust, via authenticity, by informing the user upfront about the outage.

CONSEQUENCES OF A UI WITH LOW EI

Just as one might expect, the consequences of designing a user interface lacking in EI are predictably negative.  Among the undesirable impacts of an IVR with low EI are:

  • Longer calls to the IVR
  • Lower rates of successful self-service
  • Decreased containment – and more transfers to a CSR, thereby costing the company more dollars in the call center
  • Frustration, impatience, and anger, which can easily impact a customer’s attitude toward the IVR itself, not to mention the company
  • User experience suffers, due to an increase in abandons, retries, and effort – and a decrease in engagement, patience, completed transactions, and overall customer satisfaction (“CSAT”)
  • Downstream experience suffers: when the user fails to achieve her goals on the IVR, the call center will often be subject to increased handle time, escalation, and lower first call resolution

In fact, we can reasonably expect that a poor user experience with a phone user interface, due to low EI, can lead to increased distress, less patience and more frustration at whatever the next channel is that the user decides to try, be it the company website, chat, social media, contact center, in person, or even calling the same IVR again.

HIGH UI EI BENEFITS

Conversely, many benefits may be reaped from an automated user interface which espouses and masters EI.  Users are:

  • Less likely to get angry or frustrated
  • More likely to show patience
  • More likely to trust the machine and self-serve
  • More likely to experience higher CSATs

Further, users will experience a more satisfying interface, even if they do not achieve their goal.  They will feel more positive about the company and its products.  And they will be more likely to transact via self-service in the future – thereby saving the company the cost of a human interaction. Wasn’t that the whole idea in the first place?

It is worth noting that equally as important (or perhaps even more important) as designing the UI to have high EI, is for CSRs to exercise good EI while speaking to customers.  After all, even the VUI with the highest EI cannot always meet the caller’s needs via self-service.  It is paramount that agents be trained to use the very same EI techniques to calm down irate callers, address concerns, empathize and build trust.

THE EMOTIONAL STATE OF THE USER

Emotional_Intelligence_2While designing your user interface to be emotionally intelligent will go a long way to providing your users with a good UX, you would only have a partial solution without also considering the emotional state of the user.

As Goleman says, EI requires us not only to manage ourselves and our own emotions, but also to handle relationships.  The more we know, or can predict, about our counterparts, the better prepared we will be to ensure we relate to them in an effective way.

When designing a user interface, we are therefore faced with a challenging yet essential task: defining a persona, or set of personas, that captures what typical customers may be feeling before they engage with our UIs.  Some important questions we can ask to help achieve this are:

  • Is this UI typically the user’s first point of contact when they engage with our company?
  • Is this the channel of last resort?
  • Are they using our UI because they want to (for example: for fun or convenience) or out of necessity?
  • What else might the user be doing while they interact with our UI?
  • What is the typical user’s attitude toward or expectation of this UI?

Voice user interfaces have become increasingly ubiquitous in today’s modern culture.  There are a variety of VUIs that people use regularly.  We encounter hands-free GPS and phone apps in our cars.  We use Siri, Google Now, and Alexa to interact with our phones or even some household appliances.  Dictating text messages is catching on.  Meanwhile, the more traditional IVR that people phone for customer service, to check a balance, or to pay a bill, are a fact of everyday life.

When it comes to automated telephone call flows, for many people, the phone is the channel of last resort.  They have already tried to self-serve on the web, or even via chat, and now they find the only option left is to pick up a phone and talk to an agent.  Even so, most companies are unwilling to allow a customer to speak directly to a (relatively expensive) CSR, without first encouraging them to engage with an automated phone interface, where they might be able to get what they need without the dreaded transfer.  Let’s face it: not only is a transfer more expensive for the company, it is also more taxing on the user.  As callers, we would love nothing more than to complete our transaction without having to wait in a queue and explain our issues to an agent.  Undoubtedly, the psychological stakes are raised every time a user needs to engage with yet another channel of contact.

THE BEST USER EXPERIENCE

Figure 2 captures the recipe for attaining the best user experience.  We should endeavor to design our user interfaces using best practices, while at the same time taking into account the typical user’s emotional state, as well as embracing common EI principles to enhance the UI and sensitize it to the user’s condition. There is a lot more to say about this idea.  Keep an eye on our resources section for an upcoming White Paper on the same topic.  And if you happen to be attending SpeechTek 2016 this year in Washington, D.C., please stop by to see my sunrise session (8am) on May 25.  I would love to hear from you!

AUTHORED BY MIKE MENDELSON

 

Throughout my 25 years of experience in the software industry, I have combined my dual passions for technology and language to build rich customer experiences. I am dedicated to improving self-awareness and emotional intelligence in myself and others, as I believe they are the underpinnings of great teams and leaders. Currently, I am leading PTP’s adoption of Holacracy, a new, self-organizing system for management.

Learn more about PTP by visiting  https://www.ptpinc.com/

 

The post ­­­Emotional Intelligence-Driven Voice User Interface Design appeared first on SmartAction.

Bookmark this post:
Ma.gnolia DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google


Grab your phone. We’re going to try out ngrok’s new local traffic routing feature using local Twilio numbers in the US, EU, AP, and Australia.

Still got your phone in hand? Good. Welcome to Operation Keep On Ringing In The Free World. We’re going to buy four Twilio phone numbers in the four different ngrok data center territories and make them play music from local artists, piped through ngrok’s local data centers.

What You’ll Need

A Twilio Account
The latest version of ngrok.

Local Numbers, Local ngrok Data Centers, Local Music

The first place we’ll stop on Operation Keep It Ringing etc… is the US of A. Representing the US is Bruce Springsteen.

First, head to Twilio.com and buy an US phone number. Then store the song you to play to your listeners on in a directory called “Jams”. We’ll keep all our code here as well.

Fire up terminal,

cd
into the “Jams” directory and start up server in the language of your choice. I got a php server up and running with the command
php -S localhost:8888
.

Next, open a new Terminal window and fire up an ngrok server on the same port — but use the brand new routing feature.

./ngrok http -subdomain=[whatever your subdomain is] -region=us 8888

Now we have a way to get our code and our jams out to Twilio to play for the world. I’ll be playing “Born In The USA” to anyone that calls in. I saved the file as “Bruce.mp3” in the “Jams” directory. Now, just a few lines of XML and we’re ready.

I just need to tell Twilio that the to the caller should be to the Bruce track which I’ve made accessible via my ngrok localtunnel. Open up your text editor and enter the following.


  [whatever your ngrok forwarding url is]/Bruce.mp3

Let’s save this file as “US.xml” Head back to Twilio, paste your ngrok forwarding url plus the file extension in the voice request field. My forwarding url is

[whatever your subdomain is]
and the file extension of my XML code is US.xml So I’d copy
[whatever your subdomain is]/US.xml
into the voice request URL field of my number.

FileInRequestField

Hit save and you’re done! Dial it up and you’ve got a US jam that’s locally routed.
ngrok200

Hitting Other Stops On The Tour

I used the same workflow to set up some rock-powered numbers in France, Japan, and Australia. Here’s the code powering those phone lines.

Number Locality: France
Ngrok Region:  eu
Artist Chosen:  Phoenix
Song: “Lizstomania”

./ngrok http -subdomain=[whatever your ngrok forwarding url is]-region=eu 8888


  [whatever your ngrok forwarding url is]/Phoenix.mp3

Number Locality: Japan
Ngrok Region:  ap  (Asia Pacific)
Artist Chosen:  AKB48
Song:  “Sugar Rush”

./ngrok http -subdomain=[whatever your ngrok forwarding url is] -region=ap 8888


  [whatever your ngrok forwarding url is]/AKB48.mp3

Number Locality: Australia
Ngrok Region:  au
Artist Chosen:  AC/DC
Song:  “Thunderstruck”

./ngrok http -subdomain=[whatever your ngrok forwarding url is] -region=au 8888


  [whatever your ngrok forwarding url is]/ACDC.mp3

More Music Powered Hacks

That’s all there is to it! Now you’ve got less latency when you’re testing out your apps, and 100% more rock. If you need anymore music-themed Twilio ideas, try this rock-themed IVR tutorial in PHP.

Local Telephone Numbers Rocking In The Free World (Through The Ngrok Data Center Closest To You)

Bookmark this post:
Ma.gnolia DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google


June 15, 2016

Representative democracies only work if you can represent yourself. Ian Webster made it easier to do just that with one phone call. Call 1-844-USA-0234 to be immediately connected to your members of Congress.

A phone call can be a powerful tool for policy change. A call is a record of your voice, and your opinion. Every day, representatives get a brief of how many constituents (psst, that’s you) called, and which issues they called about.
 
I know this because I used Ian’s hack to call my representatives, Senator Barbara Boxer (D-CA), Senator Dianne Feinstein (D-CA), and Congresswoman Nancy Pelosi (D-CA 12) to ask them about this comment reporting policy. It took me three minutes.

Removing The Barriers

IanWebsterIan built the hack in an evening using Twilio’s Node.js library. And yes, it is open source. When you call the number, enter in your zip code and you’ll be automatically connected with your representative. You can press star at any time to be automatically forwarded to your other representatives.
 
It’s that simple; and simplicity can seem novel when you’re attempting to toss your opinion into the gears of political process. Luckily, politicians’ phones ring just like everyone else.
 

That’s part of what inspired the hack, but only part. Ian addressed why he built this in a quote that I will not paraphrase, but rather include in full.

“To be honest, it was the Orlando shootings.  It’s easy to feel helpless in the aftermath of situations like these, where something’s so absolutely broken in our country and we can’t do anything about it.

I believe in our representative democracy, and after reading about how representatives review communications from their constituents, I concluded that even a single phone call to a Congressperson can create marginal change.  It’s not much, but if I believe strongly in something, the least I can do is take action to back it up.

I created this app because even though it’s very easy to look up your senator’s phone numbers, the friction is still too high (you need to find the site, enter your information, and place 4 separate phone calls).  Instead of doing all that, I’d rather just store this number in my phone, knowing that I can reach all my senators and representatives with one tap.”

Call Any Representative Using One Phone Number

Bookmark this post:
Ma.gnolia DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google


June 14, 2016

Not all incidents are created equal. Some can wait until the next day for the IT squad to take care of. Some happen in the wee hours of the morning and require immediate attention. When you’re managing a 75 year old S&P 500 company with 22,000 employees grossing tens of millions of dollars per year, every incident counts. That’s the case for Air Products, an industry standard supplier of gasses and chemicals. An IT issue left unaddressed could cost them untold sums of money, and affect their customers.

Going From On-Premise to Cloud Hosted

Air Products has a legacy to protect, but that doesn’t mean they’re using old legacy hardware. When they needed to upgrade their telecommunications platform they had been using for 20 years, they chose Twilio.

Air Products needed a simple solution: incident management via SMS alerts. Their on premise provider couldn’t provide the flexibility they needed. Air Products wanted a hosted, cloud-based solution that could easily integrate with ServiceNow, the frontend PaaS software they use to manage SMS scheduling, logic, and escalation.

Platform changes like this don’t happen very often at Air Products. They kept their previous SMS vendor for over 20 years. Migrating the contacts and data accumulated over 75 years of business is no small task. Bruce Hendershot, Solutions Architect at Air Products, needed the telecommunications solution he chose to be easily adopted and molded to Air Products’ tried and true architecture.

Getting Critical Alerts At The Right Time

“We didn’t want to buy functionality we didn’t need,” said Hendershot. “Twilio was really straight forward. We got the numbers set up easily.” In January of 2015, Air Product implemented Twilio SMS powered incident management for their entire organization. Now, when a severe incident alert comes through their system, it gets flagged and triggers an immediate SMS alert to the right IT specialists, engineers, and stakeholders. The team members who are alerted have the option to reply via SMS to say “I got this issue, I’m working on it.” Once they reply, the incident ticket is automatically updated to reflect who’s owning the issue. The whole process happens in an instant, because there are only seconds to spare when it comes to incidents, especially at Air Products’ scale.
Hendershot and his team are relieved to finally have an SMS provider that fits their unique needs. “Being able to generate SMS, at the end of the day, wasn’t something we wanted to make a project in itself.

“[Twilio] made that piece of it no effort at all. We’ve had no issues and no complaints.”

Now Air Products can concentrate on their next 75 successful years knowing that their SMS provider can scale alongside their business.

Air Products Uses Twilio SMS To Prevent On-site Incidents

Bookmark this post:
Ma.gnolia DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google


The word is out. The SIGNAL experience is coming to London September 20th with SIGNAL London.

London is a hotspot of developer creativity and ingenuity. It’s a place where lamp posts send you texts and cars let know where they are proactively.

Check out the highlights from SIGNAL 2016 in San Francisco below.


We’re incredibly excited to kick off SIGNAL London at The Brewery. The conference will focus on empowering the developers who are building the future of communications in all sorts of different areas.

We’ll feature technical tutorials on Twilio products, in-depth talks from experts on your favorite coding language, framework, or stack of choice, and more.

The Talks (So Far)

You’ll build a friendly C3PO bot, or engineer the next doom-delivering version of Skynet in Matt Makai’s talk – Combining Slack Bots with Twilio.

Learn how ING uses Twilio on a massive scale for their thousands and thousands of customers in their customer story feature.

Build a contact center without hiring a whole team to install some archaic equipment in a phone closet. Ameer Badri and Matthias Damm will show you how to build a cloud-based, Twilio-powered contact center from the ground up.

We’ll be adding many, many more talks so stay tuned to SIGNAL London for updates. Here are the topic tracks so far. We’ll see you there!

Tracks

 

Introducing SIGNAL London

Bookmark this post:
Ma.gnolia DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google


June 13, 2016

Server-Sent Events (SSE) are real-time events sent from a server and received by a browser, perfect for updating the front end when a server receives a webhook. We’re going to look at how to use SSE to implement Authy OneTouch using Rails 4.

Our end result should look a bit like this:

When logging in the site pops up a modal window that says it is waiting for OneTouch approval. The phone receives a push notification which opens up the approval. Selecting approve then causes the login screen to complete and the user to be logged in.

Authy OneTouch

Two factor authentication usually means copying a bunch of numbers from your phone to the place you’re trying to log in. Authy OneTouch is a more user friendly version of two factor authentication. As you can see above, the user just needs to accept the authentication attempt and they are logged in.

On the back end Authy sends a webhook to the application with the result of the authentication request. The application can then log the user in and choose how it updates the front end. Check out our tutorial on how to get started with Authy OneTouch and Rails for more detail on how it all works.

Real-Time Rails 4?

You might be thinking that Rails 5 is finally bringing real-time action to the Ruby world with Action Cable. If you are then you probably missed that Rails 4 included ActionController::Live, a means of streaming data from a Rails in real-time. Connect this up to the EventSource API in browsers and we have a full implementation of Server-Sent Events that we can use to send data from the server to the browser in real-time.

The tutorial for Authy that I mentioned earlier actually implements the OneTouch flow by polling the server for updates. As polling can be inefficient and result in many unnecessary requests to our server let’s replace it with SSE.

Tools

To follow this post and implement SSE in Rails you’re going to need a few things:

Once you’ve got all that we’ll get the tutorial application set up.

Getting started

The best instructions for running the tutorial are available in the project README. Follow the instructions all the way through until the application is running locally, you have enabled OneTouch on your Authy application and set the webhook endpoint to your ngrok URL.

Once you’ve followed the instructions you should be able to visit your application at http://localhost:3000 and sign up as a new user. Logout and log back in again and you will be presented with the following two factor authentication flow.

When logging in the site pops up a modal window that says it is waiting for OneTouch approval. The phone receives a push notification which opens up the approval. Selecting approve then causes the login screen to complete and the user to be logged in.

You can see in the console that the JavaScript is constantly polling our backend to see if the user is authenticated yet.

While the application waits for the user to approve the authentication request it polls the server once every 2 seconds which we see in the logs.

Let’s replace that polling mechanism with Server-Sent Events.

Adding Server-Sent Events

In order to run real-time features like SSE (and Action Cable when Rails 5 is released) it is recommended to use a threaded server, like Puma. The project currently uses Unicorn so we need to update that.

Open up the Gemfile and change

gem 'unicorn'

to

gem 'puma'

Stop your server and install the new dependency.

$ bundle install

We also need to make one change to config/environments/development.rb. At the bottom of the configure block, add:

  config.allow_concurrency = true

This allows concurrency in the development environment so that we can run our streaming endpoint and still respond to other incoming requests.

Start the server up again and you will see it is now running on Puma and has access to a number of threads. You can configure the minimum and maximum available threads if you want to, but for the purposes of this project, the default will do.

Now when you start the server it boots Puma and records the current thread configuration.

Updating the controller

Next, we need to set up a streaming endpoint on our Rails server. Enable streaming capabilities for the existing controller by opening app/controllers/authy_controller.rb and including the ActionController::Live module.

# app/controllers/authy_controller.rb

class AuthyController < ApplicationController
  include ActionController::Live

  # the rest of the controller
end

Now let’s create a test endpoint to see how it works.

Under the one_touch_status action, create a one_touch_status_live action:

# app/controllers/authy_controller.rb

class AuthyController < ApplicationController
  def one_touch_status_live
    response.headers['Content-Type'] = 'text/event-stream'
    sse = SSE.new(response.stream, event: 'time')
    # stream stuff here
  end
end

We start by setting the Content-Type header to text/event-stream. Then we use the ActionController::Live::SSE class to wrap the response stream to make it easy to write events to.

For our test endpoint let’s loop and emit the current time once a second.

# app/controllers/authy_controller.rb

class AuthyController < ApplicationController
  def one_touch_status_live
    response.headers['Content-Type'] = 'text/event-stream'
    sse = SSE.new(response.stream, event: 'time')
    loop do
      sse.write({ :time => Time.now })
      sleep 1
    end
  end
end

When the client disconnects the action will continue to try to send data to the client resulting in a ActionController::Live::ClientDisconnected error. We should catch that and close the stream in order to keep the error from being raised and prevent connections from leaking. We’ll put this inside an ensure block to make sure that whatever happens we close the stream.

# app/controllers/authy_controller.rb

class AuthyController < ApplicationController
  def one_touch_status_live
    response.headers['Content-Type'] = 'text/event-stream'
    sse = SSE.new(response.stream, event: 'time')
    begin
      loop do
        sse.write({ :time => Time.now })
        sleep 1
      end
    rescue ClientDisconnected
    ensure
      sse.close
    end
  end
end

Let’s add a route for this endpoint. Open up config/routes.rb and add the following route:

# config/routes.rb

Rails.application.routes.draw do
  # other routes

  get "authy/status" => 'authy#one_touch_status'
  get "authy/live_status" => 'authy#one_touch_status_live'
  post "authy/send_token"

  # other routes
end

Head back to the application at http://localhost:3000, open up the dev tools console in your browser and paste in the following:

var source = new EventSource('/authy/live_status');
source.addEventListener('time', function(event) {
  console.log(event.data);
});

You will start to see JSON objects printed to the console once per second. Stop the stream by closing it in the console with:

source.close();

When you run the JavaScript in the dev tools console you see time objects printing out once per second.

Let’s update this now to push real data from the server to the front end.

Pushing real data with PostgreSQL pub-sub

In the tutorial application when a user approves or denies the authentication request, the Authy webhook hits the /authy/callback endpoint which runs the callback action in the AuthyController. This then updates the user with the status from the parameter of the webhook.

In order to push that status to the client we’d like to listen for that update whilst we have a live connection open to our streaming endpoint. Because we are using PostgreSQL in this example we can use its publish-subscribe feature. If you are using a different database without pub-sub you could achieve the same result by using something else like Redis to fill the gap.

PostgreSQL uses the keywords NOTIFY and LISTEN to publish and subscribe to events respectively. Active Record doesn’t directly support these keywords, but we can execute them using the database connection anyway.

We’ll add the notification code to the User model so open up app/models/user.rb. First, we want to send a notification when the user is saved and their authy_status has changed.

# app/models/user.rb

class User < ActiveRecord::Base
  def notify_authy_status_change
    if authy_status_changed?
      ActiveRecord::Base.connection_pool.with_connection do |connection|
        execute_query(connection, ["NOTIFY user_?, ?", id, authy_status])
      end
    end
  end
end

NOTIFY takes two arguments, a channel to notify and some text to send to that channel. We use the user id in the channel name to only send the notification to listeners subscribed to this particular user. We then send the updated status, which will come through as either “approved” or “denied”.

Because we’re using a raw connection to the database and executing SQL, I’ve actually added a couple of methods to sanitise and execute the SQL. Active Record has a santize_sql method, however it is a protected class method. I’ve made that available to instances via the clean_sql method. The private method execute_query handles sanitising and executing the SQL to reduce repetition.

# app/models/user.rb

class User < ActiveRecord::Base
  def self.clean_sql(query)
    sanitize_sql(query)
  end

  private

  def execute_query(connection, query)
    sql = self.class.clean_sql(query)
    connection.execute(sql)
  end
end

We can run the notification method every time the user model is saved using an Active Record callback.

# app/models/user.rb

class User < ActiveRecord::Base
  after_save :notify_authy_status_change
end

Now we need a method to subscribe to the user channel and listen for these notifications.

# app/models/user.rb

class User < ActiveRecord::Base
  def on_authy_status_change
    ActiveRecord::Base.connection_pool.with_connection do |connection|
      begin
        execute_query(connection, ["LISTEN user_?", id])
        connection.raw_connection.wait_for_notify do |event, pid, status|
          yield status
        end
      ensure
        execute_query(connection, ["UNLISTEN user_?", id])
      end
    end
  end
end

In this case, LISTEN only takes one argument, the channel name. We execute the SQL and then wait for the notification to arrive. When it does we yield the status. You’ll see how this works in the updated controller action below. We also ensure that we stop listening for the notification once it has arrived. Let’s see what the updated AuthyController looks like now:

# app/controllers/authy_controller.rb

class AuthyController < ApplicationController
  def one_touch_status_live
    response.headers['Content-Type'] = 'text/event-stream'
    @user = User.find(session[:pre_2fa_auth_user_id])
    sse = SSE.new(response.stream, event: "authy_status")
    begin
      @user.on_authy_status_change do |status|
        if status == "approved"
          session[:user_id] = @user.id
          session[:pre_2fa_auth_user_id] = nil
        end
        sse.write({status: status})
      end
    rescue ClientDisconnected
    ensure
      sse.close
    end
  end
end

This time, we select the user using the temporary session store of their ID. We then subscribe to changes to their authy_status and when we receive a change, push it to the front end. If the status is “approved” we also log the user in finally. As you can see here, we use a block with on_authy_status_change and when the status is yielded in the user method, it is passed into the block.

All we need to do now is update our JavaScript to stop polling and start listening for updates.

Updating the JavaScript

Open up app/assets/javascripts/sessions.js and replace the code within the checkForOneTouch function with the following:

// app/assets/javascripts/sessions.js

  var checkForOneTouch = function() {
    var source = new EventSource("/authy/live_status")
    source.addEventListener("authy_status", function(event) {
      var data = JSON.parse(event.data);
      if (data.status === "approved") {
        source.close();
        window.location.href = "/account";
      } else if (data.status === "denied") {
        showTokenForm();
        triggerSMSToken();
      }
    })
  };

We’re listening to our SSE for the “authy_status” event. When it arrives we parse the JSON and if the event is approved we close the stream and redirect the user to their account page. Otherwise we use the existing behaviour, show the token form and trigger an SMS.

Restart the server and go through the login process again (make sure ngrok is still running otherwise you won’t get your webhook).

We run the same authentication flow as before, however this time we see that there are no polling events in the log. We have successfully implemented Server-Sent Events.

Hooray! Real-time updates to the front end, no polling required. Check out my fork of the original tutorial to see the complete changes.

Rails 4 does Real-Time

Rails 5 and Action Cable might not be released just yet, but Rails 4 can still perform some pretty sweet real-time manoeuvres. This works really well for server based updates as we’ve seen with Authy OneTouch. It would also work for live updating call statuses on a dashboard like Sam showed using Socket.io and React or creating a dashboard for conference events like Dominik did using Socket.io and Angular.

Server-Sent Events just provide one-way real-time events though. Action Cable will bring two-way real-time streams to Rails for more complicated interactions, like a chat room. Of course, you don’t have to build all that complexity yourself if you use IP Messaging ;)

Do you like the look of SSE in Rails or are you going to be holding out for Action Cable? Let me know in the comments below, give me a shout on Twitter at @philnash or drop me an email at philnash@twilio.com.

Real Time Rails 4: Using Server-Sent Events with Authy OneTouch

Bookmark this post:
Ma.gnolia DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google


Swedish communications technology and services company Ericsson is working with the BBC to improve live captioning for TV programming by reducing the delay between the live audio and the appearance of the transcribed text on the screen. Other partners in this effort include European IT services firm Atos and England’s own Screen Subtitling Systems. Together, the four companies are looking […]

Bookmark this post:
Ma.gnolia DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google


Last updated: June 26, 2016 08:01 PM All times are UTC.
Powered by: Planet

Speech Connection and Logos are Trademark of Nu Echo Inc. Copyright 2006-2008.