Archive for the ‘Ruby’ Category

SMS forwarding to an email using MailChimp

Tuesday, September 6th, 2011

Depending on your application, you might receive multiple messages back to back to back – system notifications, alerts, user confirmations and so on – that would be inconvenient to redirect to your phone one by one. As an alternative, how about receiving a full list of the inbound texts sent to you as an email? Using MailChimp with Tropo, this can be accomplished with relative ease.

MailChimp allows users to send an email to multiple email addresses at once as an email blast; this blog will show how to implement MailChimp’s API with a Tropo Scripting app using Ruby. As is typical, first step is to set up an account for MailChimp.

Go here to sign up for an account, then once signed up and logged in, we need to create a list – this is how MailChimp sends emails. Unfortunately, lists cannot be made programmatically, so to set up a new list – sign-in, fill out the requirements, then click the tab Lists.

Once there, hit the “create a subscriber list” button to the left. Following that, some information will be requested – list name, default name, and default email (which is not the email that will send the text messages, but the email that receives confirmation that the emails were sent). When everything is filled out, hit save to create a new list.

Next, the first email address that will receive the email containing the texts needs to be added. This can be done by clicking “add people”.

After selecting “add people”, the only relevant information that needs to be added is the email address. Repeat this process to add multiple email destinations.

From here, the app takes over. To begin, a few requirements are necessary – uri, to format strings into proper URLs,  net/http, to submit URLs to receive information and send the emails, and json, to read the received information.

%w(uri net/http json).each{|lib| require lib}

Following this will be the config section, which are constants that can be set in the beginning.

**Important Note**

-In the API_URL the first three characters can change and will rely strictly on the API_KEY.  An example to expect is: myapikey-us2, in this case the first three characters would be us2.

#CONFIG
YOUR_NAME = URI.encode("Kevin Bond")
API_URL = "http://us2.api.mailchimp.com/1.3"
API_KEY = 'mailchimp_api_key'
FROM_ADDRESS = "kbond@voxeo.com"
SUBJECT = URI.encode("You just received a text message!")

The next piece of code will extract the text and the caller id from the SMS. The text will be the “content” of the email (the body) and the caller id will be the “from_name”.

# Get the initial Text, and callerId
initial_text = $currentCall.initialText
caller_id = $currentCall.callerID

Now it’s finally time to utilize the MailChimp API. This piece of code will send a request to get the list id, which is the specific number that corresponds to the list we made earlier. Once received, it is parsed into JSON and read as the variable list_id.

#Get the list ID that corresponds to your email
id =Net::HTTP.get_response(URI.parse("#{API_URL}/?method=listsForEmail&apikey=#{API_KEY}&email_address=#{FROM_ADDRESS}"))
list_id = JSON.parse(id.body)

The next step in sending this email blast is to create a new email campaign. To do this, there are some parameters that need to be added to the URL. There are four in total, two variables – “api key” and “type of email” – and two arrays or hashes. The code below shows the two hashes (“content” and “options”).

#This will be the body of your email, which is the text message
content = "1=#{URI.encode(initial_text)}"

#Setting the url variables
options = "&
options[list_id]=#{list_id[0]}&
options[subject]=#{SUBJECT}&
options[from_email]=#{FROM_ADDRESS}&
options[from_name]=#{URI.encode(caller_id)}&
options[to_name]=#{YOUR_NAME}".gsub("\n","")

The other two parameters are just inserted individually. Below is the variable parameters, which holds all of the contents.

#Parameters will be the variable that goes inside of the url
#To satisfy mailchimps method, you need 4 fields, the apikey, type of email, 
#options - which is an array or hash, and content - which is also an array or hash
parameters = "apikey=#{API_KEY}&type=plaintext&options=#{options}&content#{content}"

The next MailChimp API request creates a new email campaign, it doesn’t actually send the emails. The request returns the campaign id, called cid, which is used to launch that campaign.

#This response creates a new campaign and returns the id for that campaign
id = Net::HTTP.get_response(URI.parse("#{API_URL}/?method=campaignCreate&#{parameters}"))
cid = id.body[1..10]

Now that the email campaign is created, all that is left to do is send it. The code below sets the URL, creates a new HTTP post, and finally initiates the post. The result should return “true” if the campaign successfully sent.

#This is a post to send the email using the cid, which is the campaign id
url = URI.parse("#{API_URL}/?method=campaignSendNow&apikey=#{API_KEY}&cid=#{cid}")
req = Net::HTTP::Post.new("#{API_URL}/?method=campaignSendNow&apikey=#{API_KEY}&cid=#{cid}")
res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }

Once this executes, all of the email adresses from the list will receive the email with the text message contents.

Hope this was helpful, you can go here to view the app in full. Questions or concerns can be added in the comments, or opened as a forum post here.

Voice Board and Group SMS for Burning Man

Thursday, August 25th, 2011

This is a true testimonial to the power of running Tropo in a Private Cloud using generators for disaster relief or business continuity or for handling communications for events like Burning Man!

This rack includes Tropo and OpenBTS communications equipment for powering Burning Man’s Tropo Voice Board and Group SMS apps!

Once a year, tens of thousands of BurningMan participants gather in Nevada’s Black Rock Desert to create Black Rock City, dedicated to community, art, self-expression, and self-reliance. They depart one week later, having left no trace whatsoever.  Black Rock Desert (or the Playa as Burners refer to it) is an isolated region with no electricity, running water, or communications.

Tropo has partnered with Range Networks and GWOB to setup a local OpenBTS-powered cell tower to provide both Tropo-powered Voice and SMS communications services to the Burners on the Playa.

Custom Private Cloud Tropo applications have been developed to deliver a social voice mail solution – or better yet – an asynchronous voice board messaging platform as well as a Group SMS solution like Facebook’s new messaging app but for local Burners only.

This is what the Voice Board application looks like if you were to connect to the Tropo server using a local IP address!  It’s basically a Ruby on Rails 3.1 application utilizing Tropo’s Scripting API and small Ruby script.  The website is designed to allow the outside world to interface with the Burners, provided we can establish a good satellite data uplink (more details to follow). The website grabs the latest BurningMan-tagged Flickr image and associates it with a voice memo being streamed while enjoying photos from the event.

Burners can call into our Voice Board application to record social voice memos and listen to public messages left by other Burners on the voice board. If a recording is in progress when a new call comes in, it automagically  becomes a conference room party line and continues recording the chat from the participants.

The conference room recording simply becomes another voice memo like the others – presented in descending order to new callers. As you listen to voice memos, they automagically get marked as read and disappear from your list. The Voice Board application loops through options (record memo or listen to memos) while the call isActive and lets you leave multiple voice memos or join the conference after listening to memos (if one is in progress)!

The Voice Board application also includes a Group SMS application which is available only for the local Burners. Any one who has called the Voice Board or texted a message to the Tropo Group SMS app will automagically be added to the Group SMS distribution list for the duration of the event.  They will receive text messages from other Burners any time the Voice Board is sent a text message!

The source code for our the Tropo-powered Voice Board and Group SMS application can be found at https://github.com/chrismatthieu/voiceboard

We are also in the process of establishing a satellite data connection to allow for VoIP connectivity of these communications applications to the outside world allowing the Burners to actually make real phone calls to anyone in North America.  This is powered byt the Tropo.com Public Cloud service.  If communications with the outside world can be established, Tropo will be sponsoring an unlimited number of 5 minute phone calls from the Playa to any phone number in North America to allow Burners to stay in touch with loved ones and to provide an additional route for emergency communications.

We are proudly embracing the BurningMan experience and we hope to gain more experience in using Tropo to deliver real-time communications services in times of disaster and business continuity programs as well as allowing our customers and telcos/carriers to run Tropo’s cloud communications API and platform in their own data centers and private voice clouds.

For more information on about Tropo’s involvement and applications used in the BurningMan event, please refer to our blog post below or contact Chris Matthieu at chris [at] tropo.com

http://blog.tropo.com/2011/08/23/tropo-openbts-burning-man-awesome/

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?!

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.

 

Routing GoogleVoice to Tropo and OpenVoice

Wednesday, April 27th, 2011

Do you have a GoogleVoice phone number?  Would you like to route it to your Tropo application?  

You can permanently port your GoogleVoice phone number to your Tropo application by submitting a ticket to our Provisioning team via the GetHelp link in the Tropo portal but I would like to show you how to temporarily route your GoogleVoice number to Tropo.

In this screencast, I use a few unnecessary (but fun) geeky apps like Skype (to place PSTN calls) and Blink (for receiving SIP calls).  I also route my GoogleVoice number to @Zlu’s OpenVoice application.  OpenVoice is an open source GoogleVoice clone that runs on Tropo and also integrates with our Phono webphone!  It’s built using Ruby on Rails and its source code is available on Github at http://github.com/openvoice.  (OpenVoice also has an Android app available so check it out!)

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!

Tropo-Powered Hamradio Callsign Lookup App

Wednesday, April 6th, 2011

Ham radio or amateur radio communications has been around since the early 1900s.  Ham radio technology has kept pace with traditional communications and may even be the only technology that allows people to communicate in natural disasters.  Ham radio operators can communicate over very far distances using HF (high frequencies) as well as through satellites via AMSAT and even using VoIP over the Internet using EchoLink, IRLP, or D-STAR!

There are nearly 750,000 FCC licensed ham radio operators in the United States and over 3M licensed operators worldwide.  Each operator has federally issued callsign that is used to uniquely identify the station operating on the band.

Using Tropo and Callook (Josh Dick’s W1JDD Callsign API), Chris Matthieu (N7ICE) was able quickly develop a speech recognition and text-to-speech based telephony app that is accessible by any of the following channels:

Voice and SMS: 1-480-374-3234

Skype: +990009369991489376

VoIP / SIP: sip:9991489376@sip.tropo.com

Phono: app:9991489376

Upon calling the application, you are asked to spell a callsign using military phonetics:

A – Alfa, B – Bravo, C – Charlie, D – Delta, E – Echo, F – Foxtrot, G – Golf, H – Hotel, I – India, J – Juliet, K – Kilo, L – Lima, M – Mike,  N – November, O – Oscar, P – Papa, Q – Quebec, R – Romeo, S – Sierra, T – Tango, U – Uniform, V – Victor, W – Whiskey, X – X-Ray, Y – Yankee, Z – Zulu

In addition to these commands, you can say restart to start over or stop if your callsign is entered correctly.  Upon saying stop, the Tropo application does a REST-based call to Callook to get a JSON response of the data related to the callsign inquired.  In addition to the communication channels listed above, Chris Matthieu was able to use his handheld hamradio (like the one featured above) to communicate using VHF (very high frequencies) to connect to a repeater nearly 50 miles away on a mountaintop and connect to Tropo via an auto-patch phone line to perform a callsign lookup.  Here is a screencast and source code for the application!

Here is the source code running on Tropo’s Scripting API:

require 'rest_client'
require 'json'

answer
sleep 2
say "welcome to the tropo ham radio call sign lookup application"

callsign = ""
callsigntext = ""

loop do

  result = ask "spell the callsign phonetically. say stop when done or restart to start over", {
      :choices => "alpha, bravo, charlie, delta, echo, foxtrot, golf, hotel, india, juliette, kilo, lima, mike, november, oscar, papa, quebec, romeo, sierra, tango, uniform, victor, whiskey, xray, yankee, zulu, one, two, three, four, five, six, seven, eight, nine, zero, stop, restart"}

  if result.value == "stop"
    break
  elsif result.value == "restart"
    callsign = ""
    callsigntext = ""
  else
    callsigntext = callsigntext + " " + result.value
    say "so far you entered #{callsigntext}"

    letter = case result.value
     when "alpha" then "a"
     when "bravo" then "b"
     when "charlie" then "c"
     when "delta" then "d"
     when "echo" then "e"
     when "foxtrot" then "f"
     when "golf" then "g"
     when "hotel" then "h"
     when "india" then "i"
     when "juliette" then "j"
     when "kilo" then "k"
     when "lima" then "l"
     when "mike" then "m"
     when "november" then "n"
     when "oscar" then "o"
     when "papa" then "p"
     when "quebec" then "q"
     when "romeo" then "r"
     when "sierra" then "s"
     when "tango" then "t"
     when "uniform" then "u"
     when "victor" then "v"
     when "whiskey" then "w"
     when "xray" then "x"
     when "yankee" then "y"
     when "zulu" then "z"
     when "one" then "1"
     when "two" then "2"
     when "three" then "3"
     when "four" then "4"
     when "five" then "5"
     when "six" then "6"
     when "seven" then "7"
     when "eight" then "8"
     when "nine" then "9"
     when "zero" then "0"
    end

    if letter
      callsign = callsign + letter
    end

  end

end

response = RestClient.get 'http://callook.info/' + callsign + '/json'
data = JSON.parse(response)

say callsigntext + "belongs to "
say data["name"]
say "in " + data["address"]["line2"]
say "and holds a " + data["current"]["operClass"] + " license"