Posts Tagged ‘Ruby’

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 :)

Voice Texting With Tropo Speech & SMS Technology

Wednesday, December 21st, 2011

We all agree that texting while driving is very dangerous, right? Fred Wilson, VC and principal of Union Square Ventures thinks so too. He recently wrote a blog post that starts like this:

“As a parent of two young adult drivers and a third soon to hit the road, nothing scares me more than texting while driving.”

Fred continued his blog post envisioning a Voice Texting application as follows:

“Being an engineer at heart and by training, I’ve been looking for a solution to the problem. I know that the buzz of the phone and the unread/unresponded message is like a drug to many and that the best solution would be a “hands free” way to read and respond. And the bluetooth/hands free voice solution works so well on most cars and most phones now, so why can’t we do the same with texting?”

Having two kids of my own (1 already driving and 1 studying for a drivers permit) and having access to the Tropo API and platform, I felt compelled to build a quick Voice Texting application to share with Fred Wilson! Here is what Fred had to say upon me sharing it with him…

Here is how it works:

To send a text, call (415) 349-3120 and using Tropo speech recognition say the phone number that you would like to text and then speak your message. Tropo then transcribes the message and sends your text message to phone number you spoke without taking your eyes or hands off the road.

Disclaimer: We are not promoting texting while driving even with the proper tools that would keep your eyes on the road such as a bluetooth earpiece and autodial features.

The source code for this project is written in Ruby and open sourced on GitHub in case anyone would like to extend it or perhaps even create a new business around this idea and have a head start! Here’s a video of me demonstrating the technology in action:

Drive safely!

LA .NET Hackathon 2011

Monday, December 5th, 2011

Tropo is partnering with the LA .NET Developers Group and Outlook Amusements to sponsor this weekend’s LA (Burbank) Hackathon at Outlook Amusements on Saturday, December 10, 2011 from 9:00 AM to 6:30 PM (PT).

Here’s the address: Outlook Amusements 2900 W. Alameda Ave suite 400 Burbank, CA 91505

The theme of the LA Hackathon is “Build Voice/SMS apps for Holidays”! Here are a few ideas to get you thinking:

  • Santa Caller (similar to http://santacall.us) – Build a website that allows a parent to schedule a call to their kids from Santa. Have Santa ask the kid what they would like for Christmas and then email the parents their kid’s recorded message and/or transcribe the message for the email.
  • Santa Tag (similar to http://www.bloggingbistro.com/jc-penney-comes-up-with-a-new-use-for-qr-codes-video/) – Build a website that calls someone to record a message then associates the message with a QR code that plays when scanned.
  • Holiday Greetings Hotline – Build a holiday greetings hot line where user can leave a voice message that will be transcribed into text and posted to “Holiday Greetings” twitter account.

Even though this event is sponsored by the .NET Developers Group, we will be supporting all development languages and will have Tropo expertise onsite in .NET, PHP, Ruby/Rails, and Javascript, and Node.JS!

Register today!

Win a Free Pass to Madison RubyConf!

Saturday, August 13th, 2011

Tropo is giving away 1 FREE pass to this week’s Madison Ruby conference! The conference is in beautiful Madison, Wisconsin and the venue is the elegant Overture Center for the Arts. The conference starts with workshops on Thursday, 8/18/2011, followed by two full days of dual track 40+ speaker sessions and after parties!

Entering the FREE pass to MadisonRuby give-away contest is simple:

1. Tweet this sentence to be entered to win:

“Hey @Tropo – Pick me for the free ticket to @MadisonRuby conference!”

2. The winner will be randomly selected on Monday, 8/15/2011, at midnight Pacific time from a list of all of these tweets posted on Twitter.  You can tweet it as much as you like to increase your chances!

Tropo is a proud sponsor of the MadisonRuby conference.

Tropo giving away a Parrot AR Drone @ LSRC!

Wednesday, August 10th, 2011

I’m leaving in about 30 minutes to head to Austin, TX – the site of LoneStar Ruby Conf 2011 – and boy am I excited. What am I so excited about? For one, I get to check out all the great talks, especially Ben Klang’s talk on Ruby & Adhearsion! I’m also excited to mingle with awesome Rubyists and to give away some really cool stuff, like a Parrot AR Drone! Yeah, that’s right, Tropo is holding a contest for most innovative Tropo app (Phono and SMSified apps will also be accepted, as fellow Voxeo Labs APIs) and will be giving away the AR Drone on the last day to the winner!

Below you will see a Drone fly thru our new offices as they were still under construction – man this is a cool video!

You can find more info on the event by checking out the Rubyology interview Chris Matthieu & I just had with Jim Freeze, the organizer of LSRC. It has tons of great info on what is sure to be a fantastic event!! We hope to see you there!

-John

Tropo Brings the Gold to LoneStar Ruby Conf

Thursday, July 28th, 2011

Tropo is proud to pony up the gold to sponsor the famous LoneStar Ruby Conference in Austin, Texas August 11-13, 2011!  This year marks the conference’s 5th anniversary and we are planning to make it a special one to remember.

The keynote speakers include:

James Edward Gray II

Obie Fernandez

Chad Fowler

We’ll be participating in Thursday night’s API hack night and will be providing prizes for the coolest Tropo, Phono, or SMSified application!  Start thinking and planning out your strategy now for this event and stay tuned to our Twitter feed for more information as we get closer to the conference!

See y’all there!

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 AGItate v0.1.7 Released

Friday, April 22nd, 2011

Thanks to some commits by Ben Klang of Adhearsion and MojoLingo fame, we have a new release of the Tropo AGItate script. Version 0.1.7 now includes release notes, with changes that include:

  • Add framework for “magic” channel variables. This supports things like CALLERID(all) vs. CALLERID(name) vs. CALLERID(num) that all have overlap in Asterisk. We now try to do the right thing when setting or reading each variation. More special variables can be easily added.
  • Enhanced Dial compatibility:  Allow setting the CallerID on outbound calls, set DIALSTATUS based on Tropo response and clean up parsing of dial string
  • Set the default AGI port if unspecified in the YAML
  • Update to RSpec 2
  • Allow detecting the Tropo dialed number for incoming calls (agi_dnid)
  • Fix fatal missing error on SIP failover failure
  • Update unit tests for new functionality; fix broken unit tests
  • Rspec tests now require JRuby v1.5.x or better

You may grab the latest script from Github here. As a refresher, AGItate is a script that emulates the Asterisk AGI protocol on Tropo. Allowing you to use frameworks like Adhearsion or Asterisk-Java with Tropo.

We are also cooking up some interesting developments for the Adhearsion community with Ben, so stay tuned!

Update to AGItate

Friday, March 11th, 2011

I have released v0.1.3 of AGItate today. In case you have forgotten, AGItate turns Tropo into an Asterisk AGI client for use with the likes of Adhearsion, Asterisk-Java and others.

The following enhancements were made today:

  • AGItate now requires YAML to coincide with upcoming upgrade to JRuby 1.5.6 on Tropo.
  • There is now full support for the STREAM FILE command in Asterisk AGI.
  • The SAY DIGITS AGI command speaks the digits properly again.

If you are pulling directly from Github then you already have the update, if not go ahead and follow the instructions here to get the AGItate update up and running.

How to Build a Reminder Service Using Tropo and Ruby on Rails

Sunday, February 27th, 2011

Have you ever thought about starting a Reminder Service company and getting millions of dollars in funding all from a weekend project?  Tropo is here to help you with your communications needs in this endeavor!

The Reminder Service source code that I am about to share with you was started on the Nerd Bird (good to have in-flight WiFi) from Orlando to Phoenix, on my way back from the HIMSS conference.  It’s written in Ruby on Rails 3.0.4 and the Tropo Scripting API.

This is Tropo application is designed to demonstrate building a Reminder Service application using both Voice and SMS alerts.  The application will place an outbound reminder call to you 1 week in advance and then 1 day in advance and an SMS message 1 hour in advance of your appointment time.

You can demo the Reminder Service running on Heroku now.  It’s a basic Ruby on Rails scaffolding interface with the ability to create, update, and delete reminders.  All reminders are tracked in UTC time to simplify the demo and there is no authentication because IT’S A DEMO.

The source code is on GitHub.  Simply clone this application from GitHub and run the following statements from your command line:

bundle install
rake db:create
rake db:migrate

Setup an account at Tropo and create a new Scripting API application.  Copy and paste the source code from tropo_scripting_api.rb into separate scripts running under the same application. One for placing outbound voice call reminders and one for sending SMS message reminders.

Here is the source code to place the phone call on Tropo.

message($remindermessage, {
  :to => $phonenumber,
  :channel => "VOICE"
})

Here is the source code to send an SMS message on Tropo.

message($remindermessage, {
  :to => $phonenumber,
  :network => "SMS"
})

Add a phone number to your Tropo application.  SMS messages will not work without one.

The rest of the magic happens in the API controller as shown below:

class ApiController < ApplicationController
  def check
    require 'time'

    @reminders = Reminder.where("(appointment > ?) and (appointment < ?) and ( flag1 IS NULL or flag2 IS NULL or flag3 IS NULL)", Time.now.utc, Time.now.utc+1.week )

    @reminders.each do |reminder|

      if reminder.appointment-1.hour < Time.now.utc && reminder.flag3.nil?

        # Send SMS
        RestClient.get 'https://api.tropo.com/1.0/sessions', {:params => {
          :action => 'create',
          :token => '848b6b17c6229844827847b381...58eaa12683b6ea0a8aa5e166ee7bfcc8',
          :phonenumber => formatphone(reminder.phonenumber),
          :remindermessage => 'dont forget ' + reminder.message.to_s + ' at ' + reminder.appointment.to_s}}

        # Write Flag3
        @reminder = Reminder.find(reminder.id)
        @reminder.flag3 = true
        @reminder.save

      elsif reminder.appointment-1.day < Time.now.utc  && reminder.flag2.nil?

        # Place outbound reminder call
        RestClient.get 'https://api.tropo.com/1.0/sessions', {:params => {
          :action => 'create',
          :token => '3d5eed33429706408efcc0e92307b...d04af908e583112195de9ec7b05b9e',
          :phonenumber => formatphone(reminder.phonenumber),
          :remindermessage => 'dont forget ' + reminder.message.to_s + ' at ' + reminder.appointment.to_s}}

        # Write Flag2
        @reminder = Reminder.find(reminder.id)
        @reminder.flag2 = true
        @reminder.save

      elsif reminder.appointment-1.week < Time.now.utc && reminder.flag1.nil?

        # Place outbound reminder call
        RestClient.get 'https://api.tropo.com/1.0/sessions', {:params => {
          :action => 'create',
          :token => '3d5eed33429706408efcc0e92307b04...908e583112195de9ec7b05b9e',
          :phonenumber => formatphone(reminder.phonenumber),
          :remindermessage => 'dont forget ' + reminder.message.to_s + ' at ' + reminder.appointment.to_s}}

        # Write Flag1
        @reminder = Reminder.find(reminder.id)
        @reminder.flag1 = true
        @reminder.save
      end
    end

    if @reminders
      render :text => "sent " + @reminders.length.to_s + " reminders"
    else
      render :text => "no reminders"
    end
  end

  def formatphone(phone)
    @phone = phone.gsub("(", "").gsub(")", "").gsub("-", "").gsub(".", "").gsub(" ", "")
    if @phone[0..0] != '1'
      @phone = '1' + @phone
    end
    return @phone
  end
end

Now for the drum roll! Setup a cron job to call http://localhost:3000/api/check every 5 minutes, run rails server, and open your web browser to http://localhost:3000!  Oh, one last thing…Go ask one of those “super angels” for some cash-money :)