mirror of
https://github.com/jambonz/verb-specifications.git
synced 2026-03-26 13:59:02 +00:00
Compare commits
61 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
067a49bd2c | ||
|
|
4967efa745 | ||
|
|
61669e5574 | ||
|
|
e25ef7349e | ||
|
|
26f5609996 | ||
|
|
1a1436b612 | ||
|
|
ba9a9f9b60 | ||
|
|
93c368e894 | ||
|
|
185e4df06e | ||
|
|
c22e8c9cf0 | ||
|
|
1c3d86c807 | ||
|
|
7e986acc17 | ||
|
|
d5c535c02c | ||
|
|
6e819279d1 | ||
|
|
24e73a4dc6 | ||
|
|
cfd367f185 | ||
|
|
f472de9638 | ||
|
|
45a2a039cd | ||
|
|
4a345633a3 | ||
|
|
f14ff2e319 | ||
|
|
c85cb7e67e | ||
|
|
8ccb13f962 | ||
|
|
044ce2d4bb | ||
|
|
b483e04611 | ||
|
|
c1032638b2 | ||
|
|
72225385ae | ||
|
|
6ad9d2bce0 | ||
|
|
045df8a9fe | ||
|
|
f3ede17b80 | ||
|
|
2551dbe18e | ||
|
|
f4a887a67a | ||
|
|
874abac5e3 | ||
|
|
827ddcebf0 | ||
|
|
98043693be | ||
|
|
436c8e1861 | ||
|
|
21214eb2ce | ||
|
|
017b8cd0c3 | ||
|
|
8ae7419b7a | ||
|
|
11c34aa6fc | ||
|
|
5548a67412 | ||
|
|
8f89bac676 | ||
|
|
146f691890 | ||
|
|
283512e765 | ||
|
|
d7219b990b | ||
|
|
68b3c7de01 | ||
|
|
dff94d3ac5 | ||
|
|
70f7c5ab96 | ||
|
|
403766cd4d | ||
|
|
10c7f60bad | ||
|
|
32f63759db | ||
|
|
825130348b | ||
|
|
f99b94a405 | ||
|
|
6c40dda566 | ||
|
|
899f55a272 | ||
|
|
22a6b30aa3 | ||
|
|
430a702752 | ||
|
|
8dbbe13c5f | ||
|
|
35e140f69e | ||
|
|
0a85aae84f | ||
|
|
590db8aafa | ||
|
|
c996a67dc2 |
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 jambonz
|
||||
Copyright (c) 2023 Drachtio Communications Services, LLC.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
4
index.js
4
index.js
@@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
...require('./jambonz-app-json-validation'),
|
||||
specs: require('./specs')
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
const assert = require('assert');
|
||||
const debug = require('debug')('jambonz:app-json-validation');
|
||||
const _specData = require('./specs');
|
||||
const specs = new Map();
|
||||
for (const key in _specData) { specs.set(key, _specData[key]); }
|
||||
@@ -30,7 +31,7 @@ function normalizeJambones(logger, obj) {
|
||||
throw new Error('malformed jambonz payload: missing verb property');
|
||||
}
|
||||
}
|
||||
logger.debug({ document }, `normalizeJambones: returning document with ${document.length} tasks`);
|
||||
debug({ document }, `normalizeJambones: returning document with ${document.length} tasks`);
|
||||
return document;
|
||||
}
|
||||
|
||||
@@ -44,7 +45,7 @@ function validate(logger, obj) {
|
||||
}
|
||||
|
||||
function validateVerb(name, data, logger) {
|
||||
logger.debug(`validating ${name} with data ${JSON.stringify(data)}`);
|
||||
debug(`validating ${name} with data ${JSON.stringify(data)}`);
|
||||
// validate the instruction is supported
|
||||
if (!specs.has(name)) throw new Error(`invalid instruction: ${name}`);
|
||||
|
||||
@@ -55,7 +56,7 @@ function validateVerb(name, data, logger) {
|
||||
if (dKey in specData.properties) {
|
||||
const dVal = data[dKey];
|
||||
const dSpec = specData.properties[dKey];
|
||||
logger.debug(`Task:validate validating property ${dKey} with value ${JSON.stringify(dVal)}`);
|
||||
debug(`Task:validate validating property ${dKey} with value ${JSON.stringify(dVal)}`);
|
||||
|
||||
if (typeof dSpec === 'string' && dSpec === 'array') {
|
||||
if (!Array.isArray(dVal)) throw new Error(`${name}: property ${dKey} is not an array`);
|
||||
@@ -110,4 +111,4 @@ function validateVerb(name, data, logger) {
|
||||
if (required.length > 0) throw new Error(`${name}: missing value for ${required}`);
|
||||
}
|
||||
|
||||
module.exports = { normalizeJambones, validate };
|
||||
module.exports = { normalizeJambones, validate, validateVerb };
|
||||
|
||||
17
package-lock.json
generated
17
package-lock.json
generated
@@ -1,14 +1,15 @@
|
||||
{
|
||||
"name": "verb-specifications",
|
||||
"version": "0.0.1",
|
||||
"name": "@jambonz/verb-specifications",
|
||||
"version": "0.0.28",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "verb-specifications",
|
||||
"version": "0.0.1",
|
||||
"name": "@jambonz/verb-specifications",
|
||||
"version": "0.0.28",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.3.4",
|
||||
"pino": "^8.8.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -435,7 +436,6 @@
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ms": "2.1.2"
|
||||
},
|
||||
@@ -1671,8 +1671,7 @@
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"node_modules/natural-compare": {
|
||||
"version": "1.4.0",
|
||||
@@ -2771,7 +2770,6 @@
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
}
|
||||
@@ -3671,8 +3669,7 @@
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"natural-compare": {
|
||||
"version": "1.4.0",
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
{
|
||||
"name": "verb-specifications",
|
||||
"version": "0.0.1",
|
||||
"name": "@jambonz/verb-specifications",
|
||||
"version": "0.0.28",
|
||||
"description": "Jambonz Verb Specification Utilities",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "node test/",
|
||||
"jslint": "eslint index.js"
|
||||
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -24,6 +23,7 @@
|
||||
"tape": "^5.6.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": "^4.3.4",
|
||||
"pino": "^8.8.0"
|
||||
}
|
||||
}
|
||||
|
||||
115
specs.json
115
specs.json
@@ -44,7 +44,9 @@
|
||||
"record": "#recordOptions",
|
||||
"listen": "#listenOptions",
|
||||
"amd": "#amd",
|
||||
"notifyEvents": "boolean"
|
||||
"notifyEvents": "boolean",
|
||||
"reset": "string|array",
|
||||
"onHoldMusic": "string"
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
@@ -88,7 +90,8 @@
|
||||
"name": "string",
|
||||
"actionHook": "object|string",
|
||||
"timeout": "number",
|
||||
"beep": "boolean"
|
||||
"beep": "boolean",
|
||||
"callSid": "string"
|
||||
},
|
||||
"required": [
|
||||
"name"
|
||||
@@ -100,6 +103,7 @@
|
||||
"name": "string",
|
||||
"actionHook": "object|string",
|
||||
"waitHook": "object|string",
|
||||
"priority": "number",
|
||||
"_": "object"
|
||||
},
|
||||
"required": [
|
||||
@@ -194,14 +198,17 @@
|
||||
"properties": {
|
||||
"id": "string",
|
||||
"actionHook": "object|string",
|
||||
"onHoldHook": "object|string",
|
||||
"answerOnBridge": "boolean",
|
||||
"callerId": "string",
|
||||
"callerName": "string",
|
||||
"confirmHook": "object|string",
|
||||
"referHook": "object|string",
|
||||
"dialMusic": "string",
|
||||
"dtmfCapture": "object",
|
||||
"dtmfHook": "object|string",
|
||||
"headers": "object",
|
||||
"anchorMedia": "boolean",
|
||||
"listen": "#listen",
|
||||
"target": ["#target"],
|
||||
"timeLimit": "number",
|
||||
@@ -359,7 +366,8 @@
|
||||
"enum": ["startCallRecording", "stopCallRecording", "pauseCallRecording", "resumeCallRecording"]
|
||||
},
|
||||
"recordingID": "string",
|
||||
"siprecServerURL": "string"
|
||||
"siprecServerURL": "string|array",
|
||||
"headers": "object"
|
||||
},
|
||||
"required": [
|
||||
"action"
|
||||
@@ -382,6 +390,7 @@
|
||||
"call_hook": "object|string",
|
||||
"call_status_hook": "object|string",
|
||||
"from": "string",
|
||||
"callerName": "string",
|
||||
"fromHost": "string",
|
||||
"speech_synthesis_vendor": "string",
|
||||
"speech_synthesis_voice": "string",
|
||||
@@ -391,7 +400,8 @@
|
||||
"tag": "object",
|
||||
"to": "#target",
|
||||
"headers": "object",
|
||||
"timeout": "number"
|
||||
"timeout": "number",
|
||||
"amd": "#amd"
|
||||
},
|
||||
"required": [
|
||||
"call_hook",
|
||||
@@ -416,7 +426,7 @@
|
||||
"earlyMedia": "boolean"
|
||||
},
|
||||
"required": [
|
||||
"recognizer"
|
||||
"transcriptionHook"
|
||||
]
|
||||
},
|
||||
"target": {
|
||||
@@ -465,10 +475,8 @@
|
||||
},
|
||||
"synthesizer": {
|
||||
"properties": {
|
||||
"vendor": {
|
||||
"type": "string",
|
||||
"enum": ["google", "aws", "polly", "microsoft", "nuance", "ibm", "default"]
|
||||
},
|
||||
"vendor": "string",
|
||||
"label": "string",
|
||||
"language": "string",
|
||||
"voice": "string",
|
||||
"engine": {
|
||||
@@ -478,7 +486,8 @@
|
||||
"gender": {
|
||||
"type": "string",
|
||||
"enum": ["MALE", "FEMALE", "NEUTRAL"]
|
||||
}
|
||||
},
|
||||
"options": "object"
|
||||
},
|
||||
"required": [
|
||||
"vendor"
|
||||
@@ -486,10 +495,8 @@
|
||||
},
|
||||
"recognizer": {
|
||||
"properties": {
|
||||
"vendor": {
|
||||
"type": "string",
|
||||
"enum": ["google", "aws", "microsoft", "nuance", "deepgram", "ibm", "default"]
|
||||
},
|
||||
"vendor": "string",
|
||||
"label": "string",
|
||||
"language": "string",
|
||||
"vad": "#vad",
|
||||
"hints": "array",
|
||||
@@ -555,12 +562,37 @@
|
||||
"asrTimeout": "number",
|
||||
"nuanceOptions": "#nuanceOptions",
|
||||
"deepgramOptions": "#deepgramOptions",
|
||||
"ibmOptions": "#ibmOptions"
|
||||
"ibmOptions": "#ibmOptions",
|
||||
"nvidiaOptions": "#nvidiaOptions",
|
||||
"sonioxOptions": "#sonioxOptions",
|
||||
"customOptions": "#customOptions"
|
||||
},
|
||||
"required": [
|
||||
"vendor"
|
||||
]
|
||||
},
|
||||
"customOptions": {
|
||||
"properties": {
|
||||
"authToken": "string",
|
||||
"uri": "string",
|
||||
"options": "object"
|
||||
},
|
||||
"required": [
|
||||
]
|
||||
},
|
||||
"nvidiaOptions": {
|
||||
"properties": {
|
||||
"rivaUri": "string",
|
||||
"maxAlternatives": "number",
|
||||
"profanityFilter": "boolean",
|
||||
"punctuation": "boolean",
|
||||
"wordTimeOffsets": "boolean",
|
||||
"verbatimTranscripts": "boolean",
|
||||
"customConfiguration": "object"
|
||||
},
|
||||
"required": [
|
||||
]
|
||||
},
|
||||
"ibmOptions": {
|
||||
"properties": {
|
||||
"sttApiKey": "string",
|
||||
@@ -581,26 +613,8 @@
|
||||
"deepgramOptions": {
|
||||
"properties": {
|
||||
"apiKey": "string",
|
||||
"tier": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"enhanced",
|
||||
"base"
|
||||
]
|
||||
},
|
||||
"model": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"general",
|
||||
"meeting",
|
||||
"phonecall",
|
||||
"voicemail",
|
||||
"finance",
|
||||
"conversationalai",
|
||||
"video",
|
||||
"custom"
|
||||
]
|
||||
},
|
||||
"tier": "string",
|
||||
"model": "string",
|
||||
"customModel": "string",
|
||||
"version": "string",
|
||||
"punctuate": "boolean",
|
||||
@@ -623,11 +637,36 @@
|
||||
"search": "array",
|
||||
"replace": "array",
|
||||
"keywords": "array",
|
||||
"endpointing": "boolean",
|
||||
"endpointing": "boolean | number",
|
||||
"vadTurnoff": "number",
|
||||
"tag": "string"
|
||||
}
|
||||
},
|
||||
"sonioxOptions": {
|
||||
"properties": {
|
||||
"apiKey": "string",
|
||||
"model": "string",
|
||||
"endpointDetection": "boolean",
|
||||
"profanityFilter": "boolean",
|
||||
"speechContext": "string",
|
||||
"clientRequestReference": "string",
|
||||
"storage": "#sonioxStorage"
|
||||
},
|
||||
"required": [
|
||||
]
|
||||
},
|
||||
"sonioxStorage": {
|
||||
"properties": {
|
||||
"id": "string",
|
||||
"title": "string",
|
||||
"disableStoreAudio": "boolean",
|
||||
"disableStoreTranscript": "boolean",
|
||||
"disableSearch": "boolean",
|
||||
"metadata": "object"
|
||||
},
|
||||
"required": [
|
||||
]
|
||||
},
|
||||
"nuanceOptions": {
|
||||
"properties": {
|
||||
"clientId": "string",
|
||||
@@ -679,7 +718,7 @@
|
||||
"inlineWordset": "string",
|
||||
"builtin": "string",
|
||||
"inlineGrammar": "string",
|
||||
"wakeupWord": "[string]",
|
||||
"wakeupWord": "array",
|
||||
"weightName": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
@@ -774,4 +813,4 @@
|
||||
"greetingCompletionTimeoutMs": "number"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
const test = require('tape');
|
||||
const logger = require('pino')({level: process.env.JAMBONES_LOGLEVEL || 'error'});
|
||||
const { validate } = require('../jambonz-app-json-validation');
|
||||
const { validate } = require('..');
|
||||
|
||||
test("validate correct verbs", async (t) => {
|
||||
|
||||
@@ -24,28 +24,52 @@ test("validate correct verbs", async (t) => {
|
||||
"verb": "config",
|
||||
"synthesizer": {
|
||||
"voice": "Jenny",
|
||||
"vendor": "google"
|
||||
"vendor": "google",
|
||||
"label": "label1"
|
||||
},
|
||||
"recognizer": {
|
||||
"vendor": "google",
|
||||
"language": "de-DE"
|
||||
"language": "de-DE",
|
||||
"label": "label1"
|
||||
},
|
||||
"bargeIn": {
|
||||
"enable": true,
|
||||
"input" : ["speech"],
|
||||
"actionHook": "/userInput"
|
||||
},
|
||||
"onHoldMusic": "http://server.com/hold"
|
||||
},
|
||||
{
|
||||
"verb": "config",
|
||||
"record": {
|
||||
"action": "startCallRecording",
|
||||
"siprecServerURL": ["sip:srs@recording.example.com","sip:srs@recording.example.com"],
|
||||
"headers" : {
|
||||
"X-Header1": "Value1",
|
||||
"X-Header2": "Value2"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"verb": "config",
|
||||
"record": {
|
||||
"action": "startCallRecording",
|
||||
"siprecServerURL": "sip:srs@recording.example.com"
|
||||
}
|
||||
},
|
||||
{
|
||||
"verb": "dequeue",
|
||||
"name": "support",
|
||||
"beep": true,
|
||||
"timeout": 60
|
||||
"timeout": 60,
|
||||
"callSid": "call_sid1234"
|
||||
},
|
||||
{
|
||||
"verb": "dial",
|
||||
"actionHook": "/outdial",
|
||||
"onHoldHook": "/onHoldHook",
|
||||
"callerId": "+16173331212",
|
||||
"callerName": "Tom",
|
||||
"answerOnBridge": true,
|
||||
"dtmfCapture": ["*2", "*3"],
|
||||
"dtmfHook": {
|
||||
@@ -94,7 +118,8 @@ test("validate correct verbs", async (t) => {
|
||||
"verb": "enqueue",
|
||||
"name": "support",
|
||||
"actionHook": "/queue-action",
|
||||
"waitHook": "/queue-wait"
|
||||
"waitHook": "/queue-wait",
|
||||
"priority": 50
|
||||
},
|
||||
{
|
||||
"verb": "gather",
|
||||
@@ -109,16 +134,39 @@ test("validate correct verbs", async (t) => {
|
||||
"vendor": "google",
|
||||
"language": "en-US",
|
||||
"hints": ["sales", "support"],
|
||||
"hintsBoost": 10
|
||||
"hintsBoost": 10,
|
||||
"deepgramOptions": {
|
||||
"endpointing": 500
|
||||
}
|
||||
},
|
||||
"say": {
|
||||
"text": "To speak to Sales press 1 or say Sales. To speak to customer support press 2 or say Support",
|
||||
"synthesizer": {
|
||||
"vendor": "google",
|
||||
"language": "en-US"
|
||||
"language": "en-US",
|
||||
"label": "label1"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"verb": "gather",
|
||||
"actionHook": "http://example.com/collect",
|
||||
"input": ["digits", "speech"],
|
||||
"bargein": true,
|
||||
"dtmfBargein": true,
|
||||
"finishOnKey": "#",
|
||||
"numDigits": 5,
|
||||
"timeout": 8,
|
||||
"recognizer": {
|
||||
"vendor": "google",
|
||||
"language": "en-US",
|
||||
"hints": ["sales", "support"],
|
||||
"hintsBoost": 10,
|
||||
"deepgramOptions": {
|
||||
"endpointing": true
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
"verb": "hangup",
|
||||
"headers": {
|
||||
@@ -231,10 +279,33 @@ test("validate correct verbs", async (t) => {
|
||||
"verb": "transcribe",
|
||||
"transcriptionHook": "http://example.com/transcribe",
|
||||
"recognizer": {
|
||||
"vendor": "google",
|
||||
"vendor": "nvidia",
|
||||
"language" : "en-US",
|
||||
"interim": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"verb": "rest:dial",
|
||||
"account_sid": "1291964182631236912836123912",
|
||||
"call_hook": {
|
||||
"url": "http://127.0.0.1:3100/",
|
||||
"method": "POST",
|
||||
"username": "username",
|
||||
"password": "password",
|
||||
},
|
||||
"from": "15583084810",
|
||||
"to": {
|
||||
"type": "phone",
|
||||
"number": "15583084809",
|
||||
},
|
||||
"tag": {
|
||||
"customer": "acme",
|
||||
"referenceId": "deadbeef",
|
||||
},
|
||||
"amd": {
|
||||
"actionHook": "/answeringMachineDetection",
|
||||
|
||||
}
|
||||
}
|
||||
];
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user