August 24, 2016

Here’s all the code you need to receive an SMS message and to send a reply using Ruby, Sinatra, and Twilio:

require 'sinatra'

post '/message' do
  number = params['From']
  body = params['Body']
  
  content_type 'text/xml'
  "<Response>
     <Message>
       Hello #{number}. You said: #{body}
     </Message>
   </Response>"
end

If you’d like some explanation on how that code works, watch this short video, or just keep reading.

When someone texts your Twilio number, Twilio makes an HTTP request to your app with details about the SMS passed in the request parameters. In this post, we’ll use Sinatra to handle Twilio’s request, parse the parameters, and to send a response. 

First we install Sinatra from the console:

gem install sinatra

We create a file called

app.rb
 and require Sinatra:

require 'sinatra'

Then we create a route called

message
 to accept a POST request.

post '/message' do
  # rest of code will go here
end

Details about the inbound SMS are passed via the request parameters. If you want to see all of them, you could drop a puts params in here and watch the console when the text comes in. In our case, we’ll just grab the number the message was sent from and the body of the message.

number = params['From']
body = params['Body']

(A common mistake here is to forget to capitalize the keys, so be careful there.) 

Great, so we’ve accepted an inbound SMS and pulled information from it. But how do we send a reply? After all, it’s rude when someone texts you to not text them back.

When Twilio makes that HTTP request, it expects an HTTP response in the form of TwiML, a simple set of XML tags that relay instructions back to Twilio.

So we set the Content Type to return XML.

content_type 'text/xml'

Then we implicitly return a string that contains our TwiML

<Response>
 to tell Twilio to reply with a
<Message>
 that includes the
number
 it was sent from and message
body
 
from the inbound SMS.

"<Response>
  <Message>
    Hello #{number}. You said: #{body}
  </Message>
</Response>"

We save our file, then start our Sinatra app from the console.

ruby app.rb

This app needs a publicly accessible URL, so you’ll either need to deploy it to the cloud or use a tool like ngrok to open a tunnel to your local development environment.

./ngrok http 4567

Ngrok will provide you with a url that points to your localhost.

Set up Twilio

Sign up for a free Twilio account if you don’t have one.

Buy a phone number, then click Setup Number. Scroll to the Messaging section and find the line that says “A Message Comes In.”

message-comes-in

Fill in the full path to your file (i.e.,

https://yourserver.com/message.php
) and click Save.

Now, send an SMS to your shiny new phone number number and revel in the customized response that comes back your way.

Next Steps

If you’d like to learn more about how to use Twilio and Ruby together, check out :

And if you’d like to chat more about this, drop me a line at gb@twilio.com.

Happy Hacking!

A Simple Way to Receive an SMS with Ruby, Sinatra, and Twilio

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


August 23, 2016

Thanks to the power of code, your pets are never more than a POST request away. Shannon Turner built a Twilio MMS, Raspberry Pi + Django hack so she can see what her winged companion, a lovely parrot, is up to when she’s out.
 
“Any time I miss my pet, a photo of him playing with his toy is only a text message away,” says Shannon. “I’ve had BudgieCam running for just over a month and I’ve already taken over 200 photos and nearly 100 videos.”

Building BudgieCam

 


When Shannon is on the road, she sends a text to her Twilio-powered number. Twilio gets that requests and fires off a POST request to Shannon’s Django site which triggers her Raspberry Pi (complete with Raspberry Pi Camera) to take a photo. The photo is stored on Shannon’s Pi server. Then Django instructs Twilio to send an MMS with the photo of Shannon’s pretty bird back to Shannon. This all takes place in the span of a few seconds.
 
Shannon usually doesn’t do this. She normally ships civic minded hacks. Hacks that help women learn to code, recommend movies that pass the Bechdel test, or out politicians whose ideals are quite behind the times. “This hack is just for fun,” says Shannon.
 
If you want to engineer a little fun and a whole lot more pet pictures into your life, here’s the code Shannon used to build BudgieCam on GitHub. Take a look at the Twilio integration below, and the MMS docs that will give you a good foothold in tackling project like this.
 

from django.shortcuts import render
from django.views.generic.base import TemplateView

import subprocess
import time

from twilio.rest import TwilioRestClient 

from budgie_settings import BUDGIE_PASSPHRASE, BUDGIE_FILE_PATH, BUDGIE_WEB_PATH, RASPI_IP
from twilio_credentials import ACCOUNT_SID, AUTH_TOKEN

class BudgieCamView(TemplateView):

    def get(self, request, **kwargs):

        """ Response Code 418: I'm a teapot
        """

        template = 'response.html'
        context = {
            'response': '418'
        }
        return render(request, template, context)

    def post(self, request, **kwargs):

        """ Twilio is configured to POST to this URL when a text message is received.
            1. Receive text message
            2. Verify text message and continue if verified
            3. Snap photo (use subprocess module)
            4. Photo needs to be accessible via a URL
            5. Use Twilio API to attach photo to SMS
        """

        text_message = request.POST.get('Body')
        requesting_phone_number = request.POST.get('From')
        budgiecam_phone_number = request.POST.get('To')

        context = {}

        if text_message:
            if BUDGIE_PASSPHRASE in text_message.lower():
                if 'video' in text_message.lower():
                    try:
                        budgie_filename = '{0}.h264'.format(''.join(['{0:02d}'.format(x) for x in time.localtime()[:6]]))
                        # raspivid -o video.h264 -t 10000
                        subprocess.call(['raspivid', '--nopreview', '-t', '30000','-o', '{0}{1}'.format(BUDGIE_FILE_PATH, budgie_filename)])

                        # This would convert the h264 video to mp4 but unfortunately it doesn't run quickly enough on the Raspberry Pi
                        # Maybe later versions of the Pi would be able to handle it, but this one can't.
                        # try:
                        #     print "\t Converting {0} to mp4".format(budgie_filename)
                        #     subprocess.call([
                        #         'ffmpeg',
                        #         '-i',
                        #         '{0}{1}'.format(BUDGIE_FILE_PATH, budgie_filename),
                        #         "{0}{1}.mp4".format(BUDGIE_FILE_PATH, budgie_filename[:-5])
                        #     ])

                        # except Exception:
                        #     print "[ERROR] Failed to convert {0} to mp4".format(budgie_filename)
                        # else:
                        #     subprocess.call([
                        #         'rm',
                        #         '{0}{1}'.format(BUDGIE_FILE_PATH, budgie_filename)
                        #     ])
                        #     budgie_filename = "{0}.mp4".format(budgie_filename[:-5])
                    except Exception, e:
                        print "[ERROR] Call to raspivid failed; could not take video ({0}: {1}{2})".format(e, BUDGIE_FILE_PATH, budgie_filename)
                    else:
                        client = TwilioRestClient(ACCOUNT_SID, AUTH_TOKEN)
                        client.messages.create(
                            to=requesting_phone_number,
                            from_=budgiecam_phone_number,
                            body="Video ready here: {0}{1}{2}".format(RASPI_IP, BUDGIE_WEB_PATH, budgie_filename)
                        )
                        context['response'] = '200'
                else:
                    try:
                        budgie_filename = '{0}.jpg'.format(''.join(['{0:02d}'.format(x) for x in time.localtime()[:6]]))
                        subprocess.call(['raspistill', '--nopreview', '-t', '5000', '-o', "{0}{1}".format(BUDGIE_FILE_PATH, budgie_filename)])
                    except Exception, e:
                        print "[ERROR] Call to raspistill failed; could not take photo ({0}: {1}{2})".format(e, BUDGIE_FILE_PATH, budgie_filename)
                        context['response'] = '500'
                    else:
                        client = TwilioRestClient(ACCOUNT_SID, AUTH_TOKEN)
                        client.messages.create(
                            to=requesting_phone_number,
                            from_=budgiecam_phone_number,
                            body="{0}".format(budgie_filename),
                            media_url="{0}{1}{2}".format(RASPI_IP, BUDGIE_WEB_PATH, budgie_filename),
                        )
                        context['response'] = '200'
            else:
                context['response'] = '401'
        else:
            context['response'] = '400'

        template = 'response.html'
return render(request, template, context)

Learn more about Shannon and all of the rad hacks she builds right here.

Shannon Turner Builds A Pet Cam Using Django, Raspberry Pi and Twilio

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


In just under 5 weeks on September 20th we’ll bring SIGNAL to London for its first European chapter.

Last week, Phil talked about why he’s excited about SIGNAL London and mentioned some of the amazing talks we will have that day.

Now, I know I’ve said this before but some bosses just need a little convincing before they can make a decision whether they should send you to a conference or not.

So here are three reasons why your boss should send you along with all the other developers at your company.

At SIGNAL London you will:

  1. Learn best practices directly from other developers like you
  2. Discover new technologies and tools
  3. Add voice, video, messaging, and chat to your tool belt

But that’s not all. We also have business content so even if you’re not a full-time developer you will still benefit and:

  1. Hear from companies like ServiceNow, ING, Google and DriveNow about how they are driving transformational change into their businesses.
  2. Discover new use cases and products
  3. Bring your technical team to discover technical best practices

See you at SIGNAL London 2016

Take a look at our schedule if you’re still undecided about which sessions you want to attend. Join us for £50 off by using BLOG50 as your promo code when purchasing a ticket or find out more about group discounts in our FAQ. And make sure to say hello to me in September.

If you have any questions feel free to drop me a line via:

Ahoy! Get your boss on board SIGNAL London

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


August 19, 2016

DimitriDimitri Akhrin calls it how he sees it. If something’s broken, he’s going to fix it — right after he finishes telling you how broken that thing is. “Traditional reporting systems looked like Windows 95,” he quips.
 
Akhrin saw that bank-provided portals were siloed and clunky. So, he built a system to consolidate and streamline the daily functions  of Independent Sales Organizations. His solution was IRIS CRM, which talks multiple banks and payment processing platforms through a single portal and is also a full-featured call center solution. “After implementing IRIS CRM, our clients begin experiencing an immediate increase in efficiency”, he points out.
 
IRIS CRM has doubled their revenue in the past seven months. They’ve signed up more clients in those months than the previous two years combined, doubling their number of clients. A wealth of ISOs rely on IRIS CRM to manage their business at scale, and at market speed.
 

The Communications Tools IRIS Relies On

Let’s say a sales organization using IRIS CRM gets a call from a client. An agent would see a screen pop in their browser showing who’s calling, and routes the call to the proper agent or department while pulling up the client record automatically. Managers can listen in on calls in real-time to provide coaching for extra efficiency.
 
Dialer
 
When the right person picks up, call recording rules kick-in based on the client’s preset area code settings.  IRIS CRM allows their clients to be in compliance with two-party recording laws with just a few clicks.  Each client can set the rules of when to record calls in both directions, incoming and outgoing, automatically. After the call’s over, if it was recorded the recording will be bound to the customer record, the  call length is logged and the dialer metrics dashboard is updated.  Managers compare their day’s calls using IRIS’s sales metrics dashboard. They can also set up daily SMS alerts to report on customer’s spend.
 

The Communications Kitchen Sink

In that one workflow IRIS CRM employs the proverbial “kitchen sink”: Twilio Record, Twilio Client + WebRTC, Twilio SMS, TaskRouter, and Call Tracking.
 
backendspeed
 
Akhrin is quick to point out that meeting ISO’s needs with a quickness, all in one portal is critical to their success. While ISOs typically use call routing, recording, screen pops, and contextual tracking in a client facing fashion, they can also use those same features internally.
 
“The ability for a sales manager or sales rep to listen to a phone call of another team member and hear exactly what was said instead of  through written shorthand notes, is critical,” says Akhrin. “There’s literally no ambiguity.”
 
Call recording gives ISOs the chance to coach novice salespeople on what makes a good call.  Call routing solves common problems like salespeople forwarding calls from HQ number to their cell phone when they’re out on a trip.
 
IRIS CRM’s communications suite (internally and externally) is powered by Twilio. Their rapid fire pace of product shipping is bolstered by access to documentation. “The Twilio documentation is great,” says Akhrin.
 
Akhrin’s team is focused on continually shipping new CRM features with a quickness. If their performance seems above the industry average, Akhrin has a response to that.
 
“It’s a CRM with an integrated call center on steroids.”
 
Learn more about IRIS CRM’s call center software.

Dimitri Akhrin Builds A CRM That Moves As Fast As Sales Organizations

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


At Twilio, we’re all about helping you build new things that help make conversations happen. But sometimes we like to goof around — whether it’s teaching our dog how to take a selfie or pretending to launch ourselves into outer space. Our latest experiment? Building CommsQuest IV, a retro style labyrinth game. What’s this have to do with communications? Let’s find out.

But first, you have to take Commsquest IV for a spin. Pro Tip: lock your phone’s orientation to portrait.

How it all went down

It all started with an open source project we found on GitHub. We wanted to see just how quickly we could get the ball rolling. Any guesses? You’d think it would take at least a couple days to get something to move remotely on the screen. Not with Twilio. Using Sync, programmable SMS and a team of bright young minds, we were able to ship in a couple of hours!

Creation

The first phase involved looking for an open source JavaScript project that used the keyboard for controls. We needed something with a controller because we wanted to build the unconventional — using the phone to control the player character. Browsing GitHub, we found Astray.

Development

We put Labyrinth at the center. After creating the Node.js project, we kicked off the sync process with a text message from Programmable SMS. What this did was prompt the desktop browser to send a text message to your mobile phone so that it would become your controller.

Once connected, the phone took your gyroscope and accelerometer data and sent it to your desktop browser in real time using Sync. All it took was a few lines of code.. The desktop then listened for updates to a Sync Document, we then took that new data and used it to apply a new force to the ball. That’s it!
Not to say there weren’t any problems. When we first started playing around with it, the ball was too responsive. Tweaking it here and there to find just the right balance took a while but that’s where all the fun is.

Progression

Any game wouldn’t be a game without levels. So, we added four:

Level Description
Cave of
Last-Call
Roll your stone through the cave to complete the first “telestone” call of all time!
Castle Calldropsalot Carry your spark through the tower to light the signal fire and save the castle!
Telecom
Towers
Navigate your energy node through the global communications infrastructure to the PBX box across the world!
Tomorrow
land
Roll your happy ball of light through a maze of infinite rainbows.
CommsQuest IV Level 3Level 3: Telecom Towers

As team leader, I was thrilled to be able to hack away on a new Twilio product because it would give other developers the opportunity to potentially collaborate on a new project. To be honest, I wasn’t expecting to continue working on this after a hack session, but given the level of interest, it looks like great things are yet to come.

Why did we use Sync? Because we needed to move fast. We had a limited amount of time and a need to ship. Interested in learning more about Sync, and how you can incorporate it into your projects? Take a look at Introducing Sync – Real-time State Synchronization API for more information.

I wanted to share my story with the hope of inspiring you to create something new. With more than a million developers using our platform, it’s exciting enough just to think of all the possibilities. If we can build a game in an hour, we can’t wait to see what you build.

CommsQuest IV – A Retro Game Built Using Twilio Sync

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


August 18, 2016

When building iOS applications, we often need to work with data from various APIs. But sometimes the data you want access to isn’t nicely packaged and available via a REST API. In these cases we can scrape data directly from a web page using the Kanna Swift library.

Let’s build an iOS app that will display all of the upcoming metal shows in New York City by scraping the NYC Metal Scene website.

Getting started and setting up our project

Start off by cloning this repository which contains a starter project for us to build on. This project already has a storyboard set up with a UITableView that we will use to display the data we scrape. I am using XCode version 7.3 and Swift version 2.2, so make sure this code is compatible with your version of XCode and Swift.

Open your terminal and navigate to where you want this project to live. Enter the following command to clone it, you can also download a zip file of the project:

git clone git@github.com:sagnew/upcoming-metal-shows-ios.git && cd upcoming-metal-shows-ios && git checkout tutorial

We are going to use CocoaPods to install the dependencies we’ll need for this project. Install CocoaPods if you don’t have it:

sudo gem install cocoapods

In the repository that you cloned, there is a Podfile that lists which dependencies we need to install. These are Kanna for parsing HTML and Alamofire for making HTTP requests. Install them with the following command:

pod install

CocoaPods takes care of linking all of the frameworks for you by creating a new Xcode Workspace. From now on when opening the project in Xcode, you’ll have to use UpcomingMetalShows.xcworkspace instead of your normal Xcode project:

open UpcomingMetalShows.xcworkspace

You can check that Kanna and Alamofire were installed correctly by adding these two lines to ViewController.swift:

import Kanna
import Alamofire

Press “Command-B.” to verify the project builds with those dependencies referenced.

Scraping data from a web page using Alamofire

With the starter project in place we can move on to the next step in building the app, making the HTTP request to acquire the concert data. In our case we want to make a request to http://nycmetalscene.com/ and scrape the HTML content that is returned.

Before making the request we have to configure our app to allow making an HTTP request to a non-secure website, or a website that is not accessible via HTTPS. Starting in iOS 9, Apple enabled App Transport Security which by default disallows requests to non-secure websites. To make our app work we will need to add an exception to this policy by editing the Info.plist file.

Open Info.plist, add a new Key to the Information Property List called App Transport Security Settings and set the Allow Arbitrary Loads value to YES as seen in this GIF:

appsecuritytransport.gif

With the exception in place we can grab HTML from the page we are trying to scrape. To do this, we need to send a GET request with Alamofire.

Open your ViewController.swift and add the following code to the ViewController class:

// Grabs the HTML from nycmetalscene.com for parsing.
func scrapeNYCMetalScene() -> Void {
    Alamofire.request(.GET, "http://nycmetalscene.com").responseString { response in
        print("Success: \(response.result.isSuccess)")
        self.parseHTML(response.result.value!)
    }
}

func parseHTML(html: String) -> Void {
    // Finish this next
}

The parseHTML(html: String) -> Void method will take the HTML from our GET request and use Kanna to make sense of it.

Trigger the loading of the data by adding a call to this new function at the end of viewDidLoad:

override func viewDidLoad() {
    super.viewDidLoad()
    metalShowTableView.delegate = self
    metalShowTableView.dataSource = self
    self.scrapeNYCMetalScene()
}

Now run the app again to see if the request is sent successfully

Screen Shot 2016-08-17 at 2.07.40 PM.png

Parsing scraped data with Kanna

Before writing code to parse the content returned from the GET request, let’s first take a look at the HTML that’s rendered by the browser. Every web page is different, and sometimes getting data out of them requires a bit of pattern recognition and ingenuity.

In our case we want to grab all of the metal shows included in the markup.

Screen Shot 2016-08-16 at 1.51.01 PM.png

Each show exists in a td tag and has an ID of Text followed by some number. This is the first pattern we’ll use to grab the HTML elements that contain the show info.

Next, you may notice that every piece of text on the page follows that ID pattern, not just the shows. To extract just the text nodes for concerts, we will use a second regular expression to find text that begins with the first three letters of a weekday. This pattern indicates that the text is referring to a concert.

With the two patterns for extracting concert data we’re ready to parse the content. Using Kanna, developers can use CSS selectors or Xpath queries to navigate through the HTML in a document. Let’s use CSS selectors with a regular expression to find all td nodes that have an ID beginning with “Text.”  Next we’ll loop over those results and apply the day-of-week regular expression.

Edit the parseHTML method to contain the following example code that will print out the text for all of the shows on the page:

func parseHTML(html: String) -> Void {
    if let doc = Kanna.HTML(html: html, encoding: NSUTF8StringEncoding) {

        // Search for nodes by CSS
        for show in doc.css("td[id^='Text']") {

            // Strip the string of surrounding whitespace.
            let showString = show.text!.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())

            // All text involving shows on this page currently start with the weekday.
            // Weekday formatting is inconsistent, but the first three letters are always there.
            let regex = try! NSRegularExpression(pattern: "^(mon|tue|wed|thu|fri|sat|sun)", options: [.CaseInsensitive])

            if regex.firstMatchInString(showString, options: [], range: NSMakeRange(0, showString.characters.count)) != nil {
                shows.append(showString)
                print(showString + "\n")
            }
        }
    }
}

Run the app to see that it is printing out only the shows on the page and not all of the unnecessary text, similar what is shown in the following Xcode screenshot.

Screen Shot 2016-08-17 at 2.16.05 PM.png

Next, we will work on displaying this data in the mobile app.

Displaying the data that we scraped in a UITableView

Let’s display all of the shows in a UITableView so we have an actual app.

The sample project already has one added to the application and configured in Main.storyboard, as well as the required methods in ViewController.swift. All we need to do is link our data to this view.

We are using the shows array as the data source for the UITableView. Add a line to the end of our parseHTML function to make sure that the data in the UITableView is being loaded once we are done parsing the shows:

func parseHTML(html: String) -> Void {
    if let doc = Kanna.HTML(html: html, encoding: NSUTF8StringEncoding) {

        // Search for nodes by CSS
        for show in doc.css("td[id^='Text']") {

            // Strip the string of surrounding whitespace.
            let showString = show.text!.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())

            // All text involving shows on this page currently start with the weekday.
            // Weekday formatting is inconsistent, but the first three letters are always there.
            let regex = try! NSRegularExpression(pattern: "^(mon|tue|wed|thu|fri|sat|sun)", options: [.CaseInsensitive])

            if regex.firstMatchInString(showString, options: [], range: NSMakeRange(0, showString.characters.count)) != nil {
                shows.append(showString)
                print(showString + "\n")
            }
        }
    }
    self.metalShowTableView.reloadData()
}

We also need to define what data a cell in our table view contains. Replace the tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) function with the following:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier(textCellIdentifier, forIndexPath: indexPath)
        
    let row = indexPath.row
    cell.textLabel?.text = shows[row]
        
    return cell
}

Now run the app and look at the list of upcoming metal shows in NYC

Screen Shot 2016-08-16 at 11.46.04 AM.png
Wow it looks like Megadeth, Amon Amarth, Suicidal Tendencies, Metal Church and Havok are all playing the same show in October! Sounds like a pretty sick lineup.

The vast expanse of the World Wide Web

Now you can build apps using data that isn’t neatly available to you in the format of a publicly accessible API by just grabbing it from the Internet.

Beware that changes to a web page’s HTML might break your app, so make sure to keep your code up to date.

If you want to build with something that doesn’t require scraping data from old web pages, check out Twilio’s Video and IP Messaging iOS SDKs for adding video conferencing and real time chat to your Swift applications.

I’m looking forward to see what you build now that you have access to all of the data on any web page. Feel free to reach out for any questions or to show off what you built:

Web Scraping and Parsing HTML in Swift with Kanna and Alamofire

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


Japanese robotics maker MJI has integrated human emotion recognition into its communication robot Tapia. MJI adopted Smartmedical’s Empath, a vocal emotion recognition technology used in various business fields such as mental health, call centers, and entertainment. With Empath, Tapia can understand human emotions, including joy, calm, sorrow, anger, and vigor, through dialogue with users. “The global robotics […]

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


Who knew an artist could change the trajectory of their career one SMS at a time?

Ryan Leslie, the Harvard educated, grammy-nominated rap and hip-hop artist did just this. He created SuperPhone, a platform that enables him (and you) to connect with an audience on a more personal level.

Ryan will be joining us for SIGNAL London on September 20th, 2016. You don’t want to miss it.

This is SuperPhone

We recognized Ryan as a DOER at SIGNAL, our annual conference for developers. DOERs are folks in the Twilio community who’ve done something to change the world with a text editor.

I texted +1 (646) 887-6968 in October 2015 to ask Ryan what he thought about being a part of SIGNAL. But I never expected that I’d actually get a human response, let alone from Ryan himself! After exchanging a few texts with Ryan via SuperPhone you can’t help but feel like maybe you’ve been friends for a long time. This is a powerful thing, giving an artist the freedom to have real connections with their followers. And Ryan has personally replied to over 50,000 of his fans since creating SuperPhone.

“Literally, my entire life started to change. Not just because I had a 50% conversion rate on sales,” says Ryan.

He was as excited to share this story as he is to share his music with his fans. And it could not have been more surreal to see a rapper/producer/coder/entrepreneur onstage at SIGNAL. Around 18 minutes into the video, Ryan transitions from telling his story to busting out a performance like no other in respect to what most developers experience at a tech conference.

Check out the full story and watch him perform Never Break Down at SIGNAL here:

 

DSC_8811Next Up: SIGNAL London

Ryan and the SuperPhone story are ever evolving. He will be joining us again on September 20th at The Brewery on Chiswell Street to share more with the developer community at SIGNAL London. Use the code BLOG50 on registration and you’ll get £50 off the ticket price.

 

Ryan Leslie is Coming to SIGNAL London

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


August 17, 2016

In 2008, Nate Silver came within one percentage point of perfectly predicting the popular vote results of the Presidential Election. In 2014, Silver’s team at FiveThirtyEight recorded exactly how many clouds Bob Ross painted over the course of his show’s 31 seasons.

FiveThirtyEight is not just a crack team of data-driven journalists. They’re also caretakers of a treasure trove of data readily available for our consumption on GitHub. Using Python, we can easily parse through the data to find nuggets of wisdom on everything from Bob Ross, to political polls, to how to break FIFA.

What You’ll Need

You’ll need Python 2 or 3 for this tutorial. I’m using Python 2.7.

You’ll also need Pandas (not the black and white fluffy bears, but the Python friendly kind)

Employing The Help of Pandas

Python, along with Pandas, is going to do a lot of our heavy lifting. The pandas data analysis library gives us a very easy, intuitive way to sort through our csv data, straight from the command line. Once we get set up, we can name what we’re looking for, and get a ton of information with simple commands.

Examining Mission Critical Data — How Many Bushes Did Bob Ross Paint?

Fire up your terminal and create a file called

FiveThirtyEight.py

Next, let’s get a python environment going. Type the command

python

We need to create an environment fit for pandas. Let’s run the following command:

>>>pip install pandas

Great. We’re ready for Pandas. Let’s invite them in along with

numpy
, a package for easily computing large sets of numbers. We’ll also use the requests library to get the data from FiveThirtyEight’s GitHub where their csv chock full of Bob Ross data lives.

Tragically, we know this csv won’t be changing any time soon. Bob Ross has passed on and won’t be adding to our data set. R.I.P Bob Ross.

But, If you’re working with csvs that are constantly being updated, using requests ensures you current data. Instead of downloading the latest version of a csv and hoping it’s up to date, you can request the data from a recently updated GitHub repo.

Making Requests To FiveThirtyEight’s GitHub Repo

StringIO operates like an open file command and passes the content of our csv file to pandas as a data set.

>>> import pandas as pd
>>> import numpy as np
>>> import requests
>>> from StringIO import StringIO

 
If you’re using Python 3, you’ll want to use BytesIO and run the command
 

>>>from io import BytesIO

 
Great. Now we’re set up to request data from FiveThirtyEight’s GitHub repo. We’ll do that using requests and the .get command. By defining the response variable and the content variable, we can easily call upon the response of our call to the FiveThirtyEight url and the content from that response. StringIO parses the content as a data set pandas can read, and ensures pandas doesn’t mistake the strings in the csv for urls. Once we have that content, we’ll define it as a dataframe that pandas can read using the .read_csv function.

>>>url ='https://raw.githubusercontent.com/fivethirtyeight/data/master/bob-ross/elements-by-episode.csv'
>>>response = requests.get(url)
>>>content = StringIO(response.content)
>>>df = pd.read_csv(content)

 
For the Python 3 folks, run content like so:

>>>content = BytesIO(response.content)

 
Rad! We now have all of our Bob Ross data in Terminal. Let’s see how we can view specific subsets of data. Using the

df.head()
command, pandas will give data from the first five rows of our csv file. In this case, that’s the first five episodes. If we wanted to see the first 10 episodes, we’d just pass in an argument like:

>>>df.head(10)

Now, let’s answer the burning question — how many clouds did Bob Ross paint?  By calling upon the column “CLOUDS” and asking for the sum of that row, pandas will deliver us the answer.

>>>df ["CLOUDS"].sum()


Bob Ross painted 179 happy little clouds


If we wanted to calculate the probability he’ll paint a cloud in any given episode, we could run

>>>df["CLOUDS"].mean()
.

 
Blam. There’s a 44% likelihood that Bob Ross will paint a cloud. But what if we wanted to see how many times Bob Ross has graced his happy little clouds with a tree friend?

By grouping the two rows “CLOUDS” and “TREES” together and calling the sum, we see how many times he painted trees and clouds together.

>>>df.groupby("TREES")["CLOUDS"].sum()

When you run this, you’ll see that under the 0 column, there are 41 instances where Bob Ross painted clouds with no trees, and there are 138 instances where he painted the two together. When you add 41 to 138, you get 179 — the total number of clouds Bob Ross painted.

More Fun With CSVs and Python Ahoy!

Now that you know how to parse and loop through CSV data, you can answer all sorts of questions straight from the command line.

Resources

If you’re looking for more opportunities to flex your Python skills here are a few resources.

 
If you’ve got any hot data, Bob Ross jokes, or other quips — shoot me a note @kylekellyyahner or kyleky@twilio.com

Digging Through A Treasure Trove of FiveThirtyEight Data in Python!

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


August 16, 2016

SIGNAL London is bringing the best of SIGNAL San Francisco to this side of the Atlantic. In just one day, on the 20th of September 2016, we are packing two tracks of talks with as much knowledge and experience that we can to help you change communications with the power of code.

If that’s enough to get you excited, then go grab yourself a ticket now and I’ll see you in September. Oh, and if you use the code BLOG50 you’ll get £50 off the price.

If you’re looking to be convinced, then let me share a few reasons why I’m excited for SIGNAL London.

We will learn amazing things

We’ve got speakers from both inside and outside of Twilio sharing their experiences. This is the best place outside of SIGNAL San Francisco to learn from both the people building Twilio as well as those using it day to day.

On the Twilio side of things I’m looking forward to:

How about those developers who are building the future of communications every day? I’m excited to hear from:

On a side note, if you’re a fan of Twitch, check out Twilio’s Twitch channel where you can regularly find myself and other members of the developer evangelism team live streaming our coding sessions.

We’ve also got a real taste of the future from:

And that’s not all, there are many more speakers to keep you informed and entertained over the whole day.

A selection of the speakers coming to SIGNAL London, including Chris Pope, Joseph Seal-Driver, Julia Farraioli, Katy Moe, Lukas Oberhuber, Peter Gasston, Ryan Leslie and Warren Colbert

We will meet amazing people

Of course, conferences aren’t just about sitting and listening. There’s going to be a strong hallway track too.

There’ll be plenty of Twilions there to answer questions about your applications and find out what you’re building. And there will be many other developers to meet, share experiences with and learn from. I’m most looking forward to meeting as many of you there that I can!

We will be the first to know

This year at SIGNAL San Francisco, Twilio announced Programmable Wireless, Notify, Add-ons and a whole new developer experience throughout the Console, Documentation and Debugger. Who knows what we’ll hear about in London? All I know is, if you’re there at SIGNAL London, you’ll be the first to hear.

I’m excited to see you there

So don’t hang about! Ticket prices go up on the 20th August, so grab your ticket now and get a £50 discount using the promo code BLOG50. Check out the schedule and the rest of the speakers and I’ll see you in September!

Why I’m excited about SIGNAL London

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


Speech has come a long way and is now starting to have a major impact in a variety of fields. It is set to play an even greater part in our busy, daily lives as service planners grapple with the complexity of evolving urban landscapes. As multimodal transportation and the sharing economy take on increasingly-defined roles, they will spark the birth of new, exciting services. That said, these innovative technologies can easily overwhelm. But this is where text-to-speech software can really make a difference.

Transportation is fundamental in meeting the objectives of economic competitiveness, social cohesion and sustainable growth. A European Union study estimates that 74% of Europe’s population lives and works in big cities, and by 2050 it is expected that around 82% of the continent’s population will be concentrated in urban areas, with cities and towns driving the economy, contributing up to 85% of EU Gross Domestic Product (GDP). Efficient urban transport is essential for European cities to be competitive as commercial and economic hubs, and further on a global scale.

An increasing dependence on cars due to unreliable public transport, an aging population, demands for new and flexible lifestyles: these are just a few of the critical aspects that service planners are looking at as they research new transport solutions for more efficient movement of people. In the past few years, the sharing economy paradigm has brought a new dimension to the transportation landscape. Multimodal travel has become more multi-faceted and is part of nearly every traveler’s daily commute. You may drive your car to the nearest train station, catch a local rail line and then a metro, tram or bus to reach your destination. Some professionals take a high-speed intercity to work every day. Car- or bike-share may come into the equation at some point. Different services and providers, a variety of ways of getting from A to B – punctually, or with great inconvenience – all in a single day.

For the vast majority of individuals, the key to planning the daily commute is staying informed and we mainly do that using our smartphones. We make plans according to how much we can rely on specific services.

Innovative system developers are starting to cater to a demand in smart mobility options, but there is still a world of apps and services to create. There’s debate surrounding the question of whether “urban travel experience” services lie in the public or in the private domain. Whatever the outcome is, effectively deployed, real-time multimodal journey planning, updating and ticketing are all aspects that would greatly enhance everyone’s experience – from travelers, drivers, fleet operators to network and service managers. New technologies bring opportunities for integrating data useful for journey planning and electronic ticketing, and smart cards to facilitate interoperability between public and private transport modes.

And this begs the rhetorical question: Could a great multimodal travel experience be based on anything other than multimodal technology? User opinions indicate that speech is a central element in the multimodal user experience. In all circumstances where deciphering information on screens isn’t ideal or preferred, speech mode for information fruition is essential for the less tech-savvy and anyone with specific accessibility requirements. Integrating lifelike text to speech services for travelers is key. One could consider a public transport information system designed with voice content that is pre-recorded in a studio. But it is more expensive to deploy, and it does not deliver what users need: real-time information on routes, road or track works, unforeseen delays, congestion or any other factors impacting journey times.

By choosing high quality text-to-speech technology, transportation system providers get the best of both worlds: clear, lifelike voices that instantly read the very latest information to passengers, who can decide on the best travel strategy to adopt. As in all contexts, being informed makes for a better experience.

Moreover, in today’s global economy, mobility is multilingual. And when, for example, foreign visitors land at an international airport, it is both courteous and practical to provide information in languages visitors will understand. It’s incredibly easy and cost effective to deploy a world-class, multilingual travel experience by integrating high-quality, multilingual text to speech that provides international travelers with the information they need to reach their destinations safely.

In all travel and transportation domains – underground or over ground, from platform announcements to on-board information in trains, buses or trams – adding text-to-speech voices is a win-win investment.

Ask ReadSpeaker how to deploy human-like text to speech for a satisfying multimodal user experience in all your urban mobility services.

 

 

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


August 15, 2016

In this tutorial we’ll receive and reply to a text message in PHP. If you’re the type who likes to skip to the punchline, create a file named

message.php
 and paste in this code:

<?php
$number = $_POST['From'];
$body = $_POST['Body'];

header('Content-Type: text/xml');
?>

<Response>
    <Message>
        Hello <?php echo $number ?>.
        You said <?php echo $body ?>
    </Message>
</Response>

To learn more about how this works, watch this one minute video, or just keep reading.

Twilio’s HTTP Request

When someone texts your Twilio number, Twilio makes an HTTP request to your app. Your app parses the request, then sends back an HTTP response with instructions for what Twilio should do next.

sms-http-request-cycle

Details about the inbound SMS, such as the body of the message and the number it was sent from, are passed via the request parameters. To receive and parse Twilio’s request, create a file called

message.php
 and pluck the From and Body from the
$_POST
 parameters:

<?php
$number = $_POST['From'];
$body = $_POST['Body'];

A common mistake is to forget to capitalize the first letter of the keys (

‘From’
  ,
‘Body’
), so be careful there.

When Twilio makes an HTTP request to your server, it expects an HTTP response in return. This response takes the form of TwiML, a subset of XML used to relay instructions back to Twilio. Thus, we start our response by setting the 

Content-Type
 header to
text/xml
.

Valid TwiML has instructions nested inside opening and closing 

<Response>
 tags (even if you don’t want Twilio to do anything, you should still send back an empty
<Response></Response>
). In this case, we use the
<Message>
 tag to reply with an SMS that uses the
$number
 and
$body
.

header('Content-Type: text/xml');
?>

<Response>
    <Message>
        Hello <?php echo $number ?>.
        You said <?php echo $body ?>
    </Message>
</Response>

And that’s all the code we need to receive and reply to a text message. That said, there’s lots more you can do with TwiML. If you’d like to learn more, check out the docs.

Your

message.php
 needs to have a publicly accessible URL for Twilio to reach it, so push it to a server or use ngrok to open a tunnel to localhost. Then we just need to point a Twilio number at that URL.

Setup Twilio Phone Number

Sign up for a free Twilio account if you don’t have one.

Buy a phone number, then click Setup Number. Scroll to the Messaging section and find the line that says “A Message Comes In.”

message-comes-in

Fill in the full path to your file (i.e.,

https://yourserver.com/message.php
) and click Save.

Now, send an SMS to your shiny new phone number number and revel in the customized response that comes back your way.

text-twiio-number-php

Next Steps

If you’d like to dive deeper into the world of Twilio SMS, I’d recommend you check out:

If you have any questions, drop me a line at gb@twilio.com.

A Simple Way to Receive an SMS with PHP and Twilio

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


August 12, 2016

Looking for a reason to start playing with Twilio’s PHP Helper Library, Shahzeb Khan built (650)82OCEAN while anxiously awaiting the release of his favorite artist’s latest album.

Boys Don’t Cry is the long suspected second studio release from that of one Frank Ocean. Why a project around Frank Ocean? Shahzeb says, “I mean, it’s become a meme right?”

Fans of the rap artist are all too familiar with the waiting game as the album has been a tease since mid 2013.

Are You There Frank, It’s Me Shahzeb?

Tired of watching Twitter and music blogs so closely for any news of a release, Shahzeb thought he would save time on this effort for himself and two or three friends.DSC_1850

The Junior at UC Davis is studying Computer Science and Engineering. Putting those skills to use with PHP and Twilio he built (650)82OCEAN as a Lumen application. The project’s namesake comes from the Twilio number (650) 826-2326 behind it.

The service pings iTunes, Spotify, and Twitter every minute or so for any Frank Ocean updates. Inexperienced in the minutia of the album’s history thus far, I jokingly asked, “What if the album drops on Tidal?” Shahzeb laughed, but admitted he had done his research stating that Apple Support has hinted at the release.

The most “complex” part of the application includes a Twilio Controller for Lumen running a background job to handle the sending of SMS. He’s open sourced the following code on Github.

<?php
/**
 * TextController.php: 2 lines to send a text using Twilio (for Laravel and Lumen).
 *
 * By Shahzeb Khan (www.shahzeb.co or @notshahzeb on twitter)
 */

namespace App\Http\Controllers;
use Services_Twilio;
use Log;

class TextController extends Controller
{
	protected $number, $message;

	/**
	 * Create a new TextController instance
	 * @param phone-number $num Phone number for the person being texted
	 */
    public function __construct($num)
    {
    	$this->number = $num;
    }

    /**
     * Send a text message to a given number.
     * @param  text $msg Body for the text message
     * @return bool      ture = text sent, false = error
     */
    public function sendText($msg){
	    $AccountSid = env('TWILIO_SID');
	    $AuthToken = env('TWILIO_AUTH_TOKEN');
	    $client = new Services_Twilio($AccountSid, $AuthToken);
	    $this->message = $msg;
	    
	    try {
	        $message = $client->account->messages->create(array(
	            "From" => "+".env('TWILIO_NUMBER'),
	            "To" => $this->number,
	            "Body" => $this->message,
	        ));
	    } catch (\Services_Twilio_RestException $e) {
	         Log::error("Twilio error while texting ".$this->number.": ".$e->getMessage());
	         return false;
	    }
	    
	    return true;
	    Log::info("Sent text to ".$this->number); ;
	 } 
}

Just A Few Friends

Shahzeb thought about using email at first, but after writing the code in a day he says, “Twilio is actually faster than using email services, which I wasn’t expecting. It’s scaled really well and using it has been an absolute breeze.”

He’s quickly reached 8,500 subscribers for what he likes to think of as the “Frank Ocean Album Detection Service.” It has also been covered

Another thing that took Shahzeb by surprise was having international subscribers. He had people from Brazil and Mexico emailing him to ask if the number would work internationally and subsequently informing him it did indeed work. “Having this international support without any sort of code on my part is awesome,” he said.

When asked if he had any last words for the elusive Ocean, he said, “This code will survive longer than the wait.” This will come in handy if the artist ever decides to release a third album.

Until then, we are indeed waiting and Shahzeb just added another subscriber.

 

complete-signup

Shahzeb Khan Builds Frank Ocean Album Detection

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


When someone texts your Twilio phone number, Twilio makes an HTTP request to your app. Details about the inbound message, such as what it said and the number it was sent from, are passed in the parameters of that request.

In this post we’ll look at how to receive and parse that request in JavaScript using Node.js and Express. Then we’ll look at how to reply to the inbound SMS with a message of your own.

sms-http-request-cycle

Setup your Node.js Server

For those who like to skip to the punchline, here’s all the JavaScript you’ll need:

var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({extended: false}));

app.post("/message", function (request, response) {
  console.log(request.body); 
  response.send("<Response><Message>Hello</Message></Response>")
});

app.get("/", function (request, response) {
  response.sendFile(__dirname + '/views/index.html');
});

var listener = app.listen(process.env.PORT, function () {
  console.log('Your app is listening on port ' + listener.address().port);
});

To get this app up and running quickly, we’ll use HyperDev, a service that lets you write and run Node apps directly from the browser.

Open this HyperDev project, click the Remix button to create your own copy of the project, then open

server.js
. Let’s walk through this JavaScript one chunk at a time.

First we create an Express app and include

body-parser
 to parse the inbound HTTP request.

var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended: false}));

Then we:

  • create a route to receive a POST request at
    /message
     
  • log
    request.body
     to the console. This contains the all message details from Twilio. 
  • send an HTTP response back to Twilio. This response takes the form of TwiML and tells Twilio to send a reply message. 

app.post("/message", function (request, response) {
  console.log(request.body);
  response.send("<Response><Message>Hello from Twilio!</Message></Response>")
});

Finally, we:

  • Serve up a homepage. Okay, this is just so I could give you that fancy “Remix” button. You don’t really need this. 
  • Start the server. You do need this. 

app.get("/", function (request, response) {
  response.sendFile(__dirname + '/views/index.html');
});

var listener = app.listen(process.env.PORT, function () {
  console.log('Your app is listening on port ' + listener.address().port);
});

Click the logs button above the file-tree. Here’s where we’ll see our request body along with any errors that happen during development. 

logs

 

Click the Show Live button above the Logs button. Your project is now running at

http://your-space.hyperdev.space
 (actually, it’s been running this whole time). Copy your app’s URL to the clipboard. 

Setup Twilio

You’ll need a Twilio account. You can sign up for a free trial account here.

Buy a number. At the end of that process you’ll be asked to Setup Number. Scroll to the Messaging section and find the line that says “A Message Comes In.” This is where you plug in the URL of your Node app.

message-comes-in

Paste your HyperDev project’s URL into the box and append the

/message
. (i.e., 
https://your-space.hyperdev.space/message
). Click Save

Receive an SMS

Send an SMS to your shiny new Twilio number and check out your HyperDev logs. You’ll see something that looks like:

sms-logs

Whoa! That’s a lot of data. The two most useful pieces are:

  1. the body of the inbound message. This is in
    response.body.Body
  2. the phone number the message was sent from. This is in
    response.body.From

Let’s simplify that output a bit. Go back to

server.js
  and update the
/message
 route to look like this:

app.post("/message", function (request, response) {
  console.log(request.body.Body);
  console.log(request.body.From);  
  response.send("<Response><Message>" + request.body.Body + "</Message></Response>");
});

HyperDev will automatically save the file and restart your server when you make a change. Text your number again and check out the much easier to read logs. 

Next Steps

How easy that was? Receiving a text message is as simple as setting up a basic web server and writing a few lines of JavaScript. Replying is as easy as sending back three lines of XML. And with HyperDev, writing and deploying a Node app is as easy as opening a browser.

If you’d like to dive deeper into the world of Twilio SMS, I’d recommend you check out:

If you have any questions, drop me a line at gb@twilio.com.

How to Receive an SMS in Node.js with Twilio and HyperDev

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


Tabs vs. spaces isn’t the only big discussion point in the world of programming. Another point of contention lies in statically-typed vs. dynamically-typed languages. TypeScript is Microsoft’s attempt to add a stronger type system to JavaScript while making both camps happy. Instead of wading into the debate, let’s look at three aspects of TypeScript:

  1. How to add TypeScript to an existing JavaScript project
  2. Improving your development experience and tooling
  3. Down-transpiling TypeScript and modern JavaScript to older standards

Why TypeScript?

Here are some reasons you might want to write TypeScript:

  • TypeScript is a superset of JavaScript, so the learning curve is not that steep.
  • It’s ES2015 compliant and can transpile it down to ES3 or ES5. No more need for Babel in most cases.
  • Types are optional, so you can gradually introduce them.
  • A richer development experience including better auto-complete and project wide refactoring

You can find great list of reasons here: When should I use TypeScript?

Setup your environment

There are plenty of Getting Started with TypeScript guides that focus on how to start from scratch. We will instead add TypeScript to an existing Node.js project.

Before we get started make sure you have Node.js installed and that the version is newer than 6.0. You can check this by running:

node --version

Then clone the project that we will be working on:

git clone https://github.com/dkundel/basic-node-server.git -b typescript-boilerplate
cd basic-node-server

Install all the necessary dependencies and start the server to test if it works:

npm install
npm start

Navigate in your browser to http://localhost:3000/api/gifs. If you see a bunch of Silicon Valley gifs, your Node.js project works correctly.

Next you need the TypeScript compiler. It’s recommended you install it locally to the project:

npm install typescript --save

For the best TypeScript experience, you should either use Visual Studio Code, Visual Studio or a plug-in for your favorite text editor. I’ll be using Visual Studio Code which is available for free for Mac, Windows and Linux.

Once you have your IDE set up you are all set to dive into the world of TypeScript.

Configuring the TypeScript project

A TypeScript project is typically described by a tsconfig.json file that is located in the root directory of your project. It defines various properties for the compiler such as which files to compile or ignore, which ECMAScript version it should compile to, how to treat modules and other options. It even provides support for handling JSX files named TSX and can compile them directly to React statements.

Add the following tsconfig.json file to your project:

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "sourceMap": true
  }
}

Definitions first

TypeScript is all about types. Most libraries, however, are not written in TypeScript. So how do we get type-information on all the libraries we want to use?

The answer is definition files which provide interfaces and type information for existing libraries. To manage definition files we will use the typings tool. To install it run:

npm install typings --save

Now that we have both the compiler and the typings tool we need to create npm scripts entries to use them. To do so, modify the package.json file in the root of the project:

{
  "name": "basic-node-server",
  "version": "1.0.0",
  "description": "A basic Node server that is running on Express.js. Used to show how to add TypeScript to a project",
  "main": "index.js",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1",
    "typings": "typings",
    "tsc": "tsc",
    "start": "npm run tsc && node ."
  },
  "repository": {
    "type": "git",
    "url": "git https://github.com/dkundel/basic-node-server.git"
  },
  "author": "Dominik Kundel <dominik.kundel@gmail.com>",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/dkundel/basic-node-server/issues"
  },
  "homepage": "https://github.com/dkundel/basic-node-server#readme",
  "dependencies": {
    "body-parser": "^1.15.1",
    "express": "^4.13.4",
    "typescript": "^1.8.10",
    "typings": "^1.3.1"
  }
}

Now install the typings for express, body-parser, Node and others by running:

npm run typings -- install dt~express dt~body-parser dt~express-serve-static-core dt~mime dt~serve-static env~node --global --save

If you want to know more about the typings tool and what’s going on, check out the project website.

Our first TypeScript file

You might have noticed a TypeScript file called mockdb.ts in the api/ folder of the project you cloned. Create a file named api/users.ts. This file will consume mockdb.ts and implement a set of REST endpoints for users.

Import the Router from the express library, create a new class Users with two public methods get() and getUser(), and export a new router:

import { Router } from 'express';

export class Users {
  public get() {

  }

  public getUser() {

  }
}

const users = new Users();

export const UsersRouter = Router();
UsersRouter.get('/', users.get);
UsersRouter.get('/:id', users.getUser);

If you compare this file to the structure of the existing gifs.js you will notice three slight differences.

  1. We don’t use the module.exports. Instead we use the new ES2015 export keyword.
  2. We replace require(...) with the new ES2015 import ... from ... syntax
  3. We declare methods as public or private.

So far we don’t have any type annotations and that’s fine. The type annotation in TypeScript is optional. But we want to learn how to do it! So let’s adjust the function signature of the two methods. They are both express request handlers.

We need to import the interfaces for Request, Response and NextFunction since they are the three arguments that get passed. Afterwards we can annotate the three arguments in each method with the types and declare next as optional by appending a ? to the argument name:

import { Router, Request, Response, NextFunction } from 'express';

export class Users {
  public get(req: Request, res: Response, next?: NextFunction) {

  }

  public getUser(req: Request, res: Response, next?: NextFunction) {

  }
}

const users = new Users();

export const UsersRouter = Router();
UsersRouter.get('/', users.get);
UsersRouter.get('/:id', users.getUser);

We now have typed arguments and a much better autocomplete in our IDE. For example, now you don’t have to look up the available methods on a response object on the project website.

Our routes don’t yet return anything. Let’s send Ahoy! on the routes and include the :id passed to the URL:

  public get(req: Request, res: Response, next?: NextFunction) {
    res.send(200, 'Ahoy!');
  }

  public getUser(req: Request, res: Response, next?: Function) {
    res.send(200, `Ahoy ${req.params.id}`);
  }

We also need to consume our new file. Modify api/index.js to require the file:

'use strict';

const express = require('express');

let router = express.Router();

router.use((req, res, next) => {
  console.log(`Access to API. Route: ${req.path}`);
  next();
});

router.use('/users', require('./users').UsersRouter);
router.use('/gifs', require('./gifs').GifsRouter);

module.exports = { router };

Re-run npm start and navigate to http://localhost:3000/api/users and you will see Ahoy! on the screen.

We just wrote our first TypeScript and consumed it straight from our existing JavaScript. This is that easy because by default the compiled JavaScript is put in the same place as the TypeScript file. This means we actually execute the JavaScript but develop in the TypeScript file.

Advanced TypeScript features

Now that we wrote some basic TypeScript let’s explore a couple of more features by looking more into the existing mockdb.ts.

Import the necessary components from mockdb.ts inside our users.ts file and instantiate a database instance:

import { Router, Request, Response, NextFunction } from 'express';

import { MockDB, MOCK_USERS, User } from './mockdb';

const db = new MockDB<User>(MOCK_USERS);

export class Users {
  public get(req: Request, res: Response, next?: NextFunction) {
    res.send(200, 'Hurray');
  }

  public getUser(req: Request, res: Response, next?: Function) {
    res.send(200, `Hurray ${req.params.id}`);
  }
}

const users = new Users();

export const UsersRouter = Router();
UsersRouter.get('/', users.get);
UsersRouter.get('/:id', users.getUser);

You may notice that we pass

<User>
to our constructor. This is TypeScript’s support for generics. MockDB uses them to determine which type of data is stored. In our case these are entries of the type User. The argument itself is the mock data we want to populate the database with.

Now when we try to use the database in the request handlers we get more information about the types that are returned by the calls:

Modify the get() and getUser() methods now to consume the database:

  public get(req: Request, res: Response, next?: NextFunction) {
    let data = db.get();
    res.send(200, { data });
  }

  public getUser(req: Request, res: Response, next?: Function) {
    let id = parseInt(req.params.id, 10);
    res.send(200, db.get(id));
  }

We are now consuming another TypeScript file and made use of the power of generics.

To see more features of TypeScript you can check out the mockdb.ts file. You’ll find how to define and extend interfaces, how to create optional properties, and that specific values can be types, too.

From ES2015 to ES5

Right now our codebase is a mixture of TypeScript and ES2015 JavaScript. This works well together because the TypeScript is compiled in place, so we are executing normal JavaScript.

By adding three lines in our tsconfig.json we can not only output the result of our TypeScript into a different folder but also convert our ES2015 JavaScript to be ES5 compliant:

{
  "compilerOptions": {
    "allowJs": true,
    "target": "es5",
    "module": "commonjs",
    "sourceMap": true,
    "outDir": "out"
  }
}

Re-run npm run tsc. We have now a new folder out that contains our compiled TypeScript but also our ES2015 JavaScript converted to ES5. And we did all of that without the usage of Babel! If you run node out/index.js you will be running an ES5 version of the program. So now you can run this also with older versions of Node.

Conclusion

As we’ve seen it’s super easy to move your JavaScript project to TypeScript since any JavaScript is valid TypeScript. In most cases we don’t even need a transpiler like Babel anymore. If we add type annotations we get type-safety during compile time and better tooling for our code editor.

We just looked at a small set of things TypeScript is useful for. You can find more features on the project page.

You are now well prepared to move your projects to TypeScript or even start your next project in TypeScript.

I personally love TypeScript but I’d love to hear how your experience will be. Please reach out and let me know. We can’t wait to see what you build!

Get started with writing TypeScript today!

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


August 11, 2016

If your company does or is thinking about processing credit card payments, whether it’s a single transaction or millions, it’s wise to ensure that those payments go through a PCI-DSS compliant environment. PCI-DSS is a set of security standards established by the leading credit card companies, e.g. Visa, MasterCard, American Express, and Discover. To be clear, there are a number of... Read More

The post Expert Advice on Getting Your Tech PCI Compliant appeared first on Plum Voice.

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


What do the age-old souks of the East have in common with today’s online marketplaces? Though the former may be more exotic, both are equally fascinating. Just think of Uber—as if pulling a magic carpet out of nowhere, you tap a screen and voila! your personal ride appears at the door.

Uber might not be the first name that pops up when you think of a marketplace, but it does tap into the classical supply and demand business model by connecting buyers and sellers. Looking through this lens, you quickly find the same model being adopted across a range of industries. Not all of these marketplaces, however, are created equal.

How is it that some of them achieve unicorn status whereas others fizzle and die out? This is one question we want to help you answer.

Decoding the marketplace landscape

In our quest to determine how they stand out, we explored 200 marketplaces and uncovered two distinct business models:

  • On-demand services. Powered by swipe-away frontends and sharing economy backends. Growing over three and a half fold over the past two years, they account for $36 billion in consumer spending in the U.S. alone.
  • Listing or directory services. The dog-eared yellow pages of yesterday are now online, connecting you instantly with roofers, plumbers and more. In fact, over 50% of searches for local services are done on mobile directories.

To share some of our insight and help you navigate your way through the marketplaces landscape, we created an interactive infographic based on the frequency of use, what’s exchanged and the communication functions employed.

What the infographic can tell you about unicorns

For on-demand marketplaces transactions take place with a press of a button on a daily/weekly basis, so keeping the conversation going throughout the purchase journey is key. What happens when you turn on your taxi app and see a 6 minute ETA? You turn to their competitor. This is why on-demand marketplaces need to reduce any friction between users and suppliers. Instacart, for instance, keeps customers in the loop throughout the shopper’s journey by sending alerts via chat or SMS, so they can be immediately notified if an item is missing or not found. Given the nature of the exchange is purely transactional, on-demand services deploy phone number masking to connect users and suppliers while protecting their identity. Choose “protect identity” on the infographic to see how phone number masking is used in other marketplaces.

On the other side of the spectrum, there are marketplaces that offer higher value products/services and have longer transaction cycles. Think of buying a car or a home, for example—a process which can take months or even years. The value the marketplace offers is a reliable repository of information in the form of listings and reviews. Since the transaction often takes place offline, the marketplace typically charges a subscription fee to be listed. What’s in it for the seller? More leads. Companies like Avvo, Zillow or Cargurus implement programmable phone numbers for each listing, so any time a new prospect calls, a new lead can be tracked and the seller can clearly see the number of leads generated by the marketplace.

Some of these marketplaces go the extra mile by helping professionals achieve higher conversion rates. For example, Zillow reports that if an enquiry is answered within 5 minutes, the probability to convert a lead is 100 times higher. In case the real estate agent misses a call, the company uses SMS to send lead alerts containing relevant information allowing agents to respond quicker to inquiries. Why not give the infographic a go and see other marketplaces that are using “track leads” as a communications tool?

Uncover marketplaces with Twilio

Providing communications as an app development building block to teams in hundreds of marketplaces, we’ve seen that unicorns don’t use magic, but use something just as transformative. By integrating communications building blocks into their marketplace, they are able to attract users, build trust and deliver exceptional service.

Read the Communications Blueprint for Marketplaces ebook to learn more about our findings.

Twilio Decodes Online Marketplaces

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


Last updated: August 25, 2016 01:02 PM All times are UTC.
Powered by: Planet

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