mirror of
https://github.com/jambonz/jambonz-feature-server.git
synced 2026-10-04 02:04:12 +00:00
feat: advanced queues (#362)
* feat: advanced queues * feat: advanced queues * feat: advanced queues * feat: advanced queues * update verb specification * add testcase * add testcase * add testcase * updte testcase * fixed * update queue * fix: fix waithook params * fix: fix waithook params * fix: performQueueWebhook with correct members length * fix merge conflict * debug log * debug listen test * debug listen test * debug listen test * debug listen test * debug listen test * debug listen issue * feat: add tts on account level --------- Co-authored-by: Dave Horton <daveh@beachdognet.com>
This commit is contained in:
co-authored by
Dave Horton
parent
01260ad054
commit
b7070121ee
@@ -16,6 +16,7 @@ class TaskDequeue extends Task {
|
|||||||
this.queueName = this.data.name;
|
this.queueName = this.data.name;
|
||||||
this.timeout = this.data.timeout || 0;
|
this.timeout = this.data.timeout || 0;
|
||||||
this.beep = this.data.beep === true;
|
this.beep = this.data.beep === true;
|
||||||
|
this.callSid = this.data.callSid;
|
||||||
|
|
||||||
this.emitter = new Emitter();
|
this.emitter = new Emitter();
|
||||||
this.state = DequeueResults.Timeout;
|
this.state = DequeueResults.Timeout;
|
||||||
@@ -53,7 +54,7 @@ class TaskDequeue extends Task {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_getMemberFromQueue(cs) {
|
_getMemberFromQueue(cs) {
|
||||||
const {popFront} = cs.srf.locals.dbHelpers;
|
const {retrieveFromSortedSet, retrieveByPatternSortedSet} = cs.srf.locals.dbHelpers;
|
||||||
|
|
||||||
return new Promise(async(resolve) => {
|
return new Promise(async(resolve) => {
|
||||||
let timer;
|
let timer;
|
||||||
@@ -70,7 +71,12 @@ class TaskDequeue extends Task {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
try {
|
try {
|
||||||
const url = await popFront(this.queueName);
|
let url;
|
||||||
|
if (this.callSid) {
|
||||||
|
url = await retrieveByPatternSortedSet(this.queueName, `*${this.callSid}`);
|
||||||
|
} else {
|
||||||
|
url = await retrieveFromSortedSet(this.queueName);
|
||||||
|
}
|
||||||
if (url) {
|
if (url) {
|
||||||
found = true;
|
found = true;
|
||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
@@ -78,7 +84,7 @@ class TaskDequeue extends Task {
|
|||||||
resolve(url);
|
resolve(url);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.debug({err}, 'TaskDequeue:_getMemberFromQueue error popFront');
|
this.logger.debug({err}, 'TaskDequeue:_getMemberFromQueue error Sorted Set');
|
||||||
}
|
}
|
||||||
await sleepFor(5000);
|
await sleepFor(5000);
|
||||||
} while (!this.killed && !timedout && !found);
|
} while (!this.killed && !timedout && !found);
|
||||||
|
|||||||
+28
-12
@@ -18,6 +18,7 @@ class TaskEnqueue extends Task {
|
|||||||
this.preconditions = TaskPreconditions.Endpoint;
|
this.preconditions = TaskPreconditions.Endpoint;
|
||||||
|
|
||||||
this.queueName = this.data.name;
|
this.queueName = this.data.name;
|
||||||
|
this.priority = this.data.priority;
|
||||||
this.waitHook = this.data.waitHook;
|
this.waitHook = this.data.waitHook;
|
||||||
|
|
||||||
this.emitter = new Emitter();
|
this.emitter = new Emitter();
|
||||||
@@ -70,12 +71,22 @@ class TaskEnqueue extends Task {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async _addToQueue(cs, dlg) {
|
async _addToQueue(cs, dlg) {
|
||||||
const {pushBack} = cs.srf.locals.dbHelpers;
|
const {addToSortedSet, sortedSetLength} = cs.srf.locals.dbHelpers;
|
||||||
const url = getUrl(cs);
|
const url = getUrl(cs);
|
||||||
this.waitStartTime = Date.now();
|
this.waitStartTime = Date.now();
|
||||||
this.logger.debug({queue: this.queueName, url}, 'pushing url onto queue');
|
this.logger.debug({queue: this.queueName, url}, 'pushing url onto queue');
|
||||||
const members = await pushBack(this.queueName, url);
|
if (this.priority < 0) {
|
||||||
this.logger.info(`TaskEnqueue:_addToQueue: added to queue, length now ${members}`);
|
this.logger.warn(`priority ${this.priority} is invalid, need to be non-negative integer,
|
||||||
|
999 will be used for priority`);
|
||||||
|
}
|
||||||
|
let members = await addToSortedSet(this.queueName, url, this.priority);
|
||||||
|
if (members === 1) {
|
||||||
|
this.logger.info('TaskEnqueue:_addToQueue: added to queue');
|
||||||
|
} else {
|
||||||
|
this.logger.info('TaskEnqueue:_addToQueue: failed to add to queue');
|
||||||
|
}
|
||||||
|
members = await sortedSetLength(this.queueName);
|
||||||
|
|
||||||
this.notifyUrl = url;
|
this.notifyUrl = url;
|
||||||
|
|
||||||
/* invoke account-level webhook for queue event notifications */
|
/* invoke account-level webhook for queue event notifications */
|
||||||
@@ -90,9 +101,9 @@ class TaskEnqueue extends Task {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async _removeFromQueue(cs) {
|
async _removeFromQueue(cs) {
|
||||||
const {removeFromList, lengthOfList} = cs.srf.locals.dbHelpers;
|
const {retrieveByPatternSortedSet, sortedSetLength} = cs.srf.locals.dbHelpers;
|
||||||
await removeFromList(this.queueName, getUrl(cs));
|
await retrieveByPatternSortedSet(this.queueName, `*${getUrl(cs)}`);
|
||||||
return await lengthOfList(this.queueName);
|
return await sortedSetLength(this.queueName);
|
||||||
}
|
}
|
||||||
|
|
||||||
async performAction() {
|
async performAction() {
|
||||||
@@ -279,8 +290,8 @@ class TaskEnqueue extends Task {
|
|||||||
this.emitter.emit('dequeue', opts);
|
this.emitter.emit('dequeue', opts);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const {lengthOfList} = cs.srf.locals.dbHelpers;
|
const {sortedSetLength} = cs.srf.locals.dbHelpers;
|
||||||
const members = await lengthOfList(this.queueName);
|
const members = await sortedSetLength(this.queueName);
|
||||||
this.dequeued = true;
|
this.dequeued = true;
|
||||||
cs.performQueueWebhook({
|
cs.performQueueWebhook({
|
||||||
event: 'leave',
|
event: 'leave',
|
||||||
@@ -301,7 +312,7 @@ class TaskEnqueue extends Task {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async _playHook(cs, dlg, hook, allowed = [TaskName.Play, TaskName.Say, TaskName.Pause, TaskName.Leave]) {
|
async _playHook(cs, dlg, hook, allowed = [TaskName.Play, TaskName.Say, TaskName.Pause, TaskName.Leave]) {
|
||||||
const {lengthOfList, getListPosition} = cs.srf.locals.dbHelpers;
|
const {sortedSetLength, sortedSetPositionByPattern} = cs.srf.locals.dbHelpers;
|
||||||
const b3 = this.getTracingPropagation();
|
const b3 = this.getTracingPropagation();
|
||||||
const httpHeaders = b3 && {b3};
|
const httpHeaders = b3 && {b3};
|
||||||
|
|
||||||
@@ -313,9 +324,14 @@ class TaskEnqueue extends Task {
|
|||||||
queueTime: getElapsedTime(this.waitStartTime)
|
queueTime: getElapsedTime(this.waitStartTime)
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const queueSize = await lengthOfList(this.queueName);
|
const queueSize = await sortedSetLength(this.queueName);
|
||||||
const queuePosition = await getListPosition(this.queueName, this.notifyUrl);
|
const queuePosition = await sortedSetPositionByPattern(this.queueName, `*${this.notifyUrl}`);
|
||||||
Object.assign(params, {queueSize, queuePosition});
|
Object.assign(params, {
|
||||||
|
queueSize,
|
||||||
|
queuePosition: queuePosition.length ? queuePosition[0] : 0,
|
||||||
|
callSid: this.cs.callSid,
|
||||||
|
callId: this.cs.callId,
|
||||||
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.error({err}, `TaskEnqueue:_playHook error retrieving list info for queue ${this.queueName}`);
|
this.logger.error({err}, `TaskEnqueue:_playHook error retrieving list info for queue ${this.queueName}`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ function installSrfLocals(srf, logger) {
|
|||||||
password: JAMBONES_MYSQL_PASSWORD,
|
password: JAMBONES_MYSQL_PASSWORD,
|
||||||
database: JAMBONES_MYSQL_DATABASE,
|
database: JAMBONES_MYSQL_DATABASE,
|
||||||
connectionLimit: JAMBONES_MYSQL_CONNECTION_LIMIT || 10
|
connectionLimit: JAMBONES_MYSQL_CONNECTION_LIMIT || 10
|
||||||
}, logger, tracer);
|
}, logger);
|
||||||
const {
|
const {
|
||||||
client,
|
client,
|
||||||
updateCallStatus,
|
updateCallStatus,
|
||||||
@@ -167,6 +167,11 @@ function installSrfLocals(srf, logger) {
|
|||||||
removeFromList,
|
removeFromList,
|
||||||
getListPosition,
|
getListPosition,
|
||||||
lengthOfList,
|
lengthOfList,
|
||||||
|
addToSortedSet,
|
||||||
|
retrieveFromSortedSet,
|
||||||
|
retrieveByPatternSortedSet,
|
||||||
|
sortedSetLength,
|
||||||
|
sortedSetPositionByPattern
|
||||||
} = require('@jambonz/realtimedb-helpers')({
|
} = require('@jambonz/realtimedb-helpers')({
|
||||||
host: JAMBONES_REDIS_HOST,
|
host: JAMBONES_REDIS_HOST,
|
||||||
port: JAMBONES_REDIS_PORT || 6379
|
port: JAMBONES_REDIS_PORT || 6379
|
||||||
@@ -228,7 +233,12 @@ function installSrfLocals(srf, logger) {
|
|||||||
lengthOfList,
|
lengthOfList,
|
||||||
getListPosition,
|
getListPosition,
|
||||||
getNuanceAccessToken,
|
getNuanceAccessToken,
|
||||||
getIbmAccessToken
|
getIbmAccessToken,
|
||||||
|
addToSortedSet,
|
||||||
|
retrieveFromSortedSet,
|
||||||
|
retrieveByPatternSortedSet,
|
||||||
|
sortedSetLength,
|
||||||
|
sortedSetPositionByPattern
|
||||||
},
|
},
|
||||||
parentLogger: logger,
|
parentLogger: logger,
|
||||||
getSBC,
|
getSBC,
|
||||||
|
|||||||
Generated
+108
-18
@@ -9,9 +9,9 @@
|
|||||||
"version": "0.8.3",
|
"version": "0.8.3",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jambonz/db-helpers": "^0.8.1",
|
"@jambonz/db-helpers": "^0.9.0",
|
||||||
"@jambonz/http-health-check": "^0.0.1",
|
"@jambonz/http-health-check": "^0.0.1",
|
||||||
"@jambonz/realtimedb-helpers": "^0.7.2",
|
"@jambonz/realtimedb-helpers": "^0.8.1",
|
||||||
"@jambonz/speech-utils": "^0.0.13",
|
"@jambonz/speech-utils": "^0.0.13",
|
||||||
"@jambonz/stats-collector": "^0.1.8",
|
"@jambonz/stats-collector": "^0.1.8",
|
||||||
"@jambonz/time-series": "^0.2.5",
|
"@jambonz/time-series": "^0.2.5",
|
||||||
@@ -1560,6 +1560,11 @@
|
|||||||
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
|
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@ioredis/commands": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg=="
|
||||||
|
},
|
||||||
"node_modules/@istanbuljs/load-nyc-config": {
|
"node_modules/@istanbuljs/load-nyc-config": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
|
||||||
@@ -1595,9 +1600,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@jambonz/db-helpers": {
|
"node_modules/@jambonz/db-helpers": {
|
||||||
"version": "0.8.1",
|
"version": "0.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/@jambonz/db-helpers/-/db-helpers-0.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/@jambonz/db-helpers/-/db-helpers-0.9.0.tgz",
|
||||||
"integrity": "sha512-pc5TRAYnb89oyD5Ncy9Ik+v/tBqQcNOthbDwaX1OJyGRhPdolgs4YvOTpc0KpSqx7TDjKPS9n5MlqOFWgyDbTA==",
|
"integrity": "sha512-4fvwONj4jQNIHyG76WGdE7AuMt9vDl4sfHmHrY3PSgOh+kf2BCtBEYqoxyJ96/NH9OeUYkuXoM6fjSvpS7GYVw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cidr-matcher": "^2.1.1",
|
"cidr-matcher": "^2.1.1",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
@@ -1629,13 +1634,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@jambonz/realtimedb-helpers": {
|
"node_modules/@jambonz/realtimedb-helpers": {
|
||||||
"version": "0.7.2",
|
"version": "0.8.2",
|
||||||
"resolved": "https://registry.npmjs.org/@jambonz/realtimedb-helpers/-/realtimedb-helpers-0.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/@jambonz/realtimedb-helpers/-/realtimedb-helpers-0.8.2.tgz",
|
||||||
"integrity": "sha512-hTlMw0pmwNHTAQVm3O1asHllRSwi5C+kLXjqZN4C8bdw08f6CY48qdX/aNHLlx5TWI1I5l0ReO745KrUFVPA6w==",
|
"integrity": "sha512-v7zlJ9D3gFIegqoLXdrIqDYMPsZbyZGW/Y8NBImmZ9mC6QrId9fVi5705/04g9SK870C/IadrGNiFPYVmn8JwA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jambonz/promisify-redis": "^0.0.6",
|
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"redis": "^3.1.2"
|
"ioredis": "^5.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@jambonz/speech-utils": {
|
"node_modules/@jambonz/speech-utils": {
|
||||||
@@ -3053,6 +3057,14 @@
|
|||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/cluster-key-slot": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/color-convert": {
|
"node_modules/color-convert": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
@@ -5028,6 +5040,29 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ioredis": {
|
||||||
|
"version": "5.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.3.2.tgz",
|
||||||
|
"integrity": "sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@ioredis/commands": "^1.1.1",
|
||||||
|
"cluster-key-slot": "^1.1.0",
|
||||||
|
"debug": "^4.3.4",
|
||||||
|
"denque": "^2.1.0",
|
||||||
|
"lodash.defaults": "^4.2.0",
|
||||||
|
"lodash.isarguments": "^3.1.0",
|
||||||
|
"redis-errors": "^1.2.0",
|
||||||
|
"redis-parser": "^3.0.0",
|
||||||
|
"standard-as-callback": "^2.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.22.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/ioredis"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ip": {
|
"node_modules/ip": {
|
||||||
"version": "1.1.8",
|
"version": "1.1.8",
|
||||||
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz",
|
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz",
|
||||||
@@ -5862,6 +5897,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
|
||||||
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="
|
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/lodash.defaults": {
|
||||||
|
"version": "4.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
|
||||||
|
"integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ=="
|
||||||
|
},
|
||||||
"node_modules/lodash.flattendeep": {
|
"node_modules/lodash.flattendeep": {
|
||||||
"version": "4.4.0",
|
"version": "4.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
|
||||||
@@ -5873,6 +5913,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
|
||||||
"integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="
|
"integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/lodash.isarguments": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg=="
|
||||||
|
},
|
||||||
"node_modules/lodash.isempty": {
|
"node_modules/lodash.isempty": {
|
||||||
"version": "4.4.0",
|
"version": "4.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz",
|
||||||
@@ -7797,6 +7842,11 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/standard-as-callback": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A=="
|
||||||
|
},
|
||||||
"node_modules/statuses": {
|
"node_modules/statuses": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
||||||
@@ -10025,6 +10075,11 @@
|
|||||||
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
|
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@ioredis/commands": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg=="
|
||||||
|
},
|
||||||
"@istanbuljs/load-nyc-config": {
|
"@istanbuljs/load-nyc-config": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
|
||||||
@@ -10053,9 +10108,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@jambonz/db-helpers": {
|
"@jambonz/db-helpers": {
|
||||||
"version": "0.8.1",
|
"version": "0.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/@jambonz/db-helpers/-/db-helpers-0.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/@jambonz/db-helpers/-/db-helpers-0.9.0.tgz",
|
||||||
"integrity": "sha512-pc5TRAYnb89oyD5Ncy9Ik+v/tBqQcNOthbDwaX1OJyGRhPdolgs4YvOTpc0KpSqx7TDjKPS9n5MlqOFWgyDbTA==",
|
"integrity": "sha512-4fvwONj4jQNIHyG76WGdE7AuMt9vDl4sfHmHrY3PSgOh+kf2BCtBEYqoxyJ96/NH9OeUYkuXoM6fjSvpS7GYVw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"cidr-matcher": "^2.1.1",
|
"cidr-matcher": "^2.1.1",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
@@ -10081,13 +10136,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@jambonz/realtimedb-helpers": {
|
"@jambonz/realtimedb-helpers": {
|
||||||
"version": "0.7.2",
|
"version": "0.8.2",
|
||||||
"resolved": "https://registry.npmjs.org/@jambonz/realtimedb-helpers/-/realtimedb-helpers-0.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/@jambonz/realtimedb-helpers/-/realtimedb-helpers-0.8.2.tgz",
|
||||||
"integrity": "sha512-hTlMw0pmwNHTAQVm3O1asHllRSwi5C+kLXjqZN4C8bdw08f6CY48qdX/aNHLlx5TWI1I5l0ReO745KrUFVPA6w==",
|
"integrity": "sha512-v7zlJ9D3gFIegqoLXdrIqDYMPsZbyZGW/Y8NBImmZ9mC6QrId9fVi5705/04g9SK870C/IadrGNiFPYVmn8JwA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@jambonz/promisify-redis": "^0.0.6",
|
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"redis": "^3.1.2"
|
"ioredis": "^5.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@jambonz/speech-utils": {
|
"@jambonz/speech-utils": {
|
||||||
@@ -11174,6 +11228,11 @@
|
|||||||
"wrap-ansi": "^7.0.0"
|
"wrap-ansi": "^7.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"cluster-key-slot": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA=="
|
||||||
|
},
|
||||||
"color-convert": {
|
"color-convert": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
@@ -12707,6 +12766,22 @@
|
|||||||
"side-channel": "^1.0.4"
|
"side-channel": "^1.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ioredis": {
|
||||||
|
"version": "5.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.3.2.tgz",
|
||||||
|
"integrity": "sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA==",
|
||||||
|
"requires": {
|
||||||
|
"@ioredis/commands": "^1.1.1",
|
||||||
|
"cluster-key-slot": "^1.1.0",
|
||||||
|
"debug": "^4.3.4",
|
||||||
|
"denque": "^2.1.0",
|
||||||
|
"lodash.defaults": "^4.2.0",
|
||||||
|
"lodash.isarguments": "^3.1.0",
|
||||||
|
"redis-errors": "^1.2.0",
|
||||||
|
"redis-parser": "^3.0.0",
|
||||||
|
"standard-as-callback": "^2.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"ip": {
|
"ip": {
|
||||||
"version": "1.1.8",
|
"version": "1.1.8",
|
||||||
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz",
|
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz",
|
||||||
@@ -13336,6 +13411,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
|
||||||
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="
|
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="
|
||||||
},
|
},
|
||||||
|
"lodash.defaults": {
|
||||||
|
"version": "4.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
|
||||||
|
"integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ=="
|
||||||
|
},
|
||||||
"lodash.flattendeep": {
|
"lodash.flattendeep": {
|
||||||
"version": "4.4.0",
|
"version": "4.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
|
||||||
@@ -13347,6 +13427,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
|
||||||
"integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="
|
"integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="
|
||||||
},
|
},
|
||||||
|
"lodash.isarguments": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg=="
|
||||||
|
},
|
||||||
"lodash.isempty": {
|
"lodash.isempty": {
|
||||||
"version": "4.4.0",
|
"version": "4.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz",
|
||||||
@@ -14797,6 +14882,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"standard-as-callback": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A=="
|
||||||
|
},
|
||||||
"statuses": {
|
"statuses": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
||||||
|
|||||||
+2
-2
@@ -25,9 +25,9 @@
|
|||||||
"jslint:fix": "eslint app.js tracer.js lib --fix"
|
"jslint:fix": "eslint app.js tracer.js lib --fix"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jambonz/db-helpers": "^0.8.1",
|
"@jambonz/db-helpers": "^0.9.0",
|
||||||
"@jambonz/http-health-check": "^0.0.1",
|
"@jambonz/http-health-check": "^0.0.1",
|
||||||
"@jambonz/realtimedb-helpers": "^0.7.2",
|
"@jambonz/realtimedb-helpers": "^0.8.1",
|
||||||
"@jambonz/speech-utils": "^0.0.13",
|
"@jambonz/speech-utils": "^0.0.13",
|
||||||
"@jambonz/stats-collector": "^0.1.8",
|
"@jambonz/stats-collector": "^0.1.8",
|
||||||
"@jambonz/time-series": "^0.2.5",
|
"@jambonz/time-series": "^0.2.5",
|
||||||
|
|||||||
+2
-2
@@ -39,7 +39,7 @@ test('\'config: listen\'', async(t) => {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
provisionCallHook(from, verbs);
|
await provisionCallHook(from, verbs);
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-gather-account-creds-success-send-bye.xml', '172.38.0.10', from);
|
await sippUac('uac-gather-account-creds-success-send-bye.xml', '172.38.0.10', from);
|
||||||
@@ -86,7 +86,7 @@ test('\'config: listen - stop\'', async(t) => {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
provisionCallHook(from, verbs);
|
await provisionCallHook(from, verbs);
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-gather-account-creds-success-send-bye.xml', '172.38.0.10', from);
|
await sippUac('uac-gather-account-creds-success-send-bye.xml', '172.38.0.10', from);
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ test('test create-call call-hook basic authentication', async(t) => {
|
|||||||
"text": "hello"
|
"text": "hello"
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
provisionCallHook(from, verbs);
|
await provisionCallHook(from, verbs);
|
||||||
//THEN
|
//THEN
|
||||||
await p;
|
await p;
|
||||||
|
|
||||||
@@ -150,7 +150,7 @@ test('test create-call amd', async(t) => {
|
|||||||
"length": 7
|
"length": 7
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
provisionCallHook(from, verbs);
|
await provisionCallHook(from, verbs);
|
||||||
//THEN
|
//THEN
|
||||||
await p;
|
await p;
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,4 @@
|
|||||||
/* SQLEditor (MySQL (2))*/
|
/* SQLEditor (MySQL (2))*/
|
||||||
|
|
||||||
SET FOREIGN_KEY_CHECKS=0;
|
SET FOREIGN_KEY_CHECKS=0;
|
||||||
|
|
||||||
DROP TABLE IF EXISTS account_static_ips;
|
DROP TABLE IF EXISTS account_static_ips;
|
||||||
@@ -16,6 +15,8 @@ DROP TABLE IF EXISTS call_routes;
|
|||||||
|
|
||||||
DROP TABLE IF EXISTS dns_records;
|
DROP TABLE IF EXISTS dns_records;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS lcr;
|
||||||
|
|
||||||
DROP TABLE IF EXISTS lcr_carrier_set_entry;
|
DROP TABLE IF EXISTS lcr_carrier_set_entry;
|
||||||
|
|
||||||
DROP TABLE IF EXISTS lcr_routes;
|
DROP TABLE IF EXISTS lcr_routes;
|
||||||
@@ -52,6 +53,8 @@ DROP TABLE IF EXISTS smpp_addresses;
|
|||||||
|
|
||||||
DROP TABLE IF EXISTS speech_credentials;
|
DROP TABLE IF EXISTS speech_credentials;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS system_information;
|
||||||
|
|
||||||
DROP TABLE IF EXISTS users;
|
DROP TABLE IF EXISTS users;
|
||||||
|
|
||||||
DROP TABLE IF EXISTS smpp_gateways;
|
DROP TABLE IF EXISTS smpp_gateways;
|
||||||
@@ -136,11 +139,23 @@ PRIMARY KEY (dns_record_sid)
|
|||||||
CREATE TABLE lcr_routes
|
CREATE TABLE lcr_routes
|
||||||
(
|
(
|
||||||
lcr_route_sid CHAR(36),
|
lcr_route_sid CHAR(36),
|
||||||
|
lcr_sid CHAR(36) NOT NULL,
|
||||||
regex VARCHAR(32) NOT NULL COMMENT 'regex-based pattern match against dialed number, used for LCR routing of PSTN calls',
|
regex VARCHAR(32) NOT NULL COMMENT 'regex-based pattern match against dialed number, used for LCR routing of PSTN calls',
|
||||||
description VARCHAR(1024),
|
description VARCHAR(1024),
|
||||||
priority INTEGER NOT NULL UNIQUE COMMENT 'lower priority routes are attempted first',
|
priority INTEGER NOT NULL COMMENT 'lower priority routes are attempted first',
|
||||||
PRIMARY KEY (lcr_route_sid)
|
PRIMARY KEY (lcr_route_sid)
|
||||||
) COMMENT='Least cost routing table';
|
) COMMENT='An ordered list of digit patterns in an LCR table. The patterns are tested in sequence until one matches';
|
||||||
|
|
||||||
|
CREATE TABLE lcr
|
||||||
|
(
|
||||||
|
lcr_sid CHAR(36) NOT NULL UNIQUE ,
|
||||||
|
name VARCHAR(64) COMMENT 'User-assigned name for this LCR table',
|
||||||
|
is_active BOOLEAN NOT NULL DEFAULT 1,
|
||||||
|
default_carrier_set_entry_sid CHAR(36) COMMENT 'default carrier/route to use when no digit match based results are found.',
|
||||||
|
service_provider_sid CHAR(36),
|
||||||
|
account_sid CHAR(36),
|
||||||
|
PRIMARY KEY (lcr_sid)
|
||||||
|
) COMMENT='An LCR (least cost routing) table that is used by a service provider or account to make decisions about routing outbound calls when multiple carriers are available.';
|
||||||
|
|
||||||
CREATE TABLE password_settings
|
CREATE TABLE password_settings
|
||||||
(
|
(
|
||||||
@@ -248,7 +263,10 @@ CREATE TABLE sbc_addresses
|
|||||||
sbc_address_sid CHAR(36) NOT NULL UNIQUE ,
|
sbc_address_sid CHAR(36) NOT NULL UNIQUE ,
|
||||||
ipv4 VARCHAR(255) NOT NULL,
|
ipv4 VARCHAR(255) NOT NULL,
|
||||||
port INTEGER NOT NULL DEFAULT 5060,
|
port INTEGER NOT NULL DEFAULT 5060,
|
||||||
|
tls_port INTEGER,
|
||||||
|
wss_port INTEGER,
|
||||||
service_provider_sid CHAR(36),
|
service_provider_sid CHAR(36),
|
||||||
|
last_updated DATETIME,
|
||||||
PRIMARY KEY (sbc_address_sid)
|
PRIMARY KEY (sbc_address_sid)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -307,6 +325,13 @@ created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|||||||
PRIMARY KEY (speech_credential_sid)
|
PRIMARY KEY (speech_credential_sid)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE system_information
|
||||||
|
(
|
||||||
|
domain_name VARCHAR(255),
|
||||||
|
sip_domain_name VARCHAR(255),
|
||||||
|
monitoring_domain_name VARCHAR(255)
|
||||||
|
);
|
||||||
|
|
||||||
CREATE TABLE users
|
CREATE TABLE users
|
||||||
(
|
(
|
||||||
user_sid CHAR(36) NOT NULL UNIQUE ,
|
user_sid CHAR(36) NOT NULL UNIQUE ,
|
||||||
@@ -357,6 +382,7 @@ smpp_inbound_password VARCHAR(64),
|
|||||||
register_from_user VARCHAR(128),
|
register_from_user VARCHAR(128),
|
||||||
register_from_domain VARCHAR(255),
|
register_from_domain VARCHAR(255),
|
||||||
register_public_ip_in_contact BOOLEAN NOT NULL DEFAULT false,
|
register_public_ip_in_contact BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
register_status VARCHAR(4096),
|
||||||
PRIMARY KEY (voip_carrier_sid)
|
PRIMARY KEY (voip_carrier_sid)
|
||||||
) COMMENT='A Carrier or customer PBX that can send or receive calls';
|
) COMMENT='A Carrier or customer PBX that can send or receive calls';
|
||||||
|
|
||||||
@@ -403,6 +429,7 @@ inbound BOOLEAN NOT NULL COMMENT 'if true, whitelist this IP to allow inbound ca
|
|||||||
outbound BOOLEAN NOT NULL COMMENT 'if true, include in least-cost routing when placing calls to the PSTN',
|
outbound BOOLEAN NOT NULL COMMENT 'if true, include in least-cost routing when placing calls to the PSTN',
|
||||||
voip_carrier_sid CHAR(36) NOT NULL,
|
voip_carrier_sid CHAR(36) NOT NULL,
|
||||||
is_active BOOLEAN NOT NULL DEFAULT 1,
|
is_active BOOLEAN NOT NULL DEFAULT 1,
|
||||||
|
protocol ENUM('udp','tcp','tls', 'tls/srtp') DEFAULT 'udp' COMMENT 'Outbound call protocol',
|
||||||
PRIMARY KEY (sip_gateway_sid)
|
PRIMARY KEY (sip_gateway_sid)
|
||||||
) COMMENT='A whitelisted sip gateway used for origination/termination';
|
) COMMENT='A whitelisted sip gateway used for origination/termination';
|
||||||
|
|
||||||
@@ -435,7 +462,7 @@ account_sid CHAR(36) COMMENT 'account that this application belongs to (if null,
|
|||||||
call_hook_sid CHAR(36) COMMENT 'webhook to call for inbound calls ',
|
call_hook_sid CHAR(36) COMMENT 'webhook to call for inbound calls ',
|
||||||
call_status_hook_sid CHAR(36) COMMENT 'webhook to call for call status events',
|
call_status_hook_sid CHAR(36) COMMENT 'webhook to call for call status events',
|
||||||
messaging_hook_sid CHAR(36) COMMENT 'webhook to call for inbound SMS/MMS ',
|
messaging_hook_sid CHAR(36) COMMENT 'webhook to call for inbound SMS/MMS ',
|
||||||
app_json VARCHAR(16384),
|
app_json TEXT,
|
||||||
speech_synthesis_vendor VARCHAR(64) NOT NULL DEFAULT 'google',
|
speech_synthesis_vendor VARCHAR(64) NOT NULL DEFAULT 'google',
|
||||||
speech_synthesis_language VARCHAR(12) NOT NULL DEFAULT 'en-US',
|
speech_synthesis_language VARCHAR(12) NOT NULL DEFAULT 'en-US',
|
||||||
speech_synthesis_voice VARCHAR(64),
|
speech_synthesis_voice VARCHAR(64),
|
||||||
@@ -502,6 +529,14 @@ ALTER TABLE call_routes ADD FOREIGN KEY application_sid_idxfk (application_sid)
|
|||||||
CREATE INDEX dns_record_sid_idx ON dns_records (dns_record_sid);
|
CREATE INDEX dns_record_sid_idx ON dns_records (dns_record_sid);
|
||||||
ALTER TABLE dns_records ADD FOREIGN KEY account_sid_idxfk_4 (account_sid) REFERENCES accounts (account_sid);
|
ALTER TABLE dns_records ADD FOREIGN KEY account_sid_idxfk_4 (account_sid) REFERENCES accounts (account_sid);
|
||||||
|
|
||||||
|
CREATE INDEX lcr_sid_idx ON lcr_routes (lcr_sid);
|
||||||
|
ALTER TABLE lcr_routes ADD FOREIGN KEY lcr_sid_idxfk (lcr_sid) REFERENCES lcr (lcr_sid);
|
||||||
|
|
||||||
|
CREATE INDEX lcr_sid_idx ON lcr (lcr_sid);
|
||||||
|
ALTER TABLE lcr ADD FOREIGN KEY default_carrier_set_entry_sid_idxfk (default_carrier_set_entry_sid) REFERENCES lcr_carrier_set_entry (lcr_carrier_set_entry_sid);
|
||||||
|
|
||||||
|
CREATE INDEX service_provider_sid_idx ON lcr (service_provider_sid);
|
||||||
|
CREATE INDEX account_sid_idx ON lcr (account_sid);
|
||||||
CREATE INDEX permission_sid_idx ON permissions (permission_sid);
|
CREATE INDEX permission_sid_idx ON permissions (permission_sid);
|
||||||
CREATE INDEX predefined_carrier_sid_idx ON predefined_carriers (predefined_carrier_sid);
|
CREATE INDEX predefined_carrier_sid_idx ON predefined_carriers (predefined_carrier_sid);
|
||||||
CREATE INDEX predefined_sip_gateway_sid_idx ON predefined_sip_gateways (predefined_sip_gateway_sid);
|
CREATE INDEX predefined_sip_gateway_sid_idx ON predefined_sip_gateways (predefined_sip_gateway_sid);
|
||||||
@@ -648,4 +683,4 @@ ALTER TABLE accounts ADD FOREIGN KEY device_calling_application_sid_idxfk (devic
|
|||||||
|
|
||||||
ALTER TABLE accounts ADD FOREIGN KEY siprec_hook_sid_idxfk (siprec_hook_sid) REFERENCES applications (application_sid);
|
ALTER TABLE accounts ADD FOREIGN KEY siprec_hook_sid_idxfk (siprec_hook_sid) REFERENCES applications (application_sid);
|
||||||
|
|
||||||
SET FOREIGN_KEY_CHECKS=1;
|
SET FOREIGN_KEY_CHECKS=1;
|
||||||
|
|||||||
+3
-3
@@ -43,7 +43,7 @@ test('\'dial-phone\'', async(t) => {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
provisionCallHook(from, verbs);
|
await provisionCallHook(from, verbs);
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
const p = sippUac('uas-dial.xml', '172.38.0.10', undefined, undefined, 2);
|
const p = sippUac('uas-dial.xml', '172.38.0.10', undefined, undefined, 2);
|
||||||
@@ -102,7 +102,7 @@ test('\'dial-sip\'', async(t) => {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
provisionCallHook(from, verbs);
|
await provisionCallHook(from, verbs);
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
const p = sippUac('uas-dial.xml', '172.38.0.10', undefined, undefined, 2);
|
const p = sippUac('uas-dial.xml', '172.38.0.10', undefined, undefined, 2);
|
||||||
@@ -169,7 +169,7 @@ test('\'dial-user\'', async(t) => {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
provisionCallHook(from, verbs);
|
await provisionCallHook(from, verbs);
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
const p = sippUac('uas-dial.xml', '172.38.0.10', undefined, undefined, 2);
|
const p = sippUac('uas-dial.xml', '172.38.0.10', undefined, undefined, 2);
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ test('\'gather\' test - google', async(t) => {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
let from = "gather_success";
|
let from = "gather_success";
|
||||||
provisionCallHook(from, verbs);
|
await provisionCallHook(from, verbs);
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
||||||
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
||||||
@@ -86,7 +86,7 @@ test('\'gather\' test - default (google)', async(t) => {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
let from = "gather_success";
|
let from = "gather_success";
|
||||||
provisionCallHook(from, verbs);
|
await provisionCallHook(from, verbs);
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
||||||
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
||||||
@@ -133,7 +133,7 @@ test('\'config\' test - reset to app defaults', async(t) => {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
let from = "gather_success";
|
let from = "gather_success";
|
||||||
provisionCallHook(from, verbs);
|
await provisionCallHook(from, verbs);
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
||||||
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
||||||
@@ -173,7 +173,7 @@ test('\'gather\' test - microsoft', async(t) => {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
let from = "gather_success";
|
let from = "gather_success";
|
||||||
provisionCallHook(from, verbs);
|
await provisionCallHook(from, verbs);
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
||||||
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
||||||
@@ -213,7 +213,7 @@ test('\'gather\' test - aws', async(t) => {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
let from = "gather_success";
|
let from = "gather_success";
|
||||||
provisionCallHook(from, verbs);
|
await provisionCallHook(from, verbs);
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
||||||
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
||||||
@@ -256,7 +256,7 @@ test('\'gather\' test - deepgram', async(t) => {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
let from = "gather_success";
|
let from = "gather_success";
|
||||||
provisionCallHook(from, verbs);
|
await provisionCallHook(from, verbs);
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
||||||
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
||||||
@@ -298,7 +298,7 @@ test('\'gather\' test - soniox', async(t) => {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
let from = "gather_success";
|
let from = "gather_success";
|
||||||
provisionCallHook(from, verbs);
|
await provisionCallHook(from, verbs);
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
||||||
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
||||||
|
|||||||
@@ -14,5 +14,6 @@ require('./play-tests');
|
|||||||
require('./sip-refer-tests');
|
require('./sip-refer-tests');
|
||||||
require('./listen-tests');
|
require('./listen-tests');
|
||||||
require('./config-test');
|
require('./config-test');
|
||||||
|
require('./queue-test');
|
||||||
require('./remove-test-db');
|
require('./remove-test-db');
|
||||||
require('./docker_stop');
|
require('./docker_stop');
|
||||||
@@ -35,7 +35,7 @@ test('\'listen-success\'', async(t) => {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
provisionCallHook(from, verbs);
|
await provisionCallHook(from, verbs);
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-gather-account-creds-success-send-bye.xml', '172.38.0.10', from);
|
await sippUac('uac-gather-account-creds-success-send-bye.xml', '172.38.0.10', from);
|
||||||
@@ -69,13 +69,13 @@ test('\'listen-maxLength\'', async(t) => {
|
|||||||
{
|
{
|
||||||
"verb": "listen",
|
"verb": "listen",
|
||||||
"url": `ws://172.38.0.60:3000/${from}`,
|
"url": `ws://172.38.0.60:3000/${from}`,
|
||||||
"mixType" : "mixed",
|
"mixType" : "stereo",
|
||||||
"timeout": 2,
|
"timeout": 2,
|
||||||
"maxLength": 2
|
"maxLength": 2
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
provisionCallHook(from, verbs);
|
await provisionCallHook(from, verbs);
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
||||||
@@ -109,7 +109,7 @@ test('\'listen-pause-resume\'', async(t) => {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
provisionCallHook(from, verbs);
|
await provisionCallHook(from, verbs);
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
const p = sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
const p = sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
||||||
|
|||||||
+9
-9
@@ -33,7 +33,7 @@ test('\'play\' tests single link in plain text', async(t) => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
const from = 'play_single_link';
|
const from = 'play_single_link';
|
||||||
provisionCallHook(from, verbs)
|
await provisionCallHook(from, verbs)
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-success-received-bye.xml', '172.38.0.10', from);
|
await sippUac('uac-success-received-bye.xml', '172.38.0.10', from);
|
||||||
@@ -62,7 +62,7 @@ test('\'play\' tests multi links in array', async(t) => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
const from = 'play_multi_links_in_array';
|
const from = 'play_multi_links_in_array';
|
||||||
provisionCallHook(from, verbs)
|
await provisionCallHook(from, verbs)
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-success-received-bye.xml', '172.38.0.10', from);
|
await sippUac('uac-success-received-bye.xml', '172.38.0.10', from);
|
||||||
@@ -100,8 +100,8 @@ test('\'play\' tests single link in conference', async(t) => {
|
|||||||
waitHook: `/customHook`
|
waitHook: `/customHook`
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
provisionCustomHook(from, waitHookVerbs)
|
await provisionCustomHook(from, waitHookVerbs)
|
||||||
provisionCallHook(from, verbs)
|
await provisionCallHook(from, verbs)
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-success-send-bye.xml', '172.38.0.10', from);
|
await sippUac('uac-success-send-bye.xml', '172.38.0.10', from);
|
||||||
@@ -141,8 +141,8 @@ test('\'play\' tests multi links in array in conference', async(t) => {
|
|||||||
waitHook: `/customHook`
|
waitHook: `/customHook`
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
provisionCustomHook(from, waitHookVerbs)
|
await provisionCustomHook(from, waitHookVerbs)
|
||||||
provisionCallHook(from, verbs)
|
await provisionCallHook(from, verbs)
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-success-send-bye.xml', '172.38.0.10', from);
|
await sippUac('uac-success-send-bye.xml', '172.38.0.10', from);
|
||||||
@@ -178,8 +178,8 @@ test('\'play\' tests with seekOffset and actionHook', async(t) => {
|
|||||||
const waitHookVerbs = [];
|
const waitHookVerbs = [];
|
||||||
|
|
||||||
const from = 'play_action_hook';
|
const from = 'play_action_hook';
|
||||||
provisionCallHook(from, verbs)
|
await provisionCallHook(from, verbs)
|
||||||
provisionCustomHook(from, waitHookVerbs)
|
await provisionCustomHook(from, waitHookVerbs)
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-success-received-bye.xml', '172.38.0.10', from);
|
await sippUac('uac-success-received-bye.xml', '172.38.0.10', from);
|
||||||
@@ -218,7 +218,7 @@ test('\'play\' tests with earlymedia', async(t) => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
const from = 'play_early_media';
|
const from = 'play_early_media';
|
||||||
provisionCallHook(from, verbs)
|
await provisionCallHook(from, verbs)
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-invite-expect-183-cancel.xml', '172.38.0.10', from);
|
await sippUac('uac-invite-expect-183-cancel.xml', '172.38.0.10', from);
|
||||||
|
|||||||
@@ -0,0 +1,127 @@
|
|||||||
|
const test = require('tape');
|
||||||
|
const { sippUac } = require('./sipp')('test_fs');
|
||||||
|
const clearModule = require('clear-module');
|
||||||
|
const {provisionCallHook, provisionActionHook, provisionAnyHook} = require('./utils');
|
||||||
|
const bent = require('bent');
|
||||||
|
const getJSON = bent('json');
|
||||||
|
|
||||||
|
process.on('unhandledRejection', (reason, p) => {
|
||||||
|
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||||
|
});
|
||||||
|
|
||||||
|
function connect(connectable) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
connectable.on('connect', () => {
|
||||||
|
return resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const sleepFor = (ms) => new Promise((resolve) => setTimeout(() => resolve(), ms));
|
||||||
|
|
||||||
|
test('\'enqueue-dequeue\' tests', async(t) => {
|
||||||
|
|
||||||
|
clearModule.all();
|
||||||
|
const {srf, disconnect} = require('../app');
|
||||||
|
try {
|
||||||
|
await connect(srf);
|
||||||
|
// GIVEN
|
||||||
|
const verbs = [
|
||||||
|
{
|
||||||
|
verb: 'enqueue',
|
||||||
|
name: 'support',
|
||||||
|
actionHook: '/actionHook'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const verbs2 = [
|
||||||
|
{
|
||||||
|
verb: 'dequeue',
|
||||||
|
name: 'support'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const actionVerbs = [
|
||||||
|
{
|
||||||
|
verb: 'play',
|
||||||
|
url: 'silence_stream://1000',
|
||||||
|
earlyMedia: true
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const from = 'enqueue_success';
|
||||||
|
await provisionCallHook(from, verbs);
|
||||||
|
await provisionActionHook(from, actionVerbs)
|
||||||
|
|
||||||
|
const from2 = 'dequeue_success';
|
||||||
|
await provisionCallHook(from2, verbs2);
|
||||||
|
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
const p1 = sippUac('uac-success-received-bye.xml', '172.38.0.10', from);
|
||||||
|
|
||||||
|
await sleepFor(1000);
|
||||||
|
|
||||||
|
const p2 = sippUac('uac-success-send-bye.xml', '172.38.0.11', from2);
|
||||||
|
await Promise.all([p1, p2]);
|
||||||
|
const obj = await getJSON(`http:127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
||||||
|
t.ok(obj.body.queue_result === 'bridged');
|
||||||
|
t.pass('enqueue-dequeue: succeeds connect');
|
||||||
|
disconnect();
|
||||||
|
} catch (err) {
|
||||||
|
console.log(`error received: ${err}`);
|
||||||
|
disconnect();
|
||||||
|
t.error(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('\leave\' tests', async(t) => {
|
||||||
|
|
||||||
|
clearModule.all();
|
||||||
|
const {srf, disconnect} = require('../app');
|
||||||
|
try {
|
||||||
|
await connect(srf);
|
||||||
|
// GIVEN
|
||||||
|
const verbs = [
|
||||||
|
{
|
||||||
|
verb: 'enqueue',
|
||||||
|
name: 'support1',
|
||||||
|
waitHook: '/anyHook/enqueue_success_leave',
|
||||||
|
actionHook: '/actionHook'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const anyHookVerbs = [
|
||||||
|
{
|
||||||
|
verb: 'leave'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const actionVerbs = [
|
||||||
|
{
|
||||||
|
verb: 'play',
|
||||||
|
url: 'silence_stream://1000',
|
||||||
|
earlyMedia: true
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const from = 'enqueue_success_leave';
|
||||||
|
await provisionCallHook(from, verbs);
|
||||||
|
await provisionAnyHook(from, anyHookVerbs);
|
||||||
|
await provisionActionHook(from, actionVerbs)
|
||||||
|
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
await sippUac('uac-success-received-bye.xml', '172.38.0.10', from);
|
||||||
|
const obj = await getJSON(`http:127.0.0.1:3100/lastRequest/enqueue_success_leave`);
|
||||||
|
t.ok(obj.body.queue_position === 0);
|
||||||
|
const obj1 = await getJSON(`http:127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
||||||
|
t.ok(obj1.body.queue_result === 'leave');
|
||||||
|
t.pass('enqueue-dequeue: succeeds connect');
|
||||||
|
disconnect();
|
||||||
|
} catch (err) {
|
||||||
|
console.log(`error received: ${err}`);
|
||||||
|
disconnect();
|
||||||
|
t.error(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
+3
-3
@@ -31,7 +31,7 @@ test('\'say\' tests', async(t) => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
const from = 'say_test_success';
|
const from = 'say_test_success';
|
||||||
provisionCallHook(from, verbs)
|
await provisionCallHook(from, verbs)
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-success-received-bye.xml', '172.38.0.10', from);
|
await sippUac('uac-success-received-bye.xml', '172.38.0.10', from);
|
||||||
@@ -71,7 +71,7 @@ test('\'config\' reset synthesizer tests', async(t) => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
const from = 'say_test_success';
|
const from = 'say_test_success';
|
||||||
provisionCallHook(from, verbs)
|
await provisionCallHook(from, verbs)
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-success-received-bye.xml', '172.38.0.10', from);
|
await sippUac('uac-success-received-bye.xml', '172.38.0.10', from);
|
||||||
@@ -111,7 +111,7 @@ if (MICROSOFT_CUSTOM_API_KEY && MICROSOFT_DEPLOYMENT_ID && MICROSOFT_CUSTOM_REGI
|
|||||||
];
|
];
|
||||||
|
|
||||||
const from = 'say_test_success';
|
const from = 'say_test_success';
|
||||||
provisionCallHook(from, verbs)
|
await provisionCallHook(from, verbs)
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-success-received-bye.xml', '172.38.0.10', from);
|
await sippUac('uac-success-received-bye.xml', '172.38.0.10', from);
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ test('\'refer\' tests w/202 and NOTIFY', {timeout: 25000}, async(t) => {
|
|||||||
const noVerbs = [];
|
const noVerbs = [];
|
||||||
|
|
||||||
const from = 'refer_with_notify';
|
const from = 'refer_with_notify';
|
||||||
provisionCallHook(from, verbs);
|
await provisionCallHook(from, verbs);
|
||||||
provisionActionHook(from, noVerbs)
|
await provisionActionHook(from, noVerbs)
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-refer-with-notify.xml', '172.38.0.10', from);
|
await sippUac('uac-refer-with-notify.xml', '172.38.0.10', from);
|
||||||
@@ -81,8 +81,8 @@ test('\'refer\' tests w/202 but no NOTIFY', {timeout: 25000}, async(t) => {
|
|||||||
const noVerbs = [];
|
const noVerbs = [];
|
||||||
|
|
||||||
const from = 'refer_no_notify';
|
const from = 'refer_no_notify';
|
||||||
provisionCallHook(from, verbs);
|
await provisionCallHook(from, verbs);
|
||||||
provisionActionHook(from, noVerbs)
|
await provisionActionHook(from, noVerbs)
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-refer-no-notify.xml', '172.38.0.10', from);
|
await sippUac('uac-refer-no-notify.xml', '172.38.0.10', from);
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ test('sending SIP in-dialog requests tests', async(t) => {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
let from = "sip_indialog_test";
|
let from = "sip_indialog_test";
|
||||||
provisionCallHook(from, verbs);
|
await provisionCallHook(from, verbs);
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-send-info-during-dialog.xml', '172.38.0.10', from);
|
await sippUac('uac-send-info-during-dialog.xml', '172.38.0.10', from);
|
||||||
const obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
const obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ test('\'transcribe\' test - google', async(t) => {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
let from = "gather_success";
|
let from = "gather_success";
|
||||||
provisionCallHook(from, verbs);
|
await provisionCallHook(from, verbs);
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
||||||
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
||||||
@@ -85,7 +85,7 @@ test('\'transcribe\' test - microsoft', async(t) => {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
let from = "gather_success";
|
let from = "gather_success";
|
||||||
provisionCallHook(from, verbs);
|
await provisionCallHook(from, verbs);
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
||||||
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
||||||
@@ -122,7 +122,7 @@ test('\'transcribe\' test - aws', async(t) => {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
let from = "gather_success";
|
let from = "gather_success";
|
||||||
provisionCallHook(from, verbs);
|
await provisionCallHook(from, verbs);
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
||||||
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
||||||
@@ -162,7 +162,7 @@ test('\'transcribe\' test - deepgram', async(t) => {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
let from = "gather_success";
|
let from = "gather_success";
|
||||||
provisionCallHook(from, verbs);
|
await provisionCallHook(from, verbs);
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
||||||
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
||||||
@@ -202,7 +202,7 @@ test('\'transcribe\' test - soniox', async(t) => {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
let from = "gather_success";
|
let from = "gather_success";
|
||||||
provisionCallHook(from, verbs);
|
await provisionCallHook(from, verbs);
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
|
||||||
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
|
||||||
|
|||||||
+16
-7
@@ -6,31 +6,40 @@ const bent = require('bent');
|
|||||||
* The function help testcase to register desired jambonz json response for an application call
|
* The function help testcase to register desired jambonz json response for an application call
|
||||||
* When a call has From number match the registered hook event, the desired jambonz json will be responded.
|
* When a call has From number match the registered hook event, the desired jambonz json will be responded.
|
||||||
*/
|
*/
|
||||||
const provisionCallHook = (from, verbs) => {
|
const provisionCallHook = async (from, verbs) => {
|
||||||
const mapping = {
|
const mapping = {
|
||||||
from,
|
from,
|
||||||
data: JSON.stringify(verbs)
|
data: JSON.stringify(verbs)
|
||||||
};
|
};
|
||||||
const post = bent('http://127.0.0.1:3100', 'POST', 'string', 200);
|
const post = bent('http://127.0.0.1:3100', 'POST', 'string', 200);
|
||||||
post('/appMapping', mapping);
|
await post('/appMapping', mapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
const provisionCustomHook = (from, verbs) => {
|
const provisionCustomHook = async(from, verbs) => {
|
||||||
const mapping = {
|
const mapping = {
|
||||||
from,
|
from,
|
||||||
data: JSON.stringify(verbs)
|
data: JSON.stringify(verbs)
|
||||||
};
|
};
|
||||||
const post = bent('http://127.0.0.1:3100', 'POST', 'string', 200);
|
const post = bent('http://127.0.0.1:3100', 'POST', 'string', 200);
|
||||||
post(`/customHookMapping`, mapping);
|
await post(`/customHookMapping`, mapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
const provisionActionHook = (from, verbs) => {
|
const provisionActionHook = async(from, verbs) => {
|
||||||
const mapping = {
|
const mapping = {
|
||||||
from,
|
from,
|
||||||
data: JSON.stringify(verbs)
|
data: JSON.stringify(verbs)
|
||||||
};
|
};
|
||||||
const post = bent('http://127.0.0.1:3100', 'POST', 'string', 200);
|
const post = bent('http://127.0.0.1:3100', 'POST', 'string', 200);
|
||||||
post(`/actionHook`, mapping);
|
await post(`/actionHook`, mapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { provisionCallHook, provisionCustomHook, provisionActionHook}
|
const provisionAnyHook = async(key, verbs) => {
|
||||||
|
const mapping = {
|
||||||
|
key,
|
||||||
|
data: JSON.stringify(verbs)
|
||||||
|
};
|
||||||
|
const post = bent('http://127.0.0.1:3100', 'POST', 'string', 200);
|
||||||
|
await post(`/anyHookMapping`, mapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { provisionCallHook, provisionCustomHook, provisionActionHook, provisionAnyHook}
|
||||||
|
|||||||
+23
-5
@@ -2,6 +2,7 @@ const express = require('express');
|
|||||||
const app = express();
|
const app = express();
|
||||||
const Websocket = require('ws');
|
const Websocket = require('ws');
|
||||||
const listenPort = process.env.HTTP_PORT || 3000;
|
const listenPort = process.env.HTTP_PORT || 3000;
|
||||||
|
const any_hook_json_mapping = new Map();
|
||||||
let json_mapping = new Map();
|
let json_mapping = new Map();
|
||||||
let hook_mapping = new Map();
|
let hook_mapping = new Map();
|
||||||
let ws_packet_count = new Map();
|
let ws_packet_count = new Map();
|
||||||
@@ -61,7 +62,7 @@ app.all('/', (req, res) => {
|
|||||||
console.log(req.body, 'POST /');
|
console.log(req.body, 'POST /');
|
||||||
const key = req.body.from
|
const key = req.body.from
|
||||||
addRequestToMap(key, req, hook_mapping);
|
addRequestToMap(key, req, hook_mapping);
|
||||||
return getJsonFromMap(key, req, res);
|
return getJsonFromMap(json_mapping, key, req, res);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.post('/appMapping', (req, res) => {
|
app.post('/appMapping', (req, res) => {
|
||||||
@@ -106,7 +107,7 @@ app.post('/actionHook', (req, res) => {
|
|||||||
app.all('/customHook', (req, res) => {
|
app.all('/customHook', (req, res) => {
|
||||||
let key = `${req.body.from}_customHook`;;
|
let key = `${req.body.from}_customHook`;;
|
||||||
console.log(req.body, `POST /customHook`);
|
console.log(req.body, `POST /customHook`);
|
||||||
return getJsonFromMap(key, req, res);
|
return getJsonFromMap(json_mapping, key, req, res);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.post('/customHookMapping', (req, res) => {
|
app.post('/customHookMapping', (req, res) => {
|
||||||
@@ -116,6 +117,23 @@ app.post('/customHookMapping', (req, res) => {
|
|||||||
return res.sendStatus(200);
|
return res.sendStatus(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Any Hook
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.all('/anyHook/:key', (req, res) => {
|
||||||
|
let key = req.params.key;
|
||||||
|
console.log(req.body, `POST /anyHook/${key}`);
|
||||||
|
return getJsonFromMap(any_hook_json_mapping, key, req, res);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post('/anyHookMapping', (req, res) => {
|
||||||
|
let key = req.body.key;
|
||||||
|
console.log(req.body, `POST /anyHookMapping/${key}`);
|
||||||
|
any_hook_json_mapping.set(key, req.body.data);
|
||||||
|
return res.sendStatus(200);
|
||||||
|
});
|
||||||
|
|
||||||
// Fetch Requests
|
// Fetch Requests
|
||||||
app.get('/requests/:key', (req, res) => {
|
app.get('/requests/:key', (req, res) => {
|
||||||
let key = req.params.key;
|
let key = req.params.key;
|
||||||
@@ -162,9 +180,9 @@ app.get('/ws_metadata/:key', (req, res) => {
|
|||||||
* private function
|
* private function
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function getJsonFromMap(key, req, res) {
|
function getJsonFromMap(map, key, req, res) {
|
||||||
if (!json_mapping.has(key)) return res.sendStatus(404);
|
if (!map.has(key)) return res.sendStatus(404);
|
||||||
const retData = JSON.parse(json_mapping.get(key));
|
const retData = JSON.parse(map.get(key));
|
||||||
console.log(retData, ` Response to ${req.method} ${req.url}`);
|
console.log(retData, ` Response to ${req.method} ${req.url}`);
|
||||||
addRequestToMap(key, req, hook_mapping);
|
addRequestToMap(key, req, hook_mapping);
|
||||||
return res.json(retData);
|
return res.json(retData);
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ test('basic webhook tests', async(t) => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
const from = 'sip_decline_test_success';
|
const from = 'sip_decline_test_success';
|
||||||
provisionCallHook(from, verbs)
|
await provisionCallHook(from, verbs)
|
||||||
|
|
||||||
await sippUac('uac-expect-603.xml', '172.38.0.10', from);
|
await sippUac('uac-expect-603.xml', '172.38.0.10', from);
|
||||||
t.pass('webhook successfully declines call');
|
t.pass('webhook successfully declines call');
|
||||||
@@ -73,7 +73,7 @@ test('invalid jambonz json create alert tests', async(t) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const from = 'invalid_json_create_alert';
|
const from = 'invalid_json_create_alert';
|
||||||
provisionCallHook(from, verbs)
|
await provisionCallHook(from, verbs)
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
await sippUac('uac-invite-expect-480.xml', '172.38.0.10', from);
|
await sippUac('uac-invite-expect-480.xml', '172.38.0.10', from);
|
||||||
|
|||||||
Reference in New Issue
Block a user