Skip to content

Instantly share code, notes, and snippets.

@balupton
Last active October 1, 2015 14:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save balupton/2011413 to your computer and use it in GitHub Desktop.
Save balupton/2011413 to your computer and use it in GitHub Desktop.
Bevry's Twilio Application using Node.js
// Configure
var ACCOUNT_SID,
AUTH_TOKEN,
APPLICATION_SID,
PORT_NUMBER,
BEVRY_PHONE = '000',
TEAM_MEMBERS = [
{
name: 'Ben',
role: 'CEO of Bevry',
phone: '111'
},
{
name: 'Helen',
role: 'Secretary of Bevry',
phone: '222'
}
]
// Create Server
var express = require('express'),
server = express.createServer();
server.listen(PORT_NUMBER);
// Create Twilio
var twilioAPI = require('twilio-api'),
client = new twilioAPI.Client(ACCOUNT_SID, AUTH_TOKEN);
// Bind Twilio to Server
server.use(cli.middleware());
//Get a Twilio application and register it
client.account.getApplication(APPLICATION_SID, function(err, app) {
// Check
if ( err ) throw err;
// Registers this application to intercept the appropriate HTTP requests using the Connect/Express
app.register();
// Listen to incoming calls
app.on('incomingCall', function(userCall) {
// Prepare
var userConnected = true;
// Welcome the caller
userCall.say("Welcome to Bevry, the rapid web development company. We're currently tracking down our team right now, so please wait patiently.");
// play some tune
// ...
// Prepare conference
var memberCalls = {},
membersClosed = 0,
activeMemberId,
memberJoin = function(memberId){
// Prepare
var member = TEAM_MEMBERS[memberId],
memberCall = memberCalls[memberId];
// Check if a team member is already active?
if ( activeMemberId ) {
var activeMember = TEAM_MEMBERS[activeMemberId];
memberCall.say("Team member "+activeMember.name+" got there first! Maybe next time.");
memberCall.reject('busy'); // rejects an incoming call to your Twilio number without billing you.
return;
}
// Make them active
activeMemberId = memberId;
// Let them know they are active
memberCall.say('Great! You picked up first, we are now connecting you to the caller.');
userCall.say("Great news! "+member.name+" the "+member.role+" picked up your call first, we're connecting you now. Hold tight!");
// Join them into a conference with the user
var conferenceName = call.joinConference(null,{
leaveOnStar: false,
startConferenceOnEnter: true,
endConferenceOnExit: true
},function(conferenceCall,status){
// what is call here?
// join the user as well
userCall.joinConference(conferenceName,{
leaveOnStar: false,
startConferenceOnEnter: true,
endConferenceOnExit: true
});
});
},
memberEnd = function(memberId){
// Prepare
var
member = TEAM_MEMBERS[memberId],
memberCall = memberCalls[memberId] || null;
// Check if our call is still active
if ( !memberCall ) return;
// Delete our member call reference
delete memberCalls[memberId];
++membersClosed;
// Check if the member is the active one
if ( memberId === activeMemberId ) {
// Ensure the user is hanged up
userCall.hangup();
// Hangup
memberCall.hungup();
}
else {
// Reject our call
memberCall.reject('busy');
}
// Check if all the team members have disconnected
if ( membersClosed === TEAM_MEMBERS.length ) {
if ( userConnected ) {
userConnected = false;
userCall.say("Looks like none of our team members are available right now. So leave a message after the tone.");
userCall.record();
userCall.hangup();
}
}
};
// Stop the calls if the user hangs up
userCall.on('ended',function(){
userConnected = false;
_.each(memberCalls,function(member,memberId){
memberEnd(memberId);
});
})
// Start a background conference call to try and find out which team member is available
_.each(TEAM_MEMBERS,function(member,memberId){
if ( !userConnected ) return;
app.makeCall(BEVRY_PHONE, teamMember.phone, {}, function(err,memberCall){
if ( err ) throw err;
memberCalls[memberId] = memberCall;
memberCall
.on('connected',function(status){
switch ( status ) {
case 'queued';
case 'ringing';
case 'completed';
break;
case 'in-progress';
memberJoin(memberId);
break;
default:
console.log('unknown connect status:',status);
break;
}
})
.on('ended',function(status){
switch ( status ) {
case 'busy':
case 'failed':
case 'no-answer':
case 'canceled':
memberEnd(memberId);
break;
default:
console.log('unknown ended status:',status);
break;
}
})
})
});
});
});
/*
@bminer
Copy link

bminer commented Mar 10, 2012

Please checkout the new documentation and my comments here. Thanks! Hit me up if you have any more questions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment