mirror of
https://github.com/jambonz/jambonz-api-server.git
synced 2026-01-25 02:08:24 +00:00
Compare commits
6 Commits
v0.9.5-rc9
...
v0.9.5-rc1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c3d12fafee | ||
|
|
9421bb8aa1 | ||
|
|
a15c5cd267 | ||
|
|
4de66789ef | ||
|
|
a297d2038f | ||
|
|
2e0ea56925 |
@@ -267,6 +267,8 @@ const doIt = async() => {
|
||||
if (val < 9000) upgrades.push(...sql['9000']);
|
||||
if (val < 9002) upgrades.push(...sql['9002']);
|
||||
if (val < 9003) upgrades.push(...sql['9003']);
|
||||
if (val < 9004) upgrades.push(...sql['9004']);
|
||||
if (val < 9005) upgrades.push(...sql['9005']);
|
||||
|
||||
// perform all upgrades
|
||||
logger.info({upgrades}, 'applying schema upgrades..');
|
||||
|
||||
@@ -15,7 +15,9 @@ class S3MultipartUploadStream extends Writable {
|
||||
this.uploadId = null;
|
||||
this.partNumber = 1;
|
||||
this.multipartETags = [];
|
||||
this.buffer = Buffer.alloc(0);
|
||||
// accumulate incoming chunks to avoid O(n^2) Buffer.concat on every write
|
||||
this.chunks = [];
|
||||
this.bufferedBytes = 0;
|
||||
this.minPartSize = 5 * 1024 * 1024; // 5 MB
|
||||
this.s3 = new S3Client(opts.bucketCredential);
|
||||
this.metadata = opts.metadata;
|
||||
@@ -31,13 +33,13 @@ class S3MultipartUploadStream extends Writable {
|
||||
return response.UploadId;
|
||||
}
|
||||
|
||||
async _uploadBuffer() {
|
||||
async _uploadPart(bodyBuffer) {
|
||||
const uploadPartCommand = new UploadPartCommand({
|
||||
Bucket: this.bucketName,
|
||||
Key: this.objectKey,
|
||||
PartNumber: this.partNumber,
|
||||
UploadId: this.uploadId,
|
||||
Body: this.buffer,
|
||||
Body: bodyBuffer,
|
||||
});
|
||||
|
||||
const uploadPartResponse = await this.s3.send(uploadPartCommand);
|
||||
@@ -54,11 +56,16 @@ class S3MultipartUploadStream extends Writable {
|
||||
this.uploadId = await this._initMultipartUpload();
|
||||
}
|
||||
|
||||
this.buffer = Buffer.concat([this.buffer, chunk]);
|
||||
// accumulate without concatenating on every write
|
||||
this.chunks.push(chunk);
|
||||
this.bufferedBytes += chunk.length;
|
||||
|
||||
if (this.buffer.length >= this.minPartSize) {
|
||||
await this._uploadBuffer();
|
||||
this.buffer = Buffer.alloc(0);
|
||||
if (this.bufferedBytes >= this.minPartSize) {
|
||||
const partBuffer = Buffer.concat(this.chunks, this.bufferedBytes);
|
||||
// reset accumulators before awaiting upload to allow GC
|
||||
this.chunks = [];
|
||||
this.bufferedBytes = 0;
|
||||
await this._uploadPart(partBuffer);
|
||||
}
|
||||
|
||||
callback(null);
|
||||
@@ -69,8 +76,11 @@ class S3MultipartUploadStream extends Writable {
|
||||
|
||||
async _finalize(err) {
|
||||
try {
|
||||
if (this.buffer.length > 0) {
|
||||
await this._uploadBuffer();
|
||||
if (this.bufferedBytes > 0) {
|
||||
const finalBuffer = Buffer.concat(this.chunks, this.bufferedBytes);
|
||||
this.chunks = [];
|
||||
this.bufferedBytes = 0;
|
||||
await this._uploadPart(finalBuffer);
|
||||
}
|
||||
|
||||
const completeMultipartUploadCommand = new CompleteMultipartUploadCommand({
|
||||
|
||||
@@ -51,8 +51,10 @@ async function upload(logger, socket) {
|
||||
|
||||
/**encoder */
|
||||
let encoder;
|
||||
let recordFormat;
|
||||
if (account[0].record_format === 'wav') {
|
||||
encoder = new wav.Writer({ channels: 2, sampleRate, bitDepth: 16 });
|
||||
recordFormat = 'wav';
|
||||
} else {
|
||||
// default is mp3
|
||||
encoder = new PCMToMP3Encoder({
|
||||
@@ -60,7 +62,9 @@ async function upload(logger, socket) {
|
||||
sampleRate: sampleRate,
|
||||
bitrate: 128
|
||||
}, logger);
|
||||
recordFormat = 'mp3';
|
||||
}
|
||||
logger.info({ record_format: recordFormat, channels: 2, sampleRate }, 'record upload: selected encoder');
|
||||
|
||||
/* start streaming data */
|
||||
pipeline(
|
||||
|
||||
@@ -161,6 +161,9 @@ router.post('/:sid/VoipCarriers', async(req, res) => {
|
||||
try {
|
||||
const account_sid = parseAccountSid(req);
|
||||
await validateRequest(req, account_sid);
|
||||
// Set the service_provder_sid to the relevent value for the account
|
||||
const account = await Account.retrieve(req.user.account_sid);
|
||||
payload.service_provider_sid = account[0].service_provider_sid;
|
||||
|
||||
logger.debug({payload}, 'POST /:sid/VoipCarriers');
|
||||
const uuid = await VoipCarrier.make({
|
||||
|
||||
@@ -46,10 +46,16 @@ async function validateRetrieve(req) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.user.hasScope('service_provider') || req.user.hasScope('account')) {
|
||||
if (req.user.hasScope('service_provider')) {
|
||||
if (service_provider_sid === req.user.service_provider_sid) return;
|
||||
}
|
||||
|
||||
if (req.user.hasScope('account')) {
|
||||
const results = await Account.retrieve(req.user.account_sid);
|
||||
if (service_provider_sid === results[0].service_provider_sid) return;
|
||||
}
|
||||
|
||||
|
||||
throw new DbErrorForbidden('insufficient permissions');
|
||||
} catch (error) {
|
||||
throw error;
|
||||
|
||||
@@ -18,8 +18,7 @@ const checkUserScope = async(req, voip_carrier_sid) => {
|
||||
const carrier = await lookupCarrierBySid(voip_carrier_sid);
|
||||
if (!carrier) throw new DbErrorBadRequest('invalid voip_carrier_sid');
|
||||
|
||||
if ((!carrier.service_provider_sid || carrier.service_provider_sid === req.user.service_provider_sid) &&
|
||||
(!carrier.account_sid || carrier.account_sid === req.user.account_sid)) {
|
||||
if (!carrier.account_sid || carrier.account_sid === req.user.account_sid) {
|
||||
|
||||
if (req.method !== 'GET' && !carrier.account_sid) {
|
||||
throw new DbErrorForbidden('insufficient privileges');
|
||||
|
||||
@@ -238,10 +238,10 @@ const encryptCredential = (obj) => {
|
||||
});
|
||||
return encrypt(resembleData);
|
||||
|
||||
case 'deepgramriver':
|
||||
assert(api_key, 'invalid deepgram river speech credential: api_key is required');
|
||||
const deepgramriverData = JSON.stringify({api_key});
|
||||
return encrypt(deepgramriverData);
|
||||
case 'deepgramflux':
|
||||
assert(api_key, 'invalid deepgram flux speech credential: api_key is required');
|
||||
const deepgramfluxData = JSON.stringify({api_key});
|
||||
return encrypt(deepgramfluxData);
|
||||
|
||||
case 'ibm':
|
||||
const ibmData = JSON.stringify({tts_api_key, tts_region, stt_api_key, stt_region, instance_id});
|
||||
@@ -806,7 +806,7 @@ router.get('/:sid/test', async(req, res) => {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (cred.vendor === 'deepgramriver') {
|
||||
else if (cred.vendor === 'deepgramflux') {
|
||||
const {api_key} = credential;
|
||||
if (cred.use_for_stt && api_key) {
|
||||
try {
|
||||
|
||||
@@ -1,56 +1,153 @@
|
||||
module.exports = [
|
||||
{ name: 'Multilingual', value: 'multi' },
|
||||
{ name: 'Afrikaans', value: 'af' },
|
||||
{ name: 'Amharic', value: 'am' },
|
||||
{ name: 'Arabic', value: 'ar' },
|
||||
{ name: 'Assamese', value: 'as' },
|
||||
{ name: 'Azerbaijani', value: 'az' },
|
||||
{ name: 'Bashkir', value: 'ba' },
|
||||
{ name: 'Belarusian', value: 'be' },
|
||||
{ name: 'Bulgarian', value: 'bg' },
|
||||
{ name: 'Bengali', value: 'bn' },
|
||||
{ name: 'Tibetan', value: 'bo' },
|
||||
{ name: 'Breton', value: 'br' },
|
||||
{ name: 'Bosnian', value: 'bs' },
|
||||
{ name: 'Catalan', value: 'ca' },
|
||||
{ name: 'Chinese (Mandarin, Simplified)', value: 'zh' },
|
||||
{ name: 'Chinese (Mandarin, Simplified - China)', value: 'zh-CN' },
|
||||
{ name: 'Chinese (Mandarin, Simplified - Hans)', value: 'zh-Hans' },
|
||||
{ name: 'Chinese (Mandarin, Traditional)', value: 'zh-TW' },
|
||||
{ name: 'Chinese (Mandarin, Traditional - Hant)', value: 'zh-Hant' },
|
||||
{ name: 'Chinese (Cantonese, Traditional - Hong Kong)', value: 'zh-HK' },
|
||||
{ name: 'Czech', value: 'cs' },
|
||||
{ name: 'Welsh', value: 'cy' },
|
||||
{ name: 'Danish', value: 'da' },
|
||||
{ name: 'Danish (Denmark)', value: 'da-DK' },
|
||||
{ name: 'Dutch', value: 'nl' },
|
||||
{ name: 'English', value: 'en' },
|
||||
{ name: 'English (United States)', value: 'en-US' },
|
||||
{ name: 'English (Australia)', value: 'en-AU' },
|
||||
{ name: 'English (United Kingdom)', value: 'en-GB' },
|
||||
{ name: 'English (New Zealand)', value: 'en-NZ' },
|
||||
{ name: 'English (India)', value: 'en-IN' },
|
||||
{ name: 'Estonian', value: 'et' },
|
||||
{ name: 'Finnish', value: 'fi' },
|
||||
{ name: 'Flemish', value: 'nl-BE' },
|
||||
{ name: 'French', value: 'fr' },
|
||||
{ name: 'French (Canada)', value: 'fr-CA' },
|
||||
{ name: 'German', value: 'de' },
|
||||
{ name: 'German (Austria)', value: 'de-AT' },
|
||||
{ name: 'German (Switzerland)', value: 'de-CH' },
|
||||
{ name: 'Greek', value: 'el' },
|
||||
{ name: 'German (Germany)', value: 'de-DE' },
|
||||
{ name: 'Modern Greek', value: 'el' },
|
||||
{ name: 'English', value: 'en' },
|
||||
{ name: 'English (Australia)', value: 'en-AU' },
|
||||
{ name: 'English (Canada)', value: 'en-CA' },
|
||||
{ name: 'English (United Kingdom)', value: 'en-GB' },
|
||||
{ name: 'English (Ireland)', value: 'en-IE' },
|
||||
{ name: 'English (India)', value: 'en-IN' },
|
||||
{ name: 'English (Malaysia)', value: 'en-MY' },
|
||||
{ name: 'English (New Zealand)', value: 'en-NZ' },
|
||||
{ name: 'English (Philippines)', value: 'en-PH' },
|
||||
{ name: 'English (United States)', value: 'en-US' },
|
||||
{ name: 'English (South Africa)', value: 'en-ZA' },
|
||||
{ name: 'Spanish', value: 'es' },
|
||||
{ name: 'Spanish (Latin America and the Caribbean)', value: 'es-419' },
|
||||
{ name: 'Spanish (Argentina)', value: 'es-AR' },
|
||||
{ name: 'Spanish (Colombia)', value: 'es-CO' },
|
||||
{ name: 'Spanish (Spain)', value: 'es-ES' },
|
||||
{ name: 'Spanish (Latin America)', value: 'es-LATAM' },
|
||||
{ name: 'Spanish (Mexico)', value: 'es-MX' },
|
||||
{ name: 'Spanish (United States)', value: 'es-US' },
|
||||
{ name: 'Estonian', value: 'et' },
|
||||
{ name: 'Basque', value: 'eu' },
|
||||
{ name: 'Persian', value: 'fa' },
|
||||
{ name: 'Finnish', value: 'fi' },
|
||||
{ name: 'Faroese', value: 'fo' },
|
||||
{ name: 'French', value: 'fr' },
|
||||
{ name: 'French (Belgium)', value: 'fr-BE' },
|
||||
{ name: 'French (Canada)', value: 'fr-CA' },
|
||||
{ name: 'French (Switzerland)', value: 'fr-CH' },
|
||||
{ name: 'French (France)', value: 'fr-FR' },
|
||||
{ name: 'French (Canada)', value: 'fr-ca' },
|
||||
{ name: 'Galician', value: 'gl' },
|
||||
{ name: 'Gujarati', value: 'gu' },
|
||||
{ name: 'Hausa', value: 'ha' },
|
||||
{ name: 'Hawaiian', value: 'haw' },
|
||||
{ name: 'Hebrew', value: 'he' },
|
||||
{ name: 'Hindi', value: 'hi' },
|
||||
{ name: 'Hindi (Latin)', value: 'hi-Latn' },
|
||||
{ name: 'Croatian', value: 'hr' },
|
||||
{ name: 'Haitian', value: 'ht' },
|
||||
{ name: 'Hungarian', value: 'hu' },
|
||||
{ name: 'Armenian', value: 'hy' },
|
||||
{ name: 'Indonesian', value: 'id' },
|
||||
{ name: 'Indonesian (Indonesia)', value: 'id-ID' },
|
||||
{ name: 'Icelandic', value: 'is' },
|
||||
{ name: 'Italian', value: 'it' },
|
||||
{ name: 'Italian (Italy)', value: 'it-IT' },
|
||||
{ name: 'Japanese', value: 'ja' },
|
||||
{ name: 'Japanese (Japan)', value: 'ja-JP' },
|
||||
{ name: 'Javanese', value: 'jw' },
|
||||
{ name: 'Georgian', value: 'ka' },
|
||||
{ name: 'Kazakh', value: 'kk' },
|
||||
{ name: 'Khmer', value: 'km' },
|
||||
{ name: 'Kannada', value: 'kn' },
|
||||
{ name: 'Korean', value: 'ko' },
|
||||
{ name: 'Korean (South Korea)', value: 'ko-KR' },
|
||||
{ name: 'Latvian', value: 'lv' },
|
||||
{ name: 'Korean (Republic of Korea)', value: 'ko-KR' },
|
||||
{ name: 'Latin', value: 'la' },
|
||||
{ name: 'Luxembourgish', value: 'lb' },
|
||||
{ name: 'Lingala', value: 'ln' },
|
||||
{ name: 'Lao', value: 'lo' },
|
||||
{ name: 'Lithuanian', value: 'lt' },
|
||||
{ name: 'Latvian', value: 'lv' },
|
||||
{ name: 'Malagasy', value: 'mg' },
|
||||
{ name: 'Maori', value: 'mi' },
|
||||
{ name: 'Macedonian', value: 'mk' },
|
||||
{ name: 'Malayalam', value: 'ml' },
|
||||
{ name: 'Mongolian', value: 'mn' },
|
||||
{ name: 'Marathi', value: 'mr' },
|
||||
{ name: 'Malay', value: 'ms' },
|
||||
{ name: 'Malay (Malaysia)', value: 'ms-MY' },
|
||||
{ name: 'Malay (Singapore)', value: 'ms-SG' },
|
||||
{ name: 'Maltese', value: 'mt' },
|
||||
{ name: 'Burmese', value: 'my' },
|
||||
{ name: 'Nepali', value: 'ne' },
|
||||
{ name: 'Dutch', value: 'nl' },
|
||||
{ name: 'Dutch (Belgium)', value: 'nl-BE' },
|
||||
{ name: 'Dutch (Netherlands)', value: 'nl-NL' },
|
||||
{ name: 'Norwegian Nynorsk', value: 'nn' },
|
||||
{ name: 'Norwegian', value: 'no' },
|
||||
{ name: 'Norwegian (Norway)', value: 'no-NO' },
|
||||
{ name: 'Occitan', value: 'oc' },
|
||||
{ name: 'Panjabi', value: 'pa' },
|
||||
{ name: 'Polish', value: 'pl' },
|
||||
{ name: 'Polish (Poland)', value: 'pl-PL' },
|
||||
{ name: 'Pushto', value: 'ps' },
|
||||
{ name: 'Portuguese', value: 'pt' },
|
||||
{ name: 'Portuguese (Brazil)', value: 'pt-BR' },
|
||||
{ name: 'Portuguese (Portugal)', value: 'pt-PT' },
|
||||
{ name: 'Romanian', value: 'ro' },
|
||||
{ name: 'Romanian (Moldova)', value: 'ro-MD' },
|
||||
{ name: 'Russian', value: 'ru' },
|
||||
{ name: 'Russian (Latin)', value: 'ru-Latn' },
|
||||
{ name: 'Russian (Russian Federation)', value: 'ru-RU' },
|
||||
{ name: 'Sanskrit', value: 'sa' },
|
||||
{ name: 'Sindhi', value: 'sd' },
|
||||
{ name: 'Sinhala', value: 'si' },
|
||||
{ name: 'Slovak', value: 'sk' },
|
||||
{ name: 'Spanish', value: 'es' },
|
||||
{ name: 'Spanish (Latin America)', value: 'es-419' },
|
||||
{ name: 'Slovenian', value: 'sl' },
|
||||
{ name: 'Shona', value: 'sn' },
|
||||
{ name: 'Somali', value: 'so' },
|
||||
{ name: 'Albanian', value: 'sq' },
|
||||
{ name: 'Serbian', value: 'sr' },
|
||||
{ name: 'Sundanese', value: 'su' },
|
||||
{ name: 'Swedish', value: 'sv' },
|
||||
{ name: 'Swedish (Sweden)', value: 'sv-SE' },
|
||||
{ name: 'Swahili', value: 'sw' },
|
||||
{ name: 'Tamil', value: 'ta' },
|
||||
{ name: 'Tamasheq', value: 'taq' },
|
||||
{ name: 'Telugu', value: 'te' },
|
||||
{ name: 'Tajik', value: 'tg' },
|
||||
{ name: 'Thai', value: 'th' },
|
||||
{ name: 'Thai (Thailand)', value: 'th-TH' },
|
||||
{ name: 'Turkmen', value: 'tk' },
|
||||
{ name: 'Tagalog', value: 'tl' },
|
||||
{ name: 'Turkish', value: 'tr' },
|
||||
{ name: 'Turkish (Türkiye)', value: 'tr-TR' },
|
||||
{ name: 'Tatar', value: 'tt' },
|
||||
{ name: 'Ukrainian', value: 'uk' },
|
||||
{ name: 'Vietnamese', value: 'vi' }
|
||||
{ name: 'Urdu', value: 'ur' },
|
||||
{ name: 'Uzbek', value: 'uz' },
|
||||
{ name: 'Vietnamese', value: 'vi' },
|
||||
{ name: 'Yiddish', value: 'yi' },
|
||||
{ name: 'Yoruba', value: 'yo' },
|
||||
{ name: 'Chinese (Mandarin, Mainland)', value: 'zh' },
|
||||
{ name: 'Chinese (China)', value: 'zh-CN' },
|
||||
{ name: 'Chinese (Cantonese, Hong Kong)', value: 'zh-HK' },
|
||||
{ name: 'Chinese (Han (Simplified variant))', value: 'zh-Hans' },
|
||||
{ name: 'Chinese (Han (Traditional variant))', value: 'zh-Hant' },
|
||||
{ name: 'Chinese (Traditional, Taiwan)', value: 'zh-TW' }
|
||||
];
|
||||
|
||||
@@ -686,7 +686,7 @@ function decryptCredential(obj, credential, logger, isObscureKey = true) {
|
||||
obj.deepgram_tts_uri = o.deepgram_tts_uri;
|
||||
obj.model_id = o.model_id;
|
||||
}
|
||||
else if ('deepgramriver' === obj.vendor) {
|
||||
else if ('deepgramflux' === obj.vendor) {
|
||||
const o = JSON.parse(decrypt(credential));
|
||||
obj.api_key = isObscureKey ? obscureKey(o.api_key) : o.api_key;
|
||||
}
|
||||
@@ -935,8 +935,30 @@ async function getLanguagesVoicesForDeepgram(credential, getTtsVoices, logger) {
|
||||
logger.error({response}, 'Error fetching Deepgram voices');
|
||||
throw new Error('failed to list voices');
|
||||
}
|
||||
const {stt, tts} = await response.json();
|
||||
let sttLangs = SttDeepgramLanguagesVoices;
|
||||
const {stt, tts, languages} = await response.json();
|
||||
// Helper function to get language name
|
||||
const getLanguageName = (langCode) => {
|
||||
if (languages && languages[langCode]) {
|
||||
return languages[langCode];
|
||||
}
|
||||
const existingLang = SttDeepgramLanguagesVoices.find((l) => l.value === langCode);
|
||||
return existingLang ? existingLang.name : capitalizeFirst(langCode);
|
||||
};
|
||||
// Collect unique languages from selected models
|
||||
const allSttLanguages = new Set();
|
||||
const modelsToProcess = model_id ?
|
||||
stt.filter((m) => m.canonical_name === model_id) :
|
||||
stt;
|
||||
modelsToProcess.forEach((model) => {
|
||||
if (model.languages && Array.isArray(model.languages)) {
|
||||
model.languages.forEach((lang) => allSttLanguages.add(lang));
|
||||
}
|
||||
});
|
||||
// Convert to expected format
|
||||
const sttLangs = Array.from(allSttLanguages).map((langCode) => ({
|
||||
name: getLanguageName(langCode),
|
||||
value: langCode
|
||||
})).sort((a, b) => a.name.localeCompare(b.name));
|
||||
const sttModels = Array.from(
|
||||
new Map(
|
||||
stt.map((m) => [m.canonical_name, { name: capitalizeFirst(m.canonical_name), value: m.canonical_name }])
|
||||
@@ -947,16 +969,6 @@ async function getLanguagesVoicesForDeepgram(credential, getTtsVoices, logger) {
|
||||
tts.map((m) => [m.canonical_name, { name: capitalizeFirst(m.canonical_name), value: m.canonical_name }])
|
||||
).values()
|
||||
).sort((a, b) => a.name.localeCompare(b.name));
|
||||
// if model_id is not provided, return all models, all voices, all languages
|
||||
if (!model_id) {
|
||||
return tranform(TtsLanguagesDeepgram, sttLangs, ttsModels, sttModels);
|
||||
}
|
||||
|
||||
const selectedSttModel = stt.find((m) => m.canonical_name === model_id);
|
||||
const selectedSttLangs = selectedSttModel ? selectedSttModel.languages : [];
|
||||
sttLangs = SttDeepgramLanguagesVoices.filter((l) => {
|
||||
return selectedSttLangs.includes(l.value);
|
||||
});
|
||||
return tranform(TtsLanguagesDeepgram, sttLangs, ttsModels, sttModels);
|
||||
}
|
||||
}
|
||||
|
||||
17
package-lock.json
generated
17
package-lock.json
generated
@@ -20,9 +20,9 @@
|
||||
"@jambonz/lamejs": "^1.2.2",
|
||||
"@jambonz/mw-registrar": "^0.2.7",
|
||||
"@jambonz/realtimedb-helpers": "^0.8.15",
|
||||
"@jambonz/speech-utils": "^0.2.18",
|
||||
"@jambonz/speech-utils": "^0.2.23",
|
||||
"@jambonz/time-series": "^0.2.8",
|
||||
"@jambonz/verb-specifications": "^0.0.111",
|
||||
"@jambonz/verb-specifications": "^0.0.115",
|
||||
"@soniox/soniox-node": "^1.2.2",
|
||||
"ajv": "^8.17.1",
|
||||
"argon2": "^0.40.1",
|
||||
@@ -4086,9 +4086,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@jambonz/speech-utils": {
|
||||
"version": "0.2.19",
|
||||
"resolved": "https://registry.npmjs.org/@jambonz/speech-utils/-/speech-utils-0.2.19.tgz",
|
||||
"integrity": "sha512-7Sw2pgmsMg/3y3PRhRts/oQrtMlowNS1dn6DgduiHviKSclJNx8oY8S7X8wsBQCe3xdFZYEDxfn9vpcGm4lqZw==",
|
||||
"version": "0.2.23",
|
||||
"resolved": "https://registry.npmjs.org/@jambonz/speech-utils/-/speech-utils-0.2.23.tgz",
|
||||
"integrity": "sha512-o28IBoKzdnQoUUSC1XljHVkDPWhkTH+rFnI9OWYC6p1/f8px++4Y23/JMIAJVbxqKB1CIf531JhTwy4tCnQP7g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"23": "^0.0.0",
|
||||
"@aws-sdk/client-polly": "^3.496.0",
|
||||
@@ -4253,9 +4254,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@jambonz/verb-specifications": {
|
||||
"version": "0.0.111",
|
||||
"resolved": "https://registry.npmjs.org/@jambonz/verb-specifications/-/verb-specifications-0.0.111.tgz",
|
||||
"integrity": "sha512-P2lDki5wCHGPPXpPTeMdht4NfGujF6NrLyrI8o/4U6l+2elfc/1mKl/Lz/PWGo9rQM4mTOVIhkk9ECo0NvOVoA==",
|
||||
"version": "0.0.115",
|
||||
"resolved": "https://registry.npmjs.org/@jambonz/verb-specifications/-/verb-specifications-0.0.115.tgz",
|
||||
"integrity": "sha512-T2J5skCZBADaxePkFqpm0JYwr5Iu6e9zgvk6j0/4vD6lwK29GSoSdk2LCKUY6VH2GYdaN6r3dyIw4xpFVXuMfQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.3.4",
|
||||
|
||||
@@ -31,9 +31,9 @@
|
||||
"@jambonz/lamejs": "^1.2.2",
|
||||
"@jambonz/mw-registrar": "^0.2.7",
|
||||
"@jambonz/realtimedb-helpers": "^0.8.15",
|
||||
"@jambonz/speech-utils": "^0.2.18",
|
||||
"@jambonz/speech-utils": "^0.2.23",
|
||||
"@jambonz/time-series": "^0.2.8",
|
||||
"@jambonz/verb-specifications": "^0.0.111",
|
||||
"@jambonz/verb-specifications": "^0.0.115",
|
||||
"@soniox/soniox-node": "^1.2.2",
|
||||
"ajv": "^8.17.1",
|
||||
"argon2": "^0.40.1",
|
||||
|
||||
@@ -930,21 +930,21 @@ test('speech credentials tests', async(t) => {
|
||||
auth: authUser,
|
||||
json: true,
|
||||
body: {
|
||||
vendor: 'deepgramriver',
|
||||
vendor: 'deepgramflux',
|
||||
use_for_tts: false,
|
||||
use_for_stt: true,
|
||||
api_key: 'api_key',
|
||||
}
|
||||
});
|
||||
t.ok(result.statusCode === 201, 'successfully added speech credential for Verbio');
|
||||
const deepgramriverSid = result.body.sid;
|
||||
const deepgramfluxSid = result.body.sid;
|
||||
|
||||
/* delete the credential */
|
||||
result = await request.delete(`/Accounts/${account_sid}/SpeechCredentials/${deepgramriverSid}`, {
|
||||
result = await request.delete(`/Accounts/${account_sid}/SpeechCredentials/${deepgramfluxSid}`, {
|
||||
auth: authUser,
|
||||
resolveWithFullResponse: true,
|
||||
});
|
||||
t.ok(result.statusCode === 204, 'successfully deleted speech credential deepgramriver');
|
||||
t.ok(result.statusCode === 204, 'successfully deleted speech credential deepgramflux');
|
||||
|
||||
/* Check google supportedLanguagesAndVoices */
|
||||
result = await request.get(`/Accounts/${account_sid}/SpeechCredentials/speech/supportedLanguagesAndVoices?vendor=google`, {
|
||||
|
||||
Reference in New Issue
Block a user