mirror of
https://github.com/jambonz/jambonz-echo-test.git
synced 2025-12-19 05:17:49 +00:00
initial checkin
This commit is contained in:
1
.eslintignore
Normal file
1
.eslintignore
Normal file
@@ -0,0 +1 @@
|
||||
test/*
|
||||
126
.eslintrc.json
Normal file
126
.eslintrc.json
Normal file
@@ -0,0 +1,126 @@
|
||||
{
|
||||
"env": {
|
||||
"node": true,
|
||||
"es6": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaFeatures": {
|
||||
"jsx": false,
|
||||
"modules": false
|
||||
},
|
||||
"ecmaVersion": 2020
|
||||
},
|
||||
"plugins": ["promise"],
|
||||
"rules": {
|
||||
"promise/always-return": "error",
|
||||
"promise/no-return-wrap": "error",
|
||||
"promise/param-names": "error",
|
||||
"promise/catch-or-return": "error",
|
||||
"promise/no-native": "off",
|
||||
"promise/no-nesting": "warn",
|
||||
"promise/no-promise-in-callback": "warn",
|
||||
"promise/no-callback-in-promise": "warn",
|
||||
"promise/no-return-in-finally": "warn",
|
||||
|
||||
// Possible Errors
|
||||
// http://eslint.org/docs/rules/#possible-errors
|
||||
"comma-dangle": [2, "only-multiline"],
|
||||
"no-control-regex": 2,
|
||||
"no-debugger": 2,
|
||||
"no-dupe-args": 2,
|
||||
"no-dupe-keys": 2,
|
||||
"no-duplicate-case": 2,
|
||||
"no-empty-character-class": 2,
|
||||
"no-ex-assign": 2,
|
||||
"no-extra-boolean-cast" : 2,
|
||||
"no-extra-parens": [2, "functions"],
|
||||
"no-extra-semi": 2,
|
||||
"no-func-assign": 2,
|
||||
"no-invalid-regexp": 2,
|
||||
"no-irregular-whitespace": 2,
|
||||
"no-negated-in-lhs": 2,
|
||||
"no-obj-calls": 2,
|
||||
"no-proto": 2,
|
||||
"no-unexpected-multiline": 2,
|
||||
"no-unreachable": 2,
|
||||
"use-isnan": 2,
|
||||
"valid-typeof": 2,
|
||||
|
||||
// Best Practices
|
||||
// http://eslint.org/docs/rules/#best-practices
|
||||
"no-fallthrough": 2,
|
||||
"no-octal": 2,
|
||||
"no-redeclare": 2,
|
||||
"no-self-assign": 2,
|
||||
"no-unused-labels": 2,
|
||||
|
||||
// Strict Mode
|
||||
// http://eslint.org/docs/rules/#strict-mode
|
||||
"strict": [2, "never"],
|
||||
|
||||
// Variables
|
||||
// http://eslint.org/docs/rules/#variables
|
||||
"no-delete-var": 2,
|
||||
"no-undef": 2,
|
||||
"no-unused-vars": [2, {"args": "none"}],
|
||||
|
||||
// Node.js and CommonJS
|
||||
// http://eslint.org/docs/rules/#nodejs-and-commonjs
|
||||
"no-mixed-requires": 2,
|
||||
"no-new-require": 2,
|
||||
"no-path-concat": 2,
|
||||
"no-restricted-modules": [2, "sys", "_linklist"],
|
||||
|
||||
// Stylistic Issues
|
||||
// http://eslint.org/docs/rules/#stylistic-issues
|
||||
"comma-spacing": 2,
|
||||
"eol-last": 2,
|
||||
"indent": [2, 2, {"SwitchCase": 1}],
|
||||
"keyword-spacing": 2,
|
||||
"max-len": [2, 120, 2],
|
||||
"new-parens": 2,
|
||||
"no-mixed-spaces-and-tabs": 2,
|
||||
"no-multiple-empty-lines": [2, {"max": 2}],
|
||||
"no-trailing-spaces": [2, {"skipBlankLines": false }],
|
||||
"quotes": [2, "single", "avoid-escape"],
|
||||
"semi": 2,
|
||||
"space-before-blocks": [2, "always"],
|
||||
"space-before-function-paren": [2, "never"],
|
||||
"space-in-parens": [2, "never"],
|
||||
"space-infix-ops": 2,
|
||||
"space-unary-ops": 2,
|
||||
|
||||
// ECMAScript 6
|
||||
// http://eslint.org/docs/rules/#ecmascript-6
|
||||
"arrow-parens": [2, "always"],
|
||||
"arrow-spacing": [2, {"before": true, "after": true}],
|
||||
"constructor-super": 2,
|
||||
"no-class-assign": 2,
|
||||
"no-confusing-arrow": 2,
|
||||
"no-const-assign": 2,
|
||||
"no-dupe-class-members": 2,
|
||||
"no-new-symbol": 2,
|
||||
"no-this-before-super": 2,
|
||||
"prefer-const": 2
|
||||
},
|
||||
"globals": {
|
||||
"DTRACE_HTTP_CLIENT_REQUEST" : false,
|
||||
"LTTNG_HTTP_CLIENT_REQUEST" : false,
|
||||
"COUNTER_HTTP_CLIENT_REQUEST" : false,
|
||||
"DTRACE_HTTP_CLIENT_RESPONSE" : false,
|
||||
"LTTNG_HTTP_CLIENT_RESPONSE" : false,
|
||||
"COUNTER_HTTP_CLIENT_RESPONSE" : false,
|
||||
"DTRACE_HTTP_SERVER_REQUEST" : false,
|
||||
"LTTNG_HTTP_SERVER_REQUEST" : false,
|
||||
"COUNTER_HTTP_SERVER_REQUEST" : false,
|
||||
"DTRACE_HTTP_SERVER_RESPONSE" : false,
|
||||
"LTTNG_HTTP_SERVER_RESPONSE" : false,
|
||||
"COUNTER_HTTP_SERVER_RESPONSE" : false,
|
||||
"DTRACE_NET_STREAM_END" : false,
|
||||
"LTTNG_NET_STREAM_END" : false,
|
||||
"COUNTER_NET_SERVER_CONNECTION_CLOSE" : false,
|
||||
"DTRACE_NET_SERVER_CONNECTION" : false,
|
||||
"LTTNG_NET_SERVER_CONNECTION" : false,
|
||||
"COUNTER_NET_SERVER_CONNECTION" : false
|
||||
}
|
||||
}
|
||||
41
.gitignore
vendored
Normal file
41
.gitignore
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
data/*
|
||||
.env
|
||||
ecosystem.config.js
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
|
||||
# github pages site
|
||||
_site
|
||||
|
||||
#transient test cases
|
||||
examples/nosave.*.js
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
.nyc_output/
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directory
|
||||
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
|
||||
node_modules
|
||||
|
||||
.DS_Store
|
||||
|
||||
examples/*
|
||||
13
README.md
Normal file
13
README.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# jambonz-echo-test
|
||||
|
||||
This application was created with the [create-jambonz-ws-api](https://www.npmjs.com/package/create-jambonz-ws-app) command. This documentation was generated at the time when the project was generated and describes the functionality that was initially scaffolded. Of course, you should feel free to modify or replace this documentation as you build out your own logic.
|
||||
|
||||
## Services
|
||||
|
||||
Based on the options that you have chosen, this application exposes the following services over a websocket interface:
|
||||
|
||||
|
||||
### /echo
|
||||
A application that prompts the caller for speech, transcribes it and speaks it back along with the recognized confidence factor.
|
||||
|
||||
|
||||
12
app.js
Normal file
12
app.js
Normal file
@@ -0,0 +1,12 @@
|
||||
const {createServer} = require('http');
|
||||
const {createEndpoint} = require('@jambonz/node-client-ws');
|
||||
const server = createServer();
|
||||
const makeService = createEndpoint({server});
|
||||
const logger = require('pino')({level: process.env.LOGLEVEL || 'info'});
|
||||
const port = process.env.WS_PORT || 3000;
|
||||
|
||||
require('./lib/routes')({logger, makeService});
|
||||
|
||||
server.listen(port, () => {
|
||||
logger.info(`jambonz websocket server listening at http://localhost:${port}`);
|
||||
});
|
||||
104
lib/routes/echo.js
Normal file
104
lib/routes/echo.js
Normal file
@@ -0,0 +1,104 @@
|
||||
const service = ({logger, makeService}) => {
|
||||
const svc = makeService({path: '/echo'});
|
||||
|
||||
svc.on('session:new', (session) => {
|
||||
session.locals = {logger: logger.child({call_sid: session.call_sid})};
|
||||
logger.info({session}, `new incoming call: ${session.call_sid}`);
|
||||
|
||||
session
|
||||
.on('close', onClose.bind(null, session))
|
||||
.on('error', onError.bind(null, session))
|
||||
.on('/interimTranscript', onInterim.bind(null, session))
|
||||
.on('/echo', onSpeechEvent.bind(null, session));
|
||||
|
||||
session
|
||||
.pause({length: 1.5})
|
||||
.gather({
|
||||
say: {text: 'Please say something and we will echo it back to you.'},
|
||||
input: ['speech'],
|
||||
actionHook: '/echo',
|
||||
partialResultHook: '/interimTranscript',
|
||||
timeout: 15,
|
||||
recognizer: {
|
||||
vendor: 'nuance',
|
||||
language: 'en-US',
|
||||
nuanceOptions: {
|
||||
kryptonEndpoint: '34.199.234.49:7021'
|
||||
}
|
||||
}
|
||||
})
|
||||
.send();
|
||||
});
|
||||
};
|
||||
|
||||
const onSpeechEvent = async(session, evt) => {
|
||||
const {logger} = session.locals;
|
||||
logger.info(`got speech evt: ${JSON.stringify(evt)}`);
|
||||
|
||||
switch (evt.reason) {
|
||||
case 'speechDetected':
|
||||
echoSpeech(session, evt);
|
||||
break;
|
||||
case 'timeout':
|
||||
reprompt(session);
|
||||
break;
|
||||
default:
|
||||
session.reply();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const echoSpeech = async(session, evt) => {
|
||||
const {transcript, confidence} = evt.speech.alternatives[0];
|
||||
|
||||
session
|
||||
.say({text: `You said: ${transcript}. The confident score was ${confidence.toFixed(2)}`})
|
||||
.gather({
|
||||
say: {text: 'Say something else.'},
|
||||
input: ['speech'],
|
||||
actionHook: '/echo',
|
||||
recognizer: {
|
||||
vendor: 'nuance',
|
||||
language: 'en-US',
|
||||
nuanceOptions: {
|
||||
kryptonEndpoint: '34.199.234.49:7021'
|
||||
}
|
||||
}
|
||||
})
|
||||
.reply();
|
||||
};
|
||||
|
||||
const reprompt = async(session, evt) => {
|
||||
session
|
||||
.gather({
|
||||
say: {text: 'Are you still there? I didn\'t hear anything.'},
|
||||
input: ['speech'],
|
||||
actionHook: '/echo',
|
||||
recognizer: {
|
||||
vendor: 'nuance',
|
||||
language: 'en-US',
|
||||
nuanceOptions: {
|
||||
kryptonEndpoint: '34.199.234.49:7021'
|
||||
}
|
||||
}
|
||||
})
|
||||
.reply();
|
||||
};
|
||||
|
||||
const onInterim = async(session, evt) => {
|
||||
const {logger} = session.locals;
|
||||
logger.info(`got interim transcript: ${JSON.stringify(evt)}`);
|
||||
session.reply();
|
||||
};
|
||||
|
||||
const onClose = (session, code, reason) => {
|
||||
const {logger} = session.locals;
|
||||
logger.info({session, code, reason}, `session ${session.call_sid} closed`);
|
||||
};
|
||||
|
||||
const onError = (session, err) => {
|
||||
const {logger} = session.locals;
|
||||
logger.info({err}, `session ${session.call_sid} received error`);
|
||||
};
|
||||
|
||||
module.exports = service;
|
||||
4
lib/routes/index.js
Normal file
4
lib/routes/index.js
Normal file
@@ -0,0 +1,4 @@
|
||||
module.exports = ({logger, makeService}) => {
|
||||
require('./echo')({logger, makeService});
|
||||
};
|
||||
|
||||
2392
package-lock.json
generated
Normal file
2392
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
20
package.json
Normal file
20
package.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "jambonz-echo-test",
|
||||
"version": "0.0.1",
|
||||
"description": "jambonz websocket application",
|
||||
"main": "app.js",
|
||||
"scripts": {
|
||||
"start": "node app",
|
||||
"jslint": "eslint app.js lib"
|
||||
},
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jambonz/node-client-ws": "^0.1.11",
|
||||
"pino": "^8.11.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.35.0",
|
||||
"eslint-plugin-promise": "^6.1.1"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user