tropo ecomm 2009 tutorial
DESCRIPTION
Slides from RJ Auburn's eComm tutorial session on Tropo - a new service from Voxeo that allows people to create phone applications using common web programing languages. Developers can create applications using ruby, javascript, groovy, php or python.TRANSCRIPT
Introducing TropoPowered by Voxeo
RJ Auburn CTO
Tropo
Once upon a time…
Tropo
Now XML is in the enterprise…
Tropo
Write apps directly in leading languages
Tropo.com
Ruby
Tropo
Simple to Learn
• answer• redirect• reject
• call• transfer• hangup
• ask• say• record
• log• wait• default
Tropo
Simple to Deploy
• Hosted offering • Accessible via
– PSTN numbers
– SIP URI
– Direct Skype
– iNum – Gizmo5, etc
• Inbound calling• Outbound calling• 70,000 port capacity
Tropo
Simple Business Model
• No contracts• No setup costs• No commitment• Costs as low as 3 cents per minute• Credit card or PayPal charge in $50 blocks• Five minutes from sign-up to live deployment
+ = GO
Tropo
Powerful Capabilities
• Robust call control• Play audio, record audio• Touch-tone entry• High quality speech recognition (ASR)• High quality speech synthesis (TTS)• Mashups with web services• Access to most language libraries• Soon: Conferencing, call recording,
web services, remote API
Tropo
Developing with Voxeo
XML-based Telephony
Voxeo CallXMLThe easiest telephony markup ever devised
Tool-based Telephony
Voxeo DesignerEasy web-based, Visio- like rapid app dev tool
VoiceObjects
Sophisticated service creation environment, personalization, analytics
VoiceXMLThe only 100% compliant browser
CCXMLThe world’s most proven CCXML engine
A Voxeo Company
API-based Telephony
TropoMash-up style APIin multiple language
Java Media ControlJSR 309
Java SIP ServletsJSR 116/289
A Voxeo Company
Sim
pler
app
s,al
l ski
ll le
vels
Sop
hist
icat
ed a
pps
Tropo
So lets get to the code already…
Tropo
T.1: Hello World
JavaScript and PHP
answer();say("Hello, world!");hangup();
Ruby
answersay "Hello, world!”hangup
Groovy
answer()say 'Hello, world!'hangup()
Python
answer()say("Hello, world !")hangup()
Tropo
T.2: Asking for Input - JavaScript// -----------// asking for input// -----------
answer();
result=ask( "Hi. For sales, press 1. For support, press 2.", {choices:"1, 2"} );
if (result.name=='choice'){
if (result.value=="1") { say( "sales is not available right now.") }if (result.value=="2") { say( "support is currently on the other line." ) }
}
hangup();
Tropo
T.3: Repeating the Question - Ruby# -----------# repeating the question# -----------
answer
options = { :choices => '1, 2', :repeat => 3 } result = ask 'For sales, press 1. For support, press 2.', options
if result.name == 'choice' case result.value when '1' say 'sales is not available right now.' when '2' say 'support is currently on the other line.' endend
hangup
Tropo
T.4: Changing Timeouts - Groovy// -----------// changing the default timeout// -----------
answer();
result=ask( "For sales, press 1. For support, press 2.", [choices:"1, 2",repeat:3, timeout:10] );
if (result.name=='choice'){
if (result.value=="1") { say( "sales is not available right now.") }if (result.value=="2") { say( "support is currently on the other line." ) }
}
hangup();
Tropo
T.5: Speech - Python# Using speech input instead of touch-tone
answer()
result = ask("Hi. For sales, say sales. For support, say support",{'choices':"sales, support", 'repeat':3})
if (result.name == 'choice'): if (result.value == "sales"): say("Sales is not available right now") if (result.value == "support"): say("Support is currently on the other line.")
hangup()
Tropo
T.6: Speech & DTMF - PHP<?php// -----------// using both speech and touch-tone input// -----------
answer();
$result = ask( "For sales, just say sales or press 1. For support, say support or press 2.", array( "choices" => "sales( 1, sales), support( 2, support)", "repeat" => 3 ) );
if ($result->name=="choice"){ if ($result->value=="sales") say( "sales is not available right now." ) ; if ($result->value=="support") say( "support is currently on the other line." ) ; }
hangup();
?>
Tropo
T.7: Transfer Time - Ruby# -----------# connecting the call to another number ()# -----------
answer
options = { :choices => 'sales( 1, sales), support( 2, support)', :repeat => 3 } result = ask 'For sales, say sales or press 1. For support, say support or press 2.', options
if result.name == 'choice' case result.value when 'sales' say 'Ok, let me transfer you to sales.'
transfer '14075551212' when 'support' say 'Sure, let me get support. Please hold.'
transfer '14085551212' endend
hangup
Tropo
T.8: Wrong Choices - Groovyanswer();
result=ask( "For sales, say sales or press 1. For support, say support or press 2.", [choices:"sales( 1, sales), support( 2, support)", repeat:3] );
if (result.name=='choice'){
if (result.value=="sales") {
say( "Ok, let me transfer you to sales.");transfer( "14075551212");
}if (result.value=="support") {
say( "Sure, let me get support. Please hold." );transfer( "14085551212");
}}
if( result.name=='badChoice'){
say( "I'm not sure what you wanted. Goodbye.")}
Tropo
T.9: Event Handlers - JavaScriptanswer();
result=ask( "For sales, just say sales or press 1. For support, say support or press 2.", { choices:"sales( 1, sales), support( 2, support)", repeat:3, onBadChoice: function() { say("I'm sorry, I didn't understand what you said.") } } );
if (result.name=='choice'){
if (result.value=="sales") {
say( "Ok, let me transfer you to sales." );transfer( "14075551111");
}if (result.value=="support") {
say( "Sure, let me get support. Please hold." );transfer( "14085552222");
}}
Tropo
T.10: Bad Choices - Rubyanswer
options = { :choices => 'sales( 1, sales), support( 2, support)', :repeat => 3, :onBadChoice => lambda { say ‘I did not understand what you said.' }, :onTimeout => lambda { say 'Hm. I did not hear anything.' } }
result = ask 'For sales, just say sales or press 1. For support, say support or press 2.', options
if result.name == 'choice' case result.value when 'sales' say 'Ok, let me transfer you to sales.' transfer '14075551212' when 'support' say 'Sure, let me get support. Please hold.' transfer '14085551212' endend
hangup
Tropo
T.11: Right choices - Groovy// -----------// handling good choices with event handlers too// -----------
answer();
ask( "Hi. For sales, just say sales or press 1. For support, say support or press 2.", [ choices:"sales( 1, sales), support( 2, support)", repeat:3, onBadChoice: { say("I'm sorry, I didn't understand what you said.") }, onTimeout: { say("Hm. I didn't hear anything.") }, onChoice: {event-> if (event.value=='sales') { say( "Ok, let me transfer you to sales." ); transfer( "14075551212"); } if (event.value=='support') { say( "Sure, let me get support. Please hold." ); transfer( "14085551212"); } } ] );
Tropo
T.12: onEvent - JavaScriptanswer();
ask( "Hi. For sales, just say sales or press 1. For support, say support or press 2.", { choices:"sales( 1, sales), support( 2, support)", repeat:3, onEvent: function( event ) { if (event.name=='badChoice') { say( ”I didn't understand what you said.") } if (event.name=='timeout') { say( "Hm. I didn't hear anything.") } if (event.name=='choice') { if (event.value=='sales') { say( "Ok, let me transfer you to sales." ); transfer( "14075551111"); } if (event.value=='support') { say( "Sure, let me get support. Please hold." ); transfer( "14085551111"); } } transfer( "14075552222"); } } );
Tropo
T.13: conditional accept - Ruby# -----------# reject based on callerid# -----------
answer
log "*"*100 + currentCall.inspect
if currentCall.callerID == ’4078675309'answersay 'Hello there and goodbye'hangup
else rejectend
Tropo
T.14: Bounce the Call - JavaScript// -----------// redirect// -----------
answer();
if (currentCall.callerID == '4075551111') answer() else redirect( "14075552222");
Tropo
T.15: Branching - Groovy// -----------// Changing behavior based on number called// -----------
answer();
if (currentCall.calledID == '4075551111') say( "Hello Andrew.");if (currentCall.calledID == '4075552222') say( "Hello Brian. ");
hangup();
Tropo
T.16 Recording - JavaScript
answer();
event=record("Leave your message at the beep. Thanks!", { beep:true, silenceTimeout: 5, maxTime:60, timeout:10, onRecord:function(event ) { say("you said " + event.recordURI ) } } );
log( "event.recordURI = " + event.recordURI );
hangup();
Tropo
Using Language Libraries• Tropo programs can use language libraries• Most libraries supported – Except…
– No local file access– No threads. – No exec()– Etc…
from random import *
number = randint(1,1000)
answer()say("Hello. Your magic number today is %s. Goodbye." % number)hangup()
Tropo
Mashing Up With Web Services
# python app to retrieve and say a text fileimport urllibnumber= urllib.urlopen("http://blog-files.voxeo.com/media/test.txt").read()
answer()say("Welcome to Tropo. Your magic number is %s. Goodbye." % number)hangup()
// Groovy app to retrieve and say top ten hits from Yahoo musicdef musicbase = "http://us.music.yahooapis.com/track/v1"def appid = "KgtDvNrV34Eavq_dUF81vBlVLKAOq7o1tj7Tzvu_kYbKsCtBW190VmrvVHK_0w--”
say( ", Top 10 Chart Toppers!" )def toptracksxml = new XmlSlurper().parseText( "${musicbase}/list/published/popular?count=10&appid=${appid}".toURL().text )toptracksxml.Track.each { track -> say( ", Number " + track.ItemInfo.ChartPosition["@this"] + ", " + track["@title"] + ", by " + track.Artist[0]["@name"] )}say( ", Goodbye!" )hangup()
Tropo
Getting Started with Tropo
• www.tropo.com• Login with your Voxeo Evolution ID• Or - Create a new Account for Free
• Account -> Your Applications• Create New Application• Option to create a hosted file (or use a URL)
• Account -> Your Hosted Files to edit files
Tropo
So How about some Cash?
Tropo
Write a mashup with Tropo
Get $100
Tropo
Examples• Existing examples are posted at
http://tropo.com/examples and also hosted at http://github.com/tropo
• Examples so far include: – Auto Attendant– RPG – RSS reader– Yahoo traffic via phone– Sports scores – Monty Python quote generator – Location Data– Phone Simon – Etc…
Tropo
So start writing some code!