Skip to content

Instantly share code, notes, and snippets.

@stevegraham
Created May 30, 2012 20:42
Show Gist options
  • Save stevegraham/2838829 to your computer and use it in GitHub Desktop.
Save stevegraham/2838829 to your computer and use it in GitHub Desktop.
JavaScript TwiML generator
Twilio = Object.create({})
Twilio.TwiML = {
build: function(fn) {
var prolog = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
var Buffer = function(level) {
var buffer = "";
var indent = function(i) { return new Array((i * 2) + 1).join(" ") }
var level = level || 1;
var append = function(str) {
buffer += indent(++level) + str + "\n";
level--;
}
var toAttributes = function(obj) {
var string = "";
for (key in obj) { string += " " + key + "=" + "\"" + obj[key] + "\"" }
return string;
}
var commonElement = function(verb) {
return function(str, attributes) {
append("<" + verb + toAttributes(attributes) + ">" + str + "</" + verb + ">")
}
}
var emptyElement = function(verb) {
return function(attributes) { append("<" + verb + toAttributes(attributes) + " />") }
}
var containerElement = function(verb) {
return function(fn, attributes) {
var buffer = new Buffer(level + 2);
append('<'+ verb + toAttributes(attributes) + '>');
fn(buffer);
level -= 2;
append(buffer.emit().replace(/\n$/, ''));
level += 2;
append('</' + verb + '>');
}
}
this.dial = function(arg, attributes) {
switch(typeof arg) {
case 'function':
return containerElement('Dial')(arg, attributes);
break;
case 'string':
return commonElement('Dial')(arg, attributes);
break;
}
}
this.say = commonElement('Say');
this.play = commonElement('Play');
this.redirect = commonElement('Redirect');
this.number = commonElement('Number');
this.client = commonElement('Client');
this.conference = commonElement('Conference');
this.hangup = emptyElement('Hangup');
this.reject = emptyElement('Reject');
this.record = emptyElement('Record');
this.pause = emptyElement('Pause');
this.gather = containerElement('Gather');
this.emit = function() { return buffer }
}
var buffer = new Buffer;
fn(buffer);
return prolog + "<Response>\n" + buffer.emit() + "</Response>";
}
}
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Play loop="14">/welcome.mp3</Play>
<Say loop="10" voice="woman" language="en-gb">Holy shit, batman!</Say>
<Dial action="/bar" method="GET" timeout="60" hangupOnStar="true" timeLimit="600" callerId="+2125550000" record="true">
<Number sendDigits="1234#" url="/pre_roll">+12125551234</Number>
</Dial>
<Dial>
<Client>johnny</Client>
<Number>+12123450000</Number>
</Dial>
<Dial>
<Conference muted="true" beep="false" startConferenceOnEnter="false" endConferenceOnExit="false" waitUrl="/hold_music" waitMethod="GET" maxParticipants="10">devangels</Conference>
</Dial>
<Dial action="/foo">+16465551234</Dial>
<Gather action="/dtmf" method="POST" timeout="60" finishOnKey="*" numDigits="16">
<Say>please choose an option</Say>
<Play>/decision_music.mp3</Play>
<Pause />
</Gather>
<Record action="/callback" method="POST" timeout="5" finishOnKey="#" maxLength="30" transcribe="true" transcribeCallback="/transcribe" />
<Reject reason="busy" />
<Pause length="1" />
<Redirect>http://example.com/foo</Redirect>
<Hangup />
</Response>
Twilio.TwiML.build(function(res) {
res.play("/welcome.mp3", { loop: 14 });
res.say("Holy shit, batman!", { loop: 10, voice: 'woman', language: 'en-gb' });
res.dial(function(res) { res.number("+12125551234", { sendDigits: '1234#', url: '/pre_roll' }) },
{ action: '/bar', method: 'GET', timeout: 60, hangupOnStar: true,
timeLimit: 600, callerId: '+2125550000', record: true });
res.dial(function(res) {
res.client("johnny");
res.number("+12123450000");
});
res.dial(function(res) { res.conference("devangels", { muted: true, beep: false,
startConferenceOnEnter: false, endConferenceOnExit: false,
waitUrl: '/hold_music', waitMethod: 'GET', maxParticipants: 10 }) });
res.dial("+16465551234", { action: '/foo' } );
res.gather(function(res) {
res.say('please choose an option');
res.play('/decision_music.mp3');
res.pause();
}, { action: '/dtmf', method: 'POST', timeout: 60, finishOnKey: '*', numDigits: 16 })
res.record({ action: '/callback', method: 'POST',
timeout: 5, finishOnKey: "#", maxLength: 30,
transcribe: true, transcribeCallback: '/transcribe' })
res.reject({ reason: 'busy' });
res.pause({length: 1});
res.redirect('http://example.com/foo');
res.hangup();
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment