August 26, 2015

When customers expand internationally, we often hear the question “How do I avoid routes that may be much more expensive than the ones I’ve used in the past?” The reality is that not all messages cost the same amount to send, and sometimes businesses prefer not to send or receive messages when the cost surpasses a certain price.

To address this, we’ve added a new feature that will allow Twilio SMS users to better control high costs by setting a maximum price for messages. This added cost control will help you avoid high or unpredictable costs that can surface when sending messages in new areas.

How it Works

This new feature enables you to set a maximum price to apply to all messages. Once you set that limit, we will not send messages that exceed your set price.

When parameter

MaxPrice
is used, Twilio will check the price of the message against the amount set in this parameter. (
MaxPrice
is the total price of the message —the price of longer messages that consist of several segments would be compared against this price).  

If the limit you set is less than the cost of the message Twilio will return a

Failed
status for the message in the
StatusCallback
. The initial response will still be 200 with a status of
Queued
; however, after the price has been calculated the message will return as
Failed
(Error Code 30010) as part of the status callback if the price exceeds your limit.

For outbound messages, the final price of the message is returned as a POST to the Status Callback URL. This POST request is made as soon as the price is available and may be a separate webhook from

Status
parameter updates.

For inbound messages, Twilio will POST the

MessageSid
and the price when available to the inbound request URL. This will be a separate webhook and will occur after the message has been received.

Get Started

Adding MaxPrice is straightforward. Here’s an example of a price set at $0.50:

-XPOSThttps://api.twilio.com/2010-04-01/Accounts/{AccountSid}/Messages.json \
   -d "Body=Jenny%20please%3F%21%20I%20love%20you%203" \
   -d "To=%2B15558675309" \
   -d "From=%2B14158141829" \
   -d "MaxPrice =  0.50"
   -d "MediaUrl=http://www.example.com/hearts.png" \

Control Your Messaging Costs by Setting a Maximum Price

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


August 25, 2015

It seems like everyone has an app. But, not everyone has a plan to get their users invested in it. In a flooded app market, you need a way to stand out. Appboy gives the developers and marketers the tools they need to rise above the tide.

Major brands like Urban Outfitters, PicsArt and EPIX turn to Appboy for a systematic way to grow, manage, and keep users on their apps. Using Appboy’s intelligent CRM, they can send email, in-app and push notifications, and now Twilio-powered SMS to their users.

Appboy is happy to announce a new webhooks feature that gives mobile marketers more control of the way they reach out to their users, and more ways to do it.

“We’re excited to launch our webhooks feature because it will provide clients with a variety of new ways to easily link technologies together to connect their marketing campaigns in real-time with other services and applications, like Twitter, Marketo and SMS through Twilio,” says Marissa Aydlett, Vice President, Marketing at Appboy.

Appboy specializes in offering highly curated ways to engage with customers in segments across a variety of channels. Some customers might prefer you contact them via email, others might prefer an in-app notification. Finding the right medium is critical to user growth and retention, which is why Appboy is adding more flexibility to their platform with the webhooks feature.

Take for example, an Appboy customer, Urban Outfitters. Their app is a major lever for their online sales and customer loyalty program. Keeping users engaged on the app is critical to the company’s success. But to be successful you have to make careful marketing decisions.

“It’s extremely sensitive,” Urban Outfitters Senior Marketing Manager Moira Gregonis told Bloomberg. “I don’t think anyone really likes to be marketed to, and as a brand, we don’t want to be pushy.”

Appboy is happy to offer webhooks as a brand new channel customers can use to communicate with app users in a tailored way, whether that be Twilio SMS, push notification, or in app messaging.

Learn more about Appboy’s webhooks feature and how to leverage Twilio here.

Appboy Gives Mobile Marketers A New Way To Reach Users via SMS with New Webhooks Feature

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


August 24, 2015

Last week I upgraded my ride from a 14-year-old Honda Civic with 90,000 miles to a newer Honda Accord with all the latest bells and whistles. Voice recognition is among them, allowing me to control my phone, but also some in-car systems, such as the radio and the temperature settings, by voice. All I need […]

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


August 21, 2015

Most of us don’t think to question whether or not the pictures or emojis in our text message will get through to the person on the other end. Nor do we pause to break up a long message into several parts in order to ensure messages go through in the correct order. Rather, we expect exactly what seems like the obvious: that our message will be received exactly as it was sent regardless of what is sent.

But, these expectations can actually be very challenging for a developer to address in their SMS applications. The reality is that SMS delivery, even when it comes to sending messages over 160 characters, is not as simple as it seems. Basic consumer demands can require a good deal of code for developers to solve.

We’re going to take you behind the scenes of messaging in a 3-part series to take a look at some of the things that can throw a wrench in an SMS, and how to solve them in your application. In this part, we’ll focus on how inbound concatenation plays a key role when you receive long messages.

The Wrench: Receiving Out of Order Messages

When someone sends a long text message (over 160 characters), they might assume the message will be sent (and received) as a unit. This is a common misconception.

In reality, the longer message will actually need to be split into multiple fragments before it’s sent. What this fragmenting means is that the message is at risk of being received out of order. For example, if the last “fragment” is much smaller than the first two, it may get to the end user first since the shorter message is sent the fastest.  The end result? Unless something is built into an application to reassemble messages received, end users may see out of order messages.

The Solution: Auto-assembly with Twilio Inbound Concatenation

Concatenation offers developers a solution to reassemble messages that are broken up into parts. One way an inbound concatenation feature can work is to offer developers UDH (User Data Headers, or ordered labels for messages) so that the developer can use those headers (eg, 1, 2, 3, 4) to build a reassembly solution. In this scenario, developers need to use code to successfully grab the right message when it arrives and put it in the right order before the recipient gets it.

With Twilio, inbound concatenation means something a bit different. It can be a burden to developers who build out UDH logic, and can take up valuable time they could spend building out an SMS application. We know time and development cycles are precious, so we take care of the reassembly for you without requiring you to use UDH.

On the backend, we automatically identify the order in which the messages were received, and systematically reorder them on your behalf. Check out the examples below (courtesy of Lewis Carroll’s The Jabberwocky) to get a better idea of how this kind of concatenation impacts delivery:

Concat

Twilio Inbound Concatenation with Auto-Assembly

NumSegments:
4

SmsStatus:
received

Body: ‘Twas brillig, and the slithy toves Did gyre and gimble in the wabe: All mimsy were the borogoves, And the mome raths outgrabe. “Beware the Jabberwock, my son! The jaws that bite, the claws that catch! Beware the Jubjub bird, and shun The frumious Bandersnatch!” He took his vorpal sword in hand; Long time the manxome foe he sought So rested he by the Tumtum tree And stood awhile in thought. And, as in uffish thought he stood, The Jabberwock, with eyes of flame, Came whiffling through the tulgey wood, And burbled as it came! One, two! One, two!

vs.

Standard Concatenation with UDH

NumSegments:
4

SmsStatus:
received

1: ‘Twas brillig, and the slithy toves Did gyre and gimble in the wabe: All mimsy were the borogoves, And the mome raths outgrabe. “Beware the Jabberwock,

4: s of flame, Came whiffling through the tulgey wood, And burbled as it came! One, two! One, two!

2: my son! The jaws that bite, the claws that catch! Beware the Jubjub bird, and shun The frumious Bandersnatch!” He took his vorpal sword in hand; Long t


3: ime the manxome foe he sought So rested he by the Tumtum tree And stood awhile in thought. And, as in uffish thought he stood, The Jabberwock, with eye

You can see that when this long message is sent without Twilio concatenation, it is jumbled out of order. The 4th message sends faster than the second and third. Twilio concatenation, at the top, solves fragmented sending by reassembling the message automatically so that developers don’t need to use additional code.
To read more about how to to send and receive an SMS on Twilio with concatenation, check out our how to doc here. See you next week for a second peek at common behind the scenes monkey wrenches with SMS, and how you can use Twilio features to solve them.
,

Common SMS Problems and How to Solve Them, Part 1

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


API.ai, a Palo Alto, Calif., a startup that provides a developer platform for adding artificial intelligence and natural language speech interfaces to Web and mobile apps and devices, this week closed a $3 million funding round. And while the amount of money involved might not seem significant, where it is coming from could be. The […]

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


When it comes to front-end JavaScript frameworks we have a lot of choices as developers. One of my favorites Ember.js just released version 2.0 making this the perfect time to get started using it. Ember is used by many great companies with the most notable application being Apple Music. In this post we’ll get our Ember development environment set up and build a small sample application.

What is Ember?

Ember is described by its creators as a framework for creating ambitious web applications. The core team focuses on identifying common patterns that emerge in the web development world and rolls them into a complete front-end stack. Many JavaScript frameworks start by simply providing a solution to the V in MVC but the Ember team aims to provide a complete solution to building client-side JavaScript applications that encompasses data management and application flow as well as the view layer. The development process is driven by a command-line utility called Ember CLI that incorporates common Ember patterns into the entire app development process from project creation to development time and ultimately to app distribution. The end result is a framework that focuses heavily on developer productivity. It is an opinionated framework and it is best to go with the flow and enjoy the productivity provided by these opinions.

What’s New in Ember 2.0?

The Ember team uses a semantic versioning scheme so technically nothing is “new” in Ember 2.0. All of the changes in Ember 2.0 are present in the previous 1.13.x releases. Along the “Road to Ember 2.0” many changes were made to deprecate 1.x functionality as new patterns were built. As long as these deprecations were fixed by the developer at each release their app will function perfectly now on 2.0. Here are some of the big things that were part of the 2.0 release process:

Ember CLI – The command-line interface for creating Ember apps is now a core part of the platform. Here are some of Ember CLI’s features:

  • Fast asset pipeline powered by Broccoli
  • Live reloading development server
  • Generators that help in the application process by creating the project structure according to Ember best practices

Shift to Components – Ember 1.x was built around a model-view-controller (MVC) pattern  but in the 2.0 Ember started a transition away from Views and Controllers to Components. This trend will continue throughout the 2.x release cycles until  Routable Components fully replace them.

New rendering engine –  Glimmer rendering engine vastly increases rendering speed through the use of a virtual DOM

ES6 modules at the core – The Ember team is always looking to bring new standards into the codebase and ES6 modules are one of the latest to be added to the project

Simplification of many Ember concepts:

  • New attribute binding syntax using the new template engine HTMLBars which is a superset of the templating engine from 1.x Handlebars
  • HTML syntax (angle brackets) for Components
  • More consistent scoping
  • much more…

Installing Ember

We’ll use Node.js and npm to install the tools we need for Ember development so make sure you have them installed. Ember requires Git to manage many of its dependencies so you’ll also need to make sure you have it installed and configured. If you are on a Mac or Linux system you’ll also want to install Watchman because it greatly improves file watching performance. With these prerequisites in place let’s install Ember CLI. Open up your terminal application of choice and fire off this command:

npm install -g ember-cli

Next we’ll install PhantomJS to enable running tests from the command-line:

npm install -g phantomjs2

Verify that everything was installed correctly by running the following command:

ember -v

ember -v

As of the writing of this blog post this should return 1.13.8. Ember CLI was supposed to ship 2.0 at the same time as Ember.js but is lagging slightly behind for this release. We will work around the version differences as we build our application.

Creating Our First Ember App

Let’s use Ember CLI to create our first application. Run the following command to create a new Ember project in a folder named hello-ember:

ember new hello-ember

hello Ember

As you can see, Ember CLI creates a lot of files for us. Change directories into hello-ember since we’ll be running commands here later and open this directory in your favorite text editor. You should see the following project structure:

emberstructure

The app folder contains the source files for our application and is where we will focus most of our attention in this post.

We do have to make one important change to a file outside of that directory first. As mentioned above, Ember CLI has not yet reached 2.0. This means the versions of Ember that are specified in the application created by Ember CLI are also not 2.0. Let’s fix that in bower.json. Make these highlighted changes:

{
  "name": "hello-ember",
  "dependencies": {
    "ember": "^2.0.0",
    "ember-cli-shims": "ember-cli/ember-cli-shims#0.0.3",
    "ember-cli-test-loader": "ember-cli-test-loader#0.1.3",
    "ember-data": "^2.0.0",
    …
}

Back in the terminal, run bower install to install the correct Ember and Ember Data versions for 2.0 development. Bower might prompt you for a version resolution for Ember. Select the 2.0 version from the list provided and prefix it with an exclamation point to persist the resolution to bower.json.

bower ember

Now that our project and its dependencies are set up let’s run the project using Ember CLI’s development server:

ember server

Load up http://localhost:4200 in your browser and you should see a header that says “Welcome to Ember”. Let’s see where that welcome message is coming from and update it to see Ember CLI’s live reload in action. Open app/templates/application.hbs. You should see this:

<h3 id="title">Welcome to Ember</h3>

{{outlet}}

This is the template that represents the markup that wraps the body of our application. No matter what parts of the app we visit this markup will render. Modify the header tag to say “Hello Ember” and save the file. Take a look in your browser to see the change reflected after the short Ember build process. This feature is great for productivity.

One of Ember’s core tenets is that the URL in the browser represents the state of the application. This is accomplished using a router. Currently we are at the root of the application and the route that is used to render content at the root is the index route. If we don’t specify one Ember will create an empty index route in memory filling the outlet above with nothing. Let’s use Ember CLI to define an index route that will be used to set up a model and template for the root of our application instead of the default:

ember generate route index

Running this command generates the following files:

  • app/routes/index.js – The file containing the code that Ember will run when this specific route is loaded.
  • app/templates/index.hbs The template for the index route. This will render into the {{outlet}} we saw in the application.hbs template
  • tests/unit/routes/index-test.js – The test file for the index route.

Routes are responsible for setting up any data Ember will use when rendering the template for the route. Ember uses model objects (the M in MVC) to represent data for the route. This is accomplished with what is called a model hook. Open app/routes/index.js and modify its contents to include a model function that returns an array of colors:

import Ember from 'ember';

export default Ember.Route.extend({
  model() {
    return ['red', 'green', 'blue'];
  }
});

When the route renders the index template we’ll have access to this model. We’ll create an unordered list of colors using the {{#each}} Handlebars helper. Open up /app/templates/index.hbs and replace the contents with this markup:

<ul>
  {{#each model as |color|}}
    <li>{{color}}</li>
  {{/each}}
</ul>

The helper loops through the model array and renders an <li> tag for each string. In the <li> we use HTMLBars binding syntax to show the color by putting the color inside of curly brackets. Save the file and your browser should automatically update to show the colors below the “Hello Ember” header because we’re at the root of the application where the index template renders. Try adding a color or changing the existing colors in app/routes/index.js and save the file to see them change in the browser.

Let’s try creating one more route to see how non-index routes are set up and how to link to different routes. In the terminal let’s generate a users route:

ember generate route users

Now take a look at app/router.js. Pay close attention to the router map:

Router.map(function() {
  this.route('users');
});

The highlighted line was added to this file when we generated the route. A similar line was not added for the index route because it does not need to be explicitly declared. Let’s set up the model hook for app/routes/users.js to return an array of JSON objects representing users:

import Ember from 'ember';

export default Ember.Route.extend({
  model() {
    return [{
      name: "Brent Schooley",
      twitter: "@brentschooley"
    }, {
      name: "Sam Agnew",
      twitter: "@sagnewshreds"
    }, {
      name: "Eddie Zaneski",
      twitter: "@eddiezane" 
    }];
  }
});

Each object in the model contains a user’s name and their Twitter handle. Let’s modify the app/templates/users.hbs template to render a list to show our list of users and link to their Twitter pages:

<ul>
  {{#each model as |user|}}
    <li>{{user.name}}: <a href="http://twitter.com/{{user.twitter}}">{{user.twitter}}</a></li>
  {{/each}}
</ul>

Again, we use the {{#each}} helper to loop through the model array. The difference this time is that we have objects instead of just strings so the binding statements reference properties available on these objects. Save the file and visit http://localhost:4200/users in your browser to see the results.

We now have two routes defined so let’s link them together. Update app/templates/index.hbs to use the {{#link-to}} helper to link to the users route:

<ul>
  {{#each model as |color|}}
    <li>{{color}}</li>
  {{/each}}
</ul>

{{#link-to 'users'}}Go to Users{{/link-to}}

The parameter to the {{#link-to}} helper specifies the route to generate a link for and the text inside of it is what will be displayed for the link. Save the file and click on the link to head over to the users route. Now let’s update the users template to link us back to the index route:

<ul>
  {{#each model as |user|}}
    <li>{{user.name}}: <a href="http://twitter.com/{{user.twitter}}">{{user.twitter}}</a></li>
  {{/each}}
</ul>

{{#link-to 'index'}}Go to index{{/link-to}}

Head back into the browser and test that the links. You should be able to go back and forth between the two routes now.

What’s Next?

We just build an application that covers the basics of Ember.js development. We set up a few routes, configured their models and then updated the route templates to show the model and link to each other. Now that you have the basics of Ember.js under your belt you can start building amazing things with it. Here are some things you can try on your own:

  • Load model data from an external source using Ember Data
  • Install some addons using Ember CLI
  • Build some Components to replace the loose templates in the application

I’m super excited to see what you build with Ember 2.0 so find me on Twitter @brentschooley to show it off!

Getting Started With Ember.js 2.0 Using Ember CLI

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


August 20, 2015

When handling phone calls with TwiML, you have many options for controlling the caller’s experience. You can <Say> something in a robot voice, <Dial> other numbers into the call and even <Record> the call. My personal favorite is the ability to play audio files over the phone using the <Play> TwiML verb. You can even create your own version of Dial-A-Song, a hotline run by the band They Might Be Giants that allows you to listen to their music if you call the number (844) 387-6962.

Today I’m going to show you how to make and receive phone calls using the Node.js Twilio library. We will also be using some ES6 features to “spice things up a notch.” What better way to show what we can do with Twilio voice than to allow the callers to rock out over the phone?

Here is our code in full on GitHub  if you want to skip straight to having a working app.

Gearing up

We are going to need to grab some gear and tune up first. For starters, you’ll need to have have Node.js and NPM installed. You will also need to create a Twilio account and purchase a phone number with Voice capabilities.

Now let’s initialize a new app. Open your terminal, navigate to the directory you want to start this project in and run:

npm init

This will generate a package.json file that will contain all of the information about our project. Feel free to breeze through the prompts if you are not interested in customizing the default options.

After you have that taken care of we can install our dependencies.

We will need the Twilio Node module so let’s grab that:

npm install twilio --save

When our phone number receives a call, Twilio will make an HTTP request to the URL that we provide. We will have to create a web app to handle these incoming calls. Let’s use the Express web framework to do this:

npm install express --save

We will also need to install Babel in order to run our ES6 code. Babel is a compiler for JavaScript that can turn your ES6 code into regular ES5 JavaScript that will run everywhere.

Installing Babel globally will allow you to use the babel-node command line tool which can directly run your ES6 code. You may need to use sudo to run this command:

npm install --global babel

Now that we have all of our dependencies installed we still need one important thing: a song to play over the phone. I was having trouble figuring out which tune would be appropriate until I realized there exists a song that goes with everything.

For those of you who don’t know, this is the infamous Guile’s Theme from Street Fighter 2. Luckily for us there exists even better versions of this tune provided by the wonderfully talented community of musicians at OverClocked ReMix. A band called Shinray did a metal remix of Guile’s Theme that manages to surpass the original in terms of epicness. This is freely hosted online making it a perfect candidate for our phone call’s soundtrack.

Try calling (347) 826-3536 to hear “Guile’s Theme Goes with Metal” over the phone for a sneak peek at what we are building.

Generating some TwiML

Now we are ready to build our application. The first step is to create a web app that will respond to incoming HTTP requests with TwiML – a set of XML tags that will tell Twilio what to do when you receive an incoming call. This web app will generate TwiML instructions to play the mp3 file of the Guile’s Theme remix that we are using.

Let’s start working on our Express app to take care of this. You may not be familiar with some of the new features of ES6 so let’s walk through the code that our app will contain step by step. Fire up your text editor and create a file called “index.js” where we will write our app.

First we need to import the modules we will be using. You may be used to something like

var express = require('express');

but we can use new ES6 import statements instead:

import express from 'express';
import twilio from 'twilio';

Next we need to create an app object and add a route to it that will accept HTTP requests from Twilio.

// Account SID and auth token are stored in environment variables.
let app = express();

app.post('/voice', (req, res) => {});

Notice that we used the new arrow syntax in the anonymous function that we passed to app.post() rather than using the traditional function keyword. Arrow functions lexically bind the outside scope’s this variable to the function that you’re writing.

Now let’s fill out the function that we are giving to app.post:

app.post('/voice', (req, res) => {

  // Set the url of the song we are going to play
  let songUrl = 'http://ocrmirror.org/files/music/remixes/Street_Fighter_2_Guile%27s_Theme_Goes_with_Metal_OC_ReMix.mp3'

  // Generate a TwiML response
  let twiml = new twilio.TwimlResponse();

  // Play Guile's theme over the phone.
  twiml.play(songUrl);

  // Set the response type as XML.
  res.header('Content-Type', 'text/xml');

  // Send the TwiML as the response.
  res.send(twiml.toString());
});

Here we are using the let keyword to declare our variables. It allows us to use block scoping instead of JavaScript’s traditional functional scoping with the var keyword. This allows us to avoid adding variables to the function scope that are only relevant to a particular block.

All we have left to do is to declare the port our server will listen on:

// Make our Express server listen on port 3000.
app.listen(3000, () => console.log('Listening at http://localhost:3000'));

We are using another anonymous arrow function, but this time it will be a one liner withno arguments. It may look strange at first, but this syntax allows us to keep things concise.

Here is the entire code for our Express server in case you missed anything:

import express from 'express';
import twilio from 'twilio';

// Account SID and auth token are stored in environment variables.
let app = express();

app.post('/voice', (req, res) => {

  // Set the url of the song we are going to play
  let songUrl = 'http://ocrmirror.org/files/music/remixes/Street_Fighter_2_Guile%27s_Theme_Goes_with_Metal_OC_ReMix.mp3'

  // Generate a TwiML response
  let twiml = new twilio.TwimlResponse();

  // Play Guile's theme over the phone.
  twiml.play(songUrl);

  // Set the response type as XML.
  res.header('Content-Type', 'text/xml');

  // Send the TwiML as the response.
  res.send(twiml.toString());

});

// Make our Express server listen on port 3000.
app.listen(3000, () => console.log('Listening at http://localhost:3000'));

Now let’s run our server:

babel-node index.js

Open up a new terminal window and try hitting it with curl to make sure everything is working and we receive XML as a response:

curl -X POST http://localhost:3000/voice

Our response should look like this:

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Play>http://ocrmirror.org/files/music/remixes/Street_Fighter_2_Guile's_Theme_Goes_with_Metal_OC_ReMix.mp3</Play>
</Response>

In order for Twilio to see our application and for us to be able to receive phone calls, we need to expose our server to the Internet. We can do this using ngrok. If you want to learn how to set up ngrok, you can follow my buddy Kevin’s tutorial.

Once you have that taken care of, have ngrok listen on port 3000:

ngrok http 3000

You should see a screen that looks like this with a generated link that we can visit to access our Express app.

We need to add this URL to our Twilio phone number in the account phone numbers dashboard so Twilio knows to send us an HTTP request when a call is received.

phonenumberpage

It’s time to win round one of our battle. Whip out your phone and give your Twilio number a dial to have quite possibly the most epic phone call of your life.

Initiating phone calls with NodeJS

Being able to call a phone number to hear a rockin’ version of Guile’s theme is a ton of fun. But we can also start the call ourselves with a little bit of code. This involves using the Twilio REST API.

We are going to write another quick Node script that will send a phone call to a number of your choice using the TwiML we generated earlier to play the same song.

Create a file called “makeCall.js” in your text editor and add this code:

import twilio from 'twilio';
let twilioClient = twilio();

twilioClient.makeCall({
  to: 'the_number_you_are_calling',
  from: 'your_twilio_phone_number',
  url: 'your_ngrok_url'
});

Don’t forget to replace the variables with their appropriate values (a phone number to call for testing, your Twilio number, and the URL to the TwiML that your Express app is generating).

This is all the code we need to make phone calls, but we still need to authenticate with Twilio. Head over to your Twilio account dashboard and grab your Account SID and Auth Token. Store them in environment variables like so:

export TWILIO_ACCOUNT_SID='your_account_sid_here'
export TWILIO_AUTH_TOKEN='your_auth_token_here'

No need to add these to your code, because upon initialization of the REST client object, the Twilio Node module checks to see if these environment variables exist.

You should now be able to make a phone call by entering the following in your terminal:

babel-node makeCall.js

Now listen in amazement as you once again experience the epicness of Guile’s Theme, this time initiated by your code.

You Win

You’ve won round 2 by implementing an app that can make and receive phone calls using the Twilio Node.js module, and even got it running with newer ES6 features. You are now ready to change your app to play different music files or utilize some of the other TwiML verbs that you haven’t messed around with yet. I am excited for you to move on to the next round, and look forward to seeing what you build with Twilio Voice.

Feel free to reach out if you have any more questions or want to show off your hacks.

Email: sagnew@twilio.com
Twitter: @Sagnewshreds
Github: Sagnew

Playing Jammin’ Tunes Over The Phone with the Twilio NodeJS Library in ES6

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


EuropeLiteracy is defined as “using printed and written information to function in society, to achieve one’s goals, and to develop one’s knowledge and potential.

Illiteracy, the opposite of literacy, in the strict sense, is defined as the inability to read and write simple sentences in any language. There is also a third category, filtering out the grey area between the stark black and white of literacy and illiteracy: functional illiteracy. Functional illiteracy is defined as reading and writing skills in any language that are insufficient to manage daily living and employment tasks that require reading skills beyond a basic level.

For 1 in 5 Europeans, the world is hard to read.

This literacy crisis affects every country in Europe, despite the fact that living in the digital age requires higher levels of literacy than ever before. Far too often, decision- and policy-makers take their own literacy abilities for granted, and assume that everyone else has the same abilities to read, write, process information, and critically evaluate said information.

Literacy is an issue in all countries in Europe, not a problem of developing nations. Literacy is not a problem solely attributed migrants: the majority of those with literacy problems in the European Union were born and raised in the country that they live in. For an in-depth article on functional illiteracy in France, please see our previous article from 2010.

The European Union recommends addressing literacy at all ages:

Young Children

  • Support the family: implement family literacy programmes.
  • Provide free access to Early Childhood Education and Care (ECEC).
  • Screen early for emerging literacy problems as a result of hearing, eyesight, and speech impairments.

Basic Education Years

  • Increase the number of specialist reading teachers.
  • Assess literacy achievement early, and assist if necessary.
  • Inspire the motivation to read by ensuring that curricula and teaching methods focus on reading.

Adolescents

  • Adapt teaching approaches so that reading and writing are essential skills across the curriculum.
  • Provide diverse reading materials to motivate all readers.
  • Promote cooperation between schools and businesses, so students see the necessity of literacy skills for employment.

Adults

  • Monitor adult literacy levels and practices to identify groups in need of attention.
  • Communicate widely about the need for adult literacy.
  • Provide a variety of learning opportunities that relate to life skills.

[Source: EU High Level Group of Experts on Literacy, Excecutive Summary]

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


August 19, 2015

Meet Rovie. Rovie is our underwater robotic friend here at Twilio:

Rovie and Brent. Rovie is the one on the left.

Over the past couple months myself and fellow Developer Evangelist Brent Schooley have been teaching Rovie to swim and send underwater pictures whenever she gets a text message.  Last week at That Conference we took Rovie to her first party and he enjoyed swimming in the beautiful pool at the Kalahari Resort with 500 of her closest friends.

Building Rovie

Rovie is an OpenROV – an open-source, low-cost underwater robot for exploration and education. One of my favorite things about working with an OpenROV is that the cockpit software is a Node.js application. When we wanted to modify Rovie to receive text messages we immediately opened up the cockpit application and started poking around.

Rovie’s cockpit application uses Express which made it really easy for us to add a new route that Twilio would be able to send a request to whenever an incoming message arrives at Rovie’s phone number::

app.post('/sms', function( req, res ) {
  var twilio = require('twilio');
  var resp = new twilio.TwimlResponse();

  camera.snapshot( function( filename ) {
    resp.message(function() {
      this.body('Greetings from the Kalahari Pool! Here's a picture. Check out: http://twilio.com')
        .media('http://our-openrov-ngrok-url.ngrok.com/photos/' + filename);
    });

    res.send(resp.toString());
  });
});

Here we tell Rovie to snap a picture and then respond with some TwiML that sends the picture back to whoever texted in.

Before we could run this code we needed to make this route publicly available using one of my favorite tools – ngrok. You may know ngrok as a super rad command line script that you run to open up your localhost to the outside world. But there’s also a Node.js module for ngrok that lets us open up a new ngrok tunnel directly from within our application:

var ngrok = require('ngrok');

ngrok.connect({
    authtoken: '%ngrok-key%',
    subdomain: '%our-openrov-ngrok-url%',
    port: 8080
}, function (err, url) {
    console.log( err );
});

That’s all the code we needed. Here are a couple pictures from Rovie’s big swim courtesy of the That Conference flickr album:

rovie-mms

What’s Your Summer Hack?

It’s been hot in New York City and hacking on an underwater robot has been the perfect way to cool off. Are you working on any great summer hacks? We’d love to see them! Find us on Twitter (@rickyrobinett and @brentschooley) or say “hi” in the comments.

20,000 Text Messages Under the Sea with OpenROV, Node.js and Twilio

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


Calling into customer support or similar support lines can lead to some not so great experiences. Often times I find myself being tossed back and forth between different agents with no context of who I am talking to and when I am being transferred. These kinds of calls feel a lot like this:
A better way for agents to handle incoming callers is to use a warm transfer. The term “warm transfer” can mean different things to different people. For this blog post we are going to use this scenario to explain a warm transfer: Agent A (Artemis) is speaking to the caller. Artemis needs to transfer the caller to Agent B (Barnabas). Artemis conferences in Barnabas, introduces the caller to Barnabas and then releases the call.

In this blog post we will setup a very simple call center that supports warm transfers using Twilio’s Java helper library and an Apache Tomcat server.

If you are only interested in the finished product, all of the code used in this post can be found on Github here.

“Charlie Work”

The first step to building our call center is to set up our environment. Since we are using Tomcat to implement our web server you can follow the Twilio Quickstart to get started with Tomcat and the Twilio SDK. Take your time and make sure your environment is setup properly before continuing on with this post. If you’ve never used Maven, I suggest following Option 2 in the quickstart and downloading the .jar file directly.

Your file structure should look something like this if you followed along with the quickstart:

Directory Structure

Once we have Tomcat running properly, we can test that our servlets are running locally. Open a terminal, navigate to the top of your project directory and run the following:

$ sh bin/startup.sh

You might run into an issue saying

Cannot find ./bin/catalina.sh
. We can easily fix this by running the following in our terminal (source):

$ chmod +x bin/*.sh
$ chmod +x bin/*.jar

Once our server has started, navigate to localhost:8080 in a web browser and we should see the Apache Tomcat landing page:

Our server is working locally, but we will need to be able to access it publicly so that Twilio can reach it. We can use ngrok to do this. Ngrok is a command line tool that can create a public tunnel to access your localhost. If you’ve never used ngrok before consider reading this blog post by Kevin Whinnery to get familiar with it. Once you have ngrok installed, run 

$ ngrok http 8080
 in a terminal and navigate to the URL it gives you (see image below) in a browser.

We should see the same landing page as we did at localhost:8080, meaning our server is now publicly accessible. Before moving on, consider a pair of kitten mittens to keep Tomcat quiet.
Kitten Mittens ™

“The Gang Hits the Road”

In order to handle incoming requests we need a map to tell our Tomcat server which Java files handle which requests. We can map servlets to endpoints in our server’s web.xml file, which will be located in /webapps/twilio/WEB-INF/. This servlet is going to handle all incoming/outgoing calls to our two agents. Configure this file as such:

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">

    <display-name>Twilio Warm Transfer App</display-name>

    <servlet>
        <servlet-name>TwilioCallerServlet</servlet-name>
        <servlet-class>com.twilio.TwilioCallerServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>TwilioCallerServlet</servlet-name>
        <url-pattern>/handle-caller</url-pattern>
    </servlet-mapping>
</web-app>

This mapping tells our web server that when a request to the /handle-caller URL is made it should forward to the

TwilioCallerServlet
 class. Let’s build this class in a new file now.

Building Our Servlet

Navigate to /webapps/twilio/WEB-INF/classes/com/twilio and create a new file called TwilioCallerServlet.java. This servlet will return TwiML instructions according to the incoming caller.

We first need to import a number of packages in order to use servlets and the Twilio library. Place the following code at the top of your file:

package com.twilio;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

import org.apache.http.message.BasicNameValuePair;
import org.apache.http.NameValuePair;

import com.twilio.sdk.TwilioRestClient;
import com.twilio.sdk.resource.factory.CallFactory;
import com.twilio.sdk.resource.instance.Call;
 
import java.util.ArrayList;
import java.util.List;
 
import com.twilio.sdk.verbs.TwiMLResponse;
import com.twilio.sdk.TwilioRestException;
import com.twilio.sdk.verbs.TwiMLException;
import com.twilio.sdk.verbs.Dial;
import com.twilio.sdk.verbs.Conference;
import com.twilio.sdk.verbs.Gather;

We can now create our

TwilioCallerServlet
 class. The class will contain a method called
service
 that will handle incoming HTTP requests and create HTTP responses. Place the following code after your imports:

public class TwilioCallerServlet extends HttpServlet {

    public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {

        TwiMLResponse twiml = new TwiMLResponse();
        // Dial verb allows callers to enter conference.
        Dial dial = new Dial();
        dial.setHangupOnStar(true);
        // Conference will be named SupportRoom.
        Conference conf = new Conference("SupportRoom");
        conf.setBeep(Conference.BEEP_TRUE);

        try {
            dial.append(conf);  
            twiml.append(dial);
        } catch (TwiMLException e) {
            e.printStackTrace();
        }
        // Respond with TwiML
        response.setContentType("application/xml");
        response.getWriter().print(twiml.toXML());    
    }
}

This code creates a new

TwiMLResponse()
 object and appends a Dial verb and a Conference noun to it. This means that when this TwiML is prepared by Twilio, the caller will be placed in a conference named “SupportRoom”. If you wish to learn more about TwiML verbs see the Twilio documentation here.

Testing Our Servlet

Before we move on let’s make sure that our

TwilioCallerServlet
 is functional and returning the correct TwiML. We need to compile our Java files before our Tomcat server can use them. During compilation you must specify the classpath of the jar file containing the Twilio SDK. Navigate to the top of your project directory and run this command to compile all of your java files:

$ javac -cp lib/servlet-api.jar:webapps/twilio/WEB-INF/lib/twilio-java-sdk-4.4.5-jar-with-dependencies.jar webapps/twilio/WEB-INF/classes/com/twilio/*.java

If you are receiving compilation errors then the classpaths specified in your command are not correct or you are running the command from the wrong directory.

Now we need to restart the Tomcat server for our changes to take effect. Do this by running

$ sh bin/shutdown.sh
 and then running
$ sh bin/startup.sh
 again. Remember you’ll need to restart your server any time you recompile your Java files for the changes to take effect.

Navigate to http://localhost:8080/twilio/handle-caller in your browser and you should see the following:

<Response>
    <Dial hangupOnStar="true">
        <Conference beep="true">SupportRoom</Conference>
    </Dial>
</Response>

Expanding Our Servlet

Now let’s define a couple of constants that our servlet is going to need later on. Place the following lines directly below your class definition and above the

service
 function:

final String ACCOUNT_SID = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; // Found on your Twilio Dashboard
final String AUTH_TOKEN = "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY"; // Found on your Twilio Dashboard
final String CALL_ENDPOINT = "http://XXXXXXXX.ngrok.io/twilio/handle-caller"; // Paste URL generated by ngrok
final String ARTEMIS_NUMBER = "+15555555555"; // The first agent's number
final String BARNABAS_NUMBER = "+15555555555"; // The second agent's number
final String SUPPORT_NUMBER = "+15555555555"; // Twilio number

Replace each variable with the appropriate data: Your

ACCOUNT_SID
 and
AUTH_TOKEN
 can be found on your Twilio account dashboard.
CALL_ENDPOINT
 will be the URL generated by your ngrok server with your servlet mapping appended to it (For example: http://229cd6dd.ngrok.io/twilio/handle-caller).
ARTEMIS_NUMBER
 is the phone number of your first agent. This is the number that will answer all incoming calls to your Twilio number.
BARNABAS_NUMBER
 is the phone number that will receive the warm transfer from Artemis. Lastly,
SUPPORT_NUMBER
 is your Twilio number that callers will call into.

Now let’s add some additional logic to handle agent transfers and outgoing calls. Add the following code above your

response.setContentType("application/xml");
 line:

// Check if any key presses were made.
String digits = request.getParameter("Digits");
// If digits were pressed, Artemis needs to conference Barnabas.
if (digits != null && digits.equals("1")) {
    // Call Barnabas to bring into conference.
    makeCall(CALL_ENDPOINT, BARNABAS_NUMBER, SUPPORT_NUMBER);
}
else {
    // Check if incoming call is coming directly to our Support Number.
    if(request.getParameter("To").equals(SUPPORT_NUMBER)) {
        // Call Artemis to connect to incoming caller.
        makeCall(CALL_ENDPOINT, ARTEMIS_NUMBER, request.getParameter("From"));
    }
    // Check if the incoming call is coming to Artemis.
    else if(request.getParameter("To").equals(ARTEMIS_NUMBER)) {
        // Append Gather to Artemis's TwiML
        Gather gather = new Gather();
        gather.setAction(CALL_ENDPOINT);
        gather.setNumDigits(1);
        try {
            twiml.append(gather);
        } catch (TwiMLException e) {
            e.printStackTrace();
        }
    }
    // Calls coming to Barnabas will receive the same TwiML as the initial caller.
}

Our servlet is checking if a “1” was entered into the keypad by our first agent (Artemis) after disconnecting from the conference. If it was, our second agent (Barnabas) will be dialed and Artemis will be reconnected to the conference.

If no input was sent, we must check where the incoming call is coming from. If a regular caller is dialing into your Twilio number, they must be connected with Artemis. Artemis will be sent different TwiML that contains a Gather verb to collect input from the keypad. Combined with the

setHangupOnStar
 attribute, this allows Artemis to press “*1” to dial Barnabas.

You’ll notice we haven’t defined the

makeCall
 function. Let’s add this function right before the class’s closing bracket. The following code will make calls for us using a 
TwilioRestClient
:

public void makeCall(String url, String to, String from) {
    try {
        TwilioRestClient client = new TwilioRestClient(ACCOUNT_SID, AUTH_TOKEN);

        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("Url", url));
        params.add(new BasicNameValuePair("To", to));
        params.add(new BasicNameValuePair("From", from));
         
        CallFactory callFactory = client.getAccount().getCallFactory();
        Call call = callFactory.create(params);
    }
    catch (TwilioRestException e) {
            System.out.println(e.getErrorMessage());
    }
}

“Frank’s Back in Business”

The last step is to buy a Twilio phone number and configure it to reach out to our

TwilioCallerServlet
 servlet. From the Twilio account dashboard, follow the animation below to purchase a new number. This number will serve as our support line.

In the Setup Number screen, under Voice, set your ‘Request URL’ to the

CALL_ENDPOINT
 URL we used in our code and click save:

Remember to restart your Tomcat server and make sure your ngrok tunnel is online. You can test out your application by having someone call your Twilio number. Your first agent (Artemis) will receive a phone call and be placed into a conference with the caller. When Artemis presses “*1”, your second agent (Barnabas) will then receive a call and be placed into the same conference. This allows Artemis to introduce the caller before handing them off to Barnabas.

It’s Always Servlet in Philadelphia

Congratulations! You’ve now built a call center that supports warm transferring incoming callers. With warm transfers, your callers will now feel more like this:

Note: This is a very simple implementation of a call center and it can be improved in many ways. Keep your eyes peeled for future Java posts that expand on what we’ve built here.

If you ran into any issues or have feedback on this tutorial, please don’t hesitate to leave a comment below or reach out to me via Twitter @br0dan or email me at chranj@twilio.com.

How to Warm Transfer a Call with Java and Twilio Voice

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


A few months back I showed you how I used Twilio to build my own personal assistant that would keep tabs with my Google Calendar and call into all my meetings for me.

Ever since I started using it I have managed to not only keep up with all my conference calls but also spend more time remembering about the other things I can’t automate… yet.

I have a pretty solid way of making sure I’m present on all my conference calls, but what happens when someone calls me? If you’re a developer you will know concentrating is pretty hard thing to do and making sure that you keep concentrated is almost impossible. In fact, the graph below shows it really well.

With that in mind I thought it was time for me to tackle the fact that answering calls is pretty high in a PA’s list of priorities and mine simply didn’t. This time we will build an automated assistant with .NET MVC6, Entity Framework and Twilio on a Mac that takes care of all our incoming calls and decides what to do with them based on the number that is calling.

That way I can, for example, decide to only accept calls from certain people which will then be automatically transferred to a number of my choice or ignore those calls completely by playing a personal message and ask the caller to call me later.

If you would rather skip straight to the final application feel free to download it from the Github Repository.

Our tools

Our setup

We will start by getting ourselves a Twilio number which we will then use to give away to any of our friends or contacts.

Head to your favourite terminal application and create a new Web Application Basic [without Membership and Authorization] project with Yeoman called PhonePA.

Once it’s created head to Visual Studio code and open the file project.json. Add dependencies to Twilio and Entity Framework 7, which we will use to scaffold our database via migrations.

"dependencies": {
    "Microsoft.AspNet.Diagnostics": "1.0.0-beta6",
    "Microsoft.AspNet.Mvc": "6.0.0-beta6",
    "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-beta6",
    "Microsoft.AspNet.Server.IIS": "1.0.0-beta6",
    "Microsoft.AspNet.Server.Kestrel": "1.0.0-beta6",
    "Microsoft.AspNet.Server.WebListener": "1.0.0-beta6",
    "Microsoft.AspNet.StaticFiles": "1.0.0-beta6",
    "Microsoft.AspNet.Tooling.Razor": "1.0.0-beta6",
    "Microsoft.Framework.Configuration.Json": "1.0.0-beta6",
    "Microsoft.Framework.Logging": "1.0.0-beta6",
    "Microsoft.Framework.Logging.Console": "1.0.0-beta6",
    "Kestrel": "1.0.0-beta6",
    "EntityFramework.Sqlite": "7.0.0-beta6",
    "EntityFramework.Commands": "7.0.0-beta6",
    "Twilio": "4.0.4",
    "Twilio.TwiML": "3.3.6"
  },

  "commands": {
    "kestrel": "Microsoft.AspNet.Hosting --server Kestrel --config hosting.ini",
    "web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --config hosting.ini",
    "ef": "EntityFramework.Commands"
  },

We will be using SQLite as the database for this example to keep everything self-contained. We have also added an entry under commands called ef. This is so we can invoke Entity Framework migrations straight from the Terminal later on.

Save that file and VS Code will prompt you to restore packages. Click Restore and once that is complete check that Entity Framework has been installed and configured correctly by running the following code on the same terminal screen.

dnx . ef

Still on that screen create a new directory called Models and cd into it.

mkdir Models

Back on VS Code create a new file under Models called Contact.cs and add the following to it.

using System.ComponentModel.DataAnnotations;
using Microsoft.Data.Entity;

namespace PhonePA.Models
{
    public class ContactsContext : DbContext
    {
        public DbSet<Contact> Contacts { get; set; }
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            // Declare that we want to use SQLite and name the database
			optionsBuilder.UseSqlite("Data Source=./contacts.db");
        }
    }
    public class Contact
    {
        [Key]
        public int ContactId { get; set; }
        [Display(Name = "Contact Name")]
        public string Name { get; set; }
        [Display(Name = "Phone Number")]
        public string Number { get; set; }
        [Display(Name = "Custom Message")]
        public string Message { get; set; }
        public bool Blocked { get; set; }
    }
}

Now that we have created our model go back to Terminal and get Entity Framework to create a migration for us. We will be able to verify everything that it is going to do before we apply our migration by opening the generated classes.

dnx . ef migration add InitialMigration

After running that you will notice that back in VS Code a new directory called Migrations has been automatically created. This directory will contain all the migrations we create. Open up the file called [timestamp]_InitialMigration.cs. Notice the timestamp will vary according to when you created your migration.

In this file you will be able to see everything that will be done when we apply this migration. As of version 7.0.0-beta6, Entity Framework has a bug that will prevent you from successfully running your migrations unless you comment out the AutoIncrement annotation. So lets go ahead and comment that line out as shown.

public override void Up(MigrationBuilder migration)
{
    migration.CreateTable(
        name: "Contact",
        columns: table => new
        {
            ContactId = table.Column(type: "INTEGER", nullable: false),
            //    .Annotation("Sqlite:Autoincrement", true),
            Blocked = table.Column(type: "INTEGER", nullable: false),
            Message = table.Column(type: "TEXT", nullable: true),
            Name = table.Column(type: "TEXT", nullable: true),
            Number = table.Column(type: "TEXT", nullable: true)
        },
        constraints: table =>
        {
            table.PrimaryKey("PK_Contact", x => x.ContactId);
        });
}

We’re ready to have our database scaffolded. Go ahead and run the following command on terminal.

dnx . ef migration apply

After that completes you will see that a new file called contacts.db has been created on the root directory of your project. Our database is scaffolded and ready to be used.

Run the application and check that it is running as expected. We will change the HomeController later and add a few views to allow us to create and update contacts. In terminal run the following:

dnx . kestrel

You can now navigate to http://localhost:5000 and verify that the application is running correctly.

Adding Contacts

Now that our application is running, we will modify the HomeController to display a list of our contacts already in the database. Change its contents to the following:

using System;
using System.Linq;
using Microsoft.AspNet.Mvc;
using Twilio;
using Twilio.TwiML;
using PhonePA.Models;

namespace PhonePA.Controllers
{
    public class HomeController : Controller
    {
        private ContactsContext _db;
        private TwilioRestClient _client;

        public HomeController()
        {
            _db = new ContactsContext();
        }

        public IActionResult Index()
        {
            return View(_db.Contacts);
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                _db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}

Notice we have also added some dependencies to the Twilio .NET Libraries which we will use later on.

Now that we have created our endpoint, open Views/Home/Index.cshtml and replace its contents with the following markup to display our contact’s information.

@model IEnumerable<PhonePA.Models.Contact>

@{
    ViewBag.Title = "Contacts";
}

<h2>Contacts</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Name)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Number)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Message)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Blocked)
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Name)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Number)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Message)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Blocked)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.ContactId }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.ContactId })
        </td>
    </tr>
}
</table>

Back on your Terminal kill the running application with CTRL C, start it again and browse to it. You should see a page that looks like the one below.

There aren’t any results yet since we haven’t created the functionality that will allow us to create, edit and delete contacts.

Go back to the HomeController.cs file and add the following four action methods to it:

// GET: /Home/Create
[HttpGet]
public IActionResult Create()
{
    return View();
}

//POST: /Home/Create/
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(Contact contact)
{
    ModelState.Clear();
    TryValidateModel(contact);
    if (ModelState.IsValid)
    {
        using (var db = new ContactsContext())
        {
            db.Contacts.Add(contact);
            var count = db.SaveChanges();
            return RedirectToAction("Index");
        }
    }
    return View(contact);
}

// GET: Home/Edit/5
[HttpGet]
public IActionResult Edit(int id)
{
    var contact = _db.Contacts.FirstOrDefault(s => s.ContactId == id);
    if (contact == null)
    {
        return HttpNotFound();
    }
    return View(contact);
}

//POST: /Home/Edit/
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Edit(Contact contact)
{
    ModelState.Clear();
    TryValidateModel(contact);
    if (ModelState.IsValid)
    {
        using (var db = new ContactsContext())
        {
            db.Contacts.Update(contact);
            var count = db.SaveChanges();
            return RedirectToAction("Index");
        }
    }
    return View(contact);
}

public IActionResult Delete(int id)
{
    var contact = _db.Contacts.FirstOrDefault(s => s.ContactId == id);
    if (contact == null)
    {
        return HttpNotFound();
    }
    else
    {
        _db.Contacts.Remove(contact);
        _db.SaveChanges();
        return RedirectToAction("Index");
    }
}

Now that we have added the endpoints we need, let’s create the views for them. Create a new file called Create.cshtml under /Views/Home and add the following to it:

@model PhonePA.Models.Contact

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>


@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>Contact</h4>
        <hr />
        <div class="form-group">
            @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Number, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Number, new { htmlAttributes = new { @class = "form-control" } })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Message, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Message, new { htmlAttributes = new { @class = "form-control" } })
            </div>
        </div>
        
        <div class="form-group">
            @Html.LabelFor(model => model.Blocked, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                <div class="checkbox">
                    @Html.EditorFor(model => model.Blocked)
                </div>
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

On that same directory create a new file called Edit.cshtml and add the following to it.

@model PhonePA.Models.Contact

@{
    ViewBag.Title = "Create";
}

<h2>Edit</h2>


@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>Contact</h4>
        <hr />
                @Html.HiddenFor(model => model.ContactId)
        <div class="form-group">
            @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Number, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Number, new { htmlAttributes = new { @class = "form-control" } })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Message, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Message, new { htmlAttributes = new { @class = "form-control" } })
            </div>
        </div>
        
        <div class="form-group">
            @Html.LabelFor(model => model.Blocked, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                <div class="checkbox">
                    @Html.EditorFor(model => model.Blocked)
                </div>
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

Time for another run. Start the application again on your Terminal and create a new contact. You should see that every new contact is listed on the index screen and that you can now update or delete their details.

Hooking up with Twilio

Now that we can create and edit our contacts it is time to let Twilio know about their existence and what to do about each one of them when they call our Twilio number.

Because Twilio needs access to your application we will use ngrok to make our local environment accessible externally. My colleague Kevin Whinnery wrote a great blog post on getting up and running with ngrok.

Back on your terminal open a new tab and run the following to create a tunnel to your local environment. Make sure you copy the forwarding URL.

ngrok 5000

Head back to the number you purchased earlier and under Voice change the Request URL to point to the forwarding URL and a new endpoint we will create. The URL should look like this:

http://{my-ngrok-forwarding-url}/Home/HandleCall

Save that and go back to HomeController.cs. We’re now going to add one last endpoint called HandleCall which will have logic to respond to requests coming from Twilio.

[HttpPost]
public IActionResult HandleCall(string From)
{
    var contact = _db.Contacts.FirstOrDefault(s => s.Number == From);
    var twiml = new TwilioResponse();
    if (contact != null)
    {
        // It is a contact.
        // check whether they're allowed through
        if(!contact.Blocked){
            return Content(twiml.Dial(Environment.GetEnvironmentVariable("MY_NUMBER")).ToString(), "text/xml");
        }
        else{
            return Content(twiml.Say(contact.Message).ToString(), "text/xml");
        }
    }
    else{
        return Content(twiml.Say("This number is only for contacts.").ToString(), "text/xml");
    }
}

The logic above is very simple but powerful. It checks the database for a number on every incoming call and tells Twilio what to do via TwiML. There are three possible outcomes:

  1. An incoming number doesn’t exist on the database: The caller gets a standard message saying this number is only for contacts
  2. The incoming number exists and isn’t blocked: The caller is then redirected to our real telephone number. I’ve used an environment variable for this, but you could just replace that with your own mobile number for example. For more information on creating and managing environment variables on a Mac, check this article out.
  3. The incoming number exists but is blocked: The caller gets a custom message played.

To test it out, you can create  a new contact with another mobile or landline number you own, and try to call your Twilio number from it. Depending on the status, you will see that there will be different messages being played.

What next?

We started off by having to answer every single one of our calls and now have an fully automated system that will handle each and every one of the calls to our Twilio number. It will not only answer them but also decide whether the call is important to us at that time.

There are other features we could add to our phone application such as recording calls using the <Record> verb, or building an options menu that will eventually give the caller an automated answer to something they’re looking for by using the <Gather> verb.

How about making it handle incoming SMS messages and using the statuses to auto-reply the messages?

I would love to see what you come up with. Hit me up on Twitter @marcos_placona or by email on marcos@twilio.com to tell me about it.

Building an automated assistant with .NET MVC6, Entity Framework and Twilio on a Mac

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


Share This: A recent New York Times article addressing the working culture at Amazon raised a lot of eyebrows around the country. The general view... …read more

The post Making Your Employees Happy Makes Cents appeared first on Plum Voice.

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


August 18, 2015

The best developers make hard work seem easy. As a one man developer / IT shop, that’s Adam McPhedrain’s job.

When one of his clients, a national pharmacy chain, wanted to update their communications system, Adam got the call. His job was to migrate the pharmacy’s SIP trunks to Twilio and add SMS and MMS support.

For Adam’s client, the goal was to cut down on costs, while enhancing the customer experience. The new feature set from Twilio gave customers access to proactive notifications regarding their medication, as well as an easier way to communicate with the pharmacy – via SMS and MMS.

When Adam finished the job, his client was ready to go with new SIP trunks, SMS, and MMS capability all for about half of what they previously paid for SIP trunks alone. Here’s how Adam made the magic happen.

sip

The pharmacy chain provides a litany of medical-related services for their clients. This ranges from shipping medication, to monitoring patients, managing their medication, and reporting information to clinics and physicians.

There’s a ton of sensitive HIPAA regulated information being sent and received by the pharmacy, through a variety of different mediums: SMS, MMS and SIP. When switching to Twilio, Adam’s priorities were cost, functionality and security.

“From the drawing board to production environment deployment, it took about two months for my first Elastic SIP Trunking deployment and about a month for my first REST API SMS/MMS integration,” says Adam.

When Adam’s client looked at their books, the switch to Twilio was stark. They’re saving thousands of dollars a month between just two of their locations. Most importantly, patients had a more seamless experience when engaging with the pharmacy over any channel, thanks to Adam’s engineering.

“My clients love the fact that they can receive SMS and MMS messages on the same number they receive and make calls on. It just makes sense. Security was also an important factor, and I like that Twilio supports the use of ACL’s (Access Control Lists) to control very specifically who is allowed to use the account,” says Adam.

Now that Adam’s work is complete, he’s looking for other opportunities to give his clients the flexibility their business needs. “Twilio’s Elastic SIP Trunking solution really opens up a lot of doors for people looking to not only save money, but have much greater control of what their phone system is capable of.”

How A One Man IT Shop Saved His Client Thousands By Switching To Elastic SIP Trunking

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


In the first post in this series we wrote a simple iOS app using Swift that made an outbound phone call using the Twilio Client SDK for iOS.  To do that we set up the basic server infrastructure we need in order to generate a capability token, created a TwiML application that told Twilio what experience to give the caller and used the Client SDK APIs to create a new Device and Connection.

In the second part we’ll look at using the SDK to receive inbound calls.  I’ll show you how to accept calls while the application is running in the foreground, as well as how to use notifications to alert the user of incoming calls while the application is in the background.

Just want to grab the app code and run with it?  Head on over to Github to get the full source for SwiftPhone. If you want to start from where the first post left off, grab the code from Tag 1.

If you want to build your own Swift version of BasicPhone you’ll need a copy of XCode 6.1 or newer.  For you bleeding edgers out there, sorry this won’t work with XCode 7 beta and Swift 2 just yet.

You’ll also need a Twilio account. Don’t worry, trial accounts are free, so if you don’t already have one, head on over to the Twilio website and sign up.

Calling Jenny

Any voice connection coming into Twilio be it PSTN, SIP or Twilio Client can be bridged to an instance of Twilio Client by using the <Client> TwiML noun.  Here we are telling Twilio to try connecting the inbound voice connection to an instance of Twilio Client named “jenny”:

<Response>
    <Dial>
       <Client>jenny</Client>
    </Dial>
</Response>

You can also use the REST API to have Twilio make an outbound call to an instance of Client.  This is what we’ll do to call our iOS application.  Once the call to instance of Client is answered, we’ll use same Greeting.xml we used in the previous post to have Twilio provide an experience to the person answering the call.

Using your favorite Twilio helper library, start an outbound phone call providing the From, To and URL parameters.  In my case I’ll use the Python library:

from twilio.rest import TwilioRestClient
client = TwilioRestClient()
client.calls.create(from_='client:bob', to='client:jenny', url='http://demo.devinrader.info/greeting.xml')

Notice that we can call a client name using the same Twilio API we use to call traditional telephone numbers.  Client names are prepended with the ‘client’ prefix in order to tell Twilio this value is the name of an instance of Client.

Additionally, remember that TwiML app we created in the previous post to handle outbound calls from Twilio Client?  We want to provide the same in-call experience to the answerer of our inbound call so we will pass in that TwiML Apps Sid instead of a URL:

client.calls.create(from_='client:bob', to='client:jenny', url='', application_sid='APXXXXXXXXXXX')

Now that we know how to make calls to our client using the Twilio REST API, let’s see how we receive them in our iOS app.

Your Call Is Important To Us

In the previous post we created an instance of the TCDevice object and saw how to make an outbound phone call using it.  TCDevice however is not only for making outbound calls. Passing it a capability token containing permissions that allow accepting inbound calls tells it to begin to listen for incoming calls.  

If you’ve been following along since Part 1 of this series and built the node application to generate the capability token you should be good to go.  If you went with the option of deploying the Mobile Quickstart to Heroku, you’ll need to make sure are passing the ‘client’ parameter in the URL in order for the quickstart to set the incoming calls permission.

To notify you that it is (or isn’t) listening for calls or has received a call, the TCDevice instance lets you specify a delegate, notifying that delegate of changes in its listening state or of incoming calls via methods defined in the TCDeviceDelegate protocol.

In the previous post we already generated a capability token that includes permissions for accepting inbound calls, so now all we have to do is implement the TCDeviceDelegate protocol on our Phone class and tell our instance of TCDevice where the delegate is.

Because TCDeviceDelegate is an Objective-C protocol, we first need to change the existing Phone class to inherit from NSObject and then specify we want to implement the TCDeviceDelegate protocol

public class Phone : NSObject, TCDeviceDelegate {

The protocol defines four methods, one required and three optional, that we can implement.  For our application we’ll implement the required didStopListeningForIncomingConnections method and two optional methods: didStartListeningForIncomingConnections and didReceiveIncomingConnection in our existing Phone class:

public func deviceDidStartListeningForIncomingConnections(device: TCDevice)->() {
    println("Started listening for incoming connections")
}
    
public func device(device:TCDevice, didStopListeningForIncomingConnections error:NSError)->(){
    println("Stopped listening for incoming connections")
}
    
public func device(device:TCDevice, didReceiveIncomingConnection connection:TCConnection)->() {
    println("Receiving an incoming connection")
}

With the protocol implemented we need to tell the existing TCDevice that its protocol delegate methods are located in this class.  We can do that by updating the initialization of the TCDevice in the Phone class, changing the delegate parameter value from nil to self:

func connectWithParams(params dictParams:Dictionary<String,String> = Dictionary<String,String>()) {
    
    if !self.capabilityTokenValid()
    {
        self.login();
    }
    
    self.connection = self.device?.connect(dictParams, delegate: self);
}

We’re now ready to accept an incoming call.  For now, we’ll just accept every incoming connection but don’t worry, later in the post I’ll show you how to be a bit more discriminating with your incoming calls.

public func device(device:TCDevice!, didReceiveIncomingConnection connection:TCConnection!) {
    println("Receiving an incoming connection")
    self.connection = connection
    self.connection?.accept()
}

Awesome!  Let’s test it out.

Start your app in the iPhone simulator and from the Python console (or wherever you are starting calls from), start a new call to client:jenny.  Your app should receive and accept the incoming call and you should hear the greeting from Twilio.

Who Goes There?

OK. So now we can accept incoming calls, but blindly accepting all calls probably isn’t the greatest idea.  A better experience would be to let the app’s user decide how to handle an incoming call.  Twilio Client allows us to accept, ignore or reject incoming calls. Let’s modify our app to allow the user to choose how to handle the incoming call.

We’ll start with a few changes to our existing Phone class.  When a call is received by our application, we need to give the user time to decide what to do with it.  To hold onto that connection while they decide we’ll create a new variable named pendingConnection:

var device:TCDevice!
var connection:TCConnection!
var pendingConnection:TCConnection!

Now in the didReceiveIncomingConnection function, instead of blindly accepting the incoming connection, we’ll put it into the pendingConnection variable and then send a Notification to allow interested parties to know that there is a new incoming connection:

public func device(device:TCDevice!, didReceiveIncomingConnection connection:TCConnection!) {
    println("Receiving an incoming connection")
    self.pendingConnection = connection

    NSNotificationCenter.defaultCenter().postNotificationName(
        "PendingIncomingConnectionReceived", 
        object: nil, 
        userInfo:nil)
}

Next, we’ll add 3 functions to the Phone class that let developers using the class to act on the connection:

func acceptConnection() {
    self.connection = self.pendingConnection
    self.pendingConnection = nil

    self.connection?.accept()
}
    
func rejectConnection() {
    self.pendingConnection?.reject()
    self.pendingConnection = nil
}
    
func ignoreConnection() {
    self.pendingConnection?.ignore()
    self.pendingConnection = nil
}

Notice that if the connection is accepted we take the pendingConnection and assign it to our connection variable.  In each situation we also set the pendingConnection to nil so we can accept another connection if one arrives.

With the Phone class modified to accept, reject or ignore the incoming call, change the app UI to expose those options to the user.  Add Accept, Ignore and Reject buttons to the UI and make Buttons disabled by default:

Next add Actions and Outlets for each button.  In each Action call the corresponding function from the Phone class:

@IBOutlet weak var btnAnswer: UIButton!
@IBOutlet weak var btnReject: UIButton!
@IBOutlet weak var btnIgnore: UIButton!
        
@IBAction func btnAnswer(sender: AnyObject) {
    self.phone.acceptConnection()
}
    
@IBAction func btnReject(sender: AnyObject) {
    self.phone.rejectConnection()
}

@IBAction func btnIgnore(sender: AnyObject) {
    self.phone.ignoreConnection()
}

Finally, create a Notification observer that listens for the incoming connection Notification:

override func viewDidLoad() {
    super.viewDidLoad()
        
    NSNotificationCenter.defaultCenter().addObserver(
        self, 
        selector:Selector("pendingIncomingConnectionReceived:"),
        name:"PendingIncomingConnectionReceived", object:nil)

    self.phone.login()
}

Add the pendingIncomingConnectionReceived function defined as the Notifications Selector to the ViewController and in it enable the buttons to let the user take action on the call:

func pendingIncomingConnectionReceived(notification:NSNotification) {
   self.btnAnswer.enabled = true
   self.btnReject.enabled = true
   self.btnIgnore.enabled = true
}

Fantastic!  Run the app and make another call from the console.  When the incoming call is detected by the app, the buttons should enable and you should be able to answer, ignore or reject the call.

Back from the Background

Now we have an iOS application that can both make and receive phone calls.  But, what happens if the app is in the background when Twilio sends a call to it?  No worries, the Twilio Client SDK takes care of this for you.

To allow the SDK to do this, from the Project navigator select the SwiftPhone project to open the project properties, select the Capabilities tab and make sure you have set the Audio and VoIP background capabilities for your app.

Setting these capabilities allows the SDK continue to listen for incoming connections even when it is in the background.  The delegate functions defined by TCDeviceDelegate will still get called letting us know the application has received an incoming call, but with the application not active we have no UI so we need a different way to notify the user of the call.  For this we can use LocalNotifications.

In the applications AppDelegate, start by enabling LocalNotifications for the app.  Here we are enabling several different types of notifications, including the Alert notification:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Override point for customization after application launch.
    if  UIApplication.instancesRespondToSelector(Selector("registerUserNotificationSettings:")) {
            application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound, categories: nil))
    }
        
    return true
}

Run the app again and it will prompt now you to allow notifications.  This prompt happens only once and the selection is saved for the application.

Next we need to modify the pendingIncomingConnectionReceived function.  We’ll check to see if the app is not active, and if it is not, create and show a LocalNotification:

func pendingIncomingConnectionReceived(notification:NSNotification) {
        
    if UIApplication.sharedApplication().applicationState != UIApplicationState.Active {
        var notification:UILocalNotification = UILocalNotification()
        notification.alertBody = "Incoming Call"
            UIApplication.sharedApplication().presentLocalNotificationNow(notification)
    }
        
    self.btnAnswer.enabled = true
    self.btnReject.enabled = true
    self.btnIgnore.enabled = true
}

Great!  Now run the app and put it in the background.  Make a call from the console and you will see a LocalNotification displayed:

Swipe the notification and the app will become active and allow you to answer the call.  Using LocalNotifications means you’ll also get notifications while your phone is locked:

Again, simply swipe the notification to activate the app and choose how to handle the incoming call.

Finally, answer the incoming call and then put the application into the background.  Notice that the active call continues and iOS displays the in-progress VoIP call banner:

To make the application active again, just tap the banner.

Wrapping It up

That’s it!  In short order we’ve built an iOS application using Swift that can both make and receive VoIP phone calls using the Twilio Client for iOS SDK.  We’ve added the ability to notify  users of incoming calls and to be connected to an active call even if the application is running in the background.

There are million and one ways that you could make this application even better.  Creating a much nicer UI probably the most obvious, but it would also be fun to:

  • create a dial pad that allow users to specify a phone number to dial, or DTMF tone to send
  • add a way to mute and switch between audio outputs
  • build a call timer that shows how long a call has been active
  • integrate the iOS Address Book to make outbound calling easier

What other cool ways can you enhance this simple application? I’d love to see what you come up with.  Drop me a line one twitter or via email and let me know what you’re building with Swift or the Twilio Client for iOS SDK.

A Swift Adventure: Building BasicPhone with TwilioClient – Part 2

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


August 17, 2015

ReactJS has been taking the world of front end development by storm gaining widespread usage at many software companies. Described by its own homepage as the V in MVC, React allows you to build reusable UI components and makes maintaining changes in your data’s state effortless by abstracting the DOM. Combined with a bundler utility like Webpack, React greatly simplifies building and maintaining Single Page Applications.

Facebook has done a great job of keeping React up to date, and even made it compatible with new features from ECMAScript 6 (ES6), the significant update to the JavaScript language that is finally available for use. Unfortunately, browser support for ES6 is not as widespread as many would hope which is where handy utilities like Babel come into play. Babel lets us write code that uses new ES6 features, and then transpiles that code into standard ES5 code that can run in older JavaScript environments.

In this post, we’ll go through the steps of setting up two basic React components that use ES6 features, use Babel to transpile them to ES5 and bundle them using Webpack. This is going to be fun because React, ES6, Babel and Webpack play together particularly well.

Visiting the toolshed

Before we get started writing code we have to install the right tools. First make sure you have NodeJS and npm installed as we’ll use those to install the packages we need.

With Node and npm installed fire up your terminal, head over to the directory where you want your project to live and run:

npm init

Go through all of the prompts filling out whatever information you feel is appropriate and a package.json file should be generated. This will allow us to keep track of what node modules we need for future reference.

Now let’s install React:

npm install --save react

We will also need to install Webpack and the Webpack development server for serving our bundled JavaScript application. You may need to use “sudo” to install the dev server package globally.

npm install --save-dev webpack
npm install webpack-dev-server -g

Now that our bundling tool is taken care of, we need a transpiler for interpreting our ES6 code. This is where Babel comes in. Let’s install the babel-loader and babel-core packages that we’ll use to work with Webpack.

npm install --save-dev babel-loader
npm install --save-dev babel-core

Creating your first React components

In React, components are the individual building blocks of how your data is viewed. You write components to handle how your data should look and to automatically render state changes. When you create a component, you define all of this by overriding React.Component’s render function.

Let’s dig into this by writing our first component whose job is to render the word “Hello” into the browser.

Open up a new file called “hello.jsx” in your text editor and enter this code:

import React from 'react';

class Hello extends React.Component {
  render() {
    return <h1>Hello</h1>
  }
}

There are a couple of things to note about the syntax. First off, we have ES6 import statements and class definitions, which makes our code more concise by not having to call React.createClass. But there is also some funky looking inline HTML type stuff in the component class definition’s render function. This XML-like syntax being returned from the function is called JSX. It was designed to make building React components easier because it is concise and familiar for defining tree structures with attributes.

All of this new syntax might look a bit strange, but don’t worry because in just a bit well use Babel to transpile both the ES6 syntax and the JSX syntax into ES5 JavaScript that can be run in a browser.

Here is what our Hello React component looks like without using ES6 and JSX:

var React = require('react');

var Hello = React.createClass({displayName: 'Hello',
  render: function() {
    return React.createElement("h1", null, "Hello ");
  }
});

When we use JSX, we are able to define our virtual DOM element more concisely without having to call React.createElement and passing which attributes the element should have. Our simple Hello component may have the same number of lines of code but JSX makes things much easier as you continue building components and combine them together.

Now that we have our component class, we need to add some code to “mount” this component to a DOM element. This will take our React component and render it to display within an element of an HTML page. To do this we call React.render and pass it a component object as well as an actual DOM element to attach to.

Open up “hello.jsx” once again and add this one liner:

import React from 'react';

class Hello extends React.Component {
  render() {
    return <h1>Hello</h1>
  }
}

React.render(<Hello/>, document.getElementById('hello'));

Now let’s create our second component whose job is to render the word “world”. Create a new file called “world.jsx” and add the following code. Notice that it’s eerily similar to the code we wrote for our first component:

import React from 'react';

class World extends React.Component {
  render() {
    return <h1>World</h1>
  }
}

React.render(<World/>, document.getElementById('world'));

So we have two React components, but nowhere to use them. Let’s fix this by writing a simple HTML page that contains a <div> for each component we want to mount. Create an “index.html” file and write this bare bones web page:

<!doctype html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello React</title>
  </head>
  <body>
    <div id="hello"></div>
    <div id="world"></div>
  </body>
</html>

We’ve now created all of the code we need to display “Hello World” in a browser using React components. The final step in getting this code ready to run is to pass it through Webpack.

Bundling everything with Webpack

Webpack is a module bundler that takes assets such as CSS, images or JavaScript files with lots of dependencies and turns them into something that you can provide to a client web page. It uses loaders that you specify in your configuration file to know how to transpile these assets. In our case, we want to transpile the JSX to JavaScript and ES6 code to browser-compliant ES5 code. We can do this by providing a JavaScript file as an entry point for Webpacks loader pipeline. Webpack will analyze this file and all of the subsequent dependencies used in your code to generate a bundle for you to include in your HTML. To tell Webpack about our React components, all we need to do is import those JavaScript files.

Create a “main.js” file in your text editor and add code to import both of the React components we made:

import Hello from './hello.jsx';
import World from './world.jsx';

Next we need to tell Webpack that this will be our entry point and which loaders to use when creating the bundle. We are only using the Babel loader, but we could use other loaders for things like CoffeeScript and SASS if we had other dependencies.

Fire up your text editor one more time and create a new file called “webpack.config.js” and add the following configuration:

var path = require('path');
var webpack = require('webpack');

module.exports = {
  entry: './main.js',
  output: { path: __dirname, filename: 'bundle.js' },
  module: {
    loaders: [
      { test: /.jsx?$/, loader: 'babel-loader', exclude: /node_modules/ }
    ]
  },
};

Finally, we need to make one more small modification to our HTML to include the “bundle.js” file that will be generated when we run the Webpack dev server:

<!doctype html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello React</title>
  </head>
  <body>
    <div id="hello"></div>
    <div id="world"></div>
    <script src="bundle.js"></script>
  </body>
</html>

Let’s fire up the Webpack dev server to see our components on the page live in action:

webpack-dev-server —progress —colors

Watch as your terminal comes alive while Webpack builds your code to run in-browser. Now that the dev server is running, you can navigate to “http://localhost:8080/webpack-dev-server/” in your browser to see your Hello World React app displayed beautifully on the page.

What comes next?

We’ve just built two React components using Babel for JSX and ES6 syntax and bundled them together using Webpack. This may not seem like much, but it is a solid start on the path to building bigger single page applications. You’ve now overcome the hurdle of getting a bunch of new technologies to work together and can finally start making awesome stuff with React.

Stay tuned on the Twilio blog for more React content as we continue to play around with it. I’m just as excited about this as you are.

I’m looking forward to seeing what you all build. Feel free to reach out and share your experiences or ask any questions.

Setting up React for ES6 with Webpack and Babel

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


August 13, 2015

Our world is rapidly changing for the better in the wave of software communications. It’s easy to spot this change in the hospitality industry with companies like AirBnB, or in the ride-sharing industry with companies like Lyft. Outside of the consumer industry, software is not just changing lives, it’s saving lives.

The Polaris Project works to abolish human trafficking by leveraging communications technology. Together with the Salesforce Foundation and Twilio, the Polaris Project launched the BeFree shortcode which allows victims of human trafficking to text the number to be connected with the National Human Trafficking Resource Center (NHTRC).

Twilio CEO, Jeff Lawson spoke to Fox Business about the state of software communications and the Polaris Project’s amazing work fighting against human trafficking.

Learn more about the Polaris Project’s work here

Watch the latest video at video.foxbusiness.com

How Software Communications Is Helping Fight Human Trafficking: The Polaris Project Uses SMS To Save Lives

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


GV6_iwD0Jane Kim’s idea for Exquisite Texts came from the place all great app ideas come from – senior year post modern poetry class.

Last week, she unveiled her Twilio-powered app that allows anyone to submit one line of poetry as part of a poem that will be completed by other strangers texting her app. The app has already produced many gems such as the following:

 

“but can’t you just not rhyme?

who has the time?

what’s up pretty boy

the milk i prefer is soy

the kind i drank as a boy”

[source]

The week she deployed Exquisite Texts was quite harrowing. She was busy preparing for her first tech talk at CharmCityJS, and accomplished a nearly impossible feat – finding an apartment in New York City (*rimshot*). We talked to Jane about how she got the idea for Exquisite Texts and what she thinks about code-powered art.

The Genesis of Exquisite Texts

JaneSelfie

Jane at CharmCity JS

After the post-modern poetry class, Jane started messing around with the idea making poetry collaborative, and its sentiment visible. Along with her two classmates, she first built out a prototype of what would become Exquisite Texts at PennApps in 2014. When users texted a Twilio powered number, the app would gauge the sentiment of that text (or poetic verse) and display a corresponding color on a Phillips Hue.

The project worked, but remained dormant until Janeran into Jason Rhodes, who runs CharmCityJS in Baltimore. Jason asked Jane to speak at the event last week. Once Jane agreed, she was on the clock to revamp Exquisite Texts with her drastically improved coding skills.

She ditched the Phillips Hue lights and built out the crowd-sourced poetry app, adding encryption/decryption, new middleware, and revamped the app’s data storage. When she unveiled the app at CharmCityJS, everything went great.

“The talk went really well, to my surprise” said Jane. “I think people are always really impressed with any kind of hack that involves art in some form, even if technically the hack may not be that intricate. Anything code related that involves real people and chance has always been interesting to me.”

Exquisite Texts received a ton of attention that week. And while Jane is new to the whole tech talk, internet social media explosion thing, she knows exactly why the app was so successful.

“There’s a certain kind of whimsical feeling of contributing to a black box and not knowing exactly what’s going to come out of it. If you read through any of the poems after you’ve contributed, you’ll know what I mean.

Jane Kim Crowdsources Poetry Using Twilio: Building Exquisite Texts

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


Eddie ZaneskiWhen did you know that you wanted to flip bits and change the world as a software developer? Some members of our wonderful tech community have always known exactly what they wanted to do. However, my introduction to the magical world of programming came a bit later in the game than many others. I owe the community for helping me catch up.

Two years into a math education degree is when the requirement for an introduction to programming class crept up. I didn’t really know what to expect as I copied the code off of the board into my text editor. But after fixing a missing semicolon and watching the words “Hello, World” print out to the screen my life was changed. I’d finally found something that empowered me to build. A change in major to computer science and a transfer to a community college had me raring to recoup lost years. Ironically, it turns out that my community college was actually lacking in the ‘community’ department. Driven to learn at an accelerated rate, I turned to the Internet to supplement my education. This was my first introduction to the developer community and its vastness left me awestruck.

The resources you can find online are boundless. Besides being able to look at pictures of cats and get in arguments with strangers, online communities have made it possible to learn just about anything about, well… anything. I took advantage of this knowledge made accessible by this faceless collection of strangers and started to learn more about the web through Ruby and Rails.

After finishing up my associates degree and transferring to Rutgers I found myself being led to The CAVE for the first time. My head might as well have exploded right then and there at the sheer awesomeness that was the Rutgers hacker community. Before me was a room filled with dedicated and passionate hackers teaching each other and collaborating on projects. I began to understand that the anonymous collection of avatars that lived on the internet were in fact real people from all walks of life.

A few weeks later I found myself in a giant room surrounded by 300 other hackers at my first hackathon. Everyone was here to learn something new and build something cool over the next 24 hours. The realization was that this was still only the very beginning. As long as individuals with a love for building technology exist, this community that I am now a part of will continue to grow and astound me. It is thanks to the shared passion of other developers that I have been able to catch up and immerse myself in this magnificent world. As that happened it became very clear that I wanted to help others become inaugurated into this magic.

My name is Eddie Zaneski and I have joined the Developer Evangelism crew at Twilio in NYC after serving the developer community for the past year at SendGrid. I cherish having the honor and privilege of sitting down with newcomers and watching their eyes expand as they see “Hello, World” appear for the first time. If you’re a veteran, I’d love to sit down and talk nerdy about your latest hack or favorite framework. I am looking forward to meeting you at the next meetup, conference, or hackathon that you attend.

Introducing Twilio Developer Evangelist Eddie Zaneski

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


Last updated: August 27, 2015 08:01 PM All times are UTC.
Powered by: Planet

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