mirror of
https://github.com/jambonz/jambonz-api-server.git
synced 2026-01-25 02:08:24 +00:00
Compare commits
29 Commits
subspace
...
v0.7.2-rc5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
75e7c1058b | ||
|
|
a5e4fafda4 | ||
|
|
2e041df6e4 | ||
|
|
3ee82d6c8c | ||
|
|
d396c5b252 | ||
|
|
daef0ee215 | ||
|
|
1d168e93e1 | ||
|
|
605a0e762f | ||
|
|
c9bf943656 | ||
|
|
3aac11560a | ||
|
|
bb4a20a375 | ||
|
|
45c4c626f2 | ||
|
|
65e6d75f72 | ||
|
|
c6bb273aa0 | ||
|
|
256b295be1 | ||
|
|
693ba51339 | ||
|
|
531366ee58 | ||
|
|
a36604029c | ||
|
|
63a88844aa | ||
|
|
24f6833493 | ||
|
|
4119d766d5 | ||
|
|
936a9da887 | ||
|
|
77098f273d | ||
|
|
e27b5a39a6 | ||
|
|
66872494f9 | ||
|
|
4557b32804 | ||
|
|
e55fe77171 | ||
|
|
0fd87a732f | ||
|
|
f6d358d3df |
51
.github/workflows/docker-publish-dbcreate.yml
vendored
Normal file
51
.github/workflows/docker-publish-dbcreate.yml
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
name: Docker
|
||||
|
||||
on:
|
||||
push:
|
||||
# Publish `main` as Docker `latest` image.
|
||||
branches:
|
||||
- main
|
||||
|
||||
# Publish `v1.2.3` tags as releases.
|
||||
tags:
|
||||
- v*
|
||||
|
||||
env:
|
||||
IMAGE_NAME: db-create
|
||||
|
||||
jobs:
|
||||
push:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'push'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Build image
|
||||
run: docker build . --file Dockerfile.db-create --tag $IMAGE_NAME
|
||||
|
||||
- name: Log into registry
|
||||
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
|
||||
|
||||
- name: Push image
|
||||
run: |
|
||||
IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME
|
||||
|
||||
# Change all uppercase to lowercase
|
||||
IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]')
|
||||
|
||||
# Strip git ref prefix from version
|
||||
VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
|
||||
|
||||
# Strip "v" prefix from tag name
|
||||
[[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
|
||||
|
||||
# Use Docker `latest` tag convention
|
||||
[ "$VERSION" == "main" ] && VERSION=latest
|
||||
|
||||
echo IMAGE_ID=$IMAGE_ID
|
||||
echo VERSION=$VERSION
|
||||
|
||||
docker tag $IMAGE_NAME $IMAGE_ID:$VERSION
|
||||
docker push $IMAGE_ID:$VERSION
|
||||
51
.github/workflows/docker-publish.yml
vendored
Normal file
51
.github/workflows/docker-publish.yml
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
name: Docker
|
||||
|
||||
on:
|
||||
push:
|
||||
# Publish `main` as Docker `latest` image.
|
||||
branches:
|
||||
- main
|
||||
|
||||
# Publish `v1.2.3` tags as releases.
|
||||
tags:
|
||||
- v*
|
||||
|
||||
env:
|
||||
IMAGE_NAME: api-server
|
||||
|
||||
jobs:
|
||||
push:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'push'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Build image
|
||||
run: docker build . --file Dockerfile --tag $IMAGE_NAME
|
||||
|
||||
- name: Log into registry
|
||||
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
|
||||
|
||||
- name: Push image
|
||||
run: |
|
||||
IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME
|
||||
|
||||
# Change all uppercase to lowercase
|
||||
IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]')
|
||||
|
||||
# Strip git ref prefix from version
|
||||
VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
|
||||
|
||||
# Strip "v" prefix from tag name
|
||||
[[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
|
||||
|
||||
# Use Docker `latest` tag convention
|
||||
[ "$VERSION" == "main" ] && VERSION=latest
|
||||
|
||||
echo IMAGE_ID=$IMAGE_ID
|
||||
echo VERSION=$VERSION
|
||||
|
||||
docker tag $IMAGE_NAME $IMAGE_ID:$VERSION
|
||||
docker push $IMAGE_ID:$VERSION
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,7 +1,6 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
package-lock.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:16
|
||||
FROM node:17
|
||||
WORKDIR /opt/app/
|
||||
COPY package.json ./
|
||||
RUN npm install
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:16
|
||||
FROM node:17
|
||||
WORKDIR /opt/app/
|
||||
COPY package.json ./
|
||||
RUN npm install
|
||||
|
||||
@@ -385,7 +385,7 @@ router.post('/:sid/SubspaceTeleport', async(req, res) => {
|
||||
const teleport = await enableSubspace({
|
||||
subspace_client_id,
|
||||
subspace_client_secret,
|
||||
destination: `sip:${dest}`
|
||||
destination: dest
|
||||
});
|
||||
logger.info({destination, teleport}, 'SubspaceTeleport - create teleport');
|
||||
await Account.update(req.params.sid, {
|
||||
|
||||
@@ -10,7 +10,8 @@ const {
|
||||
testAwsTts,
|
||||
testAwsStt,
|
||||
testMicrosoftStt,
|
||||
testMicrosoftTts
|
||||
testMicrosoftTts,
|
||||
testWellSaidTts
|
||||
} = require('../../utils/speech-utils');
|
||||
|
||||
router.post('/', async(req, res) => {
|
||||
@@ -66,6 +67,12 @@ router.post('/', async(req, res) => {
|
||||
});
|
||||
encrypted_credential = encrypt(data);
|
||||
}
|
||||
else if (vendor === 'wellsaid') {
|
||||
const data = JSON.stringify({
|
||||
api_key
|
||||
});
|
||||
encrypted_credential = encrypt(data);
|
||||
}
|
||||
else throw new DbErrorBadRequest(`invalid speech vendor ${vendor}`);
|
||||
const uuid = await SpeechCredential.make({
|
||||
account_sid,
|
||||
@@ -109,6 +116,10 @@ router.get('/', async(req, res) => {
|
||||
obj.api_key = o.api_key;
|
||||
obj.region = o.region;
|
||||
}
|
||||
else if ('wellsaid' === obj.vendor) {
|
||||
const o = decrypt(credential);
|
||||
obj.api_key = o.api_key;
|
||||
}
|
||||
return obj;
|
||||
}));
|
||||
} catch (err) {
|
||||
@@ -291,6 +302,19 @@ router.get('/:sid/test', async(req, res) => {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (cred.vendor === 'wellsaid') {
|
||||
const {api_key} = credential;
|
||||
if (cred.use_for_tts) {
|
||||
try {
|
||||
await testWellSaidTts(logger, {api_key});
|
||||
results.tts.status = 'ok';
|
||||
SpeechCredential.ttsTestResult(sid, true);
|
||||
} catch (err) {
|
||||
results.tts = {status: 'fail', reason: err.message};
|
||||
SpeechCredential.ttsTestResult(sid, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
res.status(200).json(results);
|
||||
} catch (err) {
|
||||
sysError(logger, res, err);
|
||||
|
||||
@@ -247,8 +247,9 @@ const enableSubspace = async(opts) => {
|
||||
|
||||
const teleport = await postTeleport('/v1/sipteleport',
|
||||
{
|
||||
name: 'Jambonz',
|
||||
destination,
|
||||
name: 'Jambonz'
|
||||
status: 'ENABLED'
|
||||
},
|
||||
{
|
||||
'Content-Type': 'application/json',
|
||||
|
||||
@@ -75,11 +75,37 @@ const testMicrosoftStt = async(logger, credentials) => {
|
||||
return true;
|
||||
};
|
||||
|
||||
const testWellSaidTts = async(logger, credentials) => {
|
||||
const {api_key} = credentials;
|
||||
try {
|
||||
const post = bent('https://api.wellsaidlabs.com', 'POST', 'buffer', {
|
||||
'X-Api-Key': api_key,
|
||||
'Accept': 'audio/mpeg',
|
||||
'Content-Type': 'application/json'
|
||||
});
|
||||
const mp3 = await post('/v1/tts/stream', {
|
||||
text: 'Hello, world',
|
||||
speaker_id: '3'
|
||||
});
|
||||
return mp3;
|
||||
} catch (err) {
|
||||
logger.info({err}, 'testWellSaidTts returned error');
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
const testWellSaidStt = async(logger, credentials) => {
|
||||
//TODO
|
||||
return true;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
testGoogleTts,
|
||||
testGoogleStt,
|
||||
testAwsTts,
|
||||
testWellSaidTts,
|
||||
testAwsStt,
|
||||
testMicrosoftTts,
|
||||
testMicrosoftStt
|
||||
testMicrosoftStt,
|
||||
testWellSaidStt,
|
||||
};
|
||||
|
||||
10660
package-lock.json
generated
Normal file
10660
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
32
package.json
32
package.json
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "jambonz-api-server",
|
||||
"version": "v0.6.7-rc8",
|
||||
"version": "v0.7.1",
|
||||
"description": "",
|
||||
"main": "app.js",
|
||||
"scripts": {
|
||||
"start": "node app.js",
|
||||
"test": "NODE_ENV=test APPLY_JAMBONZ_DB_LIMITS=1 JWT_SECRET=foobarbazzle JAMBONES_MYSQL_HOST=127.0.0.1 JAMBONES_MYSQL_PORT=3360 JAMBONES_MYSQL_USER=jambones_test JAMBONES_MYSQL_PASSWORD=jambones_test JAMBONES_MYSQL_DATABASE=jambones_test JAMBONES_REDIS_HOST=localhost JAMBONES_REDIS_PORT=16379 JAMBONES_TIME_SERIES_HOST=127.0.0.1 JAMBONES_LOGLEVEL=error JAMBONES_CREATE_CALL_URL=http://localhost/v1/createCall node test/ ",
|
||||
"test": "NODE_ENV=test APPLY_JAMBONZ_DB_LIMITS=1 JWT_SECRET=foobarbazzle JAMBONES_MYSQL_HOST=127.0.0.1 JAMBONES_MYSQL_PORT=3360 JAMBONES_MYSQL_USER=jambones_test JAMBONES_MYSQL_PASSWORD=jambones_test JAMBONES_MYSQL_DATABASE=jambones_test JAMBONES_REDIS_HOST=localhost JAMBONES_REDIS_PORT=16379 JAMBONES_TIME_SERIES_HOST=127.0.0.1 JAMBONES_LOGLEVEL=info JAMBONES_CREATE_CALL_URL=http://localhost/v1/createCall node test/ ",
|
||||
"integration-test": "NODE_ENV=test JAMBONES_TIME_SERIES_HOST=127.0.0.1 AWS_REGION='us-east-1' JAMBONES_CURRENCY=USD JWT_SECRET=foobarbazzle JAMBONES_MYSQL_HOST=127.0.0.1 JAMBONES_MYSQL_PORT=3360 JAMBONES_MYSQL_USER=jambones_test JAMBONES_MYSQL_PASSWORD=jambones_test JAMBONES_MYSQL_DATABASE=jambones_test JAMBONES_REDIS_HOST=localhost JAMBONES_REDIS_PORT=16379 JAMBONES_LOGLEVEL=debug JAMBONES_CREATE_CALL_URL=http://localhost/v1/createCall node test/serve-integration.js",
|
||||
"upgrade-db": "node ./db/upgrade-jambonz-db.js",
|
||||
"coverage": "./node_modules/.bin/nyc --reporter html --report-dir ./coverage npm run test",
|
||||
@@ -17,30 +17,30 @@
|
||||
"url": "https://github.com/jambonz/jambonz-api-server.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"@google-cloud/speech": "^4.2.0",
|
||||
"@google-cloud/text-to-speech": "^3.1.3",
|
||||
"@jambonz/db-helpers": "^0.6.12",
|
||||
"@jambonz/realtimedb-helpers": "^0.4.3",
|
||||
"@jambonz/time-series": "^0.1.5",
|
||||
"@google-cloud/speech": "^4.9.0",
|
||||
"@google-cloud/text-to-speech": "^3.4.0",
|
||||
"@jambonz/db-helpers": "^0.6.16",
|
||||
"@jambonz/realtimedb-helpers": "^0.4.17",
|
||||
"@jambonz/time-series": "^0.1.6",
|
||||
"argon2-ffi": "^2.0.0",
|
||||
"aws-sdk": "^2.839.0",
|
||||
"aws-sdk": "^2.1049.0",
|
||||
"bent": "^7.3.12",
|
||||
"cors": "^2.8.5",
|
||||
"debug": "^4.3.1",
|
||||
"debug": "^4.3.3",
|
||||
"express": "^4.17.1",
|
||||
"form-data": "^2.3.3",
|
||||
"form-urlencoded": "^6.0.4",
|
||||
"form-data": "^2.5.1",
|
||||
"form-urlencoded": "^6.0.5",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"mailgun.js": "^3.3.0",
|
||||
"mailgun.js": "^3.7.3",
|
||||
"microsoft-cognitiveservices-speech-sdk": "^1.19.0",
|
||||
"mysql2": "^2.2.5",
|
||||
"passport": "^0.5.0",
|
||||
"mysql2": "^2.3.3",
|
||||
"passport": "^0.5.2",
|
||||
"passport-http-bearer": "^1.0.1",
|
||||
"pino": "^5.17.0",
|
||||
"request-debug": "^0.2.0",
|
||||
"short-uuid": "^4.1.0",
|
||||
"stripe": "^8.138.0",
|
||||
"swagger-ui-express": "^4.1.6",
|
||||
"stripe": "^8.195.0",
|
||||
"swagger-ui-express": "^4.3.0",
|
||||
"uuid": "^3.4.0",
|
||||
"yamljs": "^0.3.0"
|
||||
},
|
||||
|
||||
@@ -10,6 +10,7 @@ networks:
|
||||
|
||||
services:
|
||||
mysql:
|
||||
platform: linux/x86_64
|
||||
image: mysql:5.7
|
||||
ports:
|
||||
- "3360:3306"
|
||||
@@ -35,7 +36,8 @@ services:
|
||||
ipv4_address: 172.58.0.3
|
||||
|
||||
influxdb:
|
||||
image: influxdb:1.8-alpine
|
||||
platform: linux/x86_64
|
||||
image: influxdb:1.8
|
||||
ports:
|
||||
- "8086:8086"
|
||||
networks:
|
||||
|
||||
@@ -133,6 +133,30 @@ test('speech credentials tests', async(t) => {
|
||||
json: true,
|
||||
});
|
||||
console.log(JSON.stringify(result));
|
||||
}
|
||||
|
||||
/* add a credential for wellsaid */
|
||||
if (process.env.WELLSAID_API_KEY) {
|
||||
result = await request.post(`/Accounts/${account_sid}/SpeechCredentials`, {
|
||||
resolveWithFullResponse: true,
|
||||
auth: authUser,
|
||||
json: true,
|
||||
body: {
|
||||
vendor: 'wellsaid',
|
||||
use_for_tts: true,
|
||||
api_key: process.env.WELLSAID_API_KEY
|
||||
}
|
||||
});
|
||||
t.ok(result.statusCode === 201, 'successfully added speech credential');
|
||||
const ms_sid = result.body.sid;
|
||||
|
||||
/* test the speech credential */
|
||||
result = await request.get(`/Accounts/${account_sid}/SpeechCredentials/${ms_sid}/test`, {
|
||||
resolveWithFullResponse: true,
|
||||
auth: authUser,
|
||||
json: true,
|
||||
});
|
||||
console.log(JSON.stringify(result));
|
||||
|
||||
/* delete the credential */
|
||||
result = await request.delete(`/Accounts/${account_sid}/SpeechCredentials/${ms_sid}`, {
|
||||
@@ -144,7 +168,6 @@ test('speech credentials tests', async(t) => {
|
||||
|
||||
await deleteObjectBySid(request, '/Accounts', account_sid);
|
||||
await deleteObjectBySid(request, '/ServiceProviders', service_provider_sid);
|
||||
|
||||
//t.end();
|
||||
}
|
||||
catch (err) {
|
||||
|
||||
Reference in New Issue
Block a user