complete workshop
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
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...
Google Search
RECENT SEARCHES
wiring 11SI delco remy alternator | birth defect t13 | t13-a roof panel | 4033 | georgia insurance department list of insurance companies ... | mai lung disease | t13 detect master/slave ata | office of academic programs august 31, 2007 responses due by ... | working t13 | sharon: | s o u n d i n v e s t m e n t h o w t h e a c o u s t i c a l ... | statics | department/school | ho-chunk | pre-grant | form 1098 | icc-asp-6-swgca-inf.1chinese | vtc t13 | icon site environmental management plan 2006–2007 | army electronic product support | working t13 draft 1153d | epitaxial growth, magnetic properties, and lattice dynamics ... | steel importers' email | steel importers' contacts | steel importer | anual for graduate | working working working working t13 t13 t13 t13 draft draft ... | 170 - t20, t20, db 137 - t17, t18, d16 104 - t18, 18, d16 71 ... | t17, | methods/analysis | t18, | 40.14 | Nivea IMC plan | environmental performance partnership agreement fy 2006-2007 | consensus statement to eliminate the improper use of drug ... | quyỀn | interactive tutorials for how to do molecular modeling for polymers | bbs/move_update.php | midst | 4.2: | tp3420a | dementia care practice recommendations phase 3 end of life care | thebigsqueeze | doyon sheeter model DL14 | invacare xpo | airclic mp reporter | growing ranks of encore teachers boost schools | 679.64 | best buy and ilford partner together to bring professional ... | how can we beat our most powerful competitors? |
Hot Tags
restoration hardware united rental used car web+hosters search+engine+keyword sport magazine domestic+violence+law wedding video printer usb tax+return travel health insurance washington lawyer walden+university wirele@ss+internet+router student health insurance wedding registry wireless plan software testing warehouse floor wireless+network+monitor waterproof vibrator purifier water refinance+a+home site sf giants poetry publishing tool hire writing+instrument credit+report+com wildlife+print
Related Articles
- NEED HELP?
- Polycom
- Third Quarter Fiscal 2004 Financial Results Conference Call
- CU515_Cover 9/19/07 5:35 PM Page 1
- Perkins & Marie Callender's Inc
- RELM Wireless Reports 2008 First Quarter Results
- Audio Call Recording
- Fox & Hound Restaurant Group
- The growing docket New cases continue to be filed at an ever-rising ...
- Compact ICS 7.0 System Coordinator Guide
- 1 Contact Information: Investor Relations 941-556-2601 investor ...
- OLD DOMINION FREIGHT LINE'S THIRD QUARTER CONFERENCE CALL ON THE INTERNET
- OTI First Half and Second Quarter 2008 Financial Results Conference ...
- ribbs.usps.gov/files/MTAC/APR00-MTAC-MIN.DOC
- Triveni Engineering & Industries Limited Investors/Analysts Conference Call
- View user manual (may be very large)
- Peer Review of 1,3-Butadiene Development Support Document
- 9300 E. CENTRAL, SUITE 100 WICHITA, KS 67206 PHONE: (316) 634-0505 FAX ...
- Minutes of the Conference Call Meeting of the
- Shell Destin News Release
Popular Articles
- Diving at Vamizi
- PARTIES OUTSIDE THE BOX email ad@partiesoutsidethebox.com Telephone ...
- WILDLIFE FEST!
- 001-002_Inhalt_PUSANMAP04
- SECURITIES AND EXCHANGE COMMISSION
- AdministratorGuide Administrator Guide
- Knowledge Area Module (KAM) I
- Alberta Immigrant Nominee Program
- Microsoft Word - AG Sheffield Lake-AFSCME Expires 2007 CC _00018123
- AIM Autosport: Success - One race at a time
- page 224 Vol. XX. NOVEMBER 1, 1899. No. 21. -CONTENTS. -
- 109 Reverse Osmosis Water Desal (Page 3)
- Globalpark Enterprise Feedback Suite EFS Panel
- NATIONAL INSTITUTES OF HEALTH NCRR Budget (Dollars in thousands ...
- 001-002_Inhalt_PUSANMAP04
- Positioning of the SmartNode 4900
- Microsoft Word - Document1
- Audiovisual Services
- VWH - R100 Warland wheel rims, 895 x 135
- 001-002_Inhalt_PUSANMAP04
pdf