complete workshop

3023 users shared this document! click Bookmark and Share
TAG:  conference call 
Published Time: -
Filetype: pdf
Filesize: 1566311
Click Here To Download...
Stop Rude Calls: A CCXML Workshop for VoiceXML Veterans Moshe Yudkowsky Disaggregate speech@pobox.com 1 2 Stop Rude Calls But this could be much more useful... Ask a user a question, e.g., “how much is two plus two?” User responds; transfer/drop call 3 Making app more useful... White list and black list Listen to messages live Forward to multiple phones ? ? 1 2 3 Basic Concepts 4 5 CCXML provides a wide range of call control, dialog control, sending & receiving outside information 6 CCXML: Movie actions and plot VoiceXML: Form fill in the blanks Contrasts 4 5 6 7 Typical Plot Start Boy Meets Girl Boy Gets Girl Boy Loses Girl Boy Chases Girl 8 Start Boy Meets Girl Boy Gets Girl Boy Loses Girl Boy Chases Girl Coffee Cup Spill Handsome Bank Robber Detective Secret Uncovered Technical Name: State Machine State Event CCXML:
Define states and
move between
them
9 Example:
Telephony
Application
DECIDE TRANSFER/ DROP START VALIDATE ALIVENESS 7 8 9 10 CCXML: lazy calmly waits forever VoiceXML: activist always talks or listens 11 CCXML Only Moves If You Push It -- via “Events” Telephony Events Ring, connect, hangup,... Data Events Data sent, data arrives,... Error Events Programming, platform... DECIDE TRANSFER/ DROP START VALIDATE ALIVENESS 12 CCXML Only Moves If You Push It -- via “Events” Telephony Events Ring, connect,
disconnect
Create call
Create conference,
join, unjoin
DECIDE TRANSFER/ DROP START VALIDATE ALIVENESS 10 11 12 13 CCXML Only Moves If You Push It -- via “Events” Data Events
Data send, data arrive
DECIDE TRANSFER/ DROP START VALIDATE ALIVENESS 14 CCXML Only Moves If You Push It -- via “Events” Interpreter Events
System startup
Handoff
Error, “kill”
DECIDE TRANSFER/ DROP START VALIDATE ALIVENESS 15 Switch VoiceXML
Server XML
Server VoiceXML Architecture 13 14 15 16 CCXML Architecture Switch VoiceXML
Server XML
Server CCXML
Server 17 Same VoiceXML Limitations... Switch VoiceXML
Server XML
Server CCXML
Server 1,000 Users ?
1,000 Servers
Explicit
management of
User Interface
Limited intelligence Starting a CCXML Call 18 16 17 18 19 Review: Overview of
complete
interaction
DECIDE TRANSFER/ DROP START VALIDATE ALIVENESS 20 Stage 1: Start the
CCXML
START VALIDATE 21 Stage 1: Not just a
single state.
Initialize Script START VALIDATE Ringing Accept 19 20 21 22 Interpreter events: CCXML.loaded
CCXML.exit
CCXML.kill
Initialize Script START VALIDATE Ringing Accepting CCXML. loaded connection. connected connection. alerting 23 24 But ringing started
immediately...
So why didn’t we
move to “Ringing”
immediately?
Initialize Script START VALIDATE Ringing Accepting CCXML. loaded connection. connected connection. alerting But doesn’t this seem
wrong? 22 23 24 25 CCXML: queue program control of state VoiceXML: immediate auto- move to states 26 CCXML Infrastructure 27 Baseline
infrastructure.
Initialize Script START VALIDATE Ringing Accept 25 26 27 28 <? xml version = "1.0" encoding = "UTF-8" ?> <! DOCTYPE ccxml PUBLIC "-//W3C//DTD CCXML 1.0//EN" "http://www.w3.org/TR/ccxml/ccxml.dtd" > < ccxml version = "1.0" > < log expr = ”’Starting...’” /> </ ccxml > 29 CCXML: Strict all defs strict ECMA VoiceXML: Hybrid some ECMA, some not 30 CCXML: Prog. States state set by app VoiceXML: Auto States state set by interp. 28 29 30 31 To manage current state, modify the state-tracking variable. To create a state, define a string with the name of the state. 32 <? xml version = "1.0" encoding = "UTF-8" ?> <! DOCTYPE ccxml PUBLIC "-//W3C//DTD CCXML 1.0//EN" "http://www.w3.org/ TR/ccxml/ccxml.dtd" > < ccxml version = "1.0" > <!-- State Names --> < var name = "src_init" expr = "'src_init'" /> < var name = "src_connected" expr = "'src_connected'" /> < var name = "src_authorized" expr = "'src_authorized'" /> < var name = "src_refused" expr = "'src_refused'" /> < var name = "src_exiting" expr = "'src_exiting'" /> <!-- state variable, initialized --> < var name = "src_currentState" expr = "src_init" /> < log expr = ”’Starting...’” /> < eventprocessor statevariable = "src_currentState" > </ eventprocessor > </ ccxml > 33 Describe State and how to
handle Events <transition> Algorithm: Look for first transition that
matches “conditions”
No transition? do something
logical
Event START VALIDATE 31 32 33 34 <transition state ="state_name" event ="event_name"> Name we give state Event this transition handles Attribute 35 < eventprocessor statevariable = "src_currentState" > <!-- loaded --> < transition state = "src_init" event = "ccxml.loaded" /> 36 < eventprocessor statevariable = "src_currentState" > <!-- loaded --> < transition state = "src_init" event = "ccxml.loaded" /> < transition state = "src_init" event = "ccxml.loaded" > < log expr = "logdelim + 'in init state'" /> </ transition > 34 35 36 37 Phone Rings How does that look? How do we answer? START VALIDATE 38 < transition state = "src_init" event = "ccxml.loaded" > < log expr = "logdelim + 'in init state'" /> </ transition > < transition state = "src_init" event = "connection.alerting" name = "evt" > < assign name = "userId" expr = "evt.connection.remote" /> < assign name = "inboundConnection" expr = "evt.connectionid" /> < accept /> < log expr = "logdelim + 'accepted connection'" /> </ transition > Shortcut to access infoEvents contain info 39 37 38 39 40 CCXML: Prog. States state set by app VoiceXML: Auto States state set by interp. (Reminder) 41 Move to a different state: explicitly set the state variable to the new state name . 42 < transition state = "src_init" event = "connection.connected" name = "evt" > < assign name = "src_currentState" expr = "src_connected" /> < send data = "nextstate" target = "session.id" /> < log expr = "logdelim + 'ready to query'" /> </ transition > < transition state = "src_connected" event = "nextstate" name = "evt" > < dialogstart src = "requestPIN" connectionid = "inboundConnection" /> </ transition > 40 41 42 43 QUESTION Many messages in the queue. How do
they pop off the queue? Or get in? Which comes first? 44 CCXML: Queue we work thru queue VoiceXML: Single Events 45 QUESTION Many messages in the queue. How do
they pop off the queue? Or get in? ANSWER They enter queue in whatever order
they arrive.
They come off one after the other,
regardless of current state.
Transition selected in document order. Which comes first? 43 44 45 46 < transition state = "src_init" event = "error.connection" name = "evt" > < log expr = "logdelim + 'uh oh'" /> </ transition > < transition event = "error.*" name = "evt" > < log expr = "logdelim + 'received error ' + evt.name + ' because ' + evt.reason" /> </ transition > 47 CCXML: Outside Data 48 < transition state = "src_init" event = "connection.alerting" name = "evt" > < assign name = "userId" expr = "evt.connection.remote" /> < assign name = "inboundConnection" expr = "evt.connectionid" /> < accept /> < log expr = "logdelim + 'accepted connection'" /> </ transition > 46 47 48 <send> Send data between CCXML sessions Send data to other places via HTTP 49 <send> attributes targettype: ccxml or basichttp target: session ID or URL data: event name namelist: data to send along 50 51 < transition state = "src_init" event = "connection.connected" name = "evt" > < assign name = "src_currentState" expr = "src_connected" /> < send data = "nextstate" target = "session.id" targettype = "send_ccxml" /> < log expr = "logdelim + 'ready to query'" /> </ transition > < transition state = "src_connected" event = "nextstate" name = "evt" > < dialogstart src = "requestPIN" connectionid = "inboundConnection" /> </ transition > 49 50 51 <send> responses error. send.failed error.send.targetunavailable error.send.targettypeinvalid send.success 52 53 STATE-BASED Create series of sub-states. Stay in sub-
states until <send> completes. Disadvantages Little/nothing else happens meantimes Reliable <send> ? How? 54 STATELESS Handle each individual <send>-related
signal regardless of current state Disadvantages Creates private state machine
Requires multiple tracking variables Reliable <send> (cont.) 52 53 54 55 < transition event = "error.send.*" > < log expr = "logdelim + 'send error'" /> </ transition > 56 CCXML: Multi thread can pass data VoiceXML: Single Thread sub-prog must term 57 SEPARATE THREAD Create separate process to interact, report
results to main thread Disadvantages Thread => CPU overhead, license Reliable <send> (best) 55 56 57 58 < transition state = "src_init" event = "connection.connected" name = "evt" > < createccxml next = "checkId" sessionid = "sendDataId" namelist = "userId parentId" method = "post" /> < log expr = "logdelim + 'start reliable send'" /> </ transition > < transition state = "src_init" event = "ccxml.created" name = "evt" > < assign name = "src_currentState" expr = "src_connected" /> < send data = "nextstate" target = "session.id" targettype = "send_ccxml" /> < log expr = "logdelim + 'send started, ready to talk'" /> </ transition > < transition state = "src_init" event = "error.createccxml" name = "evt" > < log expr = "logdelim + 'uh oh'" /> </ transition > 59 The absolute most powerful tool in the CCXML toolbox: Write a script to handle a single call, then run as many copies as needed. 60 How does outside server send to us? No standard! Ask your CCXML vendor. 58 59 60 61 IMMEDIATE:
server responds to <send> with
text/plain that includes:
report
item1=value1
item2=value2
Appears as event “report” with
evt.item1, evt.item2
Voxeo method (1) Voxeo method (2) 62 DEFERRED:
http request from server to CCXML
platform:
http://ccxml.example.com/
CCXML.send?
sessionid=xyz&eventname=abc&it
em1=value1
Appears as event “abc” with evt.item1 63 VoiceXML Integration 61 62 63 VoiceXML-specific elements dialogprepare, dialogstart dialogterminate dialog.exit dialog.transfer, etc. error.dialog.* 64 65 < transition state = "src_connected" event = "nextstate" name = "evt" > < dialogstart src = "detectHuman" connectionid = "inboundConnection" /> </ transition > <!-- dialog error --> < transition state = "src_connected" event = "error.dialog*" name = "evt" > < log expr = "logdelim + 'uh, oh'" /> </ transition > 66 < filled > < log expr = "logdelim + 'field filled'" /> < prompt > Thank you, one moment please.
</ prompt > < assign name = "human" expr = "request$.interpretation.human" /> < exit namelist = "human" /> </ filled > And on the VXML side... 64 65 66 67 < transition state = "src_connected" event = "nextstate" name = "evt" > < dialogstart src = "detectHuman" connectionid = "inboundConnection" /> </ transition > <!-- dialog error --> < transition state = "src_connected" event = "error.dialog*" name = "evt" > < log expr = "logdelim + 'uh, oh'" /> </ transition > <!-- is human? --> < transition state = "src_connected" event = "dialog.exit" name = "evt" > < assign name = "isHuman" expr = "evt.values.human" /> </ transition > 68 Call Manipulation 69 QUESTION How do I connect incoming caller to me? ANSWER Make outgoing call
Create conference
Connect together 67 68 69 Basic Elements (“Tags”) createcall createconference, join, unjoin 70 71 <!-- authorized call. make outbound connection. --> < transition state = "src_authorized" event = "nextstate" name = "evt" > < createcall dest = "clientTn" connectionid = "clientConnId" / >
</ transition > 72 <!-- connection failed. Which one failed? --> < transition state = "src_authorized" event = "connection.failed" name = "evt" > < if cond = "evt.connectionid == clientConnId" > <!-- do one thing --> < elseif cond = "evt.connectionid == inboundConnection" /> <!-- do something else --> </ if > </ transition > We have two calls. On failure, check to see
which one failed.
70 71 72 73 QUESTION How do I connect incoming caller to me? ANSWER Make outgoing call
Create conference
Connect together 74 <!-- conference info --> < var name = "srcConferenceId" /> < var name = "srcConfName" expr = "'src_conf_' + session.id" /> < transition state = "src_conferenced" event = "nextstate" name = "evt" > < createconference conferenceid = "srcConferenceId" confname = "srcConfName" /> </ transition > < transition state = "src_conferenced" event = "conference.error.create" name = "evt" > < log expr = "logdelim + 'uh oh'" /> </ transition > 75 < transition state = "src_conferenced" event = "conference.created" name = "evt" > < join id1 = "srcConferenceId" id2 = "inboundConnection" entertone = "false" exittone = "false" /> < join id1 = "srcConferenceId" id2 = "clientConnId" entertone = "false" exittone = "false" /> </ transition > 73 74 75 76 QUESTION How do I detect failure to join? QUESTION Can I use separate CCXML instance
devoted to task of joining calls? ASSERTION Previous code segment is bad example. 77 CCXML: Call in Session in original thread VoiceXML: Call in Thread active thread 78 POSSIBLE
PROCEDURE: Add more states
Join 1, validate
Join 2, validate
Go to
“nominal” and
wait for
hangups. Join 1 START_ CONFERENCE NOMINAL Join 2 76 77 78 79 REAL QUESTION Does it actually make a difference which
call fails? If not, play announcement to
survivor and just hang up. 80 < transition state = "src_conferenced" event = "pleaseDisconnect" name = "evt" > < disconnect connectionid = "inboundConnection" /> </ transition > About hanging up... Adding script to track different calls works for a couple of calls, but rapidly gets out of control. Scaling Up: Problems and Solutions 81 79 80 81 82 Master Master Leg Leg Call Call Leg (1) Leg (1) Conference Conference Call Call Leg (n) Leg (n) Conference Call Scenario Master Call Leg Conference Object Twelve Call Legs Make outbound calls Retry each call if necessary Track individual data 83 Outbound Legs Possible Architecture: Create array of “outbound”
objects
Use array to track status of each
call
As call status changes, take
action & update status
84 82 83 84 Outbound Legs Possible Architecture: Write CCXML instance to handle
single call leg
Use multiple instances 85 86 The absolute most powerful tool in the CCXML toolbox: Write a script to handle a single call, then run as many copies as needed. 87 Main Main Loop Loop Call Call Leg (1) Leg (1) Conference Conference Call Call Leg (n) Leg (n) Voice Conference Manager Multiple Instances 85 86 87 88 Each call leg instance handles the simple tasks associated with a single leg Main Main Loop Loop Call Call Leg (1) Leg (1) Conference Conference Call Call Leg (n) Leg (n) Start Status Action Best Practices & Debugging 89 90 Conference Conference Conference Conference Problem: Connect Conferences 88 89 90 Wrong! 91 Conference Conference Conference Conference Call Leg Call Leg 92 Remember: CCXML has only one end of a call. 93 Conference Conference Conference Conference Call Leg Call Leg Call Leg Call Leg 91 92 93 Avoid Confusing State Names 94 CONNECTED START Potential human
confusion between
state name and
canonical state
name
95 <dialogstart type=”’application/voicxml+xml’”
src=”’../vxml/askAccountNumber.vxml’”/>
Never, ever use a string if you can avoid it 96 <transition event=”connection.connected”
state=”’s_init_endOfInitialzation’”/>
Never, ever use a string if you can avoid it 94 95 96 97 <assign name=”item1”
expr=”’statusSucceess’”/>
Never, ever use a string if you can avoid it 98 Best Practices (1) Use separate CCXML module when
tasks are asynchronous and mixed
99 Main Main Module Module Send Send Instance Instance Send Send Manager Manager 97 98 99 100 Best Practices (1) Use separate CCXML module when
tasks are asynchronous and mixed
Use separate CCXML instances
when you start imitating state
machine
Consider separate CCXML modules
for logically separate tasks
101 Best Practices (2) Use variables, not strings Don’t neglect standard
programming practices
Use unique conference names if
you want them to be unique!
Use unique “statevariable” names
for each CCXML module
102 Best Practices (3) The kindergarten rules: Play nicely with others (use comments) Clean up after yourself (use destroyconference, etc.) 100 101 102 What I Really Prefer A separate instance for each
outgoing call
A separate instance to manage
conference
Send messages from master
instance to call instances to tell
them to join conference
103 104 The only real source of debugging
information is your log files. 105 Create your own standard delimiter <var name=”logdelim
expr=”’ ::::::LOG:::::: ‘”/>
103 104 105 106 <log expr=” logdelim + ‘var is ’ + varValue + ‘from inside object: ’ + JSON.stringify (object)”/> Log statements can contain strings, ECMAScript values, and ECMAScript functions About Disaggregate Moshe Yudkowsky
Disaggregate
2952 W. Fargo
Chicago, IL 60645
+1 773 764 8727
www.Disaggregate.com
106 107



Download complete workshop.pdf
Comments
Your talk will be first one...
Your Name:
Your Email:
Your Talk:
Google Search
Google
RECENT SEARCHES