@jambonz/speech-utils 0.2.30 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +1 -8
- package/index.js +1 -1
- package/lib/get-tts-voices.js +1 -20
- package/lib/synth-audio.js +5 -45
- package/lib/utils.js +1 -7
- package/package.json +1 -2
- package/test/docker_start.js +1 -1
- package/test/docker_stop.js +1 -1
- package/test/index.js +1 -1
- package/test/list-voices.js +0 -65
- package/test/synth.js +0 -40
- package/lib/get-ibm-access-token.js +0 -48
- package/test/ibm.js +0 -78
package/.github/workflows/ci.yml
CHANGED
|
@@ -13,11 +13,6 @@ jobs:
|
|
|
13
13
|
with:
|
|
14
14
|
node-version: '20'
|
|
15
15
|
- run: npm install
|
|
16
|
-
- name: Install Docker Compose
|
|
17
|
-
run: |
|
|
18
|
-
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
|
19
|
-
sudo chmod +x /usr/local/bin/docker-compose
|
|
20
|
-
docker-compose --version
|
|
21
16
|
- run: npm run jslint
|
|
22
17
|
- run: sudo apt update && sudo apt install -y squid
|
|
23
18
|
- run: sudo cp test/squid.conf /etc/squid/squid.conf
|
|
@@ -28,9 +23,7 @@ jobs:
|
|
|
28
23
|
AWS_REGION: ${{ secrets.AWS_REGION }}
|
|
29
24
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
30
25
|
GCP_JSON_KEY: ${{ secrets.GCP_JSON_KEY }}
|
|
31
|
-
|
|
32
|
-
IBM_TTS_API_KEY: ${{ secrets.IBM_TTS_API_KEY }}
|
|
33
|
-
IBM_TTS_REGION: ${{ secrets.IBM_TTS_REGION }}
|
|
26
|
+
|
|
34
27
|
MICROSOFT_API_KEY: ${{ secrets.MICROSOFT_API_KEY }}
|
|
35
28
|
MICROSOFT_REGION: ${{ secrets.MICROSOFT_REGION }}
|
|
36
29
|
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
package/index.js
CHANGED
|
@@ -16,7 +16,7 @@ module.exports = (opts, logger) => {
|
|
|
16
16
|
synthAudio: require('./lib/synth-audio').bind(null, client, createHash, retrieveHash, logger),
|
|
17
17
|
getVerbioAccessToken: require('./lib/get-verbio-token').bind(null, client, logger),
|
|
18
18
|
getNuanceAccessToken: require('./lib/get-nuance-access-token').bind(null, client, logger),
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
getAwsAuthToken: require('./lib/get-aws-sts-token').bind(null, logger, createHash, retrieveHash),
|
|
21
21
|
getTtsVoices: require('./lib/get-tts-voices').bind(null, client, createHash, retrieveHash, logger),
|
|
22
22
|
};
|
package/lib/get-tts-voices.js
CHANGED
|
@@ -3,8 +3,6 @@ const {noopLogger, createNuanceClient, createKryptonClient} = require('./utils')
|
|
|
3
3
|
const getNuanceAccessToken = require('./get-nuance-access-token');
|
|
4
4
|
const getVerbioAccessToken = require('./get-verbio-token');
|
|
5
5
|
const {GetVoicesRequest, Voice} = require('../stubs/nuance/synthesizer_pb');
|
|
6
|
-
const TextToSpeechV1 = require('ibm-watson/text-to-speech/v1');
|
|
7
|
-
const { IamAuthenticator } = require('ibm-watson/auth');
|
|
8
6
|
const ttsGoogle = require('@google-cloud/text-to-speech');
|
|
9
7
|
const { PollyClient, DescribeVoicesCommand } = require('@aws-sdk/client-polly');
|
|
10
8
|
const getAwsAuthToken = require('./get-aws-sts-token');
|
|
@@ -12,21 +10,6 @@ const {Pool} = require('undici');
|
|
|
12
10
|
const { HTTP_TIMEOUT } = require('./config');
|
|
13
11
|
const verbioVoicePool = new Pool('https://us.rest.speechcenter.verbio.com');
|
|
14
12
|
|
|
15
|
-
const getIbmVoices = async(client, logger, credentials) => {
|
|
16
|
-
const {tts_region, tts_api_key} = credentials;
|
|
17
|
-
console.log(`region: ${tts_region}, api_key: ${tts_api_key}`);
|
|
18
|
-
|
|
19
|
-
const textToSpeech = new TextToSpeechV1({
|
|
20
|
-
authenticator: new IamAuthenticator({
|
|
21
|
-
apikey: tts_api_key,
|
|
22
|
-
}),
|
|
23
|
-
serviceUrl: `https://api.${tts_region}.text-to-speech.watson.cloud.ibm.com`
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
const voices = await textToSpeech.listVoices();
|
|
27
|
-
return voices;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
13
|
const getNuanceVoices = async(client, logger, credentials) => {
|
|
31
14
|
const {client_id: clientId, secret: secret, nuance_tts_uri} = credentials;
|
|
32
15
|
|
|
@@ -165,14 +148,12 @@ const getVerbioVoices = async(client, logger, credentials) => {
|
|
|
165
148
|
async function getTtsVoices(client, createHash, retrieveHash, logger, {vendor, credentials}) {
|
|
166
149
|
logger = logger || noopLogger;
|
|
167
150
|
|
|
168
|
-
assert.ok(['nuance', '
|
|
151
|
+
assert.ok(['nuance', 'google', 'aws', 'polly', 'verbio'].includes(vendor),
|
|
169
152
|
`getTtsVoices not supported for vendor ${vendor}`);
|
|
170
153
|
|
|
171
154
|
switch (vendor) {
|
|
172
155
|
case 'nuance':
|
|
173
156
|
return getNuanceVoices(client, logger, credentials);
|
|
174
|
-
case 'ibm':
|
|
175
|
-
return getIbmVoices(client, logger, credentials);
|
|
176
157
|
case 'google':
|
|
177
158
|
return getGoogleVoices(client, logger, credentials);
|
|
178
159
|
case 'aws':
|
package/lib/synth-audio.js
CHANGED
|
@@ -6,8 +6,7 @@ const { PollyClient, SynthesizeSpeechCommand } = require('@aws-sdk/client-polly'
|
|
|
6
6
|
const { CartesiaClient } = require('@cartesia/cartesia-js');
|
|
7
7
|
|
|
8
8
|
const sdk = require('microsoft-cognitiveservices-speech-sdk');
|
|
9
|
-
|
|
10
|
-
const { IamAuthenticator } = require('ibm-watson/auth');
|
|
9
|
+
|
|
11
10
|
const {
|
|
12
11
|
ResultReason,
|
|
13
12
|
SpeechConfig,
|
|
@@ -96,7 +95,7 @@ async function synthAudio(client, createHash, retrieveHash, logger, stats, { acc
|
|
|
96
95
|
let rtt;
|
|
97
96
|
logger = logger || noopLogger;
|
|
98
97
|
|
|
99
|
-
assert.ok(['google', 'aws', 'polly', 'microsoft', 'wellsaid', 'nuance', 'nvidia', '
|
|
98
|
+
assert.ok(['google', 'aws', 'polly', 'microsoft', 'wellsaid', 'nuance', 'nvidia', 'elevenlabs',
|
|
100
99
|
'whisper', 'deepgram', 'playht', 'rimelabs', 'verbio', 'cartesia', 'inworld', 'resemble'].includes(vendor) ||
|
|
101
100
|
vendor.startsWith('custom'),
|
|
102
101
|
`synthAudio supported vendors are google, aws, microsoft, nuance, nvidia and wellsaid ..etc, not ${vendor}`);
|
|
@@ -122,11 +121,6 @@ async function synthAudio(client, createHash, retrieveHash, logger, stats, { acc
|
|
|
122
121
|
assert.ok(language, 'synthAudio requires language when nvidia is used');
|
|
123
122
|
assert.ok(credentials.riva_server_uri, 'synthAudio requires riva_server_uri in credentials when nvidia is used');
|
|
124
123
|
}
|
|
125
|
-
else if ('ibm' === vendor) {
|
|
126
|
-
assert.ok(voice, 'synthAudio requires voice when ibm is used');
|
|
127
|
-
assert.ok(credentials.tts_region, 'synthAudio requires tts_region in credentials when ibm watson is used');
|
|
128
|
-
assert.ok(credentials.tts_api_key, 'synthAudio requires tts_api_key in credentials when nuance is used');
|
|
129
|
-
}
|
|
130
124
|
else if ('wellsaid' === vendor) {
|
|
131
125
|
language = 'en-US'; // WellSaid only supports English atm
|
|
132
126
|
assert.ok(voice, 'synthAudio requires voice when wellsaid is used');
|
|
@@ -230,9 +224,6 @@ async function synthAudio(client, createHash, retrieveHash, logger, stats, { acc
|
|
|
230
224
|
audioData = await synthNvidia(client, logger, {credentials, stats, language, voice, model, key, text,
|
|
231
225
|
renderForCaching, disableTtsStreaming, disableTtsCache});
|
|
232
226
|
break;
|
|
233
|
-
case 'ibm':
|
|
234
|
-
audioData = await synthIbm(logger, {credentials, stats, voice, key, text});
|
|
235
|
-
break;
|
|
236
227
|
case 'wellsaid':
|
|
237
228
|
audioData = await synthWellSaid(logger, {credentials, stats, language, voice, key, text});
|
|
238
229
|
break;
|
|
@@ -535,39 +526,6 @@ const synthGoogle = async(logger, {
|
|
|
535
526
|
}
|
|
536
527
|
};
|
|
537
528
|
|
|
538
|
-
const synthIbm = async(logger, {credentials, stats, voice, text}) => {
|
|
539
|
-
const {tts_api_key, tts_region} = credentials;
|
|
540
|
-
const params = {
|
|
541
|
-
text,
|
|
542
|
-
voice,
|
|
543
|
-
accept: 'audio/mp3'
|
|
544
|
-
};
|
|
545
|
-
|
|
546
|
-
try {
|
|
547
|
-
const textToSpeech = new TextToSpeechV1({
|
|
548
|
-
authenticator: new IamAuthenticator({
|
|
549
|
-
apikey: tts_api_key,
|
|
550
|
-
}),
|
|
551
|
-
serviceUrl: `https://api.${tts_region}.text-to-speech.watson.cloud.ibm.com`
|
|
552
|
-
});
|
|
553
|
-
|
|
554
|
-
const r = await textToSpeech.synthesize(params);
|
|
555
|
-
const chunks = [];
|
|
556
|
-
for await (const chunk of r.result) {
|
|
557
|
-
chunks.push(chunk);
|
|
558
|
-
}
|
|
559
|
-
return {
|
|
560
|
-
audioContent: Buffer.concat(chunks),
|
|
561
|
-
extension: 'mp3',
|
|
562
|
-
sampleRate: 8000
|
|
563
|
-
};
|
|
564
|
-
} catch (err) {
|
|
565
|
-
logger.info({err, params}, 'synthAudio: Error synthesizing speech using ibm');
|
|
566
|
-
stats.increment('tts.count', ['vendor:ibm', 'accepted:no']);
|
|
567
|
-
throw new Error(err.statusText || err.message);
|
|
568
|
-
}
|
|
569
|
-
};
|
|
570
|
-
|
|
571
529
|
async function _synthOnPremMicrosoft(logger, {
|
|
572
530
|
credentials,
|
|
573
531
|
language,
|
|
@@ -969,7 +927,7 @@ const synthElevenlabs = async(logger, {
|
|
|
969
927
|
const optimize_streaming_latency = opts.optimize_streaming_latency ?
|
|
970
928
|
`?optimize_streaming_latency=${opts.optimize_streaming_latency}` : '';
|
|
971
929
|
try {
|
|
972
|
-
const post = bent(`https://${api_uri}`, 'POST', 'buffer', {
|
|
930
|
+
const post = bent(`https://${api_uri || 'api.elevenlabs.io'}`, 'POST', 'buffer', {
|
|
973
931
|
'xi-api-key': api_key,
|
|
974
932
|
'Accept': 'audio/mpeg',
|
|
975
933
|
'Content-Type': 'application/json'
|
|
@@ -1178,6 +1136,8 @@ const synthRimelabs = async(logger, {
|
|
|
1178
1136
|
if (opts.repetition_penalty) params += `,repetition_penalty=${opts.repetition_penalty}`;
|
|
1179
1137
|
if (opts.top_p) params += `,top_p=${opts.top_p}`;
|
|
1180
1138
|
if (opts.max_tokens) params += `,max_tokens=${opts.max_tokens}`;
|
|
1139
|
+
// Coda model parameters
|
|
1140
|
+
if (opts.timeScaleFactor) params += `,time_scale_factor=${opts.timeScaleFactor}`;
|
|
1181
1141
|
params += '}';
|
|
1182
1142
|
|
|
1183
1143
|
return {
|
package/lib/utils.js
CHANGED
|
@@ -54,12 +54,6 @@ function makeBasicAuthHeader(username, password) {
|
|
|
54
54
|
return {Authorization: header};
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
function makeIbmKey(apiKey) {
|
|
58
|
-
const hash = crypto.createHash('sha1');
|
|
59
|
-
hash.update(apiKey);
|
|
60
|
-
return `ibm:${hash.digest('hex')}`;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
57
|
function makeAwsKey(awsAccessKeyId) {
|
|
64
58
|
const hash = crypto.createHash('sha1');
|
|
65
59
|
hash.update(awsAccessKeyId);
|
|
@@ -143,7 +137,7 @@ const createRivaClient = async(rivaUri) => {
|
|
|
143
137
|
module.exports = {
|
|
144
138
|
makeSynthKey,
|
|
145
139
|
makeNuanceKey,
|
|
146
|
-
|
|
140
|
+
|
|
147
141
|
makePlayhtKey,
|
|
148
142
|
makeAwsKey,
|
|
149
143
|
makeVerbioKey,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jambonz/speech-utils",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "TTS-related speech utilities for jambonz",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"author": "Dave Horton",
|
|
@@ -37,7 +37,6 @@
|
|
|
37
37
|
"debug": "^4.3.4",
|
|
38
38
|
"form-urlencoded": "^6.1.4",
|
|
39
39
|
"google-protobuf": "^3.21.2",
|
|
40
|
-
"ibm-watson": "^11.0.0",
|
|
41
40
|
"microsoft-cognitiveservices-speech-sdk": "1.38.0",
|
|
42
41
|
"openai": "^4.98.0",
|
|
43
42
|
"undici": "^7.5.0"
|
package/test/docker_start.js
CHANGED
|
@@ -2,7 +2,7 @@ const test = require('tape').test ;
|
|
|
2
2
|
const exec = require('child_process').exec ;
|
|
3
3
|
|
|
4
4
|
test('starting docker network..', (t) => {
|
|
5
|
-
exec(`docker
|
|
5
|
+
exec(`docker compose -f ${__dirname}/docker-compose-testbed.yaml up -d`, (err, stdout, stderr) => {
|
|
6
6
|
setTimeout(() => {
|
|
7
7
|
t.end(err);
|
|
8
8
|
}, 2000);
|
package/test/docker_stop.js
CHANGED
|
@@ -3,7 +3,7 @@ const exec = require('child_process').exec ;
|
|
|
3
3
|
|
|
4
4
|
test('stopping docker network..', (t) => {
|
|
5
5
|
t.timeoutAfter(10000);
|
|
6
|
-
exec(`docker
|
|
6
|
+
exec(`docker compose -f ${__dirname}/docker-compose-testbed.yaml down`, (err, stdout, stderr) => {
|
|
7
7
|
//console.log(`stderr: ${stderr}`);
|
|
8
8
|
process.exit(0);
|
|
9
9
|
});
|
package/test/index.js
CHANGED
package/test/list-voices.js
CHANGED
|
@@ -38,71 +38,6 @@ test('Verbio - get Access key and voices', async(t) => {
|
|
|
38
38
|
client.quit();
|
|
39
39
|
});
|
|
40
40
|
|
|
41
|
-
test('IBM - create access key', async(t) => {
|
|
42
|
-
const fn = require('..');
|
|
43
|
-
const {client, getIbmAccessToken} = fn(opts, logger);
|
|
44
|
-
|
|
45
|
-
if (!process.env.IBM_API_KEY ) {
|
|
46
|
-
t.pass('skipping IBM test since no IBM api_key provided');
|
|
47
|
-
t.end();
|
|
48
|
-
client.quit();
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
try {
|
|
52
|
-
let obj = await getIbmAccessToken(process.env.IBM_API_KEY);
|
|
53
|
-
//console.log({obj}, 'received access token from IBM');
|
|
54
|
-
t.ok(obj.access_token && !obj.servedFromCache, 'successfull received access token from IBM');
|
|
55
|
-
|
|
56
|
-
obj = await getIbmAccessToken(process.env.IBM_API_KEY);
|
|
57
|
-
//console.log({obj}, 'received access token from IBM - second request');
|
|
58
|
-
t.ok(obj.access_token && obj.servedFromCache, 'successfully received access token from cache');
|
|
59
|
-
|
|
60
|
-
await client.flushall();
|
|
61
|
-
t.end();
|
|
62
|
-
}
|
|
63
|
-
catch (err) {
|
|
64
|
-
console.error(err);
|
|
65
|
-
t.end(err);
|
|
66
|
-
}
|
|
67
|
-
client.quit();
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
test('IBM - retrieve tts voices test', async(t) => {
|
|
71
|
-
const fn = require('..');
|
|
72
|
-
const {client, getTtsVoices} = fn(opts, logger);
|
|
73
|
-
|
|
74
|
-
if (!process.env.IBM_TTS_API_KEY || !process.env.IBM_TTS_REGION) {
|
|
75
|
-
t.pass('skipping IBM test since no IBM api_key and/or region provided');
|
|
76
|
-
t.end();
|
|
77
|
-
client.quit();
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
try {
|
|
81
|
-
const opts = {
|
|
82
|
-
vendor: 'ibm',
|
|
83
|
-
credentials: {
|
|
84
|
-
tts_api_key: process.env.IBM_TTS_API_KEY,
|
|
85
|
-
tts_region: process.env.IBM_TTS_REGION
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
const obj = await getTtsVoices(opts);
|
|
89
|
-
const {voices} = obj.result;
|
|
90
|
-
//console.log(JSON.stringify(voices));
|
|
91
|
-
t.ok(voices.length > 0 && voices[0].language,
|
|
92
|
-
`GetVoices: successfully retrieved ${voices.length} voices from IBM`);
|
|
93
|
-
|
|
94
|
-
await client.flushall();
|
|
95
|
-
|
|
96
|
-
t.end();
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
catch (err) {
|
|
100
|
-
console.error(err);
|
|
101
|
-
t.end(err);
|
|
102
|
-
}
|
|
103
|
-
client.quit();
|
|
104
|
-
});
|
|
105
|
-
|
|
106
41
|
test('Nuance hosted tests', async(t) => {
|
|
107
42
|
const fn = require('..');
|
|
108
43
|
const {client, getTtsVoices} = fn(opts, logger);
|
package/test/synth.js
CHANGED
|
@@ -872,46 +872,6 @@ test('Nvidia speech synth tests', async(t) => {
|
|
|
872
872
|
client.quit();
|
|
873
873
|
});
|
|
874
874
|
|
|
875
|
-
test('IBM watson speech synth tests', async(t) => {
|
|
876
|
-
const fn = require('..');
|
|
877
|
-
const {synthAudio, client} = fn(opts, logger);
|
|
878
|
-
|
|
879
|
-
if (!process.env.IBM_TTS_API_KEY || !process.env.IBM_TTS_REGION) {
|
|
880
|
-
t.pass('skipping IBM Watson speech synth tests since IBM_TTS_API_KEY or IBM_TTS_API_KEY not provided');
|
|
881
|
-
return t.end();
|
|
882
|
-
}
|
|
883
|
-
const text = `<speak> Hi there and welcome to jambones! jambones is the <sub alias="seapass">CPaaS</sub> designed with the needs of communication service providers in mind. This is an example of simple text-to-speech, but there is so much more you can do. Try us out!</speak>`;
|
|
884
|
-
try {
|
|
885
|
-
let opts = await synthAudio(stats, {
|
|
886
|
-
vendor: 'ibm',
|
|
887
|
-
credentials: {
|
|
888
|
-
tts_api_key: process.env.IBM_TTS_API_KEY,
|
|
889
|
-
tts_region: process.env.IBM_TTS_REGION,
|
|
890
|
-
},
|
|
891
|
-
language: 'en-US',
|
|
892
|
-
voice: 'en-US_AllisonV2Voice',
|
|
893
|
-
text,
|
|
894
|
-
});
|
|
895
|
-
t.ok(!opts.servedFromCache, `successfully synthesized ibm audio to ${opts.filePath}`);
|
|
896
|
-
|
|
897
|
-
opts = await synthAudio(stats, {
|
|
898
|
-
vendor: 'ibm',
|
|
899
|
-
credentials: {
|
|
900
|
-
tts_api_key: process.env.IBM_TTS_API_KEY,
|
|
901
|
-
tts_region: process.env.IBM_TTS_REGION,
|
|
902
|
-
},
|
|
903
|
-
language: 'en-US',
|
|
904
|
-
voice: 'en-US_AllisonV2Voice',
|
|
905
|
-
text,
|
|
906
|
-
});
|
|
907
|
-
t.ok(opts.servedFromCache, `successfully retrieved ibm audio from cache ${opts.filePath}`);
|
|
908
|
-
} catch (err) {
|
|
909
|
-
console.error(JSON.stringify(err));
|
|
910
|
-
t.end(err);
|
|
911
|
-
}
|
|
912
|
-
client.quit();
|
|
913
|
-
});
|
|
914
|
-
|
|
915
875
|
test('Custom Vendor speech synth tests', async(t) => {
|
|
916
876
|
const fn = require('..');
|
|
917
877
|
const {synthAudio, client} = fn(opts, logger);
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
const formurlencoded = require('form-urlencoded');
|
|
2
|
-
const {Pool} = require('undici');
|
|
3
|
-
const pool = new Pool('https://iam.cloud.ibm.com');
|
|
4
|
-
const {makeIbmKey, noopLogger} = require('./utils');
|
|
5
|
-
const { HTTP_TIMEOUT } = require('./config');
|
|
6
|
-
const debug = require('debug')('jambonz:realtimedb-helpers');
|
|
7
|
-
|
|
8
|
-
async function getIbmAccessToken(client, logger, apiKey) {
|
|
9
|
-
logger = logger || noopLogger;
|
|
10
|
-
try {
|
|
11
|
-
const key = makeIbmKey(apiKey);
|
|
12
|
-
const access_token = await client.get(key);
|
|
13
|
-
if (access_token) return {access_token, servedFromCache: true};
|
|
14
|
-
|
|
15
|
-
/* access token not found in cache, so fetch it from Ibm */
|
|
16
|
-
const payload = {
|
|
17
|
-
grant_type: 'urn:ibm:params:oauth:grant-type:apikey',
|
|
18
|
-
apikey: apiKey
|
|
19
|
-
};
|
|
20
|
-
const {statusCode, headers, body} = await pool.request({
|
|
21
|
-
path: '/identity/token',
|
|
22
|
-
method: 'POST',
|
|
23
|
-
headers: {
|
|
24
|
-
'Content-Type': 'application/x-www-form-urlencoded'
|
|
25
|
-
},
|
|
26
|
-
body: formurlencoded(payload),
|
|
27
|
-
timeout: HTTP_TIMEOUT,
|
|
28
|
-
followRedirects: false
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
if (200 !== statusCode) {
|
|
32
|
-
const json = await body.json();
|
|
33
|
-
logger.debug({statusCode, headers, body: json}, 'error fetching access token from Ibm');
|
|
34
|
-
const err = new Error();
|
|
35
|
-
err.statusCode = statusCode;
|
|
36
|
-
throw err;
|
|
37
|
-
}
|
|
38
|
-
const json = await body.json();
|
|
39
|
-
await client.set(key, json.access_token, 'EX', json.expires_in - 30);
|
|
40
|
-
return {...json, servedFromCache: false};
|
|
41
|
-
} catch (err) {
|
|
42
|
-
debug(err, 'getIbmAccessToken: Error retrieving Ibm access token');
|
|
43
|
-
logger.error(err, 'getIbmAccessToken: Error retrieving Ibm access token for client_id ${clientId}');
|
|
44
|
-
throw err;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
module.exports = getIbmAccessToken;
|
package/test/ibm.js
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
const test = require('tape').test ;
|
|
2
|
-
const config = require('config');
|
|
3
|
-
const opts = config.get('redis');
|
|
4
|
-
const fs = require('fs');
|
|
5
|
-
const logger = require('pino')({level: 'error'});
|
|
6
|
-
process.on('unhandledRejection', (reason, p) => {
|
|
7
|
-
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
const stats = {
|
|
11
|
-
increment: () => {},
|
|
12
|
-
histogram: () => {}
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
test('IBM - create access key', async(t) => {
|
|
16
|
-
const fn = require('..');
|
|
17
|
-
const {client, getIbmAccessToken} = fn(opts, logger);
|
|
18
|
-
|
|
19
|
-
if (!process.env.IBM_API_KEY ) {
|
|
20
|
-
t.pass('skipping IBM test since no IBM api_key provided');
|
|
21
|
-
t.end();
|
|
22
|
-
client.quit();
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
try {
|
|
26
|
-
let obj = await getIbmAccessToken(process.env.IBM_API_KEY);
|
|
27
|
-
//console.log({obj}, 'received access token from IBM');
|
|
28
|
-
t.ok(obj.access_token && !obj.servedFromCache, 'successfull received access token from IBM');
|
|
29
|
-
|
|
30
|
-
obj = await getIbmAccessToken(process.env.IBM_API_KEY);
|
|
31
|
-
//console.log({obj}, 'received access token from IBM - second request');
|
|
32
|
-
t.ok(obj.access_token && obj.servedFromCache, 'successfully received access token from cache');
|
|
33
|
-
|
|
34
|
-
await client.flushall();
|
|
35
|
-
t.end();
|
|
36
|
-
}
|
|
37
|
-
catch (err) {
|
|
38
|
-
console.error(err);
|
|
39
|
-
t.end(err);
|
|
40
|
-
}
|
|
41
|
-
client.quit();
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
test('IBM - retrieve tts voices test', async(t) => {
|
|
45
|
-
const fn = require('..');
|
|
46
|
-
const {client, getTtsVoices} = fn(opts, logger);
|
|
47
|
-
|
|
48
|
-
if (!process.env.IBM_TTS_API_KEY || !process.env.IBM_TTS_REGION) {
|
|
49
|
-
t.pass('skipping IBM test since no IBM api_key and/or region provided');
|
|
50
|
-
t.end();
|
|
51
|
-
client.quit();
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
try {
|
|
55
|
-
const opts = {
|
|
56
|
-
vendor: 'ibm',
|
|
57
|
-
credentials: {
|
|
58
|
-
tts_api_key: process.env.IBM_TTS_API_KEY,
|
|
59
|
-
tts_region: process.env.IBM_TTS_REGION
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
const obj = await getTtsVoices(opts);
|
|
63
|
-
const {voices} = obj.result;
|
|
64
|
-
//console.log(JSON.stringify(voices));
|
|
65
|
-
t.ok(voices.length > 0 && voices[0].language,
|
|
66
|
-
`GetVoices: successfully retrieved ${voices.length} voices from IBM`);
|
|
67
|
-
|
|
68
|
-
await client.flushall();
|
|
69
|
-
|
|
70
|
-
t.end();
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
catch (err) {
|
|
74
|
-
console.error(err);
|
|
75
|
-
t.end(err);
|
|
76
|
-
}
|
|
77
|
-
client.quit();
|
|
78
|
-
});
|