dialtone api gordon guthrie twilio. twiml - xmhell hello world
TRANSCRIPT
Dialtone api
Gordon Guthrie
Twilio
Twiml - XMHell
<?xml version="1.0" encoding="UTF-8" ?>
<Response>
<Say>Hello World</Say>
</Response>
bits and bobsPrimary Verbs<Say><Play><Gather><Record><Sms><Dial>
Nouns<Number><Client><Conference>
Secondary Verbs<Hangup><Redirect><Reject><Pause>
…event cycle…
browser
app server
I wan
na d
o
som
eth
ing h
ere
’s a
cap
ab
ilit
y
I am,I can
http
TwiML
Twilio
there are some pains
…shonktastic…
<?xml version="1.0" encoding="UTF-8" ?><Response>
<Say>Hello World</Say></Response>
"AccountSid=yabollocks&ToZip=&FromState=&Called=%2B441315101875&FromCountry=GB&CallerCountry=GB&CalledZip=&Direction=inbound&FromCity=&CalledCountry=GB&CallerState=&CallSid=yahoor&CalledState=Edinburgh&From=%2B447776251669&CallerZip=&FromZip=&CallStatus=ringing&ToCity=&ToState=Edinburgh&To=%2B441315101875&ToCountry=GB&CallerCity=&ApiVersion=2010-04-01&Caller=%2B447776251669&CalledCity="
…interaction is a pain…
dial the website
press 1 for X 2 for Y
2ra p
un
ter
yer h
oote
r
lets make it better
turn ‘em both into Erlang Records
-record(twilio, { account_sid = [], application_sid = [], direction = [], call_status = [], call_sid = [], api_version = [], custom_params = [], called = null, caller = null, from = null, to = null, call_duration = null, inprogress = null, recording = null }).
-record(twilio_caller,
{
number = [],
city = [],
zip = [],
state = [],
country = [],
country_code = [],
prefix = []
}).
-record(say, {
voice :: string(),
language :: string(),
loop :: integer(),
text = "" :: string()
}).
<say voice=‘woman’ language=‘de’ text=‘pogue ma hone and poke ma hontas, ya fanny’>
…design goals…
• make Twiml a proper executable run-time language– with validation
• implement a run-time• make it super-simple to use
– don’t debug live systems– don’t create unusable IVR trees
…a state machine in URLs…
browser
app server
http
TwiML
Twilio
extended Twiml
#say{}
#play{}
#gather{}
#record{}
#sms{}
#dial{body = [#nouns{}]}
Twilio
extended Twiml
#gather{body = [#ext{}], autoMenuEXT = true, after_EXT = [TwiML]}Nouns#response_EXT{}#default_EXT{}
#function_EXT{}
#goto_EXT{}#repeat_EXT{}
Erlang
Flo
w O
f C
on
trol
…put it all together… SAY = #say{text = "burb"}, PLAY = #play{url = "some file"}, REPEAT = #repeat_EXT{}, RESPONSE = #response_EXT{title = "berk", response = "1", body = [SAY, PLAY]}, GATHER = #gather{autoMenu_EXT = true, body = [SAY, PLAY], after_EXT = [RESPONSE, REPEAT]},twiml:compile([GATHER], ascii),
…compiles to…1 - GATHER (request Keypad Input) 1.1 - SAY "burb" 1.2 - PLAY some file 1.3 - SAY "Press 1 for BERK. " 1.2 - end of Gather (wait for response) 1.3 - Response 1 : BERK 1.3.1 - SAY "burb" 1.3.2 - PLAY some file 1.3.3 - HANGUP 1.4 - GOTO 1
…or…[{"1",{{xml,"<Gather>"},into}}, {"1.1",{{xml,"<Say>burb</Say>"},next}}, {"1.2",{{xml,"<Play>some file</Play>"},next}}, {"1.3",{{xml,"<Say>Press 1 for BERK. </Say>"},next}}, {"1.2",{{xml,"</Gather>"},gather}}, {"1.3",{{response_EXT,"1","berk",[]},into}}, {"1.3.1",{{xml,"<Say>burb</Say>"},next}}, {"1.3.2",{{xml,"<Play>some file</Play>"},next}}, {"1.3.3",{{xml,"<Hangup/>"},exit}}, {"1.4",{{goto_EXT,"1"},"1"}}]
Thanks to Ryan Huffman who wrote the initial
implementationhttps://github.com/huffman/twilio_erlang
http://www.twilio.com/docs/libraries