Posts Tagged ‘sip’

Meet Phono – Tropo’s Web Phone

Monday, January 23rd, 2012

Have you heard about Phono, our open source Javascript Phone API project?

Phono is a free HTML5 jQuery-based web phone that you can add to any web page to place or receive open SIP-based VoIP calls to/from any web browser (or iOS/Android mobile device using Phono Mobile)!

Phono can be connected to Tropo to place or receive phone calls to/from real telephone numbers! Phono can also interact with Tropo voice applications directly from a web page using Tropo’s speech recognition and text-to-speech in 24 languages as well as record and play media such as WAV or MP3 files or conduct conference calls, call transfers, call recording, etc.

To make things even better, Phono and Tropo both support SIP headers which are basically key/value pairs of data that you can sent along with calls. SIP headers are very common in call center applications and enterprise screen-pop implementations. Using SIP headers allows Phono to place a call into a Tropo application and pass along data instructing Tropo to transfer the call to another telephone number. This is how all of the click-to-call demo applications work on phono.com. These demo applications are also limited to 10 minutes in length so that you can experience the quality of a Phono call and write your own Tropo application for longer calls.

Because we have had a few questions lately on this topic, I wanted to provide some sample code for both Phono and Tropo to make this easier for you to apply to your application. This demo application allows you to enter a phone number on a web page and call it using Phono and Tropo. The web page has a simple form that asks for a phone number and has a call button that initiates a SIP VoIP call to Tropo app:9996182316. Reviewing the Phono code below, you will find that it uses jQuery to pass the phone number value in the textbox to Tropo as a SIP header.

<html>
  <head>
    <script src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
    <script src="http://s.phono.com/releases/0.3/jquery.phono.js"></script>
  </head>
  <body>
	<input id="phonenumber" type="text">
    <input id="call" type="button" disabled="true" value="Loading..." />
    <span id="status"></span>
    <script>
    $(document).ready(function(){
      var phono = $.phono({
        apiKey: "your secret key",
        onReady: function() {
          $("#call").attr("disabled", false).val("Call");
        }
      });

      $("#call").click(function() {
        $("#call").attr("disabled", true).val("Busy");
        phono.phone.dial("app:9996182316", {
		  	headers: [
			             {
			               name:"x-numbertodial",
			               value:$('#phonenumber').val()
			             }
			           ],
          onRing: function() {
            $("#status").html("Ringing");
          },
          onAnswer: function() {
            $("#status").html("Answered");
          },
          onHangup: function() {
            $("#call").attr("disabled", false).val("Call");
            $("#status").html("Hungup");
          }
        });
      });
    })
    </script>
  </body>
</html>

You could write a Tropo transfer application using the Scripting API in one line of Ruby code that transfers the call to the phone number in the SIP header like this:

transfer $currentCall.getHeader("x-numbertodial")

What if you wanted to add a timer that ends the call after 10 minutes like we do on phono.com for demo purposes? This feature is also simple but it requires multithreading your Ruby application and using our REST API for sending a signal to interrupt the transfer method once your timer reaches its alarm.

require "net/http"

# Create second thread for timer and announcements
Thread.new do
  sleep 600 # Note: Sleep is in seconds so 600 = 10 minutes

  http = Net::HTTP.new "api.tropo.com"

  request = Net::HTTP::Get.new "/1.0/sessions/#{$currentCall.sessionId}/signals?action=signal&value=limitreached"
  response = http.request request
end

say "hold please while we transfer your call."
transfer $currentCall.getHeader("x-numbertodial"), :allowsignals => "limitreached"
say "your limit has been reached."

That’s cool but what if you wanted to block certain phone numbers or limit the demo calls to North America? You could add area codes or phone numbers to a regex array and check the desired phone number against the list of regexes to see if you should allow the call to transfer or not like this example:

phone = $currentCall.getHeader "x-numbertodial"

# Blocked North American area codes
blocked = [
  /^\+?1?8[024]9/,
  /^\+?1?26[48]/,
  /^\+?1?24[26]/,
  /^\+?1?34[05]/,
  /^\+?1?[62]84/,
  /^\+?1?67[10]/,
  /^\+?1?78[47]/,
  /^\+?1?8[024]9/,
  /^\+?1?86[89]/,
  /^\+?1?441/,
  /^\+?1?473/,
  /^\+?1?664/,
  /^\+?1?649/,
  /^\+?1?721/,
  /^\+?1?758/,
  /^\+?1?767/,
  /^\+?1?876/,
  /^\+?1?939/
]

block_call = blocked.any? { |x| phone =~ x }

You could add this code immediately above your transfer and add a conditional statement that says something like this example:

if block_call
  say "calls to this area code are blocked."
else
  say "hold please while we transfer your call."
  transfer phone, :allowsignals => "limitreached"
  say "your limit has been reached."
end

You could also add billing functionality to the Tropo script by applying a rate based on country code and multiply it times the number of seconds that the call was in progress. To accomplish this goal, you would add a timestamp at the beginning of the script and a timestamp directly following the transfer method. When either party hangs up, the Tropo script will continue running with the line immediately following the blocked method such as transfer in this case.

If necessary, you could also check to see if the Phono caller is still on the call by interrogating the $currentCall.isActive property or by wrapping your entire application in a while loop like this example:

while $currentCall.isActive
  # Do Stuff
end

I think that should get you started! You can now build your next-generation click-to-call application using Phono and Tropo! Please let us know how you are using Phono with your Tropo applications :)

WebPulp.TV Interviews Tropo

Tuesday, December 20th, 2011

Jose de Castro, our Chief Architect, was recently interviewed by Josh Owens from WebPulp.TV on the interworkings of Tropo’s Webscale cloud communications platform.

Topics covered include:

  • scripting languages (ruby, python, php, groovy, and javascript)
  • scaling our data centers and APIs
  • message queues (rabbitMQ and activeMQ)
  • media server technology
  • VoIP and SIP QoS
  • redundant telco carriers and networks
  • speech recognition and text-to-speech in 24 languages
  • human vs. answering machine detection
  • virtualization
  • using DNS as key value stores
  • splunk logging
  • sponsorship of adhearsion, the ruby telephony framework
  • rayo, Voxeo Labs’ new realtime communication protocol

Webpulp.tv – Tropo – Jose De Castro from Gaslight Software on Vimeo.

The Conference Pop-In Timer

Thursday, July 21st, 2011

Have you ever wanted to set a timer on a conference call and pop-in at a certain time to either:

1) announce something, say, every 15 minutes;
2) let participants know that they have 2 minutes remaining; or
3) ask them a question or survey?

This is easy to do by connecting Tropo applications!  I created a quick demo using the Tropo Scripting API that allows people to call into a Tropo phone number, SIP address, or Skype address and after x seconds announce that they have two minutes remaining.  The demo code below is written in Ruby and it uses threading to start a timer and wait/sleep until x seconds has transpired.  Once the timer expires, it calls and conferences a second Tropo application via its SIP address and simply announces the warning message.  You could easily extend the second Tropo application to prompt the user to answer a single question or a take a poll/survey and report their answers back to the main application either via a database or via SIP headers on the transfer back to the application.

Here’s the Ruby source code on the main application:

#Method to create timeStamp as our conferenceID
def get_conference_id()
	timeVar  = Time.new
	returnValue = timeVar.strftime("%Y%H%M%S")
	return returnValue
end

conferenceOptions={
			:mute=>false,
			:playTones=>true,
			:leaveprompt=>"beep"
			}

begin

  #Create conference ID
  conferenceID = get_conference_id()

	log "@"*5 + "User has answered"

	#Create second thread for second for timer and announcements
	Thread.new do
		log "@"*5 + "Start second tread"

    sleep 10

    call 'sip:9996137086@sip.tropo.com', {
	:onAnswer=>lambda{|event|
		log "@"*5+"answered join conference"
		newCall = event.value
                newCall.conference(conferenceID,conferenceOptions)
		}
        }

  end #thread

  say 'You are now in conference.'
	conference(conferenceID,conferenceOptions)

end

Here’s the Ruby source code of the announcement application:

say "you have two minutes remaining."

Note the SIP address used in the main application. It’s the SIP address assigned to your second announcement application by Tropo when it’s created. Every Tropo application automatically gets a SIP address, iNum address, Skype address, and Phono address assigned to it upon creation. You can transfer and conference calls app-to-app using SIP addresses and even pass data between them using SIP headers. How’s that for webscale?!

Tropo Powered Virtual Call Center in 10 Minutes

Thursday, July 7th, 2011

A few months ago, my colleague Dave Hoff and I blogged about a CouchDB based solution to enable a virtual call center powered by Phono – the jQuery extension that lets you build telephone and instant messaging clients inside a web browser.

That series had a fairly heavy emphasis on the use of Asterisk as the engine driving calls from customers to remote agents.

We’re now revisiting this solution with an emphasis on making it easy for anyone (including those with no need for an Asterisk application) to get a remote call center solution up and running quickly and with amazing ease.

This screencast will demonstrate how to get a fully functional, cloud-based remote call center solution deployed and working in about 10 minutes.

You’ll need a few items to follow along and get your own virtual call center up and running.

But don’t worry – they’re easy to get and (for development purposes) free to use.

  • A Tropo account.
  • A Phono API key.
  • An instance of the open source NoSQL database, CouchDB.
  • The CouchApp command line utility for deploying CouchApps.

You can clone the solution demonstrated in this screencast by doing the following at the command line:

git clone git@github.com:mheadd/remoteagent.git

As I emphasize in this screencast, the potential to extend and expand the features currently included in this solution are almost endless.

Because Tropo and Phono support open standards like SIP, XMPP and HTTP you can integrate with almost any system that you need to, so you can provide cutting edge features in your virtual call center.

The solution demonstrated here is completely open source. Clone it, extend it, make it your own – the only limit is your imagination.

Have fun!

ASR-as-a-Service

Saturday, May 21st, 2011

Automated Speech Recognition (ASR) as-a-Service can be powered via Tropo and SIP using this simple open source code provided below.  This service is perfect for adding speech recognition to your existing Asterisk, FreeSwitch, YATE, or enterprise app from the stone ages.

Here’s how it works!

You can transfer a phone call via SIP from a platform that doesn’t support ASR to Tropo along with the following SIP headers: prompt, choices, and returnaddress (SIP address). Tropo automatically answers the call and prompts the user the the text-to-speech (TTS) prompt passed. It automatically loads the ASR grammar with the choices passed. Upon successfully processing the speech recognition, Tropo transfers the call and the recognized result back to the return SIP adrress along with an x-voxeo-result SIP header containing your keyword spoken by the user.

Here’s the Tropo code using our hosted Scripting API:

This code is written in Ruby using our Tropo Scripting API.  You can use $currentCall.getHeader to get the SIP headers passed to your Tropo application and you can send headers to other SIP applications using the Tropo transfer method.  The speech recognition magic happens in the Ask method.

recoresult = ask $currentCall.getHeader("x-sbc-prompt"), {
   :choices => $currentCall.getHeader("x-sbc-choices")}

transfer $currentCall.getHeader("x-sbc-returnaddress"), {
    :headers => {'x-voxeo-result' => recoresult.value}
    }

Here’s how we tested it.

We used Phono, our browser-based webphone, to call Tropo and pass the prompt, choices, and returnaddress parameters.

phono.phone.dial("sip:9996106030@sip.tropo.com", {
  	headers: [
	{
		name:"returnaddress",
		value: "sip:9996106032@sip.tropo.com" // you could use returnaddress var to send the results back to Phono's SIP address
	},
	{
		name:"prompt",
		value: "What is your favorite color?"
	},
	{
		name:"choices",
		value: "blue,green,red,yellow"
	}
	],

Just to prove that yet another SIP application could receive the speech recognition results, we created another Tropo application in Ruby using the Scripting API to simple say the results.

say "You said " + $currentCall.getHeader("x-voxeo-result")

This second test application would typically be omitted for a real application since the returnaddress would most likely be the originating SIP address of your switch to return to your original callflow.  It’s cool that you could transfer to yet another application for additional processing!

What’s Next?

You can clone or fork this open source project on Github and use it today for as little as $.03 per minute for the Tropo call.  Let us know if you would prefer for us to build this service out for commercial use.

 

Extending GoogeVoice with Tropo

Friday, May 13th, 2011

We are always excited to see developers using Tropo to extend GoogleVoice functionality and features by adding things like SIP and Call Forwarding and Call-In enhancements.  Terry Swanson (@FunnyBoy243) is one of these cool developers who wrote 2 of these extensions and opensourced them for others to share and contribute:

His Call Forwarding Extender Tropo Script includes the following features that extend/add to the current Google Voice feature-set:

  1. Easy forwarding to SIP Numbers (especially compared to IPKall)
  2. Outbound call recoding
  3. Allows forwarding to numbers that cannot be verified through Google Voice (such as numbers with extensions).  You can append “postd=DIGITSp” and/or “pause=WAITTIMEms” in the CALL_DEST variable to allow the script to forward to your extension. For example, “+14155551212;postd=ppppp1234pp56″ would dial (415) 555-1212 wait 5 seconds (1 second for each p) dial 1 2 3 4, wait 2 seconds then dial 5 6. Look enter the Parameters section of the Tropo API for more information.

You can have this script call multiple SIP/Telephone numbers at the same time by using an array for the CALL_DEST variable. All numbers will ring and the first to answer the call will take the call.

Example: $CALL_DEST = array(“sip:2233486745@sip2sip.info”, “sip:2233486712@sip2sip.info”);

For step by step instructions, check out Terry’s original post here.

His Google Voice Call In Extender Tropo Script includes the following features that extend/add to the current Google Voice feature-set:

  1. SIP Address for your Google Voice number.
  2. Skype number for your Google Voice number.
  3. Phone Number Aliases for your Google Voice number – You can have multiple phone numbers from different areas forward to the same Google Voice number so they wont have to pay long distance fees to call your Google Voice number.

Here are some additional tips and tricks with this extension:

  1. You can have this script call multiple Google Voice numbers at the same time by using an array for the GV_NUM variable. All numbers will ring and the first to answer the call will take the call. Example: $GV_NUM = array(“5103364032″, “5103364002″);
  2. You can add International Phone numbers to allow people from other countries to call your Google Voice number without paying International rates.
  3. You can use the Skype number to make free telephone calls using Google Voice.

For step by step instructions, check out Terry’s original post here.

Hats off to you, Terry!  Keep up the good work!

How to Build a VoIP-Based Baby Monitor

Thursday, February 17th, 2011

Two members of the Phono/Tropo team, and soon a third member, have recently added new babies to their families. Congratulations Mark, Justin, and John!

All of this excitement got the hacker in me thinking…  What would a modern Baby Monitor look like today?  Armed with the Phono and Tropo APIs, I started hacking and 2 hours later had the following example application to share with you!  Here’s the link to the demo.  Let us know what you think! http://phonophone.heroku.com/babymonitor.html

Phono, the jQuery WebPhone from the Tropo team, runs in the web browser to monitor activity in the room where it is running.  Tropo is used to manage the baby monitor’s conference room (based on the access code) and the dial-in numbers to listen to the baby monitor via PSTN, Skype, SIP, or iNum.  The Phono side of the conference is unmuted so you can hear activity while the Tropo side of the conference is muted.  You can have many people (Mom, Dad, Grandparents, etc.) dialed in listening to the same baby monitor using any combination of the access channels listed above.

Check out the Phono Blog to learn more about this demo and see the source code!

Asterisk & Tropo and a Single Adhearsion Dialplan

Friday, October 8th, 2010

A key goal of Tropo AGItate is to allow you to use Tropo seamlessly with an existing Asterisk server. With AGItate you may add any Tropo feature to your existing Asterisk server without installing additional Asterisk modules and using the AGI protocol you already know. These features include:

  • Speech Synthesis/TTS in 7 languages and 2 dialects
  • Speech Recognition/ASR in 7 languages and 2 dialects
  • Transcription of audio messages, like voicemail
  • Multi-channel support for SMS, Instant Messaging and Twitter
  • Conferencing
  • and more

The ease of interoperability between Asterisk and the Tropo cloud highlights exactly why we run and make available an open SIP network. Every application created gets a SIP address automatically:

To show this in action I have chosen Adhearsion as the framework to serve diaplans for both Asterisk and Tropo to process a single caller on an Asterisk server. Here is a quick overview of how it works:

Through the use of SIP, SIP headers and call tagging in Adhearsion, you may write a single dialplan that handles the call and interaction between the Asterisk and Tropo cloud seamlessly. Here is a quick walkthrough of the dialplan itself and the dialplan taking calls in action:

The entire dialplan may be seen here:

# Serves up FastAGI to your Asterisk server
asterisk_agi {
  # Add a custom SIP Header to the session so that when we send to
  # Tropo we may know which Asterisk call the Tropo call is
  # servicing
  execute 'SIPAddHeader', "x-ahn-id: #{channel}"

  # Send the call to your Tropo AGItate app on Tropo
  # option 'g' is required in order for the call to come back
  # to the dialplan
  dial 'SIP/9991479110@sip.tropo.com', { :options => 'g' }

  # After the call comes back find this call and then
  # grab the tag of the result we are looking for
  this_call = Adhearsion.active_calls.find(channel)
  favorite_muppet = ''
  this_call.tags.each do |tag|
    hash = JSON.parse tag
    favorite_muppet = hash['favorite_muppet'] if hash['favorite_muppet']
  end

  # Play back the appropriate audio file based on the user's input by passing the appropriate value
  # in a custom SIP header
  case favorite_muppet
  when 'kermit'
    # Tropo supports wav/mp3 playback, so pass it a link
    execute 'SIPAddHeader', "x-ahn-mp3file: http://downloads.members.tripod.com/Tiny_Dancer/beingreen.mp3"
  when 'swedish chef'
    execute 'SIPAddHeader', "x-ahn-mp3file: http://dl.dropbox.com/u/25511/Voxeo/TTS-Example/SwedishChef.mp3"
  else
    execute 'SIPAddHeader', "x-ahn-choice: bad"
  end
  dial 'SIP/9991479110@sip.tropo.com', { :options => 'm(silence)' }
}

# Serves up FastAGI to your Tropo AGItate application
tropo_agi {
  # Grab the SIP headers from the Tropo cloud delivered in the first message over AGI and made
  # available in Adhearsion as 'tropo_headers'
  headers = JSON.parse tropo_headers

  if headers['x-ahn-mp3file']
    # If we have the mp3file header, then lets play the fileback, otherwise ask for the input
    play headers['x-ahn-mp3file']
  elsif headers['x-ahn-choice']
    # If the bad choice header is here, we know they did not choose a Muppet they should have
    play 'You silly muppet fan, the best muppets are kermit or the swedish chef. Try again another time. Goodbye.'
  else
    # Invoke the Tropo Speech Synthesis/TTS to speak to the caller
    # https://www.tropo.com/docs/scripting/say.htm
    play 'Welcome to the Muppetorium.'
    # Invoke the Tropo Speech Recognition/ASR to ask the caller for input
    # https://www.tropo.com/docs/scripting/ask.htm
    result = execute 'ask', { :prompt   => 'Which is your favorite muppets character?',
                              :choices  => 'kermit, fozzie, statler, waldorf, oscar, bert, ernie, swedish chef',
                              :attempts => 3,
                              :timeout  => 10 }.to_json

    # Parse the result from Tropo into a Ruby hash
    result = JSON.parse result.split('200 result=')[1]

    # Find the active Adhearsion call object based on the SIP header passed into Tropo
    call = Adhearsion.active_calls.find headers['x-ahn-id']

    # Tag that call object with the value of the speech recognition, hangup the call between Asterisk and Tropo
    # so that Asterisk may continue handling it on its own
    call.tag({ :favorite_muppet => result['interpretation'] }.to_json)
  end
}

Or downloaded here. Thats it! You now have a fully featured Asterisk instance leveraging the best of what the cloud has to offer without adding or purchasing any additional software for your Asterisk box.

To get started with AGItate we created a howto walkthrough that you may see here. Tropo is free for development use, so there is no reason not to give it a try. Enjoy!

Dial Multiple Phone and SIP Numbers & First to Answer Wins

Wednesday, May 19th, 2010

Courtesy of Mark Hillary

In order to support @zlu‘s OpenVoice project release for Google I/O we have introduced a new feature to Tropo that allows you to dial multiple phone numbers at once. Multiple number dialing not only supports phone numbers, but SIP addresses as well. The first endpoint to answer, whether a phone or SIP device, will get the call and your application will move onto the next step in your WebAPI session (coming to scripting soon).

To take advantage of this new feature, the call object in WebAPI now takes an array of addresses (‘tel:’ or ‘sip:’) in the ‘to’ parameter. A Ruby Sinatra example:

%w(rubygems sinatra tropo-webapi-ruby).each { |lib| require lib }

post '/dial-numbers' do
  tropo = Tropo::Generator.new do
    call :to => [ 'tel:+14155551212', 'tel:+15105551212' ]
    say 'Hello, happy you were the first phone to answer!'
  end
  tropo.response
end

The corresponding JSON that is generated:

{
   "tropo":[
      {
         "call":{
            "to":[
               "tel:+14155551212",
               "tel:+15105551212"
            ]
         }
      },
      {
         "say":[
            {
               "value":"Hello, happy you were the first phone to answer!"
            }
         ]
      }
   ]
}

Thats it, now of those two numbers the first to pick up will get the phone call. Enjoy!

How-To: Distinguish PSTN, Skype, iNum, and SIP in your Tropo applications

Tuesday, February 23rd, 2010

Here at the secret layers of Tropo Support we often see similar questions raised by our developer base. We pay attention to these trends, since they often indicate that something may be lacking in our documentation.   If we do find something is lacking we of course want to address by expanding on concepts or adding additional examples to help shore up our doc sets and help out our developers.

Recently I have started to notice a trend of developers asking how to determine the source of callers dialing into their applications (Skype, PSTN, SIP, or iNum).  We’ll since we are often asked this question I figured I would provide a nice Ruby example for the ‘class’ =), I do hope this help!

Regards,
John Dyer
Customer Engineer
Voxeo Support

# -----------
# route based on DNIS
# John Dyer
# Voxeo Support
# -----------
log "@"*10 + $currentCall.inspect   # List some headers
log "@"*10  + $currentCall.getHeader("x-voxeo-to")  # log to header

module SipRegex
  def evaluate_sip_header(header)
    case header
      when /^<sip:990/            # SKYPE
        "SKYPE"
      when /<sip:999/              # SIP
        "SIP"
      when /^<sip:883/            # iNUM
        "INUM"
      when /<sip:|[1-9]\d\d/      # PSTN
        "PSTN"
      else
        "OTHER"
    end
  end
end
include SipRegex

toHeader = evaluate_sip_header($currentCall.getHeader("x-voxeo-to"))

if toHeader == 'PSTN'
    answer
    log "@"*10 + toHeader
    hangup
  elsif toHeader == 'SKYPE'
    answer
    log "@"*10 + toHeader
    hangup
  elsif  toHeader == 'SIP'
    answer
    log "@"*10 + toHeader
    hangup
  elsif  toHeader == 'INUM'
    answer
    log "@"*10 + toHeader
    hangup
  elsif toHeader == 'OTHER'
    answer
    log "@"*10 + toHeader
    hangup
  else
    log "@"*10 + "SOMETHING BAD HAPPENED" 
end