Quantcast
Channel: Voice – Twilio Cloud Communications Blog
Viewing all 65 articles
Browse latest View live

The On-Demand Economy At SIGNAL

$
0
0

On the surface, there’s the ride, the bag of groceries, the errand you were too busy to run yourself, the whatever you ordered with the press of a button. Beneath the surface of that on-demand app, there’s a web of APIs, all connected to one another.

When you unpack the code that powers the leading on-demand businesses like Lyft, Airbnb, Instacart and others, you see one common ingredient – communication. At SIGNAL‘s On Demand Track, we’re diving into what technology stack, strategies, and swaths of data make the leading on-demand companies successful. Register right here.

Twilio Talks: Learning What Powers The On-Demand Economy

Instacart couldn’t have launched without Stripe or Checkr. Airbnb couldn’t have scaled without engineering trust between tenants and renters. In the on-demand economy the technology that powers communication, and communication itself, are inextricably linked.

Last week, at Twilio HQ, we hosted a Twilio Talks series with a panel of guests from top on-demand companies to break down what role communication plays in their business. Here are a few choice quotes. For more nuggets of wisdom, we’ll see you at SIGNAL.

The Highlights

The Full Panel


 

The Lineup

headshots
 


 


 


 


 

We’ll see you at SIGNAL.

The On-Demand Economy At SIGNAL


Calling Rails 5: Getting started with Twilio on Rails

$
0
0

I’m sad I missed RailsConf 2016 in Kansas City but it got me thinking about Rails again. Rails 5 RaceCar 1 was just released and there is a release candidate around the corner, so it’s about time to see how it plays with Twilio.

Let’s build a quick Twilio application with Rails 5. You’ll need Ruby installed, a Twilio account and a Twilio number. If you don’t already have one, you can sign up for a free Twilio account now. If you want to test this locally, you’ll need ngrok too. I’m a big fan of ngrok and I’m sure you will be too.

A brand new set of tracks

We’ll start by installing Rails 5. Open up your terminal and get yourself the latest and greatest.

$ gem install rails --version 5.0.0.rc1

Let’s create a new Rails application.

$ rails new calling-rails
$ cd calling-rails

We can check out a new feature of Rails 5 already at this point by running the tests with the new, all encompassing rails command.

$ rails test

Sure, we have no tests and if you’ve been using Rails 4 it looks the same as the old rake test command, but the difference is that in Rails 5 all commands will live under the rails command instead of some under rails and some under rake. We can’t see it yet, but the test runner has actually picked up some very nice upgrades along the way as well.

We can run our Rails server at this point too. Just enter:

$ rails server

on the command line and open up http://localhost:3000.

The successful Rails install page. It says 'Yay! You're on Rails!'.

Yay! Check out the new branding and illustration for the successful install page.

Adding gems

Certain things haven’t changed with this latest version of Rails. To add the twilio-ruby gem, stop the server then open up the Gemfile, add the line:

gem "twilio-ruby"

and install the gem using Bundler.

$ bundle install

Taking control

To get our Twilio app off the ground, we’re going to need a controller.

$ rails generate controller twilio

Open up app/controllers/twilio_controller.rb and let’s build a voice endpoint for our Twilio number. The idea is that when a call is made to our Twilio number, Twilio will send an HTTP request to our application to ask what to do with it. This action will respond to that request with the instructions in TwiML, which is a set of XML tags and attributes that Twilio understands.

First, we need to disable verifying the Rails authenticity token. This is intended to stop CSRF attacks, but that doesn’t apply when we’re expecting to receive a webhook from an external service. We also have our own way of verifying a request came from Twilio using Rack middleware.

class TwilioController < ApplicationController
  skip_before_action :verify_authenticity_token
end

Now we can write an action to respond to an incoming phone call. We’re going to build up some TwiML to speak a response to us down the phone, send us a congratulatory SMS message and play us out with a favourite tune.

class TwilioController < ApplicationController
  skip_before_action :verify_authenticity_token

  def voice
    response = Twilio::TwiML::Response.new do |r|
      r.Say "Yay! You’re on Rails!", voice: "alice"
      r.Sms "Well done building your first Twilio on Rails 5 app!"
      r.Play "http://linode.rabasa.com/cantina.mp3"
    end
    render :xml => response.to_xml
  end
end

We’re using the Twilio Ruby library’s TwiML builder (which is actually based on the builder gem) to generate our XML which we then render with the correct content type using the Rails render method.

Routing requests

In order to serve our request from Twilio, we’ll need a route too. Open up config/routes.rb and enter:

Rails.application.routes.draw do
  post 'twilio/voice' => 'twilio#voice'
end

Now a POST request to our application at the path /twilio/voice will route through to the action we just wrote. Start the server and we’ll get Twilio POSTing those requests.

$ rails server

Tunnelling with ngrok

We need to make our local application available to the internet so that Twilio can get through to it. I like using ngrok to do this, so I just open a new terminal window and type:

$ ngrok http 3000

When ngrok starts, it looks like this. Grab the URL you can see, we’re going to need that right away.

The ngrok live console shows a URL that is forwarding to your application on localhost. You will need to copy the HTTP URL to use in the Twilio console.

We need the URL, along with the route we created earlier, so that we can tell Twilio what URL to call when we phone our number. Jump into your Twilio console, find or buy a number that you want to use for this (make sure it can receive phone calls) and edit the number.

Find the Voice section, make sure you have Webhooks/TwiML selected as your configure option. Then, for when a call comes in, enter the full URL to your voice action.

Fill in the ngrok URL combined with the path to the action that we created to the field in the number editing page under Voice : 'a call comes in'.

Save the settings, whip out your phone and dial up your number. Soon enough you’ll be hearing the celebratory tones of a successful Twilio call.

Rocking on Rails 5

Now we’ve built our first Rails 5 and Twilio app there’s much more to be done. You could read up on all the other changes between Rails 4 and 5, particularly the brand new, real time ActionCable. It seems like a useful candidate for making a snappy user interface for two factor authentication with Authy OneTouch.

If you want to talk more about Ruby, Rails and communications then SIGNAL is the place to be. Not only are there over a hundred sessions on topics from real time communications to security and even bots, but we have two members of the Rails Committers team speaking. Eileen Uchitelle will be covering common software vulnerabilities and Sean Griffin will be diving into the hidden semantics of the code we write. I’ll be there too, and while I haven’t managed to get a commit into Rails yet, I do have a promo code that will get you 20% off to join Eileen and Sean in just two short weeks. Register now and use the code PNASH20 at checkout.

I hope to see you at SIGNAL. If you need me before, just drop me a comment below, hit me up on Twitter or grab me over email

Calling Rails 5: Getting started with Twilio on Rails

Bias-Free Hiring: How Interviewing.io Is Changing The Landscape Of Tech Hiring

$
0
0

AlineLerner“All I wanted to do was get to the code.”

The person responsible for this quote believes that resumes are a terrible way to gauge technical ability. This person argues that including or excluding candidates based on the prestige of their alma mater, or previous employer is what’s broken about hiring developers. Code should come first.

This person built a platform that mutes those extraneous details – school, gender, age, race. This person is a recruiter. She’s also a developer. Surprised? That’s the idea behind Interviewing.io.

Cutting Through The Phone Screen

In a previous life, Aline Lerner, founder and CEO of Interviewing.io, was a recruiter at a mid-sized startup. She looked at the resumes of engineers who had interviewed there over the course of a year and tried to figure out what might be strong signals to look for. As it turned out, number of typos and grammatical errors mattered more than anything else. Where people went to school or what degree they earned didn’t matter at all.

During that year, Aline also logged 500 technical phone screens and realized that she was having what seemed like the same unavoidable conversation over and over. It was small talk followed by questions that didn’t necessarily shed much light on the candidate’s viability.

“The candidate can tell you about the project that they’re working on and it could be the coolest thing in the world, but if they can’t write the code in the second part of the interview it’s all for naught.”

Catch Aline speaking about bias-free hiring at SIGNAL
here

The initial 10-15 minutes of conversation were always pleasant. But pleasantries don’t tell the recruiter, candidate, or hiring company anything about how the developer would fit. A proper fit rests on the developer’s problem solving skills and technical ability. That’s what Interviewing.io puts first. Using Twilio’s Voice API and a voice modulator, Interviewing.io provides a bias-free platform for interviews.

A Spider, An Elephant, and Voice Modulation

I logged on to the Interviewing.io platform as an interviewer, Epic Elephant, ready to interview a candidate, Defenstrated Spider. I heard a man’s voice on the other end of the line. The man told me how the Interview.io platform works. Interviewees and interviewers are both anonymous. The interviewee solves coding problems in real-time while the interviewer provides feedback.

When the Spider and I, the Elephant, both agreed to drop our anonymous handles, I saw the Spider’s contact information. The man I had been talking to was Aline.

Using Interviewing.io’s platform, you can code and solve technical challenges anonymously


 

How To Code Biases Out Of Interviews

Interviewing.io uses CoderPad and Twilio Client to power the platform. Aline wanted to build a “one stop shop” that made it easy for anyone to start chatting and start coding. Aline and her team are still tweaking the platform to eventually add an video chat feature once both parties agree to drop their avatars. For now, it’s just voice. And Aline is more than happy with Twilio Voice.

“Twilio was a no brainer” says Aline. Interviewing.io matches the audio (including the realtime voice modulation) from the Twilio conference call between the attendees to the recorded video of the coding session and stores interviews in the acount portal so both parties can learn from their previous interviews.

Punching Above Her Weight

Aline’s vision of a hiring meritocracy seems to be working so far. Historically, over half of Interviewing.io’s candidates have made it to company onsites, and this year, Interviewing.io has made hires for Yelp, Twitch, Mattermark, and others. Contrast that to just a few years ago, when Aline was sending her clients transcripts of candidates interviews, trying to prove with any data she could muster that while a candidate might not fit the typical mold, they could produce extraordinary results.

Aline said during those days “it seemed like the problems in this industry were bigger than I could solve on my own.” She was (and is) right. She can’t solve the hiring problem without a little open mindedness from her clients, a little flexibility from her users, and a little trust between one Spider and one Elephant.

Bias-Free Hiring: How Interviewing.io Is Changing The Landscape Of Tech Hiring

Introducing Dual Channel Recording

$
0
0

You don’t need to spend hours analyzing call recordings to figure out who said what. Those days are over. Today, we are excited to announce Dual-Channel Recording. With a simple TwiML command, you can get a recording of your call with two distinct channels, one per party. Now you can find out who said what, with one line of code.

Learn more about Dual-Channel Recording right here

The Conversations with Your Customers Are an Invaluable Mine of Information

It’s easy to sense the level of customers frustration or delight from what they say verbally. For example, voice conversations with your customers can provide subtle sentiment nuances about your products. Or repeated requests and inquiries can signal emerging trends and their most pressing needs. Gauging the same subtlety from their online transactions is much more difficult as the human connection is missing. Yet, in the average call center, less than 10% of recorded calls are retrieved or analyzed.

Businesses miss out on valuable data because mining call recordings for data can be expensive and time consuming — if you don’t have the right tools. Context is key when it comes to analyzing calls. Without the knowledge of who said what, typical programmatic call analysis isn’t worth much. Companies commonly listen back to conversations and manually analyze the customer’s feedback and sentiment. That plan can quickly become unfeasible when you scale. When your call volume grows, you need an easier way to pick out the two parties on a call.

You won’t have to sit down and manually parse the customer’s voice from the agent’s anymore. Using Dual-Channel recording, transcription and keyword analysis is simple with each party’s audio separated into its own track. You can now extract the data you need programmatically, using one TwiML command.

Here are a few ways you can use Dual-Channel Recordings to save yourself time, and add value to your business.

  • Product Manager – Build Dashboards to surface commonly recurring product requests, and customer complaints.
  • Online Directory Owner – Analyze what listing professionals said about your pricing to their customers. This will help you forecast the volume you can deliver.
  • Call Center Manager – Add transcriptions of past calls to your agents’ interface. This will give them context they can use to avoid asking the customer questions they’ve already been asked.

The Power of Call Recording

CallRevu, for example, uses call recordings to train car dealership sales reps and monitor their performance in real time.

“Our business is all about helping our dealerships understand their engagement with their customers. With dual-channel recording we will be able to efficiently extract insights from their call recordings and give tailored guidance to dealership reps to optimize sales opportunities.” – Mike Markette, Partner and COO of CallRevu

CalRevu aggregates thousands of calls quarterly in the automotive sector and extracts keywords and trends from such massive volume of info. CallRevu’s customers convert their leads faster using this data.

Voice conversations are chock full of insights you can use to deliver a better customer experience. We’re excited that you can now grab those insights, and make the most of them easily with Dual-Channel recording. Apply here.

Introducing Dual Channel Recording

Introducing Conference Events

$
0
0

Today, we are announcing Public Beta for Conference Events. You will be able to subscribe to changes in participant and conference states and be notified accordingly. You will not have to poll the API’s anymore to maintain the state of each participants. This drastically reduces the complexity of your application. Conference Events will be available for free. We’ve also made Call Progress Events available for free to bolster this capability.

Webhooks for Key Events

You can enable Call Progress Events by using the new

StatusCallbackEvent
TwiML parameter, now available for the
Conference
; noun within the
Dial
verb. This complements the
StatusCallbackEvents
already available on
Number
,
Client
, and
SIP
. The
StatusCallbackEvent
parameter will trigger a webhook on specific state changes of the conference or participants resources.
So far, you could only receive an event when a conference ended, if you had specified that the conferences was to be recorded. Now you can subscribe to all the following events.
  • conference-start
    The conference has started and audio is being mixed between all participants. This occurs when there is at least one participant in the conference and a particpant with
    startConferenceOnEnter="true"
    joins.
  •  

  • conference-end
    The last participant has left the conference or a particpant with
    endConferenceOnExit="true"
    leaves the conference.
  •  

  • participant-join
    Notifies when a participant joins.
  •  

  • participant-leave
    Notifies when a participant leaves.
  •  

  • participant-mute
    Notifies when a participant have been muted. This can be done through an API call to the participant resource.
  •  

  • participant-unmute
    Notifies when a participant have been un-muted. This can be done through an API call to the participant resource.

 
 
For example, if you want to request a webhook on all the possible conference state changes, you can do so with TwiML.




TeamMeeting

In this case

StartConferenceOnEnter
was set to the default value of true so the conference starts whenever the second participant joins.
ConferenceEvents
 

Modify the status of a participant

In addition to eliminating the need to poll resources to check status change, you will no longer need to discover and maintain Conference and Calls SIDs. They will be returned back in the same webhook, so you can use that info to modify the participant resource.

Expanding our example diagramed above, you can mute all the participants except the presenter, Mary, whenever everybody have joined and the Team Meeting is ready to start. As some participants might never join, you can avoid keeping the others waiting too long by setting a timer after the conference starts.

This is an example of webhook you would get when the participant Alice joins the call.

AccountSid    AC25e16e9a716a4a1786a7c83f58e30482
CallSid    CA8a0727575027a5c4d9614e633c929546
ConferenceSid    CF47001dbd9067b3007c1fcd05f43183f8
EndConferenceOnExit    false
FriendlyName    TeamMeeting
Muted    false
StartConferenceOnEnter    true
StatusCallbackEvent    participant-join

 
You can store Alice’s call SID and update any associated UIs.
Alice1
 
Let’s say we got a call SID for participants Alice (xxx), Bob (yyy) and Charles (zzz) before the timer expired. You can now POST your API request to mute them and start Mary’s presentation.
 
Alice2
 

$ curl -XPOST https://api.twilio.com/2010-04-01/Accounts/AC5ef8732a3c49700934481addd5ce1659/Conferences/CFbbe4632a3c49700934481addd5ce1659/Participants/CA386025c9bf5d6052a1d1ea42b4d16662.json \
    -d "Muted=True" \
    -u 'AC5ef8732a3c49700934481addd5ce1659:{AuthToken}'

 
This is just a simple use case but the possibilities are endless. You can control any call leg and take actions in response to a given change in participant status.
We think Conference Events will help you build Collaboration and Call Center application faster and more efficiently. Learn more about Call Progress Events in our TwiML docs for . We can’t wait to see what you build.

Introducing Conference Events

How to Add Phone Calling Bots to Slack with Python

$
0
0

Slack is awesome for text and emoji-based conversations with colleagues. However, sometimes it’s far easier to quickly answer a question over the phone. While Slack is just starting to add voice calling between users, there is no way to patch someone in by their good old telephone number. Let’s add phone calls to Slack by creating a bot with Python, Twilio and the Slack Real Time Messaging API.

Tools We Need

Our bot, which we’ll name callbot, requires a few libraries and APIs. To build our bot we need:

Here’s a handy step-by-step guide to setting up Python, pip and virtualenv.

Our Twilio requirements are:

The Slack dependencies are:

Ensure that Python version 2 or 3 is installed. We’ll configure everything else throughout the remainder of this tutorial.

You can follow along by writing the code in this post or skip ahead to the finished project by cloning the companion GitHub repository.

Configuring Our Environment

Now that we know what tools we need, go to the terminal (or Command Prompt on Windows) and change into a directory where you want to store this project. Within that directory, create a new virtualenv to isolate our application dependencies from other Python projects you’re working on.

virtualenv callbot

Activate the virtualenv:

source callbot/bin/activate

Depending on how your virtualenv and shell are set up, your prompt should look like something like this screenshot.

virtualenv.png

We’ll use the official slackclient API helper library to access their API to send and receive messages from a Slack channel. Install the slackclient and Twilio helper libraries along with phonenumbers into your virtualenv with the pip command:

pip install slackclient twilio phonenumbers

We next need to obtain an access token for the Slack Bot and our Twilio API credentials.

Slack Real Time Messaging API

Slack provides programmatic access to their chat application through a web API. Open up the landing page for the Slack Web API and sign up to create a Slack team or sign into your existing account. You can create a new team for free if you don’t have admin privileges on an existing team.
slack-api-sign-in.png

After you have signed in go to the Bot Users page.
custom-bot-users.jpg

Give your bot the name “callbot” and click the “Add bot integration” button.
callbot.png

The page will reload and you’ll see a new generated access token. You can also change the logo to a custom design, like I did with this bot by giving it the Twilio logo.

slack-token.png

Scroll down and click the “Save Integration” button. Your bot is now ready to access the Slack API.

A common practice for Python developers is to export secret tokens like our Slack token as environment variables. Export the token with the name SLACK_BOT_TOKEN:

export SLACK_BOT_TOKEN='your slack token pasted here'

Awesome. We’re authorized to use the Slack API as a bot. Now we just need a Twilio account and credentials to start handling phone calls.

Twilio Phone Numbers

We need access to the Twilio API to make phone calls from our application. Sign up for a free Twilio account or log into your existing account if you already have one. Our Slack bot will only dial outbound phone calls. Therefore, nothing needs to change on the number configuration screen.

twilio-phone-number.png

With our phone number in hand, go to the Console Dashboard screen and look for your Twilio Account SID and Auth Token:

console-account-sid.png

As we did earlier with the SLACK_BOT_TOKEN, we will use the newly-exported environment variables in our Python script.

On the command line, export Twilio credentials as an environment variables:

(callbot)$ export TWILIO_ACCOUNT_SID='your twilio account sid'
(callbot)$ export TWILIO_AUTH_TOKEN='your twilio auth token'
(callbot)$ export TWILIO_NUMBER='your twilio phone number, for example  12025551234'

There is one more bit of information we need: our bot’s ID in Slack. Next we’ll write a short script to snag that from the Slack API.

Obtaining Our Bot’s ID

Time to write some Python code! We’re going to get warmed up by writing a quick helper Python script to get callbot’s ID because it varies based on the Slack team. We need the callbot ID because it will allow our application code to determine if messages parsed from the Slack Real Time Messaging API are directed at our bot.

This script will also help test that our SLACK_BOT_TOKEN environment variable is set properly. Create a new file named get_bot_id.py with the following code.

import os
from slackclient import SlackClient


BOT_NAME = 'callbot'

slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN'))


if __name__ == "__main__":
    api_call = slack_client.api_call("users.list")
    if api_call.get('ok'):
        # retrieve all users so we can find our bot
        users = api_call.get('members')
        for user in users:
            if 'name' in user and user.get('name') == BOT_NAME:
                print("Bot ID for '" + user['name'] + "' is " + user.get('id'))
    else:
        print("could not find bot user with the name " + BOT_NAME)

The above code imports the SlackClient and instantiates it with our SLACK_BOT_TOKEN. When the script is executed by the python command we hit the API for a list of Slack users and get the ID for the one that matches the name callbot.

We only need to run this script once to obtain our bot’s ID.

python get_bot_id.py

When we run the script, we’ll get a single line of output with our Bot’s ID.
get-callbot-id.png

Copy the ID and export it as an environment variable named BOT_ID.

(callbot)$ export BOT_ID='bot id returned by script'

Again, the script only needs to be run once to make sure we have the appropriate bot ID for our Slack team. Now we’re ready to code up our Python application that’ll run our callbot.

Coding Our CallBot

We have all the appropriate environment variables set for our Python code to appropriately use the Twilio and Slack APIs. Create a new file named callbot.py and add the following imports.

import os
import phonenumbers
import time
import uuid
from slackclient import SlackClient
from twilio.rest import TwilioRestClient

The os and SlackClient imports should look familiar because we used them earlier in the get_bot_id.py script.

With our dependencies imported we can use them to grab those environment variable values and instantiate the Slack and Twilio clients.

# environment variables
BOT_ID = os.environ.get("BOT_ID")
TWILIO_NUMBER = os.environ.get("TWILIO_NUMBER")

# constants
AT_BOT = "<@" + BOT_ID + ">:"
CALL_COMMAND = "call"
TWIMLET = "https://twimlets.com/echo?Twiml=%3CResponse%3E%0A%20%20%3CDial%3E%3CConference%3E{{name}}%3C%2FConference%3E%3C%2FDial%3E%0A%3C%2FResponse%3E&"

# instantiate Slack & Twilio clients
slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN'))
twilio_client = TwilioRestClient()

Our code instantiates the SlackClient with our SLACK_BOT_TOKEN from an environment variable. TwilioRestClient automatically pulls the TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN from environment variables with those exact names during its declaration. Continue the Python script with the following lines of code that will handle starting the bot.

if __name__ == "__main__":
    READ_WEBSOCKET_DELAY = 1 # 1 second delay between reading from firehose
    if slack_client.rtm_connect():
        print("CallBot connected and running!")
        while True:
            command, channel = parse_slack_output(slack_client.rtm_read())
            if command and channel:
                handle_command(command, channel)
            time.sleep(READ_WEBSOCKET_DELAY)
    else:
        print("Connection failed. Invalid Slack token or bot ID?")

The SlackClient connects to the Slack Real Time Messaging API WebSocket connection then continuously loops and parses messages from the Messaging firehose. If any of those messages are directed at our bot, a function named handle_command will determine what to do with the command.

Above the Python code we just wrote, add two new functions to parse Slack output and handle commands.

def handle_command(command, channel):
    """
        Receives commands directed at the bot and determines if they
        are valid commands. If so, then acts on the commands. If not,
        returns back what it needs for clarification.
    """
    response = "Not sure what you mean. Use the *" + \ 
               CALL_COMMAND + "* command with numbers, delimited by spaces."
    if command.startswith(CALL_COMMAND):
        response = "calling stub..."
    slack_client.api_call("chat.postMessage", channel=channel,
                          text=response, as_user=True)


def parse_slack_output(slack_rtm_output):
    """
        The Slack Real Time Messaging API is a firehose of data, so
        this parsing function returns None unless a message is
        directed at the Bot, based on its ID.
    """
    output_list = slack_rtm_output
    if output_list and len(output_list) > 0:
        for output in output_list:
            if output and 'text' in output and AT_BOT in output['text']:
                # return text after the @ mention, whitespace removed
                return output['text'].split(AT_BOT)[1].strip(), 
                       output['channel']
    return None, None

The parse_slack_output function takes messages from Slack and determines if they are directed at our Slack CallBot. If a message starts with a direct message to our bot ID, then we know our bot needs to handle a command. handle_command function is currently a stub function that either passes back a generic help message or has a stub within a condition if the command starts with “call”.

With most of our code in place, let’s test our CallBot by using the python callbot.py command.
callbot-running.png
Go into the Slack channel with CallBot and enter “@callbot: call 14045551234 14155550909” (or replace these two numbers with your own test phone numbers). CallBot will answer back but not really dial numbers.

Our CallBot can respond to commands but it doesn’t place calls yet. We can fix that by adding two new functions named call_command and validate_phone_numbers. handle_command can then invoke call_command instead of just serving as a stub. Change your code to match the entire callbot.py application below. Code changes from our previous version are highlighted.

import os
import phonenumbers
import time
import uuid
from slackclient import SlackClient
from twilio.rest import TwilioRestClient


# environment variables
BOT_ID = os.environ.get("BOT_ID")
TWILIO_NUMBER = os.environ.get("TWILIO_NUMBER")

# constants
AT_BOT = "<@" + BOT_ID + ">:"
CALL_COMMAND = "call"
TWIMLET = "https://twimlets.com/echo?Twiml=%3CResponse%3E%0A%20%20%3CDial%3E%3CConference%3E{{name}}%3C%2FConference%3E%3C%2FDial%3E%0A%3C%2FResponse%3E&"

# instantiate Slack & Twilio clients
slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN'))
twilio_client = TwilioRestClient()


def handle_command(command, channel):
    """
        Receives commands directed at the bot and determines if they
        are valid commands. If so, then acts on the commands. If not,
        returns back what it needs for clarification.
    """
    response = "Not sure what you mean. Use the *" + \
               CALL_COMMAND + "* command with numbers, delimited by spaces."
    if command.startswith(CALL_COMMAND):
        response = call_command(command[len(CALL_COMMAND):].strip())
    slack_client.api_call("chat.postMessage", channel=channel,
                          text=response, as_user=True)


def call_command(phone_numbers_list_as_string):
    """
        Validates a string of phone numbers, delimited by spaces, then
        dials everyone into a single call if they are all valid.
    """
    # generate random ID for this conference call
    conference_name = str(uuid.uuid4())
    # split phone numbers by spaces
    phone_numbers = phone_numbers_list_as_string.split(" ")
    # make sure at least 2 phone numbers are specified
    if len(phone_numbers) > 1:
        # check that phone numbers are in a valid format
        are_numbers_valid, response = validate_phone_numbers(phone_numbers)
        if are_numbers_valid:
            # all phone numbers are valid, so dial them together
            for phone_number in phone_numbers:
                twilio_client.calls.create(to=phone_number,
                                           from_=TWILIO_NUMBER,
                                           url=TWIMLET.replace('{{name}}',
                                           conference_name))
            response = "calling: " + phone_numbers_list_as_string
    else:
        response = "the *call* command requires at least 2 phone numbers"
    return response


def validate_phone_numbers(phone_numbers):
    """
        Uses the python-phonenumbers library to make sure each phone number
        is in a valid format.
    """
    invalid_response = " is not a valid phone number format. Please " + \
                       "correct the number and retry. No calls have yet " + \   
                       "been dialed."
    for phone_number in phone_numbers:
        try:
            validate_phone_number = phonenumbers.parse(phone_number)
            if not phonenumbers.is_valid_number(validate_phone_number):
                return False, phone_number   invalid_response
        except:
            return False, phone_number   invalid_response
    return True, None


def parse_slack_output(slack_rtm_output):
    """
        The Slack Real Time Messaging API is a firehose of data, so
        this parsing function returns None unless a message is
        directed at the Bot, based on its ID.
    """
    output_list = slack_rtm_output
    if output_list and len(output_list) > 0:
        for output in output_list:
            if output and 'text' in output and AT_BOT in output['text']:
                # return text after the @ mention, whitespace removed
                return output['text'].split(AT_BOT)[1].strip(), 
                       output['channel']
    return None, None


if __name__ == "__main__":
    READ_WEBSOCKET_DELAY = 1 # 1 second delay between reading from firehose
    if slack_client.rtm_connect():
        print("CallBot connected and running!")
        while True:
            command, channel = parse_slack_output(slack_client.rtm_read())
            if command and channel:
                handle_command(command, channel)
            time.sleep(READ_WEBSOCKET_DELAY)
    else:
        print("Connection failed. Invalid Slack token or bot ID?")

The above two new functions, call_command and validate_phone_numbers, do the bulk of the work for CallBot. validate_phone_numbers uses the phonenumbers Python library to ensure each phone number is parsable and conforms to at least one phone number type from around the world. call_command ensures that at least two phone numbers are specified and calls validate_phone_numbers for some additional checks. If every phone number is valid then call_command invokes the Twilio Voice API to place each outbound phone call.

Time to run our bot now that all of our code in place. On the command line, execute python callbot.py.
callbot-running.png

In Slack, start giving CallBot commands. You can start testing it with invalid phone numbers. If we specify an invalid phone number format for one or more of the numbers, we’ll get back a helpful error message.
not-valid-format.png

Now try with two legitimate phone numbers.
calling-success.png
Wait a second for the incoming call…
success.png
Now we’re on a conference call with one or more people we’ve dialed through Slack. Time to hash out those questions over the phone so we can get back to coding.

Wrapping Up

Woohoo, our new callbot is all done! Actually, there so much more that can be done with the Slack and Twilio APIs. Check out these posts to learn even more about what you can do Here are several more ideas to try out now that you’ve got the basics down:

  1. Implement a persistent backend like PostgreSQL and use it to store a phone number for each username
  2. Add SMS capability to the bot
  3. Use Twilio Lookup to determine if a number is truly valid instead of just parseable
  4. Boost the parser with better parsing and natural language processing so it’s more natural for Slack users to interact with

Questions? Drop a comment below or contact me on these channels:

Twitter: @mattmakai
GitHub: makaimc
Email: makai@twilio.com
Twitch (Python & Swift live coding):  Team Twilio

How to Add Phone Calling Bots to Slack with Python

Engineering Chance Out Of The Equation: Athena Fights Assault Programmatically

$
0
0

Yasmine Mustafa recognizes that chance might have saved her life. But that doesn’t preclude her from fighting against it.
 
Her earliest memory is huddling together with her friends, family, and neighbors as they braced for the next bomb to rattle their bomb shelter. Moments later, two men would come calling for her baby brother. These U.S. Embassy employees escorted her whole family out of Kuwait just as the Persian Gulf War began. They relocated to Philadelphia — where, months earlier, Yasmine’s mother gave birth to her brother while accompanying her father on a business trip. The fact Yasmine’s brother would be born a U.S. Citizen on a business trip and rescued from a war zone is nothing but pure chance.
 
Chance can make or break you, or leave you somewhere in the murky middle. Yasmine is a self-made entrepreneur fighting against the darker side of chance. She and her team built a safety alert tool called Athena to reduce women’s chance of being assaulted.
 
Athena is a wearable device that, at the press of a button, allows users to send out a call, text, and GPS information to a network of their emergency contacts using Twilio.
 
 

The Inspiration For Athena

Being born female should not place you at higher risk of being harmed. Yet, when Yasmine solo-trekked through South America on sabbatical for 6 months, she heard countless stories from women who had been assaulted.
 
When she returned home to Philadelphia, a woman was brutally attacked one block from her home. Shortly thereafter, she called serial entrepreneur and friend, Anthony Gold, and the two founded ROAR. A few months later, they started making plans for an IndieGoGo campaign to fund Athena.

By the second day of Athena’s IndieGogo campaign, ROAR raised $40,000 of their $40,000 goal. The 10th day, they raised $100,000. By the end of the campaign they raised over $300,000.
 
Today, ROAR has Athena pre-orders from every state in the U.S and over 50 countries.

ROAR’s Mission

Anthony credits Athena’s initial success to both need, thoughtful design, and core social mission. Devices like tasers or pepper spray are predicated on a close-quarters fight with a would-be attacker. Athena uses the power of communication to alert a network and stop an attack before it starts.
 
ROAR is also attempting to fight the root causes of violence against women. As a certified B-Corp, they donate a portion of their proceeds to educational programs that are proven to increase empathy and reduce violence. A substantial percentage of their proceeds go to raising awareness about the warning signs of abuse and putting an end to violence in relationships.
 
Yasmine, Anthony, and the rest of the ROAR team wake up every day asking themselves what more they can be doing to help reduce assaults and further empower women. And nothing would bring them more joy than for there to no longer be a need for products like Athena and companies like ROAR. Until then, they plan to do everything in their power to make a difference.
 
ROAR has their work cut out for them, but the tide seems to be shifting their favor. Yasmine knows that all she needs to improve thousands of women’s lives is a flicker of chance.

Engineering Chance Out Of The Equation: Athena Fights Assault Programmatically

Build a Fantasy Football Hotline with Ruby and Twilio Voice

$
0
0

A phone was once the fastest way for a sports fan to get their news. In the 70s, 80s and 90s a business called Sports Phone served as a fan’s lifeline for up-to-the minute sports reports.

Grantland recently ran this fascinating piece on the rise and fall of Sports Phone:

The concept couldn’t be simpler: You call a number and hear a minute-long message with the latest scores and sports news. A half hour later, if you want another update, you call again — and pay another dime.

By 1979, the service was averaging about 100,000 calls per day… the company could get upward of 300,000 calls on a good college football Saturday or an NFL Sunday…

Sports Phone enjoyed an impressive run from 1972 to 2000 but was ultimately crushed by cable news and, of course, the Internet. In fact, it took us less than 30 minutes to create our own Fantasy Football Sports Phone using an RSS feed, Twilio Voice, and 31 lines of Ruby.

The gist is that we call a number and a robot voice reads us the headlines from one of RotoWorld‘s RSS feeds. Want to give it a try? Call 888.808.4929.

Here’s what the final code looks like:

require 'rss'
require 'open-uri'
require 'sinatra'

def get_news
  twiml = ""
  url = 'http://www.rotoworld.com/rss/feed.aspx?sport=nfl&ftype=news&count=10&format=rss'
  open(url) do |rss|
    feed = RSS::Parser.parse(rss)
    feed.items.each do |item|
      twiml += "<Say voice='alice'> #{item.description}</Say>"
      twiml += "<Pause length='1'/>"
    end
  end
  
  puts twiml
  twiml
end

post '/call' do
  content_type "text/xml"

  "<Response>
    <Say voice='alice'>
      Thanks for calling the Fantasy Football news line powered by Roto World and Twillio.
    </Say>
    <Pause length='1'/>
    #{get_news}
    <Say voice='alice'>Goodbye.</Say>
    </Response>"
end

In the rest of this post, we’ll break down the two steps you need to create your own “Dial an RSS Feed” hotline:

  1. Parse an RSS feed with Ruby
  2. Answer a phone call with Twilio and Ruby

Parse an RSS feed in Ruby

Our first step is to parse RotoWorld’s Player News RSS Feed. Fortunately, that functionality is baked into the standard library. The code below is straight out of the Ruby documentation on how to parse an RSS feed, though we’ve made three small modifications:

  1. Grab the item description
  2. Wrap the description in TwiML (more on that later)
  3. Collect all of the TwiML into the
    twiml
     variable and return it

require 'rss'
require 'open-uri'

def get_news
  twiml = ''
  url = 'http://www.rotoworld.com/rss/feed.aspx?sport=nfl&ftype=news&count=10&format=rss'
  open(url) do |rss|
    feed = RSS::Parser.parse(rss)
    feed.items.each do |item|
      twiml += "<Say voice='alice'> #{item.description}</Say>"
      twiml += "<Pause length='1'/>"
    end
  end

  puts twiml
  twiml
end

get_news

Create a new directory called

sports-phone
 and
cd
 into it. Save the above code to
app.rb
, and run
ruby app.rb
. You’ll see a bunch of headlines wrapped in XML. That’s how we’re going to make Twilio talk.

news-twiml

Great! Now let’s get a phone number hooked up to this RSS reader.

Answer a phone call in Ruby

Sign up for a free Twilio account if you don’t have one. Buy a phone number, then click Setup Number. Find the field in the Voice section that says “A Call Comes In.”

When someone calls our Twilio number, Twilio makes an HTTP request to the URL we punch into this field. In return, Twilio expects an HTTP response in the of TwiML – a simple set of XML tags that tell Twilio what to do next.

We’ll use Sinatra, the lightweight web framework, to handle that POST request. Before we install that gem though, you’ll probably want to use rbenv or rvm to keep the gems for this project secluded from all your others (though, strictly speaking, it’s not essential to make the code run):

echo "2.3.1" > .ruby-version
echo "sports-phone" > .ruby-gemset
cd ..
cd sports-phone

Then install Sinatra.

gem install sinatra

And require it at the top of

app.rb
:
require 'sinatra'

We need a route that responds to a POST request on

/call
 with TwiML that tells Twilio to:
  1. <Say>
     a greeting
  2. <Say>
     the news and
    <Pause>
     between each headline
  3. <Say>
     goodbye

To do this, delete the last line in your code:

get_news
. Replace it with:
post '/call' do
  content_type "text/xml"
  "<Response>
    <Say voice='alice'>
      Thanks for calling the Fantasy Football news line powered by Roto World and Twillio.
    </Say>
    <Pause length='1'/>
    #{get_news}
    <Say voice='alice'>Goodbye.</Say>
  </Response>"
end

Side note: for more complicated logic, you may want to use the Twilio Ruby gem to generate TwiML, but for simple stuff I prefer to write the XML by hand.

Your app’s going to need a publicly accessible URL so that Twilio can send it that POST request. Easiest way to do this on your local machine is to use ngrok. Alternatively, you can deploy your app to the cloud, but that means re-deploying every time you make a change.

Run ngrok to accept HTTP requests on Sinatra’s default port: 4567.

ngrok http 4567

Grab the URL ngrok gives you and paste it into the “a call comes in” field, and append the

/call
 endpoint.

call-comes-in-ngrok

Restart your app, call your number, and listen to that smooth robot voice read you the latest fantasy news.

Next Steps

Grantland’s article talks about how the success of Sports Phone spawned “a number of similar Dial-It services, as they were called — time, weather, horoscopes, Dial-a-Joke, a Dr. Joyce Brothers hotline, and so on.” You’ve now got a Sinatra app that can answer a phone call and read off an RSS feed. Go nuts.

And since you’ve got the infrastructure in place, it’s pretty easy to toss in a little extra TwiML to build more complicated voice apps. For instance, you could use the <Gather> verb to turn this into an IVR (“phone tree” in layman’s terms) that lets the caller “Press 1 to…” choose the news they want to hear. You could use the re-create the methodology of the original Sports Line by using TwiML to <Record> a short message, and then <Play> that recording for subsequent callers.

If you’d like to learn more about all the crazy stuff you can build with Twilio Voice and Ruby, check out:

I’d love to hear from you if you have any questions or want to show off what you build. Drop me a line at gb@twilio.com.

Build a Fantasy Football Hotline with Ruby and Twilio Voice


How to Make and Receive Phone Calls with Python, Bottle and Twilio Voice

$
0
0

Python web applications that combine the Bottle web framework with the Twilio Voice API can easily make and receive phone calls. Our calls will read a snippet of text then play an MP3 file. The call instructions can be modified to provide other useful actions such as gathering input from the number pad or putting all callers together in a conference call.

Our Project Tools

Our Bottle application will need either Python 2 or 3 to be installed. Python 3 is recommended for new applications. We will also need the following tools throughout this walkthrough:

You can snag all the code for this tutorial in the python-twilio-example-apps GitHub repository. Copy and modify the code however you want – it is all open sourced under the MIT license.

Install Dependencies

Before we write our Python code we will create a new virtual environment to isolate our application dependencies. Open your terminal and execute the virtualenv command to create a new virtualenv:

virtualenv bottlephone

Execute the activate script within the virtualenv, which activates this Python installation for the shell we are working in. Be aware that you need to explicitly activate the virtualenv in each terminal window where you want to execute the Bottle application.

source bottlephone/bin/activate

The command prompt will change when the virtualenv is activated. You should see (bottlephone) $. The following screenshot is what my environment looks like after I ran the activate script:

bottlephone-virtualenv.png

Next use the pip command to install the Bottle and Twilio Python packages into your virtualenv.

pip install bottle twilio

Our two required dependencies will be locally installed once the installation script finishes. Time to write some Python code!

Python Coding with Bottle

The Bottle web application will have three endpoints:

  • / – returns a simple message to let us know our Bottle app is running
  • /twiml – responds with TwiML (a set of instructions written in XML) that instructs Twilio what to do with phone calls
  • /dial-phone/<outbound_phone_number>, where “outbound_phone_number” is a phone number in the format ” 12025551234″

With that overview out of the way, we can proceed to writing the code for our initial Bottle application. Create a new file named app.py with the following lines of code:

import os
import bottle
from bottle import route, run, post, Response


app = bottle.default_app()


@route('/')
def index():
    """Returns standard text response to show app is working."""
    return Response("Bottle app up and running!")


if __name__ == '__main__':
    run(host='127.0.0.1', port=5000, debug=False, reloader=True)

Save the file. Make sure your virtualenv is still activated so our code can rely on the Bottle code library. Run the app via the Bottle development server with the following command: 

python app.py

Our development server should boot up successfully:

(bottlephone) matt@ubuntu:~/bottlephone$ python app.py
Bottle v0.12.9 server starting up (using WSGIRefServer())...
Listening on http://127.0.0.1:5000/
Hit Ctrl-C to quit.

Test out the app by going to localhost:5000 in a web browser. We should get a simple success message that the app is running and responding to requests.

bottle-dev-server.png
Next we need to obtain a phone number that our Bottle app can use to call other phone numbers.

Getting Our Twilio Number

Our basic Bottle web app runs but what we really want to do is make some phone calls.
In your web browser go to the Twilio website and sign up for a free account. You can also sign into your existing Twilio account if you already have one.

console-phone-numbers.png

The Twilio trial account allows you to dial and receive phone calls to your own validated phone number. To dial and receive calls from any phone number then you need to upgrade your account. Trial accounts are great for initial development before your application goes live but upgraded accounts are where the real power of Twilio is revealed.

Once you are signed into your Twilio account, go to the manage phone numbers screen. On this screen you can buy one or more phone numbers or click on an existing phone number in your account to configure it.

number-config-screen.png

There is nothing for us to configure right now on the phone number configuration page but we will come back to it shortly. Now that we have a phone number in hand, let’s add the final bit of code to our Bottle app to get this app working.

Filling in Our Bottle App

We need to add two new routes to our Bottle app so it can dial outbound phone calls. Modify your existing app.py file with the two new functions below, twiml_response and outbound_call:

import os
import bottle
from bottle import route, run, post, Response
from twilio import twiml
from twilio.rest import TwilioRestClient


app = bottle.default_app()
# copy the account SID and auth token from the Twilio Console and paste below
twilio_client = TwilioRestClient('paste account SID here' , 'auth token here')


# input your Twilio number in the second string on the next line
TWILIO_NUMBER = os.environ.get('TWILIO_NUMBER', '+12023350173')
NGROK_BASE_URL = os.environ.get('NGROK_BASE_URL', '')


@route('/')
def index():
    """Returns standard text response to show app is working."""
    return Response("Bottle app up and running!")


@post('/twiml')
def twiml_response():
    """Provides TwiML instructions in response to a Twilio POST webhook
    event so that Twilio knows how to handle the outbound phone call
    when someone picks up the phone.
    """
    response = twiml.Response()
    response.say("Hello, this call is from a Bottle web application.")
    response.play("https://api.twilio.com/cowbell.mp3", loop=10)
    return Response(str(response))


@route('/dial-phone/')
def outbound_call(outbound_phone_number):
    """Uses the Twilio Python helper library to send a POST request to
    Twilio telling it to dial an outbound phone call from our
    specific Twilio phone number (that phone number must be owned by our
    Twilio account).
    """
    # the url must match the Ngrok Forwarding URL plus the route defined in
    # the previous function that responds with TwiML instructions
    twilio_client.calls.create(to=outbound_phone_number,
                               from_=TWILIO_NUMBER,
                               url=NGROK_BASE_URL + '/twiml')
    return Response('phone call placed to ' + outbound_phone_number + '!')


if __name__ == '__main__':
    run(host='127.0.0.1', port=5000, debug=False, reloader=True)

Make sure to replace the phone number listed above with your Twilio phone number. Also modify the placeholders for the Twilio credentials to properly instantiate the TwilioRestClient.

There is one issue with our local development environment configuration: Twilio won’t be able to reach that /twiml route. We need to deploy our app to a reachable server or use a localhost tunneling tool like Ngrok. Ngrok provides an external URL that connects to a port running on your machine. Download and install the Ngrok application for your operating system.

Run the following command to make our Bottle app on port 5000 available publicly on the Internet.

./ngrok http 5000

Ngrok will start up and provide us with a Forwarding URL, with both HTTP and HTTPS versions.

The Forwarding URL plus the route will instruct Twilio to handle the phone call when someone answers. Insert the Ngrok forwarding URL into the app.py file where NGROK_BASE_URL is specified:

ngrok-forwarding-url.png

One bit to be aware of when using Ngrok is that your Forwarding URL will change whenever you restart the application, so you’ll need to update your code with the latest Forwarding URL.
To get even more out of Ngrok after finishing your Bottle project, make sure to read this 6 awesome reasons to use Ngrok when testing webhooks post.

Making Calls

Make sure your Bottle development server is still running or re-run it with the python app.py command in a shell where your virtualenv is still activated.

Bring up your application in the web browser. Go to “localhost:5000/dial-phone/my-phone-number”, where “my-phone-number” is a number in the ” 12023350173″ E.164 format. For example, here is what happens when I get the call on my iPhone:

success.png

When we pick up the phone call we also see the /twiml route get called via Ngrok.

post-twiml.png

With only a couple of Bottle routes plus Twilio’s Voice API we were able to make phones ring!

Dialing Our Application

Outbound calls are handy, but what about if someone dials our application’s phone number? We have done all the hard work to make inbound calls possible. We just need to copy our Ngrok forwarding URL plus TwiML endpoint into the phone number configuration screen for the phone number we want to dial.

ngrok-number-config.png

Click “Save” and dial your application’s number. You should get the same message and MP3 played as when you dialed the outbound phone call.

Next Steps

We can make and receive phone calls from our Bottle web application using our Twilio phone number. Next you could try to add even more features to your app by going through one of these tutorials:

Questions? Contact me via

How to Make and Receive Phone Calls with Python, Bottle and Twilio Voice

More Accurate Call Transcriptions Available Now

$
0
0

Phone call transcription is a must-have for any modern contact center. Not only do transcriptions play a role in training and quality assurance, but they also offer important insights into customer experience. Having the greatest possible accuracy is critical, because these words are driving business decisions. Anyone who’s experienced a failed autocorrect knows how errors in a conversation can change the meaning of what’s being said.

Today, we are increasing the accuracy of call transcriptions by making dual-channel recordings and the VoiceBase High Accuracy Transcription Add-on publicly available. For anyone using Twilio today, adding dual-channel recordings is a simple one-line change to your code and integrating VoiceBase takes only a few clicks in the Console. There’s no need to patch together multiple technologies and vendors to make it work. Read on to learn more about dual-channel transcriptions or get started now by jumping straight to the code.

What makes dual-channel recording transcription more accurate?

Background noise, spotty mobile coverage, and people talking with different accents can all contribute to a poor transcription. In a mono-channel recording audio from both the caller and the agent is combined in one track. This is less accurate because noise from one side can interfere with talking on the other side. Mono-channel recording also introduces new problems like cross talk. When both callers are talking at the same time, the transcription can become garbled.

twilio-dual-channel-recording-flow-v2

With a dual-channel recording, each side of the conversation is recorded in a separate track. This is just like a stereo audio recording with different audio on the right and left channels. Some issues like cross talk are completely eliminated. Additionally, dual-channel helps to reduce errors from background noise because noise from one side of the call won’t interfere with the other side. All of this adds up to create a more accurate transcription.

Where do accurate transcriptions count?

Duplicate your best agents – Call recording is a great mechanism to see what’s working and what isn’t without the need to be live on a call with an agent. Transcribing recorded audio into text takes this a step further, greatly reducing the time needed to consume recorded calls.

Using machine learning to parse all of your call transcriptions is the best way to leverage this data at scale. With Twilio dual-channel recordings and the VoiceBase Add-on, you’ll automatically receive keywords extracted from your transcripts. This allows you to measure keyword density across many calls and note which keywords your most successful agents use.

Hear your customer’s voice – When a customer mentions a competitor on a sales call, it means something completely different than if an agent mentions a competitor’s name. When using Twilio dual-channel recordings and VoiceBase Add-on you’ll be provided speaker identification in the transcript. This makes it easy to use the agent side of conversations for training purposes and the caller side to hear your customer’s voice. Learn what your customers truly love and what they don’t like about your products.

Pricing

The pricing for dual-channel recordings is $0.0025 per minute for generation (the same as standard mono recording). Storage of dual-channel recordings is $0.001 per minute (double the price of mono recording because the file is twice the size). VoiceBase transcriptions are priced at $0.015 per minute.

Get started with dual-channel and VoiceBase

twilio-dual-channel-plus-voicebase

There are currently two ways to record a Twilio call with with dual-channel:

Note: Dual-channel transcriptions are currently supported only by the VoiceBase High Accuracy Transcription Add-on. Twilio’s native transcription and the IBM Watson Speech to Text Add-on can process dual channel recordings, but do not take advantage of the two channels. (Dual-channel support for IBM Speech to Text Add-on is coming soon.)

I’ll walk through how to set up a VoiceBase dual-channel transcription with TwiML.

Configure a voice phone number

First we’ll set up a phone number with a simple call-forwarding TwiML Bin. Head to the Console buy a new phone number or configure an existing one. In voice section set

Configure with to Webhooks/TwiML
, set
A call comes in to TwiML
, and click on the plus to add a new TwiML Bin.

configure-voice-phone-number

create-recording-twiml-bin

Give your TwiML Bin a recognizable name. I’ll use “Dual-chan Record.” Then paste the following code into it:

<?xml version="1.0" encoding="UTF-8"?>
<Response>
   <Dial record="record-from-answer-dual">
     +14155551234
   </Dial>
</Response>

Replace the

+14155551234
with your phone number. Be sure to include your country code in the E.164 format. Click
Create
to save your new TwiML Bin. (Remember, you can always edit or update this TwilML Bin in the dev tools section of the Console.) Finally, select your newly created TwiML Bin and
Save
the phone number configuration.

screen-shot-2016-12-05-at-10-31-06-pm

Configure the VoiceBase Add-on

Head over to the VoiceBase High Accuracy Transcription Add-on section of the Console. Click to install the Add-on, accept the Terms of Service, then click Agree & Install.

voicebase-add-on-instal

On the Configure tab select the recording option(s) you’d like to use. In this case,

<Dial>
. Then, set the callback URL to a web server that can receive post requests. RequestBin is a great tool to use that allows you to configure and test webhooks quickly with no need for a server. Using ngrok with Twilio webhooks works nicely as well. If you’d like to set up a local server you can follow this tutorial to process Add-ons Recording Webhooks using Python.

voicebase-configure-dial-verb

And that’s it! Setting up Twilio dual-channel + VoiceBase is about as difficult as microwaving a Hot Pocket.

Test it out

Have a friend dial your Twilio number. It’ll forward to your phone and you both can chat.

Important Tip: Be sure to let them know they’re being recorded. Depending on your region it may be illegal to record a call without informing the caller. I’m not authorized to give legal advice in any region, so be sure to double check your local laws regarding phone call recording.

You’ll get a webhook with a JSON response similar to this:

{  
   "status":"successful",
   "message":null,
   "code":null,
   "results":{  
      "voicebase_transcription":{  
         "request_sid":"XRaabbcc",
         "status":"successful",
         "message":null,
         "code":null,
         "payload":[  
            {  
               "content_type":"application/json",
               "url":"https://api.twilio.com/2010-04-01/Accounts/ACaabbcc/Recordings/REaabbcc/AddOnResults/XRaabbcc/Payloads/XHaabbcc/Data"
            }
         ],
         "links":{  
            "add_on_result":"https://api.twilio.com/2010-04-01/Accounts/ACaabbcc/Recordings/REaabbcc/AddOnResults/XRaabbcc",
            "payloads":"https://api.twilio.com/2010-04-01/Accounts/ACaabbcc/Recordings/REaabbcc/AddOnResults/XRaabbcc/Payloads",
            "recording":"https://api.twilio.com/2010-04-01/Accounts/ACaabbcc/Recordings/REaabbcc"
         }
      }
   }
}

To get the results of your transcription do a do an authenticated GET request to the payload url with your Twilio API key and secret. You’ll receive a JSON object similar to below with with each speaker identified. (I’ve truncated the individual words for readability.)  You can find more info the Add-ons Payload Subresource Docs.

{  
   "callback":{  
      "errors":[  
      ],
      "event":{  
         "status":"finished"
      },
      "success":true,
      "warnings":[  
      ]
   },
   "media":{  
      "keywords":{  
         "words":[...]
      },
      "status":"finished",
      "transcripts":{  
         "text":"Speaker 2: Check Speaker 1: Test test test this is the side of one of the conversation Speaker 2:.  Yes this is side.  Two of the conversation.  Speaker 1:. ",
         "words":[...],
         "srt":"1\n00:00:08,41 --> 00:00:09,32\nSpeaker 2: Check\n\n2\n00:00:11,34 --> 00:00:16,27\nSpeaker 1: Test test test this is\nthe side of one of the conversation\n\n3\n00:00:21,02 --> 00:00:26,70\nSpeaker 2:. Yes this is side.\nTwo of the conversation.\n\n4\n00:00:28,82 --> 00:00:28,82\nSpeaker 1:.\n\n"
      },
      "mediaId":"daa6e14d-d1d6-42c0-b9e6-9d21d636900a",
      "metadata":{  
         "length":{  
            "descriptive":"28.0 sec",
            "milliseconds":28821
         },
         "contentType":"audio/x-wav",
         "external":{  
            "id":"XRaabbcc"
         }
      }
   }
}

Introducing the Recording Status Callback

So, in addition to the transcript, you’d also like to get a copy of the recording file?

The transcription webhook will include a Recording field that contains the URL where your file can be downloaded. But, you can also be notified as soon as the recording is ready.

In the past, you’d have to poll the API to know when your recording is done, but now we support a recording-specific webhook. recordingStatusCallback contains all the relevant recording related information and is now supported for <Record>, <Dial> , the Outbound API, and <Conference> recordings.

Here’s our TwiML from above, updated with the recording status callback:

<?xml version="1.0" encoding="UTF-8"?>
<Response>
   <Dial record="record-from-answer-dual" recordingStatusCallback=”https://requestb.in/qgue8eqg”>
     +14155551234
   </Dial>
</Response>

And the response looks something like this:

RecordingUrl: https://api.twilio.com/2010-04-01/Accounts/ACaabbcc/Recordings/REaabbcc
CallSid: CAaabbcc
RecordingSource: DialVerb
RecordingChannels: 2
RecordingStatus: completed
AccountSid: ACaabbcc
RecordingSid: REaabbcc
RecordingDuration: 4

What are you building?

We’re very excited about the release of dual-channel recordings, improvements like recordingStatusCallback, and the availability of Recording Analysis Add-ons from VoiceBase and IBM. I’d love to hear more about what you’re building with these new tools and answer any questions you have. Tell me what you are up to by leaving a comment below or pinging @billychia on twitter.

More Accurate Call Transcriptions Available Now

Giving Fake Spies Real Phone Numbers

$
0
0

previewThe car is real. It’s not yours, but you’re in it. The people walking through the car park are real. Some of them could be actors. The car park is pretty close to where you met the rest of the people who are part of the game.

The plot seems familiar, like a story you absorb through osmosis after falling asleep with the news on. A politician is on the brink of passing a critical climate change bill, meeting the ire powerful energy corporations in the process.

The bit that seems like outright fantasy is your task — to make sure the bill passes while unearthing a secret that could jeopardize the bill. The moment your suspension of disbelief starts to wane, a phone in the glovebox starts ringing. It’s for you.

Yes, You’re Really Hacking a Fake Voicemail

You hack into a politician’s voicemail account. Right after you hang up, a text from a shadowy character demands your attention. The moment is either serendipitous or expertly programed. (Pssst…it’s the latter). But, whatever force delivered the message, the feeling is the same.

In reality, you should not hack your co-worker’s voicemail. But the game’s air of fantasy gives you the muster to hack various contact’s voicemails.

You’re looking for spy-game clues, not looking for the man behind the curtain. That man is John Sear.

Weaving Fantasy Into the Blanket of Reality

In A Moment Of Madness, elegant Twilio engineering rides on the back of a crafty narrative to blur the line between reality and fantasy. Sear is a veteran game designer, working with immersive theater companies to build productions that turn “reality into a blanket and a platform for the game.” Together with Katie Day of the theatre company The Other Way Works and writer Tim Wright, they built a game to get lost in.

John Sear uses various Twilio numbers and recordings of trained actors to build voicemail accounts. Critical contacts in the game all have voicemail accounts that players mine for information. While information itself is fake, the encounter is eerily real

The game’s “blanket of reality” turns a car in a car park into counter-espionage headquarters for you and your partner. You have to have a partner because, as John points out, “a single player experience was terrifying — calling strangers, being a spy on your own in a car park. When it’s two-player, it’s fun. You’re like ‘What’s our spy name again?’”

Trading In Your Real Name for Your Spy Name

When you’re playing A Moment Of Madness, you should forget you’re playing a game. Sear keeps players submerged in a fantasy by adding the tiny trappings of reality. If you’re coming up short on clues while thumbing through the dossier you found in your glove box, you can phone a friend (or fellow spy).

John tracks how players are advancing through the game by monitoring the litany of Twilio numbers powering the game’s texts, calls and voicemails. He built a C# app to display webhook data in realtime so map every moment along the player’s journey from when they first text “we’re in” when they get in the car, to when they finally crack a secret voicemail account.

MoM

When the spy-gaming us up, all the different groups meet back where they started and exchange intel. They have to make a final decision on what they’ll do with the information they’ve amassed. This is the part of the game John can’t control — the human part. In an otherwise carefully engineered system, this is a variable John doesn’t try to control with code. Whatever choice the group makes to determine the fate of the climate bill, the politician, and their spy career is their call — one they’re making in a world John built.

Giving Fake Spies Real Phone Numbers

How to Dial and Answer Phone Calls with Spark and Java 8 in IntelliJ

$
0
0

Java web applications can easily dial and receive phone calls by combining the Spark web framework with the Twilio Voice API. Our example phone calls will say a snippet of text then play an MP3 file, but they can easily be modified to provide other useful actions like gathering user input from the number pad or creating conference calls.

Our Project Tools

Our Spark web app will use the Java 8 JDK and Apache Maven so make sure you have those tools installed. If you need to get Java 8 and Apache Maven installed on your Windows machine, check out this tutorial (you can skip over the GWT bits). We will also need the following tools throughout this walkthrough:

You can snag all the code for this tutorial in the java-twilio-example-apps GitHub repository. Copy and modify the code as you see fit – it is all open source under the MIT license.

Starting Our Project

IntelliJ can create our project boilerplate for us as well as install Spark and the Twilio Java helper library.
Start IntelliJ and select “Create New Project”, then choose Maven.
new-maven-project.jpg
Click Next, then fill in the GroupId, ArtifactId and Version on the New Project screen. You can keep the defaults shown in the following screenshot or use your own settings.
new-project.png
Click the “Next” button. On the following screen, fill in javaCalls for the Project name and place the project in its own subdirectory under where you keep your Java projects.
project-name.png
I typically store my projects under the C:\devel\projects path, but you can put this folder wherever your projects are typically located.
Click the “Finish” button and IntelliJ will open up the IDE.
intellij-ide.jpg
Now we’re ready to install the project dependencies via Maven and finally get to coding.

Installing Our Dependencies

Open the pom.xml Maven file. Add the following two new dependencies highlighted below:


    
    4.0.0

    
    com.mycompany.app
    javaCalls
    1.0

    
    
        
             com.sparkjava
             spark-core
            2.5.5
        

        
            com.twilio.sdk
            twilio
            (7.0,7.9)
        
    

The above XML provides Maven instructions for what application dependencies to install. In our case, we only have two dependencies, one for Spark and the other for the Twilio Java helper library. Save the pom.xml file.
Maven should automatically download the dependencies. If it does not, go to “Settings” -> “Build, Execution, Deployment” -> “Build Tools” -> “Maven” -> “Importing”, then enable the checkbox to “Import Maven projects automatically”.
import-maven-projects-automatically.png
Our two required dependencies will be locally installed as soon as Maven finishes running.
Now that our jar dependencies are installed we can write some Java code.

Java Coding with Spark

Our Spark web application will have three endpoints:

  • / – returns a plain text message to let us know our Spark app is running
  • /twiml – responds with TwiML (a set of instructions written in XML) that instructs Twilio what to do with phone calls
  • /dial-phone/<outbound_phone_number>, where “outbound_phone_number” is a phone number in the format “+12025551234”

Create a new file named PhoneCalls.java to the src/main/java folder inside your project. Write the following lines of code in PhoneCalls.java:

import static spark.Spark.get;

public class PhoneCalls {

    // lets us know our app is up and running
    public static void main(String[] args) {
        get("/", (req, res) -> "Spark app up and running!");
    }
}

Save the file. Click “Build” -> “Build Project”, or press Ctrl-F9 to compile and build via IntelliJ. Then click “Run” -> “Run PhoneCalls.java” or press Shift-F10 to run the application.
If IntelliJ gives a compilation error that says “Method references are not supported at this language level”, type Alt enter and select “Set language level to 8 – Lambdas, type annotations, etc.” from the drop-down list. Rebuild and the error should go away.

The Spark development server will start running. If you see warnings about “Failed to load class org.slf4j.impl.StaticLoggerBinder” don’t worry about that for now as we won’t need to do any logging.
Test out the app by going to http://localhost:4567/ in your web browser. We should get a success message that the app is running and responding to requests.
spark-app-running.png
Next we need to buy a Twilio phone number that our Spark app can use to call other phone numbers.

Obtaining Our Twilio Number

Our Spark web app runs but what we really want to do is make some phone calls.
In your web browser go to the Twilio website and sign up for a free account. You can also sign into your existing Twilio account if you already have one.
click-to-numbers.png
The Twilio trial account allows you to dial and receive phone calls to your own validated phone number. To dial and receive calls from any phone number you need to upgrade your account. Trial accounts are great for initial development before your application goes live but upgraded accounts are where the real power of Twilio is revealed.
Once you are signed into your Twilio account, go to the manage phone numbers screen. On this screen you can buy one or more phone numbers or click on an existing phone number in your account to configure it.
buy-or-configure.png
There is nothing for us to configure right now on the phone number configuration page but we will come back to it shortly so keep it open in your browser. Now that we have a phone number in hand, let’s add the final bit of code to our Spark app to get this app fully functional.

Finishing Our Spark App

There is one issue with our local development environment configuration: Twilio won’t be able to reach that /twiml route. We need to deploy our app to a reachable server or use a localhost tunneling tool like Ngrok. Ngrok provides an external URL that connects to a port running on your machine. Download and install the Ngrok application for your operating system.
Run the following command to make our Spark app on port 4567 available publicly on the Internet via Ngrok. You either need to be in the same directory as ngrok.exe:

ngrok http 4567

Ngrok will start up and provide us with a Forwarding URL, with both HTTP and HTTPS versions. Keep the HTTPS version of the Forwarding URL handy as we’ll use it in our Java code in just a moment.
We need to add two new routes to our Spark app so it can dial outbound phone calls. Modify your existing PhoneCalls.java file with the two new lambda functions below to handle the twiml_response and outbound_call endpoints:

import java.net.URI;

import com.twilio.http.TwilioRestClient;
import com.twilio.rest.api.v2010.account.Call;
import com.twilio.rest.api.v2010.account.CallCreator;
import com.twilio.twiml.Play;
import com.twilio.twiml.Say;
import com.twilio.twiml.VoiceResponse;
import com.twilio.type.PhoneNumber;

import static spark.Spark.get;
import static spark.Spark.post;


public class PhoneCalls {

    // find your Account SID & Auth Token in Twilio Console: twilio.com/console
    public static final String ACCOUNT_SID = "ACxxxxxxxxx"; // your Account SID found in the Twilio Console
    public static final String AUTH_TOKEN = "yyyy"; // your auth token also found in the Twilio Console

    // use the +12025551234 format for the value in the following constant
    public static final String TWILIO_NUMBER = "+12023359765"; // Twilio phone number for dialing outbound phone calls

    public static final String NGROK_BASE_URL = "https://0e64e563.ngrok.io"; // paste your ngrok Forwarding URL such as https://0e64e563.ngrok.io


    public static void main(String[] args) {

        // instantiate the TwilioRestClient helper library with our Twilio credentials set as constants
        TwilioRestClient client = new TwilioRestClient.Builder(ACCOUNT_SID, AUTH_TOKEN).build();

        // lets us know our app is up and running
        get("/", (request, response) -> "Spark app up and running!");

        // twiml endpoint
        post("/twiml", (request, response) -> {
            // generate the TwiML response to tell Twilio what to do
            Say sayHello = new Say.Builder("Hello from Twilio, Java 8 and Spark!").build();
            Play playSong = new Play.Builder("https://api.twilio.com/cowbell.mp3").build();
            VoiceResponse voiceResponse = new VoiceResponse.Builder().say(sayHello).play(playSong).build();
            return voiceResponse.toXml();
        });

        // this endpoint handles dialing outbound phone calls with the TwilioRestClient object
        get("/dial-phone/:number", (request, response) -> {
            String phoneNumber = request.params(":number");
            /* as long as the phone number is not blank or null, we'll attempt to dial it, but
               you can add more exception handling here */
            if (!phoneNumber.isEmpty()) {
                PhoneNumber to = new PhoneNumber(phoneNumber);
                PhoneNumber from = new PhoneNumber(TWILIO_NUMBER);
                URI uri = URI.create(NGROK_BASE_URL + "/twiml");

                // Make the call using the TwilioRestClient we instantiated
                Call call = new CallCreator(to, from, uri).create(client);
                return "Dialing " + phoneNumber + " from your Twilio phone number...";
            } else {
                return "Hey, you need to enter a valid phone number in the URL!";
            }
        });
    }
}

The Forwarding URL plus the route will instruct Twilio to handle the phone call when someone answers. Insert the Ngrok forwarding URL into the PhoneCalls.java file where NGROK_BASE_URL is specified:
ngrok-java.png
One bit to be aware of when using Ngrok is that your Forwarding URL will change whenever you restart Ngrok, so you’ll need to update your code with the latest Forwarding URL.
Ensure that you have replaced the phone number listed above with your Twilio phone number. Also modify the placeholders within ACCOUNT_SID and AUTH_TOKEN constants so your application can properly instantiate the TwilioRestClient.

Making Calls

Stop your Spark application. Rebuild the project then start the Spark application so it loads up the new code you just wrote.
Bring up your application in the web browser. Go to “localhost:4567/dial-phone/my-phone-number”, where “my-phone-number” is a number in the “+12023350173” E.164 format. For example, here is what happens when I get the call on my phone:
success-java-spark.jpg
When we pick up the phone call we also see the /twiml route get called via Ngrok.
it-works.png
With only a couple of Spark routes plus Twilio’s Voice API and we were able to make phones ring!

Dialing Our Application

Outbound calls are handy, but what if someone misses our call and dials the phone number back? Luckily, we’ve already done all the hard work to make inbound calls possible. We just need to copy our Ngrok forwarding URL plus TwiML endpoint into the phone number configuration screen.
ngrok-number-config.png
Click “Save” and dial your application’s number with your cell phone. You should get the same message and MP3 played as when you dialed the outbound phone call.

What’s Next?

We can now dial and answer phone calls from our Spark web application using our Twilio phone number. Next you could try to add even more features to your application by learning from one of the following tutorials:

Questions? Contact me via

How to Dial and Answer Phone Calls with Spark and Java 8 in IntelliJ

Voice Insights for Chrome gets a facelift

$
0
0

Voice Insights is an analytics tool that provides you with actionable insights into metrics that affect call quality in real time, even when a call is in progress. We are excited to announce the latest updates to Voice Insights based on your fantastic feedback. We enhanced our Voice Insights dashboards to let you easily track and understand your end users’ experience with Twilio. Sitting behind these new dashboards are significant improvements we have made in accurately capturing and analyzing call quality metrics.

If you’re new to Voice Insights, you can get started with a single flip of a switch here. Using Voice Insights requires no code changes if you’re using Twilio JS 1.3 or 1.4. If you already know about Voice Insights, you can skip ahead to enhancements or read on for some more background.

Background – What is Voice Insights?

You’re working hard to deliver a great calling experience to your users. Rapidly diagnosing call quality problems caused by unstable networks or unreliable devices is essential. You need the right tools to do it.

We launched Insights last September to help you get visibility into factors affecting Twilio Client calls and proactively manage your end user’s experience. We enabled features such as on-device network monitors, audio device selection APIs, and in-call feedback reporting, with the release of Twilio Client 1.4. Voice Insights provides you with analytics on these on-device events from your Client app. With Insights you are able to:

  • Rapidly address call quality problems: Through on-device alerts and in-console dashboards monitoring metrics such as jitter, packet loss, audio stream level and Mean Opinion Score for each call, you can know which users are having problems. Using the Client APIs, you can alert users on their devices of deteriorating network conditions or audio device faults to self-serve improvements in call quality.
  • Track key metrics & proactively reach out to affected users: You can now track key metrics on calls that were dropped, calls that failed to connect, or calls that were affected by network conditions. Using the filters for client ID and IP address, you’ll be able to proactively reach out to your affected users affected by call quality.

Enhancements with the Latest Release

Eliminate False Positives at the Beginning of the Call

Prior to this release, every call started with warnings of high latency, low Mean Opinion Score (MOS) and high packet loss. These warnings were generated during setup-time due to the default network metrics reported by the WebRTC getstats APIs, which do not reflect the actual network conditions. For instance, we found that the first sample in every call has 100% packet loss and a latency greater than 1 second and as a result an unacceptably low MOS. (See image below) This resulted in at least 3 warning events to be fired at the beginning of every call, resulting in a large number of events that were false positives.

We fixed this by avoiding firing any warnings within the first 15 seconds of the call, while the metrics are still being normalized. After 15 seconds, you’ll continue to see any network anomalies highlighted through warnings and on metrics graphs. These changes are reflected in the events log, and through the grayed portion of the charts on the call metrics tab.

Twilio Client JS 1.3 and 1.4 SDKs are constantly sampling jitter, packet loss, latency, and calculate a running MOS. When these metrics drop below a certain threshold for a period of 5 seconds, a network warning event is generated.

During our analysis, we came across case where despite slightly deteriorated network, the perception of the user wasn’t affected. We found that a much more accurate indicator of choppy audio was the “ICE Liveness check failed”  event, that resulted in a breakdown of information-exchange required to keep the media session active.

When this event is logged, the call continues, but in most cases, the quality is perceivably degraded. Read more on WebRTC and ICE events here. We eliminated the false positives on aggregates dashboards by replacing the raw warnings on network statistics with the section – “Calls affected by network”. This section provides a count of the number of calls where there was at least one occurrence where ICE connectivity was lost or Low MOS was recorded.

Fix Over-counting the Number of Warnings

We found that each blip in the network could generate at least 4 warnings that represent the same instance of the problem. As these warnings were aggregated across the account, the dashboards showed an inflated number of warnings making it hard to estimate the actual impact on the account.

For example, in the call metrics image above, a blip in the network at 15 seconds into the call resulted in 5 warnings, all of which represented the same instance of the problem. An aggregation of 50 such warnings over a day would still not tell you how many calls had the problem. It could be a single call with 50 warnings, or 10 calls with 5 warnings each. The inability to know the distinction between these cases was limiting in quickly identifying and addressing the root cause.

With the latest release, account dashboards now reflect the number of calls that had quality problems rather than a raw number of warnings and errors. This helps in accurately understanding the calls that were actually affected by a bad network. You will still see the breakdown of the warnings under the “Calls affected by networks” section of the aggregates dashboard.

Breaking Down the Calls By Issues

Instead of reporting the raw number of errors and warnings for the entire call, we have now broken down the affected calls by categories of issues:

    • Failed to connect: These are calls that failed to setup. This could be due to authentication problems, due to device setup failures, because of exceeding rate limit, or because the user denied permission to access audio devices.
    • Terminated with error: These are calls which were disconnected because of an error. These present a subset of the calls that were dropped. Most often, client calls terminate with errors because of severe network degradation.
    • Affected by network: These are calls where ICE liveness check failed, and ICE connectivity was lost, or the MOS dipped below the threshold. These calls did not necessarily drop because of the network, but the user experience was significantly degraded by a poor network.

Detailed Dashboard to Drill Into KPIs

Customers reported that despite the data aggregation at an account level, it was hard to track KPIs that accurately reflected the health of the Twilio app. We received feedback on the key metrics that are important to customers – total number of calls, call duration, end-user feedback, the number of bad calls, and who disconnected the call. We redesigned the dashboards to help you easily keep track of these KPIs with an overview page, and then drill into the metrics by each user, and IP address where necessary.

Overall, we have focused on ensuring that you can easily understand and proactively address the call quality problems that are affecting your users. We are working hard to enhance Voice Insights and appreciate your feedback. Our mission is to ensure that you spend zero minutes worrying about call quality as we enhance our Voice SDKs, and provide tools such as Voice Insights to enable proactive actions to manage your users.

Voice Insights for Chrome gets a facelift

New Phone Numbers Available in 12 Countries

$
0
0

We’re always working hard to expand our global coverage, and today, we’re excited to announce that you can now use Twilio phone numbers in the following countries:

  • Local Voice numbers: Croatia, Hungary, Iceland, Kenya, Nigeria, Norway, Philippines, and Slovenia
  • Mobile SMS numbers: Latvia, Portugal, Republic of Korea, and Taiwan

With a local phone number, your customers can reach you by calling a familiar area code. The geographical prefix gives your business a local identity that customers recognize and trust. Mobile numbers with voice or sms capability allow your customers to communicate with you at local call and messaging rates, reducing friction and improving customer experience.

These new numbers are available now through the Twilio Console and the Phone Number API.

Toll-free numbers too

We’re also launching toll-free phone numbers in 10 new countries and want to give you first access. If you’re interested in trying out these new numbers, sign up for a developer preview.

  • Toll-free Voice numbers: Brazil, France, Germany, India, Ireland, Italy, Mexico, New Zealand, Spain, and Switzerland.

These numbers have gone through a rigorous performance and reliability testing process. As a next step, we are offering these numbers by request as a developer preview, so we can verify the quality with real world testing.

We have thoroughly vetted these numbers and don’t expect issues, but we advise against using test numbers in production. Also, we may have limited stock of preview numbers, so bear with us if we’re unable to accommodate your request.

If you’re interested in testing with developer preview numbers, get in touch!

We can’t wait to see what you build!!

New Phone Numbers Available in 12 Countries

Developer Digest: Automating Wedding Stress Away in Python

$
0
0

Old things are new again, just new in a different way. That old NES you used to play Super Mario Bros on…? Well Andrew Reitano’s newly-hacked NES lets strangers turn any level into a water level with one text. This issue of the Developer Digest celebrates the developers making the old new and novel, from fax machines, to wedding invitations, to that trusty old password you still use.

 

The Digest

A Bunch of Awesome People (Like You) Are Coming to SIGNAL

You’ll learn why the founder of ngrok is hyped about grpc. You’ll share your projects. You’ll learn to wield new Twilio tools. You’ll hone your craft. There’s a session, a track, a speaker, a space for you at SIGNAL. Grab your ticket now, and use the code DEVDIGEST20 to get 20% off your ticket.

os.remove(Stressful_Wedding_Planning.txt)
Thomas automated away the stresses of planning his wedding using Python. Instead of mailing save the date invitations, he fired off an HTTP request to Twilio. How many guests are having the sirloin entree? The answer is one command away. Read how Thomas did it.

Twilio Programmable Fax— No Foolin’

Two things: Yes, it’s real. Yes, it is also 2017. Fax is now programmable. As proof you can send ASCII Art in Node, or check out the docs, or read how your pizza orders might be powered by fax.

Seriously, It’s Real. Tomasz Already Made Fax Serverless

With a quickness, Thomasz shows you how to use Auth0 Webtasks to send faxes sans server. He even shows you how to expose this as a Slack command. Get /faxing.

Build Passwordless Auth with Elixr and Phoenix
QWERTY1234 is not a solid password. Entering in your email, mother’s maiden name, and zipcode is not a solid user experience. Made by Many shows you how to build passwordless authentication using a few simple APIs.

Docker + Rails Made Simple
Remember the name Guillaume Montard. He put together Dockrails, a simple CLI to generate and run a rails environment using Docker. Get a refresher now.

.NET From The Computer to the Cloud with Docker & now.sh
Yep, it’s a double dose of Docker goodness. Dominik Kundel wants you to share that .NET Core app with the world. Learn how to get that bad boy online in this tutorial.

 

Who Picked Up That Call? Was It You, Answering Machine?

Calls work best when they reach their intended recipient (who normally isn’t an answering machine). You can use the newly released Answering Machine Detection feature for Twilio Voice. Learn how to use it now.
 

Closing Thoughts

Let that nostalgia sink in for a bit. Just chase it with some creativity. In a little while, those old programming haunts of yours could spark a new project or a new hack. When that spark hits, let us know.

Developer Digest: Automating Wedding Stress Away in Python


Announcing Phone Numbers in 70 countries, Transparent Toll-Free Pricing, and Hosted SMS

$
0
0
  • SMS in 5 new countries, Voice in 13 new countries, Toll-free in 27 new countries.
  • Toll-free priced by inbound caller type lets you pay only for what you use.
  • Add SMS to your existing US & CA phone numbers without changing voice providers.

Having the right tool for the job makes all the difference. When engaging with your customers, phone numbers are a great example of how picking the wrong type of phone number can stop you in your tracks.  Each method of communications, from making outbound calls, to receiving inbound calls, to exchanging SMS all require different approaches to phone numbers. That’s why giving you a vast and diverse set of phone number options is so important. And that’s why we are so excited to announce three big ships:

  • 45 new phone number types, for a total of 70 countries: Twilio is adding Programmable SMS numbers in 5 new countries, Programmable Voice / SIP Trunking numbers in 13 new countries, and toll-free numbers in 27 new countries. This means you can now provision Twilio phone numbers in 70+ countries.
  • Toll-free pricing transparency: In countries where carriers charge a different rate based on the type of phone that calls the toll-free number, we will now show you the pricing difference to help you manage your costs.
  • Hosted SMS:  In the US and Canada you can now add SMS to any phone number without changing your existing voice provider.

All of this ensures you have the right number for the job for whatever you want to build.

Get Outbound Calls Answered with Localized Numbers

Outbound Calls

When you make a phone call to someone, you want them to pick up. The trick is people don’t like to answer phone calls from unfamiliar numbers. The best way to increase your chances of getting a customer to pick up your call is to use a phone number in their local area. They’ll also be more likely to call you back on a number that doesn’t cost them long-distance charges. To enable you to provide a local experience in more countries around the world we’re releasing new SMS and Voice numbers.

Available today through the Twilio Console and the Phone Number API:

  • Voice numbers in: Chile, Colombia, Panama, and Thailand

Available by request as Developer Preview:

  • Voice numbers in: Algeria, Georgia, Ghana, Indonesia, Macau, Mali, Pakistan, Trinidad, Ukraine
  • SMS numbers in: Brazil, Croatia, Guatemala, Philippines, and Singapore

If you are building a Twilio app that makes outbound calls such as CRM dialers or anonymous communications,  a local experience is a must.

Increase Inbound Calls with Toll-Free Numbers

Inbound Calls

Even when someone is on a phone plan that includes long-distance, they are still more likely to get in touch with businesses on their 800 number. Toll-free numbers represent a professional brand and make sense when you want one number to advertise nation-wide. There are some solutions, like contact centers and conference calling, where toll-free is expected. To make sure you get more calls from your customers around the world we’re releasing toll-free numbers in 27 new countries.

Available on-demand through the Twilio Console and the Phone Number API:

  • Toll-free numbers in: Austria, Belgium, Brazil, Czech Republic, Denmark, Germany, Finland, Hong Kong, Indonesia, Ireland, Japan, Mexico, Netherlands, New Zealand, Norway, Philippines, Poland, Portugal, Slovakia, South Korea, Spain, Sweden, and Switzerland

Available by request as Developer Preview:

  • Toll-free numbers in: France, India, Italy, and Singapore

Paying a Fair Rate for Toll-free Calls

Previously, when you looked at our pricing page you’d see one rate to receive toll-free calls.

Single Price

But this isn’t how toll-free works in many countries around the world. Carriers will often charge a different rate based on the type of phone that is calling the number. For example, in Germany it costs less to receive a toll-free call from a landline phone than a mobile phone. A single “blended” flat rate doesn’t accurately represent this. This means that you could end up paying more than you need to.

Caller Type Price

So today we are happy to introduce pricing based on the inbound caller type. You’ll now see two prices listed, one for mobile and one for landline, when you view pricing for countries that use caller type billing: Ireland, Germany, Italy, Brazil, New Zealand, Spain, and Switzerland. We believe this is a more transparent and fair way to price. So that you pay for exactly what you use.

Hosted SMS: Add SMS to any number without changing a thing

Hosted SMS

For many business transactions people prefer to text rather than call. In fact, every day people text businesses at their existing numbers and never get a response because the numbers aren’t set up to receive text messages. Now, with Twilio™ Hosted SMS you can SMS enable your existing US and Canada numbers without changing how your voice phone calls work.

Twilio makes this happen by setting up a dual-routing configuration within the telephone network. When a call comes in to your number the carrier knows to route it to your existing voice provider. When a text comes in to the same number, the carrier knows to route it to Twilio. With the Hosted SMS API you can completely automate the process of SMS enabling voice numbers that you own.

To get started

We can’t wait see see what you build!

Announcing Phone Numbers in 70 countries, Transparent Toll-Free Pricing, and Hosted SMS

Introducing Speech Recognition – Public Beta Now Open

$
0
0
  • Convert speech to text and analyze its intent during any voice call.
  • Support for 89 languages and dialects.
  • Available now in public beta.

Speech is a powerful and expressive medium for customer communications. With speech technology improving massively over the last four years, we were excited to leverage that progress to finally offer Twilio developers a speech recognition feature for Programmable Voice. Starting today, Twilio Speech Recognition allows developers to convert speech to text and analyze its intent during any voice call, and is available in public beta. There are no models to train or complicated machine learning to orchestrate.

Our customers have long used keypad input to navigate users through phone menus and collect their feedback on surveys. While keypad input is now universally understood by users, it can be cumbersome and imprecise, and isn’t always a great experience for the caller.

Over the next several years, we expect speech-driven interfaces to become ubiquitous. The potential for nuanced human-machine interaction driven by speech is readily apparent to anyone who has asked Alexa to play their favorite music from Spotify.

With Speech Recognition, you can now capture speech from your customers in real-time. It works in 89 languages and dialects, and has a simple, pay-as-you go pricing structure.

<Gather> with Speech

Speech recognition is integrated directly into Twilio’s <Gather> verb so you can update the code you already have in place. Because it supports 89 languages and dialects, you can upgrade your application to support customers across a broad range of regions. Adding speech is as simple as adding a new parameter called “input” as shown in the TwiML below.



	
		Welcome to Twilio, how can I help you?

If you specify speech as an input, Twilio will add a new parameter called SpeechResult in the request to your action url.

 

AccountSid AC25e16e9a616a4a1786a7c83f58e30082
ApiVersion 2010-04-01
CallSid CA607dee6b7647243904ebc8db64a2a5c2
CallStatus in-progress
Called +18182004120
Confidence 0.77388394
Direction inbound
From +15623000628
Language en-US
SpeechResult      I’d like to learn more about Speech Recognition
To +18182104120

 

If you’d like to build more responsive applications, we also offer the ability to get speech results in real time as we process speech. To access the real-time voice stream, you can specify a partial results callback:



	
		Welcome to Twilio, how can I help you?

Once you specify a callback url for partialResultCallback, you will get requests as your customers speak. Since HTTP requests may arrive out of order, we include a sequence number to help you use your customer’s speech as it was spoken.

SequenceNumber: 1
UnstableSpeechResult: Disco
 
SequenceNumber: 2
UnstableSpeechResult: fiscal
 
SequenceNumber: 0
UnstableSpeechResult: this
 
SequenceNumber: 3
UnstableSpeechResult: Fiscal Sanity
 
SequenceNumber: 4
UnstableSpeechResult: this call Sandra
 
SequenceNumber: 5
UnstableSpeechResult: this will send
 
SequenceNumber: 7
UnstableSpeechResult: this will send requests
 
SequenceNumber: 6
UnstableSpeechResult: this will send requests
 
SequenceNumber: 8
UnstableSpeechResult: this will send requests
 
SequenceNumber: 9
UnstableSpeechResult: this will send requests
 
SequenceNumber: 10
UnstableSpeechResult: this will send requests as
 
SequenceNumber: 11
UnstableSpeechResult: This will send requests as you.
 
SequenceNumber: 12
UnstableSpeechResult: This will send requests as you see.
 
SequenceNumber: 13
UnstableSpeechResult: This will send requests as you speak.
 
SequenceNumber: 14
UnstableSpeechResult: This will send requests as you speak.
 
SequenceNumber: 15
UnstableSpeechResult: This will send requests as you speak.
 
SequenceNumber: 16
UnstableSpeechResult: This will send requests as you speak.
 
SpeechResult: This will send requests as you speak.

This allows you to evaluate the speech of your user as they speak to build responsive voice applications. A detailed explanation of Speech Recognition features and TwiML examples can be found here.

Pricing

Speech Recognition uses a scalable pay-as-you go model, with requests starting at $0.02 per 15 seconds of recognition. Those who have operated a speech recognition system know how time consuming and difficult planning for channels or ports can be. Speech Recognition from Twilio does away with this burden and scales with your businessplug it in and it just works. If you’re planning for significant traffic, it’s important to know that volume-based discounts can cut the price of Speech Recognition to as little as $0.008 per 15 seconds. Full volume tiers can be found here.

How to Get Started

Speech recognition is available to all Twilio developers today. To get started, check out our docs. If you have any questions about moving your traffic or adding Speech Recognition to your Twilio application, don’t hesitate to reach out to our Sales team.

What’s Next: Understand

Speech Recognition is only the beginning for voice-driven interfaces built on Twilio. Coming soon, we will be releasing a new verb: Understand. It’s exactly what you hope it is: an API to analyze text and determine intent during a live call using natural language understanding. Powered by machine learning, Understand will give developers what they need to build intelligent, nuanced human-machine interactions in order to turn freeform text into structured data. It will work natively with both Twilio Programmable Voice and SMS, as well as Amazon Alexa.

Stay tuned for morewe can’t wait to see what you build.

Introducing Speech Recognition – Public Beta Now Open

Coming Soon – Twilio Frame, UI Components for in-app Chat, Voice, & Video

$
0
0
  • UI components and tools for JS, iOS, and Android.
  • Integrated with Programmable Chat, Video, and Voice SDKs.
  • Coming soon to a Twilio SDK near you.

Today at SIGNAL, we announced Twilio Frame, a set of UI components and tools for embedding chat, voice and video in your web and mobile apps. Twilio Frame provides you with the tools to quickly build a rich, branded visual experience that works across iOS, Android, and web and is already wired to work with your Twilio apps. Frame is built on top of Twilio’s Chat, Video, and Voice SDKs allowing you to seamlessly move between different communication channels on the same screen.

Gettin’ GUI with it

Twilio’s first products, Programmable Voice and Messaging, opened the black box of telecom to millions of web developers. SMS and voice apps don’t have front-end requirements; the user interface is simply the phone’s native dialing or texting app. Since then we’ve introduced new IP-based communications products to embed voice, video, and chat within web and mobile applications. This allows users to communicate in context of what they are working on in the app, authenticate without leaving that app, and take advantage of rich features like typing indicators and screen-sharing.

Unfortunately (or fortunately), in-app chat, voice and, video come with an added burden of designing and building a user interface. We’re excited to introduce Twilo Frame because it takes care of that front-end design and build effort. You can create a UI that is engaging, on-brand, and works across different devices – and hopefully shave weeks or months off your design and development effort.

First Frame

Twilio Frame provides frameworks, libraries, and UI elements that let you quickly create a tailored communication experience that’s as unique as your users and your brand. The UI is built on top of Twilio SDKs, so you don’t have to spend time connecting the two. This means you can get to production faster, focus on user experience, and iterate based on customer feedback.

Twilio Frame is coming soon and will initially support Programmable Chat in JavaScript, followed by iOS and Android. Then we’ll add support for Video, Voice, and Authy SDKs.

UI kit Twilio Frame

The Twilio JavaScript Chat Frame will be published on Twilio CDN and also made available on NPM package registry. These packages will contain all the tools required for building a UI for the Programmable Chat JavaScript SDK.

Coming Soon

If you’re interested in building with Twilio Frame, tell us about your use case and we’ll keep you up to date when they’re ready for you to use. We can’t wait to see what you build with Twilio Frame.

Coming Soon – Twilio Frame, UI Components for in-app Chat, Voice, & Video

All Stories from SIGNAL 2017

$
0
0

Are you sitting down? Alright, good. Post-SIGNAL, your head is likely spinning from the whirlwind of announcements. Never fear, we’ve got the rundown for you.

No two developer tool belts are alike. There are 1.6 million of your fellow developers on the Twilio platform. Each of them—including you—is building something to solve a nuanced problem, with a nuanced set of tools. SIGNAL just put your tool belt at full capacity.

With that primer, let’s dive into all 42 stories from SIGNAL, starting with the headliners:


The Comprehensive List


Programmable Communications Cloud

To build products you need the right building blocks. Twilio’s Programmable Communications Cloud is comprised of the core building blocks you rely on—Programmable Voice, SMS, Chat, Video, and Fax.

  1. A new Speech Recognition feature for Programmable Voice turns speech into text in real-time. It works at the speed of your voice, giving you searchable logs of your conversation and creating records and data out of thin air.
  2. Soon you’ll be able to unleash Twilio Understand to turn freeform text into data so you can analyze sentiment and iterate.
  3. Twilio Frame (coming soon) will give developers the UI components and tools they need to build chat, voice, and video apps. It’ll spare you the cycles of designing buttons and icons for your apps.
  4. When you’re running your communications suite on PSTN, you need insight into how it’s performing in order to make critical decisions. Now there’s a way—meet Voice Insights for Carrier Calls.
  5. Answering Machine Detection tells you if there’s a human or machine on the other end. You can sniff out those answering machines right now. Use AMD here.
  6. *Sniffle.* They grow up so fast. Programmable Chat is now generally available.
  7. Go fax yourself. Seriously—now there’s an API for that.
  8. Video’s so hot right now, and so is our Programmable Video product, which just went GA.
  9. Video Group Rooms let you handle up to 50 participants at a time on a single video call. It comes with a built-in audio and video recording feature.
  10. Now using SMS Queue Insights, get visibility into any messages stuck in the cloud just waiting to be delivered.
  11. Message Body Redaction (developer preview) stays true to its name—it removes the bodies, or content, of messages before they’re stored long term. This keeps customer data safe and secure.
  12. Concatenation can be frustrating. You want your messages sent in the right order, in the right form. Not split up and out of order. Don’t worry, Smart Encoding for Copilot’s got you covered.

Engagement Cloud

Your customers won’t wait. They expect to be able to interact with your business at any time, on any medium, and we’re obsessed with making these interactions easier. We’ve observed that most communications built by businesses to engage with their customers fall into one of three categories—communication between systems, departments, or with specific individuals. So we shipped products to serve those distinct types of experiences. The Engagement Cloud consists of a collection of declarative APIs that do much of the heavy lifting of building custom experiences for you. They give you the logic needed for every type of customer interaction.

  1. We announced Twilio Proxy—a declarative API that creates proxied one-on-one text and voice conversations between customers and the right worker in your company. Proxy is available now in public beta.
  2. Contact centers rejoice! Now there are workforce management Add-ons for TaskRouter (developer preview).
  3. Twilio Verification SDK for Android (developer preview) simplifies and automates phone number workflows in your Android apps.
  4. Level up your notification game by going multi-channel. Twilio Notify is now available to everyone in public beta.
  5. We added support for Firebase Cloud Messaging (FCM) for Notify.

Super Network

Everyday, you make calls, send messages, and push HTTP requests all over the world. Twilio’s Super Network is the infrastructure powering those connections. Whether you’re using phone numbers, short codes, SIP trunking, Wireless, Twilio Interconnect, or Lookup to communicate, you’re using one part of the Super Network ecosystem. Here’s what’s new with the Super Network.

  1. We’ve just announced that we now have local phone numbers in over 70 countries, from France to Thailand to Brazil.
  2. If you’re looking for toll-free numbers to use in those countries, we’ve got you covered. We’ve just increased our inventory of toll-free numbers with 27 new countries.
  3. If you’re new to the cloud and trying to get that landline plugged into the Super Network, now there’s an easy way to do that—Hosted SMS. It lets you add SMS to any phone number, even landlines, without changing your existing voice provider.
  4. Programmable Wireless has opened up access and is now available to everyone.
  5. We’ve started testing global coverage for Programmable Wireless in almost 200 countries.
  6. IoT Authentication Tools (coming soon) will make provisioning and trusting devices much simpler for developers.
  7. We brought a new data center in Oregon online for Elastic SIP Trunking to improve audio fidelity and resiliency on the west coast of the United States.
  8. We launched two new Interconnect exchanges in Europe and Asia.

Runtime

You can’t build what you need to without the right set of developer tools. Twilio Runtime is a virtual toolset you can use to develop Twilio apps faster and more easily.

  1. We announced Twilio Functions to give you the ability to write and host code without having to push your code to a server—Twilio is that server. There’s no need to git push heroku master or ./ngrok http 8000 if you don’t want to. Simply write your code in the Functions portal, click “run” and your app is live.
  2. Many Twilio applications require static assets, like mp3 files for <Play> or HTML/CSS/JS files for Video quickstart applications. Now using Assets, you can host those static files on Twilio and easily incorporate them into apps.
  3. Debugger Webhook gives you the ability to receive an HTTP request from Twilio every time an application error occurs.
  4. There’s a new version of our API Explorer, which is the quickest way to make real requests to Twilio’s REST API.
  5. Our Sync product is now officially open in public beta and available for any developers who need to synchronize application state in the cloud.
  6. Businesses can now control user authentication and user revocation with Single Sign-On (SSO)—part of the Twilio Enterprise Plan.
  7. We launched Public Key Client Validation—say that 10 times fast.
  8. Our API SLA for Enterprise Plan customers is now 99.99%.

Marketplace

Marketplace allows you to do more with less code. You can connect your business, customers, and your stack to a ton of third-party apps and pre-integrated partner technologies on the Twilio platform.

  1. With Twilio Channels, you can now send and receive messages on multiple channels with the Twilio API you already use. We’re talking channels like Facebook Messenger, Slack, Twitter, Notifications for Alexa, and more (some Channels are in developer preview, some are coming soon).
  2. Contact centers rejoice again! There are also analytics Add-ons for TaskRouter (developer preview).
  3. We beefed up the Marketplace with a new OpenCNAM Add-on that gives you a caller’s name in real-time based on the phone number.
  4. Now you can use the Deepgram Phrase Detector Add-on to locate keywords and phrases even in noisy, low-quality audio.
  5. We introduced yet another Add-on optimized for call centers—VoiceBase PCI Detection and Redaction—for cleansing call recordings of sensitive data.
  6. Marketing intelligence? There’s an Add-on for that and it’s called the Digital Segment Business Information Add-on.
  7. Attention advertisers: if you run Facebook Lead Ads, now you can get notified when a new lead comes in. Using Facebook, Zapier, and Twilio together, you can turn new leads into buyers.
  8. There’s a new IBM Watson Tone Analyzer Add-on that uses linguistic analysis to give you insights into the tone and emotions of your customers, so you can act accordingly.
  9. We announced a partnership with Amazon that lets you integrate Twilio APIs into Amazon Connect’s contact flows to create intelligent, personalized experiences.

Whew. That was a doozy. SIGNAL is a moment built by, created for, and comprised of the Twilio community. Without you, there would be no suites, networks, or developer tool belts for us to build. We can’t thank you enough for coming to SIGNAL and being a member of the community. We’ll see you next year!

All Stories from SIGNAL 2017

Contact Centers: Introducing Agent Conference

$
0
0
  • Place outbound calls to prospects without TwiML fetch.
  • Agent Whisper feature to coach agents.
  • Available now in public beta.

Conference is at the core of many advanced Twilio call flows. Over the last year, we’ve made Twilio Conference more powerful and easier to use. We shipped conference events with speaker detection, hold API, end conference API, region selection, and made all conferences Global Low Latency (GLL) by default.

Today we’re excited to announce the public beta of Agent Conference—a new set of conference features that make it easy to connect contact center agents to your customers. It includes two powerful features for contact centers: Agent Whisper and an Outbound Conference Call API.

Agent Whisper

Quality assurance is crucial for contact centers to provide great customer experiences. Supervisors play a big role listening into calls to monitor agents and coach them when they need help. This has always been possible with Twilio by adding a supervisor to a conference and placing them on mute. However, if you want that supervisor to be able to coach an agent in real-time, mute won’t help. Agent Whisper adds the ability for a supervisor to hear all participants in a conference and speak to only one participant—your agent.

The API for Agent Whisper is straightforward. Using the whisper param, specify the call SID of the agent in that conference who should be able to hear the supervisor.

<Response>
 <Dial>
  <Conference whisper="CA1bd06ff67e14ccf3d5ac9ba896305a6b">Support</Conference>
 </Dial>
</Response>

The above TwiML will put a supervisor into the conference, they will be able to hear all participants and only speak to CA1bd06ff67e14ccf3d5ac9ba896305a6b (the agent). In this case, the customer will not hear the supervisor.

Say you would like the supervisor to barge into the call and speak to all participants. To do that you would use the transfer API and then return this TwiML:

<Response>
 <Dial>
  <Conference>Support</Conference>
 </Dial>
</Response>

We now offer full whisper monitor and barge functionality within Conference.

The full docs for Agent Whisper can be found here.

Outbound Conference Call API

When you’re placing outbound calls to connect agents to customers or prospects, you want the experience to be as responsive and smooth as possible. To enable that experience, we’ve added a new API for placing outbound calls from conferences.

This API has a few unique properties. It’s a declarative API for specifying “create an outbound call and connect it to a conference”. Instead of creating an outbound call and then once the call connects having Twilio fetch TwiML, calls created with this API are connected to a conference immediately on creation.

However, what is most powerful is that agents can now hear the state of the outbound call (like ringing or disconnect messages) while still being in a Conference. We call this “early media”. This not only improves agent productivity but also makes it possible to have supervisors in outbound call flow scenarios.

An example request for this API is below:

curl 'https://api.twilio.com/2010-04-01/Accounts/AC25e16e9a716a4a1768c7c83f58e30482/Conferences/AgentConf12/Participants' -X POST \
--data-urlencode 'To=+15624421212' \
--data-urlencode 'From=+18180021216' \
--data-urlencode 'EarlyMedia=true \
-u AC25e16e9a716a4a1768c7c83f58e30482:[Token]

We now offer full whisper monitor and barge functionality within Conference.

Another cool feature is the ability to address the Conference by friendly name in addition to a SID, in this case, AgentConf12. This is a small but powerful feature because it reduces the state you have to keep track on your application making. The full docs for this feature can be found here.

Pricing

Agent Conference offers advanced features for building agent-centric call flows on Twilio. It’s priced starting at $0.0033 per participant per minute.

Region Conference Agent Conference
US – East $0.0018 $0.0033
Europe – Dublin $0.0025 $0.004
APAC – Tokyo $0.003 $0.0045
APAC – Sydney $0.003 $0.0045
APAC – Singapore $0.003 $0.0045
South America – São Paulo $0.004 $0.0055

*Prices above are per participant per minute.

How to get started

Agent Conference is available to all Twilio developers today. To get started:

If you have any questions about the feature or how to implement it, don’t hesitate to reach out to our Sales team.

What’s Next: SDKs and Conference Features

Next, the Conference team is working to enhance Agent Conference by offering better visibility and control over participants via a client-side JavaScript SDK. We’re also planning to add DTMF event detection and the ability to <Play> or <Say> to participants.

Stay tuned for morewe can’t wait to see what you build.

Contact Centers: Introducing Agent Conference

Viewing all 65 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>