Comparing version
var Readable = require('readable-stream'); | ||
var EventEmitter = require('events').EventEmitter; | ||
var state = require('./state'); | ||
var Q = require('q'); | ||
@@ -92,2 +93,7 @@ var Context = function (stream) { | ||
Context.prototype.end = function () { | ||
this.stream.end(); | ||
return Q.resolve(); | ||
}; | ||
Context.prototype.exec = function() { | ||
@@ -103,2 +109,22 @@ var args = Array.prototype.slice.call(arguments, 0); | ||
Context.prototype.sendCommand = function (command) { | ||
var defer = new Q.defer(); | ||
this.send(command + '\n', function (err, result){ | ||
if (err) { | ||
defer.reject(err); | ||
} else { | ||
defer.resolve(result); | ||
} | ||
}); | ||
return defer.promise; | ||
}; | ||
Context.prototype.onEvent = function (event) { | ||
var defer = new Q.defer(); | ||
this.on(event, function (data) { | ||
defer.resolve(data); | ||
}); | ||
return defer.promise; | ||
} | ||
Context.prototype.dial = function (num, timeout, params, cb) { | ||
@@ -108,136 +134,136 @@ this.exec('Dial', num + ',' + timeout + ',' + params, cb); | ||
Context.prototype.databaseDel = function (family, key, cb) { | ||
this.send('DATABASE DEL ' + family + ' ' + key + '\n', cb || function () { }); | ||
Context.prototype.databaseDel = function (family, key) { | ||
return this.sendCommand('DATABASE DEL ' + family + ' ' + key); | ||
}; | ||
Context.prototype.databaseDelTree = function (family, keytree, cb) { | ||
this.send('DATABASE DELTREE ' + family + ' ' + keytree + '\n', cb || function () { }); | ||
Context.prototype.databaseDelTree = function (family, keytree) { | ||
return this.sendCommand('DATABASE DELTREE ' + family + ' ' + keytree); | ||
}; | ||
Context.prototype.databaseGet = function (family, key, cb) { | ||
this.send('DATABASE GET ' + family + ' ' + key + '\n', cb || function () { }); | ||
Context.prototype.databaseGet = function (family, key) { | ||
return this.sendCommand('DATABASE GET ' + family + ' ' + key); | ||
}; | ||
Context.prototype.databasePut = function (family, key, value, cb) { | ||
this.send('DATABASE PUT ' + family + ' ' + key + ' ' + value + '\n', cb || function () { }); | ||
Context.prototype.databasePut = function (family, key, value) { | ||
return this.sendCommand('DATABASE PUT ' + family + ' ' + key + ' ' + value); | ||
}; | ||
Context.prototype.speechCreate = function (engine, cb) { | ||
this.send('SPEECH CREATE ' + engine + '\n', cb || function () { }); | ||
Context.prototype.speechCreate = function (engine) { | ||
return this.sendCommand('SPEECH CREATE ' + engine); | ||
}; | ||
Context.prototype.speechDestroy = function (cb) { | ||
this.send('SPEECH DESTROY\n', cb || function () { }); | ||
Context.prototype.speechDestroy = function () { | ||
return this.sendCommand('SPEECH DESTROY'); | ||
}; | ||
Context.prototype.speechActivateGrammar = function (name, cb) { | ||
this.send('SPEECH ACTIVATE GRAMMAR ' + name + '\n', cb || function () { }); | ||
Context.prototype.speechActivateGrammar = function (name) { | ||
return this.sendCommand('SPEECH ACTIVATE GRAMMAR ' + name); | ||
}; | ||
Context.prototype.speechDeactivateGrammar = function (name, cb) { | ||
this.send('SPEECH DEACTIVATE GRAMMAR ' + name + '\n', cb || function () { }); | ||
Context.prototype.speechDeactivateGrammar = function (name) { | ||
return this.sendCommand('SPEECH DEACTIVATE GRAMMAR ' + name); | ||
}; | ||
Context.prototype.speechLoadGrammar = function (name, path, cb) { | ||
this.send('SPEECH LOAD GRAMMAR ' + name + ' ' + path + '\n', cb || function () { }); | ||
Context.prototype.speechLoadGrammar = function (name, path) { | ||
return this.sendCommand('SPEECH LOAD GRAMMAR ' + name + ' ' + path); | ||
}; | ||
Context.prototype.speechUnloadGrammar = function (name, cb) { | ||
this.send('SPEECH UNLOAD GRAMMAR ' + name + '\n', cb || function () { }); | ||
Context.prototype.speechUnloadGrammar = function (name) { | ||
return this.sendCommand('SPEECH UNLOAD GRAMMAR ' + name); | ||
}; | ||
Context.prototype.speechSet = function (name, value, cb) { | ||
this.send('SPEECH SET ' + name + ' ' + value + '\n', cb || function () { }); | ||
Context.prototype.speechSet = function (name, value) { | ||
return this.sendCommand('SPEECH SET ' + name + ' ' + value); | ||
}; | ||
Context.prototype.speechRecognize = function (prompt, timeout, offset, cb) { | ||
this.send('SPEECH RECOGNIZE ' + prompt + ' ' + timeout + ' ' + offset + '\n', cb || function () { }); | ||
Context.prototype.speechRecognize = function (prompt, timeout, offset) { | ||
return this.sendCommand('SPEECH RECOGNIZE ' + prompt + ' ' + timeout + ' ' + offset); | ||
}; | ||
Context.prototype.getVariable = function (name, cb) { | ||
this.send('GET VARIABLE ' + name + '\n', cb || function () { }); | ||
Context.prototype.getVariable = function (name) { | ||
return this.sendCommand('GET VARIABLE ' + name); | ||
}; | ||
Context.prototype.getFullVariable = function (variable, channel, cb) { | ||
this.send('GET FULL VARIABLE ' + variable + ' ' + channel + '\n', cb || function () { }); | ||
Context.prototype.getFullVariable = function (variable, channel) { | ||
return this.sendCommand('GET FULL VARIABLE ' + variable + ' ' + channel); | ||
}; | ||
Context.prototype.getData = function (file, timeout, maxdigits, cb) { | ||
this.send('GET DATA ' + file + ' ' + timeout + ' ' + maxdigits + '\n', cb || function () { }); | ||
Context.prototype.getData = function (file, timeout, maxdigits) { | ||
return this.sendCommand('GET DATA ' + file + ' ' + timeout + ' ' + maxdigits); | ||
}; | ||
Context.prototype.getOption = function (file, escape_digits, timeout, cb) { | ||
this.send('GET OPTION ' + file + ' "' + escape_digits + '" ' + timeout + '\n', cb || function () { }); | ||
Context.prototype.getOption = function (file, escape_digits, timeout) { | ||
return this.sendCommand('GET OPTION ' + file + ' "' + escape_digits + '" ' + timeout); | ||
}; | ||
Context.prototype.receiveChar = function (timeout, cb) { | ||
this.send('RECEIVE CHAR ' + timeout + '\n', cb || function () { }); | ||
Context.prototype.receiveChar = function (timeout) { | ||
return this.sendCommand('RECEIVE CHAR ' + timeout); | ||
}; | ||
Context.prototype.receiveText = function (timeout, cb) { | ||
this.send('RECEIVE TEXT ' + timeout + '\n', cb || function () { }); | ||
Context.prototype.receiveText = function (timeout) { | ||
return this.sendCommand('RECEIVE TEXT ' + timeout); | ||
}; | ||
Context.prototype.setAutoHangup = function (seconds, cb) { | ||
this.send('SET AUTOHANGUP ' + seconds + '\n', cb || function () { }); | ||
Context.prototype.setAutoHangup = function (seconds) { | ||
return this.sendCommand('SET AUTOHANGUP ' + seconds); | ||
}; | ||
Context.prototype.setCallerID = function (number, cb) { | ||
this.send('SET CALLERID ' + number + '\n', cb || function () { }); | ||
Context.prototype.setCallerID = function (number) { | ||
return this.sendCommand('SET CALLERID ' + number); | ||
}; | ||
Context.prototype.setContext = function (context, cb) { | ||
this.send('SET CONTEXT ' + context + '\n', cb || function () { }); | ||
Context.prototype.setContext = function (context) { | ||
return this.sendCommand('SET CONTEXT ' + context); | ||
}; | ||
Context.prototype.setExtension = function (extension, cb) { | ||
this.send('SET EXTENSION ' + extension + '\n', cb || function () { }); | ||
Context.prototype.setExtension = function (extension) { | ||
return this.sendCommand('SET EXTENSION ' + extension); | ||
}; | ||
Context.prototype.setPriority = function (priority, cb) { | ||
this.send('SET PRIORITY ' + priority + '\n', cb || function () { }); | ||
Context.prototype.setPriority = function (priority) { | ||
return this.sendCommand('SET PRIORITY ' + priority); | ||
}; | ||
Context.prototype.setMusic = function (musicclass, cb) { | ||
this.send('SET MUSIC ' + musicclass + '\n', cb || function () { }); | ||
Context.prototype.setMusic = function (musicclass) { | ||
return this.sendCommand('SET MUSIC ' + musicclass); | ||
}; | ||
Context.prototype.setVariable = function (name, value, cb) { | ||
this.send('SET VARIABLE ' + name + ' ' + value + '\n', cb || function () { }); | ||
Context.prototype.setVariable = function (name, value) { | ||
return this.sendCommand('SET VARIABLE ' + name + ' ' + value); | ||
}; | ||
Context.prototype.sendImage = function (image, cb) { | ||
this.send('SEND IMAGE ' + image + '\n', cb || function() { }); | ||
Context.prototype.sendImage = function (image) { | ||
return this.sendCommand('SEND IMAGE ' + image); | ||
}; | ||
Context.prototype.sendText = function (text, cb) { | ||
this.send('SEND TEXT "' + text + '"\n', cb || function() { }); | ||
Context.prototype.sendText = function (text) { | ||
return this.sendCommand('SEND TEXT "' + text + '"'); | ||
}; | ||
Context.prototype.channelStatus = function (name, cb) { | ||
this.send('CHANNEL STATUS ' + name + '\n', cb || function() { }); | ||
Context.prototype.channelStatus = function (name) { | ||
return this.sendCommand('CHANNEL STATUS ' + name); | ||
}; | ||
Context.prototype.answer = function (cb) { | ||
this.send('ANSWER\n', cb || function () { }); | ||
Context.prototype.answer = function () { | ||
return this.sendCommand('ANSWER'); | ||
}; | ||
Context.prototype.verbose = function (message, level, cb) { | ||
this.send('VERBOSE "' + message + '" ' + level + '\n', cb || function () { }); | ||
Context.prototype.verbose = function (message, level) { | ||
return this.sendCommand('VERBOSE "' + message + '" ' + level); | ||
}; | ||
Context.prototype.tddMode = function (value, cb) { | ||
this.send('TDD MODE ' + value + '\n', cb || function () { }); | ||
Context.prototype.tddMode = function (value) { | ||
return this.sendCommand('TDD MODE ' + value); | ||
}; | ||
Context.prototype.noop = function (cb) { | ||
this.send('NOOP\n', cb || function () { }); | ||
return this.sendCommand('NOOP'); | ||
}; | ||
Context.prototype.gosub = function (context, extension, priority, option, cb) { | ||
Context.prototype.gosub = function (context, extension, priority, option) { | ||
var str = [context, extension, priority, option].join(' '); | ||
this.send('GOSUB ' + str + '\n', cb || function () { }); | ||
return this.sendCommand('GOSUB ' + str); | ||
}; | ||
Context.prototype.recordFile = function (filename, format, escape_digits, timeout, offset, beep, silence, cb) { | ||
Context.prototype.recordFile = function (filename, format, escape_digits, timeout, offset, beep, silence) { | ||
var str = [ | ||
@@ -252,62 +278,51 @@ '"' + filename + '"', | ||
].join(' '); | ||
this.send('RECORD FILE ' + str + '\n', cb || function() { }); | ||
return this.sendCommand('RECORD FILE ' + str); | ||
}; | ||
Context.prototype.sayNumber = function (number, escape_digits, cb) { | ||
this.send('SAY NUMBER ' + number + ' "' + escape_digits + '"' + '\n', cb || function() { }); | ||
Context.prototype.sayNumber = function (number, escape_digits) { | ||
return this.sendCommand('SAY NUMBER ' + number + ' "' + escape_digits + '"'); | ||
}; | ||
Context.prototype.sayAlpha = function (number, escape_digits, cb) { | ||
this.send('SAY ALPHA ' + number + ' "' + escape_digits + '"' + '\n', cb || function() { }); | ||
Context.prototype.sayAlpha = function (number, escape_digits) { | ||
return this.sendCommand('SAY ALPHA ' + number + ' "' + escape_digits + '"'); | ||
}; | ||
Context.prototype.sayDate = function (seconds, escape_digits, cb) { //seconds since 1.01.1970 | ||
this.send('SAY DATE ' + seconds + ' "' + escape_digits + '"' + '\n', cb || function() { }); | ||
Context.prototype.sayDate = function (seconds, escape_digits) { //seconds since 1.01.1970 | ||
return this.sendCommand('SAY DATE ' + seconds + ' "' + escape_digits + '"'); | ||
}; | ||
Context.prototype.sayTime = function (seconds, escape_digits, cb) { //seconds since 1.01.1970 | ||
this.send('SAY TIME ' + seconds + ' "' + escape_digits + '"' + '\n', cb || function() { }); | ||
Context.prototype.sayTime = function (seconds, escape_digits) { //seconds since 1.01.1970 | ||
return this.sendCommand('SAY TIME ' + seconds + ' "' + escape_digits + '"'); | ||
}; | ||
Context.prototype.sayDateTime = function (seconds, escape_digits, format, timezone, cb) { //seconds since 1.01.1970 | ||
this.send('SAY DATETIME ' + seconds + ' "' + escape_digits + '" ' + format + ' ' + timezone + '\n', cb || function() { }); | ||
Context.prototype.sayDateTime = function (seconds, escape_digits, format, timezone) { //seconds since 1.01.1970 | ||
return this.sendCommand('SAY DATETIME ' + seconds + ' "' + escape_digits + '" ' + format + ' ' + timezone); | ||
}; | ||
Context.prototype.sayDigits = function (digits, escape_digits, cb) { | ||
this.send('SAY DIGITS ' + digits + ' "' + escape_digits + '"' + '\n', cb || function() { }); | ||
Context.prototype.sayDigits = function (digits, escape_digits) { | ||
return this.sendCommand('SAY DIGITS ' + digits + ' "' + escape_digits + '"'); | ||
}; | ||
Context.prototype.sayPhonetic = function (string, escape_digits, cb) { | ||
this.send('SAY PHONETIC ' + string + ' "' + escape_digits + '"' + '\n', cb || function() { }); | ||
Context.prototype.sayPhonetic = function (string, escape_digits) { | ||
return this.sendCommand('SAY PHONETIC ' + string + ' "' + escape_digits + '"'); | ||
}; | ||
Context.prototype.streamFile = function (filename, acceptDigits, cb) { | ||
if(typeof acceptDigits === 'function') { | ||
cb = acceptDigits; | ||
acceptDigits = "1234567890#*"; | ||
} | ||
this.send('STREAM FILE "' + filename + '" "' + acceptDigits + '"\n', cb); | ||
Context.prototype.streamFile = function (filename, digits) { | ||
var acceptDigits = digits ? digits : "1234567890#*"; | ||
return this.sendCommand('STREAM FILE "' + filename + '" "' + acceptDigits + '"'); | ||
}; | ||
Context.prototype.waitForDigit = function (timeout, cb) { | ||
if(typeof timeout === 'function') { | ||
cb = timeout; | ||
//default to 2 second timeout | ||
timeout = 5000; | ||
} | ||
this.send('WAIT FOR DIGIT ' + timeout + '\n', cb); | ||
Context.prototype.waitForDigit = function (timeoutIn) { | ||
var timeout = timeoutIn ? timeoutIn : 5000; | ||
return this.sendCommand('WAIT FOR DIGIT ' + timeout); | ||
}; | ||
Context.prototype.hangup = function (cb) { | ||
this.send('HANGUP\n', cb); | ||
Context.prototype.hangup = function () { | ||
return this.sendCommand('HANGUP'); | ||
}; | ||
Context.prototype.end = function () { | ||
this.stream.end(); | ||
Context.prototype.asyncAGIBreak = function () { | ||
return this.sendCommand('ASYNCAGI BREAK'); | ||
}; | ||
Context.prototype.asyncAGIBreak = function (cb) { | ||
this.send('ASYNCAGI BREAK\n', cb || function() { }); | ||
}; | ||
module.exports = Context; |
@@ -5,3 +5,3 @@ { | ||
"description": "Write AGI-server quickly! (AGI - Asterisk Gateway Interface)", | ||
"version": "0.0.9", | ||
"version": "0.1.0", | ||
"repository": { | ||
@@ -19,2 +19,3 @@ "type": "git", | ||
"dependencies": { | ||
"q": "^1.4.1", | ||
"readable-stream": "*" | ||
@@ -27,3 +28,3 @@ }, | ||
"istanbul": "^0.3.5", | ||
"memorystream": "^0.3.0", | ||
"memorystream": "^0.3.0", | ||
"mocha": "*", | ||
@@ -30,0 +31,0 @@ "mocha-istanbul": "^0.2.0" |
@@ -19,11 +19,17 @@ # ding-dong | ||
```js | ||
````` | ||
var ding = require('ding-dong'); | ||
ding.createServer(function(context) { | ||
context.on('variables', function(vars) { | ||
console.log('received new call from: ' + vars.agi_callerid + ' with uniqueid: ' + vars.agi_uniqueid); | ||
}); | ||
context.onEvent('variables') | ||
.then(function(vars) { | ||
console.log('received new call from: ' + vars.agi_callerid + ' with uniqueid: ' + vars.agi_uniqueid); | ||
}) | ||
.fail(console.log); | ||
}).listen(3000); | ||
``` | ||
````` | ||
### Add to Asterisk extensions.conf | ||
````` | ||
@@ -35,2 +41,5 @@ [default] | ||
attention: using javascript promises | ||
### new ding.Context(stream) | ||
@@ -40,12 +49,15 @@ | ||
### context.exec(command, [args], [callback]) | ||
### context.exec(command, [args]) | ||
Dispatches the `EXEC` AGI command to asterisk with supplied command name and arguments. _callback_ is called with the result of the dispatch. | ||
```js | ||
context.exec('Dial', opt1, opt2, .., optN, function(err, res) { | ||
context.exec('Dial', opt1, opt2, .., optN) | ||
.then(function(result) | ||
//the channel call app Dial with options | ||
}); | ||
context.exec('RecieveFax', '/tmp/myfax.tif', function(err, res) { | ||
context.exec('RecieveFax', '/tmp/myfax.tif') | ||
.then(function(result) { | ||
//fax has been recieved by asterisk and written to /tmp/myfax.tif | ||
@@ -60,17 +72,18 @@ }); | ||
```js | ||
context.hangup(function(err, res) { | ||
//the channel has now been hungup. | ||
}); | ||
context.hangup(); | ||
``` | ||
Projects | ||
======== | ||
Use ding-dong | ||
============= | ||
[Voicer](http://github.com/antirek/voicer) - AGI yandex voice recognizer for Asterisk | ||
[voicer](http://github.com/antirek/voicer) - AGI yandex voice recognizer for Asterisk | ||
[agi-number-archer](http://github.com/antirek/agi-number-archer) - AGI server for find region code of phone number (Russia) | ||
[lcr-finder](http://github.com/antirek/voicer) - least cost router for Asterisk | ||
## Links | ||
[Asterisk AGI](https://wiki.asterisk.org/wiki/display/AST/Asterisk+13+AGI+Commands) |
@@ -314,14 +314,3 @@ var MemoryStream = require('memorystream'); | ||
expect(this.context.sent.join('')).to.eql('GET VARIABLE test\n'); | ||
}); | ||
it('gets result', function(done) { | ||
this.context.getVariable('test', function(err, res) { | ||
expect(res.result).eql('1 (abcd)'); | ||
done(); | ||
}); | ||
var self = this; | ||
process.nextTick(function() { | ||
self.context.stream.write('200 result=1 (abcd)\n'); | ||
}) | ||
}); | ||
}); | ||
}); | ||
@@ -347,9 +336,3 @@ | ||
expect(this.context.sent.join('')).to.eql('STREAM FILE "test" "1234567890#*"\n'); | ||
}); | ||
it('defaults to all digits', function() { | ||
this.context.streamFile('test', function() {}); | ||
expect(this.context.sent.join('')).to.eql('STREAM FILE "test" "1234567890#*"\n'); | ||
}); | ||
}); | ||
}); | ||
@@ -359,3 +342,3 @@ | ||
it('record', function () { | ||
this.context.recordFile('test', 'wav', '#', 10, function() {}); | ||
this.context.recordFile('test', 'wav', '#', 10, 0, 1, 2, function() {}); | ||
expect(this.context.sent.join('')).to.eql('RECORD FILE "test" wav # 10000 0 1 2\n'); | ||
@@ -430,3 +413,3 @@ }); | ||
it('send text', function () { | ||
this.context.sendText('1234', function() {}); | ||
this.context.sendText('1234'); | ||
expect(this.context.sent.join('')).to.eql('SEND TEXT "1234"\n'); | ||
@@ -438,3 +421,3 @@ }); | ||
it('sends with default timeout', function() { | ||
this.context.waitForDigit(function() {}); | ||
this.context.waitForDigit(); | ||
expect(this.context.sent.join('')).to.eql('WAIT FOR DIGIT 5000\n'); | ||
@@ -441,0 +424,0 @@ }); |
11
10%740
0.95%86
17.81%29774
-1.99%2
100%