Slide 1

Slide 1 text

Asterisk, HTML5 and NodeJS; a world of endless possibilities Dan Jenkins Astricon 2012 @dan_jenkins @holidayextras

Slide 2

Slide 2 text

The next half an hour.... •Introductions •Who Holiday Extras are •HTML5 •What’s NodeJS •How we’ve used NodeJS within our production environment •Demonstration

Slide 3

Slide 3 text

Who am I? 2 Years Author of Asterisk-AMI Module Dan Jenkins @dan_jenkins Senior Web Developer & VoIP Engineer

Slide 4

Slide 4 text

It’s in the name, we sell extras for holidays We’re partners with some big names in the UK travel industry easyJet British Airways Thomas Cook Theatre Breaks Theme Park Breaks Legoland, Alton Towers to name just a few

Slide 5

Slide 5 text

Over 800,000 calls through our Contact Centre last year Operate in mainland Europe too, with Holiday Extras DE Since moving to Asterisk, we’ve taken ~516,000 phone calls in our Contact Centre We’ve been using Asterisk in production since April We believe Holidays should be Hassle Free We’re a 29 year old start up We are the market leaders!

Slide 6

Slide 6 text

Get on with it!

Slide 7

Slide 7 text

What’s so great about HTML5? No extra plugins required! Make fully featured apps direct in the browser Faster time to launch Over 60% of users with Internet access have browsers that suppport HTML5 Easier to iterate, there’s millions of web developers out there

Slide 8

Slide 8 text

What can you do with HTML5? Get User Media (Microphone & Video) WebRTC (SIP phone in the browser) Two way, real-time, communication Client-side databases Web workers (Threads) Offline Application cache

Slide 9

Slide 9 text

So, what’s NodeJS? “Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.”

Slide 10

Slide 10 text

What have Holiday Extras done? Integrated control of the call directly into our in-house CRM system, this also allows us to look up our customer in realtime We’ve been through about 3 iterations of the integration NodeJS and HTML5 have given us the ability to do this We are able to move fast to react to the current needs of our business

Slide 11

Slide 11 text

How does it all fit together? Asterisk Chrome + SF Firefox + SF Safari + SF NodeJS Server Web Sockets Asterisk-AMI TCP Socket SIP

Slide 12

Slide 12 text

Now for the demo @dan_jenkins @holidayextras

Slide 13

Slide 13 text

Firstly, install the module npm install asterisk-ami Prerequisite: install NodeJS first!

Slide 14

Slide 14 text

Create a basic NodeJS server Output a ping response from Asterisk in the command line, from the NodeJS app

Slide 15

Slide 15 text

server.js var AsteriskAmi = require('asterisk-ami'); var ami = new AsteriskAmi( { host: '172.16.172.130', username: 'astricon', password: 'secret' } ); ami.on('ami_data', function(data){ console.log('AMI DATA', data); }); ami.connect(function(response){ console.log('connected to the AMI'); setInterval(function(){ ami.send({action: 'Ping'});//run a callback event when we have connected to the socket }, 2000); }); process.on('SIGINT', function () { ami.disconnect(); " process.exit(0); }); github.com/danjenkins/astricon-2012

Slide 16

Slide 16 text

Time to step it up a notch, let’s make it output to a webpage Output that same ping response to a browser, using NodeJS

Slide 17

Slide 17 text

server.js var AsteriskAmi = require('asterisk-ami'); var nowjs = require("now"); var fs = require('fs'); var express = require('express'); var http = require('http'); var ami = new AsteriskAmi( { host: '172.16.172.130', username: 'astricon', password: 'secret' } ); var app = express(); var server = http.createServer(app).listen(8080, function(){ console.log('listening on http://localhost:8080'); }); app.configure(function(){ app.use("/assets", express.static(__dirname + '/assets')); }); github.com/danjenkins/astricon-2012

Slide 18

Slide 18 text

app.use(express.errorHandler()); app.get('/', function(req, res) { var stream = fs.createReadStream(__dirname + '/webpage.html'); stream.on('error', function (err) { res.statusCode = 500; res.end(String(err)); }); stream.pipe(res); }) var everyone = nowjs.initialize(server); ami.on('ami_data', function(data){ if(everyone.now.echoAsteriskData instanceof Function){ everyone.now.echoAsteriskData(data); } }); github.com/danjenkins/astricon-2012

Slide 19

Slide 19 text

ami.connect(function(response){ console.log('connected to the AMI'); setInterval(function(){ ami.send({action: 'Ping'});//run a callback event when we have connected to the socket }, 2000); }); process.on('SIGINT', function () { ami.disconnect(); process.exit(0); }); github.com/danjenkins/astricon-2012

Slide 20

Slide 20 text

webpage.html var output = function(data){ var html = '<div>' + (data instanceof Object ? JSON.stringify(data) : data) + '</div>'; var div = document.getElementById('output'); div.innerHTML = html + div.innerHTML; } now.echoAsteriskData = function(data){ output(data); } now.ready(function(){ output('connected via nowjs'); }); github.com/danjenkins/astricon-2012

Slide 21

Slide 21 text

Now, let’s create a call from the webpage via Bria - Asterisk 11 - SIP Phone Let’s make the browser do something, make it create a call between two sip extensions

Slide 22

Slide 22 text

server.js +everyone.now.send_data_to_asterisk = function(data){ + console.log('got data from browser', data); + ami.send(data); +} github.com/danjenkins/astricon-2012

Slide 23

Slide 23 text

webpage.html $('.btn').click(function(e){ var obj = {}; if($(this).is('.help')){ obj = {action: 'ListCommands'}; }else if($(this).is('.reload')){ obj = {action: 'reload'}; }else if($(this).is('.login')){ obj = {action: 'QueueAdd', queue: '10', interface: 'sip/2000', penalty: 1, paused: true}; }else if($(this).is('.unpause')){ obj = {action: 'QueuePause', queue: '10', interface: 'sip/2000', paused: false}; }else if($(this).is('.dial')){ obj = { action: 'originate', channel: 'SIP/1000', exten: 10, context: 'from-internal', priority : 1, async: true, callerid: '1000 VIA AMI "1000"' }; }else if($(this).is('.logout')){ obj = {action: 'QueueRemove', queue: '10', interface: 'sip/2000'}; } now.send_data_to_asterisk(obj); e.preventDefault(); }) github.com/danjenkins/astricon-2012

Slide 24

Slide 24 text

Questions?

Slide 25

Slide 25 text

Dan Jenkins Astricon 2012 [email protected] hungrygeek.holidayextras.co.uk npm.im/asterisk-ami github.com/holidayextras/node-asterisk-ami @dan_jenkins Thank You!