Posts Tagged ‘conference’

Winner of the MadisonRuby Conference Ticket

Monday, August 15th, 2011

Over the weekend, we kicked off a MadisonRuby Conference ticket give-away promotion sponsored by Tropo.  We were excited to see 23 participants in our tweet-for-a-ticket contest!  So how to you randomly select a winner for a Ruby conference giveaway? You write a quick Ruby script, Duh!  With the help of BigTiger, the MadisonRuby conference organizer, we wrote the following script on github, ran it, and here is the winner….

@STATICNULL IS THE WINNER OF THE FREE TROPO TICKET TO MADISONRUBY CONFERENCE!!!!!

 

 

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.

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

Building a full-featured conference call application with Tropo and PHP

Friday, June 24th, 2011

Tropo’s conference function makes it easy for you to join multiple callers onto a single call together. One line of code and you have a conference call…

<?php conference('someid'); ?>

That’s it. A basic conference line. Use that as your application and everyone calling into your number will be joined into a single conference call. How many users? By default, Tropo allows up to 100 users into a single conference. We can do more if you need it, but you might want to think through your use case a bit first. 100 people all talking on one line gets crazy fast.

Now let’s take this basic concept and turn it into a full-fledged application. Our requirements for the conference call start with allowing the entry of a conference ID so that this number can be used for more than one call.

<?php
$response = ask('Enter your conference ID', array(
    'choices' => '[4 DIGITS]'
));
conference($response->value);
?>

We’d also like to allow conference IDs of multiple lengths (instead of just 4 digits), and to let the caller tell us when they’re done with entry by pressing #. How about conference IDs of 3-10 digits?

<?php
$response = ask('Enter your conference ID. Press the pound key when finished.', array(
    'choices' => '[3-10 DIGITS]',
    'terminator' => '#'
));
conference($response->value);
?>

In noisy rooms offices, background noise sometimes get misinterpreted as input. Since we’re only accepting numeric conference IDs, let’s turn off speech recognition and restrict input to the keypad

<?php
$response = ask('Enter your conference ID. Press the pound key when finished.', array(
    'choices' => '[3-10 DIGITS]',
    'terminator' => '#',
    'mode' => 'keypad'
));
conference($response->value);
?>

Let’s tell them if their conference ID was accepted and notify them they’re entering the room.

<?php
$response = ask('Enter your conference ID. Press the pound key when finished.', array(
    'choices' => '[3-10 DIGITS]',
    'terminator' => '#',
    'mode' => 'keypad'
));
say('Conference ID ' . $response->value . ' accepted. You will now be placed into the conference. Please announce yourself.');
conference($response->value);
?>

Hmm. That conference id is being read as a number (one thousand two hundred thirty four) instead of as digits (one two three four). A little ssml magic will fix that.

<?php
$response = ask('Enter your conference ID. Press the pound key when finished.', array(
    'choices' => '[3-10 DIGITS]',
    'terminator' => '#',
    'mode' => 'keypad'
));
say('<speak>Conference ID <say-as interpret-as="vxml:digits">' . $response->value . '</say-as> accepted. You will now be placed into the conference. Please announce yourself.</speak>');
conference($response->value);
?>

Often I hit the wrong conference id and need to hang up and try again. For our conference line, how about we let someone exit the room and pick another one.

We’ll add a loop that loops as long as the call is active. Once someone exits, the loop starts over and they’ll be prompted for their conference id again. We’ll also add a terminator to the conference so someone can exit and let them know that option is available.

<?php
answer();
while ($currentCall->isActive()) {
	$response = ask('Enter your conference ID. Press the pound key when finished.', array(
	    'choices' => '[3-10 DIGITS]',
	    'terminator' => '#',
	    'mode' => 'keypad'
	));
	say('<speak>Conference ID <say-as interpret-as="vxml:digits">' . $response->value . '</say-as> accepted. You will now be placed into the conference. Press pound to exit without disconnecting. Please announce yourself.</speak>');
	conference($response->value, array('terminator' => '#'));
}
?>

What if someone doesn’t enter a conference id? Or enters too few or too many numbers? Let’s check the return of the ask function to see if the ask succeeded, failed, or timed out. If it’s a timeout or failure, play a message and the loop starts again, asking for the conference id again.

<?php
answer();
while ($currentCall->isActive()) {
	$response = ask('Enter your conference ID. Press the pound key when finished.', array(
	    'choices' => '[3-10 DIGITS]',
	    'terminator' => '#',
	    'mode' => 'keypad'
	));
	switch($response->name) {
    case 'choice':
      say('<speak>Conference ID <say-as interpret-as="vxml:digits">' . $response->value . '</say-as> accepted. You will now be placed into the conference. Press pound to exit without disconnecting. Please announce yourself.</speak>');
      conference($response->value, array('terminator' => '#'));
      // Pause a moment before asking for another conference.
      sleep(1);
      break;
    case 'badChoice':
      say('Sorry, that is not a valid conference ID.', array('voice' => $voice));
      break;
    case 'silenceTimeout':
    case 'timeout':
      say('Sorry, I didn\'t hear anything.', array('voice' => $voice));
      break;
  }
}
?>

Now that we are handling a timeout, the default timeout seems way too long for this type of application. If the user doesn’t enter a conference ID in 8 seconds, prompt again.

<?php
answer();
while ($currentCall->isActive()) {
	$response = ask('Enter your conference ID. Press the pound key when finished.', array(
	    'choices' => '[3-10 DIGITS]',
	    'terminator' => '#',
	    'mode' => 'keypad',
	    'timeout' => 8
	));
	switch($response->name) {
    case 'choice':
      say('<speak>Conference ID <say-as interpret-as="vxml:digits">' . $response->value . '</say-as> accepted. You will now be placed into the conference. Press pound to exit without disconnecting. Please announce yourself.</speak>');
      conference($response->value, array('terminator' => '#'));
      // Pause a moment before asking for another conference.
      sleep(1);
      break;
    case 'badChoice':
      say('Sorry, that is not a valid conference ID.', array('voice' => $voice));
      break;
    case 'silenceTimeout':
    case 'timeout':
      say('Sorry, I didn\'t hear anything.', array('voice' => $voice));
      break;
  }
}
?>

What if we want to restrict the conference IDs that someone can use? Maybe create a conference application that uses reservations and creates rooms for people. We could fetch a list of currently-valid conference IDs from a database. In this sample, I’m just going to hard-code those in an array.

<?php
$pins = array();
$pins['1337'] = '';
$pins['1234'] = '';
$pins['2600'] = '';
answer();
while ($currentCall->isActive()) {
	$response = ask('Enter your conference ID. Press the pound key when finished.', array(
	    'choices' => '[3-10 DIGITS]',
	    'terminator' => '#',
	    'mode' => 'keypad',
	    'timeout' => 8
	));
	switch($response->name) {
    case 'choice':
	    if (!array_key_exists($response->value, $pins)) {
	      say('Sorry, that is not a valid conference ID.');
	      break;
	    }
      say('<speak>Conference ID <say-as interpret-as="vxml:digits">' . $response->value . '</say-as> accepted. You will now be placed into the conference. Press pound to exit without disconnecting. Please announce yourself.</speak>');
      conference($response->value, array('terminator' => '#'));
      // Pause a moment before asking for another conference.
      sleep(1);
      break;
    case 'badChoice':
      say('Sorry, that is not a valid conference ID.', array('voice' => $voice));
      break;
    case 'silenceTimeout':
    case 'timeout':
      say('Sorry, I didn\'t hear anything.', array('voice' => $voice));
      break;
  }
}
?>

Now for a fun feature. Let’s let conference ID owners — the room administrator — get a text message any time someone joins their conference room. Never miss a conference call again. And for kicks, send a text message when they leave, too.

<?php
// An array of conference IDs and phone numbers to alert.
// If a conference ID is used that has a phone number attached,
// when someone joins or leaves that conference, the attached phone
// number will get an SMS alerting them.
$pins = array();
$pins['1337'] = '14075551212';
$pins['1234'] = '19255556789';
$pins['2600'] = '';
answer();

while ($currentCall->isActive()) {
  $response = ask('Enter your conference ID. Press the pound key when finished.', array(
      'choices' => '[3-10 DIGITS]',
      'terminator' => '#',
      'mode' => 'keypad',
      'timeout' => 8
  ));
  switch($response->name) {
    case 'choice':
      if (!array_key_exists($response->value, $pins)) {
        say('Sorry, that is not a valid conference ID.');
        break;
      }
      if (array_key_exists($response->value, $pins) && !empty($pins[$response->value])) {
        // Send an alert that someone has entered the conference
        message($currentCall->callerID . ' has entered conference ' . $response->value, array('to' => $pins[$response->value], 'network' => 'SMS'));
      }
      say('<speak>Conference ID <say-as interpret-as="vxml:digits">' . $response->value . '</say-as> accepted. You will now be placed into the conference. Press pound to exit without disconnecting. Please announce yourself.</speak>');
      conference($response->value, array('terminator' => '#'));
      if (array_key_exists($response->value, $pins) && !empty($pins[$response->value])) {
        // Send an alert that someone has left the conference
        message($currentCall->callerID . ' has left conference ' . $response->value, array('to' => $pins[$response->value], 'network' => 'SMS'));
      }
      // Pause a moment before asking for another conference.
      sleep(1);
      break;
    case 'badChoice':
      say('Sorry, that is not a valid conference ID.', array('voice' => $voice));
      break;
    case 'silenceTimeout':
    case 'timeout':
      say('Sorry, I didn\'t hear anything.', array('voice' => $voice));
      break;
  }
}
?>

And there’s a full-featured conference calling application in about 50 lines of code. We started with a basic one-liner and slowly added features to build a conference calling service that rivals the professional conference applications. The full code is available from the Tropo Samples repository on Github. The download on Github has some additional configuration, like allowing you to set a voice for all the prompts and turn on and off the feature that restricts this to known conference IDs.

How robust is the code? This exact application is what we use every day as our conference calling line. Calls with customers, sales prospects, and each other all happen over a conference line backed by the code in this tutorial.

Join Tropo at MagicRuby 11 Orlando Feb 4-5

Thursday, January 20th, 2011

Ruby Developers take note:  Tropo is sponsoring  MagicRuby 11!   MagicRuby is a free Ruby conference produced by Jeremy McAnally taking place February 4th and 5th at the Contemporary Resort in Disney World in Orlando, Florida.

Conference organizers have assembled an amazing lineup of speakers including keynoter and Ruby luminary Chad Fowler of InfoEther. Other speakers include guys from GithubRed HatEngine YardEnvy Labs and Intridea.

One example of the amazing talks scheduled at MagicRuby 2011: our friends at Envy Labs are giving a talk about lessons they don’t teach in programming classes. It takes more than just technical skills to succeed at being a software developer. You may also need to communicate effectively, manage projects, train your clients, and mainly just play well with others. We developers are an anti-social breed who enjoy being left to our own devices, so many of these skills don’t come naturally.

Gregg Pollack and Caike Souza will give some tips to help software developers improve their craft and increase the odds of succeeding at our chosen field. They’ll also share some of the core principles that they hold dear at Envy Labs, and show how they implement them on a daily basis.

Tropo Sponsors MountainWest RubyConf

Tuesday, January 11th, 2011

Tropo is now a proud sponsor of the 2011 MountainWest RubyConf!

MWRC is a two-day single-track conference for just $100. Come rub elbows with some of the smartest Rubyists in the world.

March 17-18, 2011
Salt Lake City Public Library
210 E 400 S
Salt Lake City, UT 84111

This conference is in a great venue (the public library’s auditorium) and it typically gets over 100300 Rubyists in attendance.  They are currently overwhelmed with the number and quality of proposals submitted this year and their Board of Advisors has a difficult task to pare them down.

Registration will opeon on (or before) January 17th.  Get your ticket and come hang out for two days of Ruby fun.  We’ll be on-site with Tropo schwag and ready to lend a hand with your Voice, SMS, IM, or Twitter hacking!

RubyConf 2010

Thursday, September 30th, 2010

Tropo is proud to announce that we are now sponsoring RubyConf 2010 in New Orleans on November 11-13!

This is the place to be for Ruby developers!  Jason Goecke, VP of Innovation for Voxeo Labs, and Chris Matthieu, Director of Business Development, will be on-site attending the conference and helping co-host the Open Government Hack-a-thon along with Sunlight Labs!

We will have Voice, SMS, IM, and Twitter communications experts on-hand as well as open government data API experts on-hand and of course hundreds of Ruby web experts on-hand to help you build and launch your next open government app!

We hope to get local government officials and agencies involved in the hack-a-thon so stay tuned for more details!  There will also be free food and plenty of coffee to keep you caffeinated!  Did we mention prizes?!

Stay tuned…

Tropo’s in Poland, so we’re speaking Polish

Friday, May 28th, 2010

This weekend, Jason Goecke is at Euruko, Europe’s Ruby conference talking about Tropo. Since Euruko is held in Krakow, Poland we’ve added a little something for the locals.

result = ask '1 teraz proszę powiedzieć', {:voice =>"zosia",
                                           :choices => "jeden",
                                           :recognizer => "pl-pl"}

That’s right, Tropo’s speech recognition and text to speech both now include Polish.

Polish speech recognition can be triggered by setting your recognizer to “pl-pl” on ask() or conference(). And for text to speech you have your choice of voices: “zosia” for female or “krzysztof” for male.

We added it for a Ruby conference, but it’s available in every programming language.

Here’s PHP:

<?php
$result = ask('1 teraz proszę powiedzieć', array(
                                           'voice' =>"krzysztof",
                                           'choices' => "jeden",
                                           'recognizer' => "pl-pl"
                                        ));
?>

Oh, for those that don’t speak Polish, the examples say “Say one now” and then have “one” as the choice.

Tutorial: Click-to-Call applications (w/ conferencing)

Saturday, April 24th, 2010

Hello,

A great use of Token initiated calls, or calls initiated via HTTP request, are click to call applications. This is when you have a fancy button on your website and can have your customers simply ‘click to call’ your call center. This allows them to get right to the people they need quickly and effectively, but how do you do it? Well over here at the ‘Halls of Justice’, sorry I mean Tropo Support we get this a lot. This being the case I have gone ahead and put together a nice example to show you just how to put a click to call application together!

So before we start I need to make one thing clear, Scripting is top down execution, or the fancy word is synchronous. This means task 2 can’t start until task 1 is complete, but to get around this we will make use of threads, providing our language of choice supports it. In Ruby this is pretty simple, and other markups may allow for threading, but that is a whole another discussion. In this example it’s Ruby and we are using with threads, just go with it =):

So, in order to start a new thread you just need a call to Thread.new. A new thread will be created to execute the code inside the thread block, then the original thread will return from Thread.new right away and continue with the next statement

# Thread #1 is running here
 Thread.new
  # Thread #2 runs this code
 end
# Thread #1 runs this code

If you want to read up on this more there is a great tutorial I have linked here which you should check out.

Now this whole posting is predicated on the fact that you do know how to do a token call, so if you don’t please take a quick look at the Tropo Session API (Token Initiation ) documentation. You can find this here in our documentation so please give it a read if you have not already.

In this example we are going to base our code on a code snippet provided in that section of our documentation:

call('tel:+1' + $numberToDial, {
  :onAnswer => lambda { |event|
    say("Hello " + $customerName + ", " + $message);
    log("Contacted customer: " + $numberToDial);
    hangup()
  }}
)

So this example will call someone, and it will play a message, but that is only going to get us halfway there I am afraid; The reason is we not only need to call our user (customer) we also need to call our call center. Once have them both on the line we then need to get them to talk to each other using a conference. Since as I mentioned Ruby is executed top down we’ll need to use threads in order to achieve this goal. Yea, it may sound complicated, but in actuality it’s bark is much worse then it’s bite; Lets take a look at the finished example below:

#Define Global Options
operatorNumber = "4074181800"
applicationCallerID = "8008675309"

#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()

#Call First Leg (User)
	call 'tel:+1'+$numberToCall, {
	        :callerID => applicationCallerID,
	        :onAnswer => lambda{|event|
			log "@"*5 + "User has answered"
			#Create second thread for second leg (Operator)
			Thread.new do
				log "@"*5 + "Start second tread"
					call 'tel:+1'+operatorNumber, {
						:callerID=>applicationCallerID,
						:onAnswer=>lambda{|event|
							log "@"*5+"Operator answered join conference"
							newCall = event.value
							#announce caller
							newCall.say("You have a call from " + $callerName)
							#join operator to conference
							newCall.conference(conferenceID,conferenceOptions)
						}
					}
			end

			newCall = event.value
			# prompt user
			newCall.say("Please hold while we connect you")
			newCall.conference(conferenceID,conferenceOptions)
		}
	}
end

The only thing really not covered here is the fact that you need to have a conference to join the callers, and since we are using threads we need to make sure each one joins the right conference. This is done with the conference ID, and in my example we are going to use a time stamp, called from a method, as our conferenceID.

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

So I think this part is pretty simple, and I don’t think going in to much more then a ‘hey look at that, it’s that thing you like’ type of explanation is really needed here; Of course if I am wrong please comment below, or contact our support team, and we would be glad to offer more clarification.

So as a whole you can see the script is pretty simple, we just fire off an HTTP request to the session API which can be done by a form on our website (obviously you need to change the values highlighted here):

<form action="http://api.tropo.com/1.0/sessions" method="get" accept-charset="utf-8">
	<input type="text" name="numberToCall" value="4075551212"/><br>
	<input type="text" name="callerName" value="John"/><br>
	<input type="hidden" name="token" value="token_id_goes_here"/>
	<input type="hidden" name="action" value="create"/>
	<p><input type="submit" value="Continue &rarr;"></p>
</form>

Of if you want you can also use CURL as well:

curl -I "http://api.tropo.com/1.0/sessions?action=create&token=my_token_id_goes_here&numberToCall=4075551212&callerName=john"

You can even get real fancy and build an XML payload which you can then post to the sessions API (curl -d @token.xml “http://api.tropo.com/1.0/sessions”)

<session>
 <token>my_token_id_goes_here</token>
 <var name="callerName" value="John"/>
 <var name="numberToCall" value="4075551212"/>
</session>

Once we caller 1 has answered we do a Thread.new and call caller two, and then as mentioned above Thread.new instantly returns us the the first thread and then we join caller 1 to the conference. Then once caller two answers we announce caller 1′s name and join him to the waiting conference participant, pretty simple huh?

Well I really do hope this is helpful, and if there are any questions on any of this please let us know!

Regards,

John Dyer
Customer Engineer
Voxeo Support

Tutorial – Adding Tropo to Google Wave

Tuesday, February 16th, 2010

There is another great tutorial that Zhao Lu (aka – @zlu) has done, showing how to use Tropo with Google Wave. Zhao takes JRuby, the Rave gem (created by Jason Rush, aka @diminish7) and creating a Google Wave Robot that allows you to create a callable conference in a Wave.

The complete tutorial and code example is available on Github @ http://github.com/zlu/tropo-wave-tutorial. Thanks again to Zhao!