@fonoster/apiserver 0.6.2 → 0.7.0
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/dist/applications/buildService.d.ts +3 -3
- package/dist/applications/createApplication.d.ts +2 -2
- package/dist/applications/createGetFnUtil.d.ts +2 -2
- package/dist/applications/deleteApplication.d.ts +3 -3
- package/dist/applications/getApplication.d.ts +2 -2
- package/dist/applications/getApplication.js +1 -3
- package/dist/applications/types.d.ts +1 -1
- package/dist/applications/utils/applicationWithEncodedStruct.js +20 -1
- package/dist/applications/utils/convertToApplicationData.js +1 -1
- package/dist/applications/utils/getApplicationValidationSchema.d.ts +3 -3
- package/dist/applications/utils/getApplicationValidationSchema.js +6 -3
- package/dist/applications/utils/prepareForValidation.js +1 -1
- package/dist/calls/ListCallsRequestSchema.d.ts +1 -4
- package/dist/calls/ListCallsRequestSchema.js +0 -4
- package/dist/calls/buildService.d.ts +2 -2
- package/dist/calls/buildService.js +6 -5
- package/dist/calls/createCall.d.ts +6 -4
- package/dist/calls/createCall.js +18 -8
- package/dist/calls/createFetchCalls.js +3 -7
- package/dist/calls/createFetchSingleCall.js +9 -2
- package/dist/calls/{trackCall.d.ts → makeTrackCall.d.ts} +3 -3
- package/dist/calls/makeTrackCall.js +67 -0
- package/dist/calls/runCallManager.js +12 -13
- package/dist/calls/types.d.ts +8 -42
- package/dist/calls/types.js +5 -38
- package/dist/core/seed.js +20 -0
- package/dist/core/services.d.ts +24 -25
- package/dist/envs.d.ts +0 -2
- package/dist/envs.js +1 -3
- package/dist/events/createInfluxDbPub.js +2 -1
- package/dist/events/mapCallDirectionToEnum.d.ts +3 -0
- package/dist/events/mapCallDirectionToEnum.js +37 -0
- package/dist/events/nats.js +5 -6
- package/dist/events/transformEvent.d.ts +2 -0
- package/dist/events/transformEvent.js +72 -0
- package/dist/index.js +4 -5
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/makeHandleDialEventsWithNats.d.ts +5 -0
- package/dist/{voice/handlers/StasisEnd.js → utils/makeHandleDialEventsWithNats.js} +10 -15
- package/dist/utils/makeHandleDialEventsWithVoiceClient.d.ts +5 -0
- package/dist/{voice/handlers/dial/handleDialEvents.js → utils/makeHandleDialEventsWithVoiceClient.js} +6 -17
- package/dist/utils/mapDialStatus.d.ts +3 -0
- package/dist/utils/mapDialStatus.js +38 -0
- package/dist/voice/VoiceClientImpl.d.ts +10 -1
- package/dist/voice/VoiceClientImpl.js +47 -7
- package/dist/voice/VoiceDispatcher.d.ts +6 -2
- package/dist/voice/VoiceDispatcher.js +50 -37
- package/dist/voice/connectToAri.js +3 -1
- package/dist/voice/createExternalMediaConfig.d.ts +3 -0
- package/dist/voice/createExternalMediaConfig.js +4 -1
- package/dist/voice/handlers/Answer.js +1 -1
- package/dist/voice/handlers/Hangup.js +1 -1
- package/dist/voice/handlers/Mute.js +1 -1
- package/dist/voice/handlers/Play.js +2 -2
- package/dist/voice/handlers/PlayDtmf.js +1 -1
- package/dist/voice/handlers/PlaybackControl.js +1 -1
- package/dist/voice/handlers/Record.js +2 -2
- package/dist/voice/handlers/Say.js +2 -2
- package/dist/voice/handlers/StreamGather.d.ts +3 -0
- package/dist/voice/handlers/StreamGather.js +66 -0
- package/dist/voice/handlers/Unmute.js +1 -1
- package/dist/voice/handlers/dial/Dial.js +10 -6
- package/dist/voice/handlers/gather/Gather.js +5 -4
- package/dist/voice/handlers/index.d.ts +12 -0
- package/dist/voice/handlers/index.js +46 -0
- package/dist/voice/handlers/{awaitForPlaybackFinished.js → utils/awaitForPlaybackFinished.js} +1 -1
- package/dist/voice/handlers/{awaitForRecordingFinished.js → utils/awaitForRecordingFinished.js} +1 -1
- package/dist/voice/handlers/utils/index.d.ts +3 -0
- package/dist/voice/handlers/utils/index.js +37 -0
- package/dist/voice/handlers/utils/isDtmf.d.ts +2 -0
- package/dist/voice/handlers/utils/isDtmf.js +24 -0
- package/dist/voice/integrations/findIntegrationsCredentials.d.ts +1 -1
- package/dist/voice/integrations/findIntegrationsCredentials.js +2 -1
- package/dist/voice/integrations/getSttConfig.d.ts +4 -2
- package/dist/voice/integrations/getSttConfig.js +4 -1
- package/dist/voice/integrations/getTtsConfig.d.ts +2 -1
- package/dist/voice/integrations/getTtsConfig.js +5 -1
- package/dist/voice/integrations/makeCreateContainer.js +1 -1
- package/dist/voice/integrations/types.d.ts +1 -1
- package/dist/voice/makeCreateVoiceClient.js +4 -10
- package/dist/voice/makeGetChannelVar.d.ts +2 -1
- package/dist/voice/makeGetChannelVar.js +13 -0
- package/dist/voice/stt/AbstractSpeechToText.d.ts +4 -3
- package/dist/voice/stt/Deepgram.d.ts +18 -0
- package/dist/voice/stt/Deepgram.js +156 -0
- package/dist/voice/stt/Google.d.ts +5 -6
- package/dist/voice/stt/Google.js +13 -13
- package/dist/voice/stt/SpeechToTextFactory.js +2 -0
- package/dist/voice/stt/types.d.ts +22 -10
- package/dist/voice/stt/types.js +7 -0
- package/dist/voice/tts/Deepgram.d.ts +25 -0
- package/dist/voice/tts/Deepgram.js +122 -0
- package/dist/voice/tts/Google.d.ts +2 -1
- package/dist/voice/tts/Google.js +7 -8
- package/dist/voice/tts/TextToSpeechFactory.js +2 -0
- package/dist/voice/types/ari.d.ts +2 -1
- package/dist/voice/types/ari.js +1 -0
- package/dist/voice/types/voice.d.ts +9 -1
- package/package.json +10 -9
- package/dist/calls/createTrackCallSubscriber.d.ts +0 -5
- package/dist/calls/createTrackCallSubscriber.js +0 -52
- package/dist/calls/trackCall.js +0 -63
- package/dist/voice/handlers/StasisEnd.d.ts +0 -4
- package/dist/voice/handlers/dial/handleDialEvents.d.ts +0 -5
- /package/dist/voice/handlers/{awaitForPlaybackFinished.d.ts → utils/awaitForPlaybackFinished.d.ts} +0 -0
- /package/dist/voice/handlers/{awaitForRecordingFinished.d.ts → utils/awaitForRecordingFinished.d.ts} +0 -0
- /package/dist/voice/handlers/{withErrorHandling.d.ts → utils/withErrorHandling.d.ts} +0 -0
- /package/dist/voice/handlers/{withErrorHandling.js → utils/withErrorHandling.js} +0 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
/*
|
|
18
|
+
* Copyright (C) 2024 by Fonoster Inc (https://fonoster.com)
|
|
19
|
+
* http://github.com/fonoster/fonoster
|
|
20
|
+
*
|
|
21
|
+
* This file is part of Fonoster
|
|
22
|
+
*
|
|
23
|
+
* Licensed under the MIT License (the "License");
|
|
24
|
+
* you may not use this file except in compliance with
|
|
25
|
+
* the License. You may obtain a copy of the License at
|
|
26
|
+
*
|
|
27
|
+
* https://opensource.org/licenses/MIT
|
|
28
|
+
*
|
|
29
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
30
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
31
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
32
|
+
* See the License for the specific language governing permissions and
|
|
33
|
+
* limitations under the License.
|
|
34
|
+
*/
|
|
35
|
+
__exportStar(require("./awaitForPlaybackFinished"), exports);
|
|
36
|
+
__exportStar(require("./awaitForRecordingFinished"), exports);
|
|
37
|
+
__exportStar(require("./isDtmf"), exports);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isDtmf = isDtmf;
|
|
4
|
+
/*
|
|
5
|
+
* Copyright (C) 2024 by Fonoster Inc (https://fonoster.com)
|
|
6
|
+
* http://github.com/fonoster/fonoster
|
|
7
|
+
*
|
|
8
|
+
* This file is part of Fonoster
|
|
9
|
+
*
|
|
10
|
+
* Licensed under the MIT License (the "License");
|
|
11
|
+
* you may not use this file except in compliance with
|
|
12
|
+
* the License. You may obtain a copy of the License at
|
|
13
|
+
*
|
|
14
|
+
* https://opensource.org/licenses/MIT
|
|
15
|
+
*
|
|
16
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
17
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
18
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
19
|
+
* See the License for the specific language governing permissions and
|
|
20
|
+
* limitations under the License.
|
|
21
|
+
*/
|
|
22
|
+
function isDtmf(digit) {
|
|
23
|
+
return /^[0-9*#]+$/.test(digit);
|
|
24
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { IntegrationConfig } from "./types";
|
|
2
|
-
declare function findIntegrationsCredentials(integrations: IntegrationConfig[], engine: string):
|
|
2
|
+
declare function findIntegrationsCredentials(integrations: IntegrationConfig[], engine: string): Record<string, unknown>;
|
|
3
3
|
export { findIntegrationsCredentials };
|
|
@@ -2,5 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.findIntegrationsCredentials = findIntegrationsCredentials;
|
|
4
4
|
function findIntegrationsCredentials(integrations, engine) {
|
|
5
|
-
|
|
5
|
+
var _a;
|
|
6
|
+
return (_a = integrations.find((i) => i.productRef === engine)) === null || _a === void 0 ? void 0 : _a.credentials;
|
|
6
7
|
}
|
|
@@ -2,7 +2,9 @@ import { VoiceLanguage } from "@fonoster/common";
|
|
|
2
2
|
import { Application } from "@fonoster/types";
|
|
3
3
|
import { IntegrationConfig } from "./types";
|
|
4
4
|
declare function getSttConfig(integrations: IntegrationConfig[], app: Application): {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
config: {
|
|
6
|
+
languageCode: VoiceLanguage;
|
|
7
|
+
};
|
|
8
|
+
credentials: Record<string, unknown>;
|
|
7
9
|
};
|
|
8
10
|
export { getSttConfig };
|
|
@@ -5,5 +5,8 @@ const findIntegrationsCredentials_1 = require("./findIntegrationsCredentials");
|
|
|
5
5
|
function getSttConfig(integrations, app) {
|
|
6
6
|
const config = app.speechToText.config;
|
|
7
7
|
const credentials = (0, findIntegrationsCredentials_1.findIntegrationsCredentials)(integrations, app.speechToText.productRef);
|
|
8
|
-
return
|
|
8
|
+
return {
|
|
9
|
+
config,
|
|
10
|
+
credentials
|
|
11
|
+
};
|
|
9
12
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Application } from "@fonoster/types";
|
|
2
2
|
import { IntegrationConfig } from "./types";
|
|
3
3
|
declare function getTtsConfig(integrations: IntegrationConfig[], app: Application): {
|
|
4
|
-
|
|
4
|
+
config: Record<string, unknown>;
|
|
5
|
+
credentials: Record<string, unknown>;
|
|
5
6
|
pathToFiles: string;
|
|
6
7
|
};
|
|
7
8
|
export { getTtsConfig };
|
|
@@ -6,5 +6,9 @@ const envs_1 = require("../../envs");
|
|
|
6
6
|
function getTtsConfig(integrations, app) {
|
|
7
7
|
const config = app.textToSpeech.config;
|
|
8
8
|
const credentials = (0, findIntegrationsCredentials_1.findIntegrationsCredentials)(integrations, app.textToSpeech.productRef);
|
|
9
|
-
return
|
|
9
|
+
return {
|
|
10
|
+
config,
|
|
11
|
+
credentials,
|
|
12
|
+
pathToFiles: envs_1.TTS_PATH_TO_FILES
|
|
13
|
+
};
|
|
10
14
|
}
|
|
@@ -43,24 +43,18 @@ function makeCreateVoiceClient(createContainer) {
|
|
|
43
43
|
const { ari, event, channel } = params;
|
|
44
44
|
const { id: sessionRef, caller } = event.channel;
|
|
45
45
|
const { name: callerName, number: callerNumber } = caller;
|
|
46
|
-
const getChannelVar = (0, makeGetChannelVar_1.
|
|
46
|
+
const getChannelVar = (0, makeGetChannelVar_1.makeGetChannelVarWithoutThrow)(channel);
|
|
47
47
|
// Variables set by Asterisk's dialplan
|
|
48
48
|
const appRef = (_a = (yield getChannelVar(types_1.ChannelVar.APP_REF))) === null || _a === void 0 ? void 0 : _a.value;
|
|
49
49
|
const ingressNumber = ((_b = (yield getChannelVar(types_1.ChannelVar.INGRESS_NUMBER))) === null || _b === void 0 ? void 0 : _b.value) || "";
|
|
50
|
-
const { accessKeyId,
|
|
50
|
+
const { accessKeyId, endpoint, tts, stt } = yield createContainer(appRef);
|
|
51
51
|
const sessionToken = yield createToken({ accessKeyId, appRef });
|
|
52
|
-
|
|
53
|
-
try {
|
|
54
|
-
metadataStr = (_c = (yield getChannelVar(types_1.ChannelVar.METADATA))) === null || _c === void 0 ? void 0 : _c.value;
|
|
55
|
-
}
|
|
56
|
-
catch (e) {
|
|
57
|
-
// Do nothing
|
|
58
|
-
}
|
|
52
|
+
const metadataStr = (_c = (yield getChannelVar(types_1.ChannelVar.METADATA))) === null || _c === void 0 ? void 0 : _c.value;
|
|
59
53
|
const config = {
|
|
60
54
|
appRef,
|
|
61
55
|
sessionRef,
|
|
62
56
|
accessKeyId,
|
|
63
|
-
|
|
57
|
+
endpoint,
|
|
64
58
|
callerName,
|
|
65
59
|
callerNumber,
|
|
66
60
|
ingressNumber,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Channel } from "ari-client";
|
|
2
2
|
import { ChannelVar } from "./types";
|
|
3
3
|
declare function makeGetChannelVar(channel: Channel): (variable: ChannelVar) => Promise<import("ari-client").Variable>;
|
|
4
|
-
|
|
4
|
+
declare function makeGetChannelVarWithoutThrow(channel: Channel): (variable: ChannelVar) => Promise<import("ari-client").Variable>;
|
|
5
|
+
export { makeGetChannelVar, makeGetChannelVarWithoutThrow };
|
|
@@ -10,6 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.makeGetChannelVar = makeGetChannelVar;
|
|
13
|
+
exports.makeGetChannelVarWithoutThrow = makeGetChannelVarWithoutThrow;
|
|
13
14
|
const ChannelVarNotFoundError_1 = require("./ChannelVarNotFoundError");
|
|
14
15
|
function makeGetChannelVar(channel) {
|
|
15
16
|
return (variable) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -23,3 +24,15 @@ function makeGetChannelVar(channel) {
|
|
|
23
24
|
}
|
|
24
25
|
});
|
|
25
26
|
}
|
|
27
|
+
function makeGetChannelVarWithoutThrow(channel) {
|
|
28
|
+
return (variable) => __awaiter(this, void 0, void 0, function* () {
|
|
29
|
+
try {
|
|
30
|
+
return yield channel.getChannelVar({
|
|
31
|
+
variable
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
catch (e) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Stream } from "stream";
|
|
2
2
|
import * as z from "zod";
|
|
3
|
-
import { SpeechResult,
|
|
4
|
-
|
|
3
|
+
import { SpeechResult, StreamSpeech, SttConfig } from "./types";
|
|
4
|
+
import { SpeechToText } from "../types";
|
|
5
|
+
declare abstract class AbstractSpeechToText<E, T extends SttConfig = SttConfig> implements SpeechToText {
|
|
5
6
|
abstract readonly engineName: E;
|
|
6
7
|
config: T;
|
|
7
8
|
constructor(config: T);
|
|
8
|
-
abstract streamTranscribe(stream: Stream):
|
|
9
|
+
abstract streamTranscribe(stream: Stream): StreamSpeech;
|
|
9
10
|
abstract transcribe(stream: Stream): Promise<SpeechResult>;
|
|
10
11
|
getName(): E;
|
|
11
12
|
static getConfigValidationSchema(): z.Schema;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Stream } from "stream";
|
|
2
|
+
import * as z from "zod";
|
|
3
|
+
import { AbstractSpeechToText } from "./AbstractSpeechToText";
|
|
4
|
+
import { DeepgramSttConfig, SpeechResult, StreamSpeech } from "./types";
|
|
5
|
+
import { SpeechToText } from "../types";
|
|
6
|
+
declare const DeepgramClient: any;
|
|
7
|
+
declare const ENGINE_NAME = "stt.deepgram";
|
|
8
|
+
declare class Deepgram extends AbstractSpeechToText<typeof ENGINE_NAME> implements SpeechToText {
|
|
9
|
+
client: typeof DeepgramClient;
|
|
10
|
+
engineConfig: DeepgramSttConfig;
|
|
11
|
+
readonly engineName = "stt.deepgram";
|
|
12
|
+
constructor(config: DeepgramSttConfig);
|
|
13
|
+
streamTranscribe(stream: Stream): StreamSpeech;
|
|
14
|
+
transcribe(stream: Stream): Promise<SpeechResult>;
|
|
15
|
+
static getConfigValidationSchema(): z.Schema;
|
|
16
|
+
static getCredentialsValidationSchema(): z.Schema;
|
|
17
|
+
}
|
|
18
|
+
export { Deepgram, ENGINE_NAME };
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
+
exports.ENGINE_NAME = exports.Deepgram = void 0;
|
|
36
|
+
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
37
|
+
/*
|
|
38
|
+
* Copyright (C) 2024 by Fonoster Inc (https://fonoster.com)
|
|
39
|
+
* http://github.com/fonoster/fonoster
|
|
40
|
+
*
|
|
41
|
+
* This file is part of Fonoster
|
|
42
|
+
*
|
|
43
|
+
* Licensed under the MIT License (the "License");
|
|
44
|
+
* you may not use this file except in compliance with
|
|
45
|
+
* the License. You may obtain a copy of the License at
|
|
46
|
+
*
|
|
47
|
+
* https://opensource.org/licenses/MIT
|
|
48
|
+
*
|
|
49
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
50
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
51
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
52
|
+
* See the License for the specific language governing permissions and
|
|
53
|
+
* limitations under the License.
|
|
54
|
+
*/
|
|
55
|
+
const stream_1 = require("stream");
|
|
56
|
+
const common_1 = require("@fonoster/common");
|
|
57
|
+
const logger_1 = require("@fonoster/logger");
|
|
58
|
+
const z = __importStar(require("zod"));
|
|
59
|
+
const AbstractSpeechToText_1 = require("./AbstractSpeechToText");
|
|
60
|
+
const types_1 = require("./types");
|
|
61
|
+
const { DeepgramClient, LiveTranscriptionEvents, createClient } = require("@deepgram/sdk"); // Why Deepgram :(
|
|
62
|
+
const ENGINE_NAME = "stt.deepgram";
|
|
63
|
+
exports.ENGINE_NAME = ENGINE_NAME;
|
|
64
|
+
const logger = (0, logger_1.getLogger)({ service: "apiserver", filePath: __filename });
|
|
65
|
+
class Deepgram extends AbstractSpeechToText_1.AbstractSpeechToText {
|
|
66
|
+
constructor(config) {
|
|
67
|
+
super(config);
|
|
68
|
+
this.engineName = ENGINE_NAME;
|
|
69
|
+
this.client = createClient(config.credentials.apiKey);
|
|
70
|
+
this.engineConfig = config;
|
|
71
|
+
}
|
|
72
|
+
streamTranscribe(stream) {
|
|
73
|
+
const connection = this.client.listen.live(buildTranscribeConfig(this.engineConfig.config));
|
|
74
|
+
const out = new stream_1.Stream();
|
|
75
|
+
connection.on(LiveTranscriptionEvents.Open, () => {
|
|
76
|
+
// WARNING: This is a workaround to keep the connection open while the system
|
|
77
|
+
// is playing a file which causes the stream to be paused. We need to look into why
|
|
78
|
+
// the stream is being paused.
|
|
79
|
+
const keepAliveInterval = setInterval(() => {
|
|
80
|
+
const keepAliveMsg = JSON.stringify({ type: "KeepAlive" });
|
|
81
|
+
connection.send(keepAliveMsg);
|
|
82
|
+
}, 3000);
|
|
83
|
+
stream.on("data", (chunk) => {
|
|
84
|
+
connection.send(chunk);
|
|
85
|
+
});
|
|
86
|
+
connection.on(LiveTranscriptionEvents.Transcript, (data) => {
|
|
87
|
+
if (!data.channel.alternatives[0].transcript || !data.speech_final) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
out.emit("data", {
|
|
91
|
+
speech: data.channel.alternatives[0].transcript
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
connection.on(LiveTranscriptionEvents.Error, (err) => {
|
|
95
|
+
logger.warn("error on Deepgram connection", { err });
|
|
96
|
+
clearInterval(keepAliveInterval);
|
|
97
|
+
connection.destroy();
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
return out;
|
|
101
|
+
}
|
|
102
|
+
transcribe(stream) {
|
|
103
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
104
|
+
return new Promise((resolve, reject) => {
|
|
105
|
+
const connection = this.client.listen.live(buildTranscribeConfig(this.engineConfig.config));
|
|
106
|
+
stream.on("data", (chunk) => {
|
|
107
|
+
connection.send(chunk);
|
|
108
|
+
});
|
|
109
|
+
connection.on(LiveTranscriptionEvents.Open, () => {
|
|
110
|
+
connection.on(LiveTranscriptionEvents.Transcript, (data) => {
|
|
111
|
+
if (data.channel.alternatives[0].transcript && data.speech_final) {
|
|
112
|
+
const result = {
|
|
113
|
+
speech: data.channel.alternatives[0].transcript,
|
|
114
|
+
isFinal: true
|
|
115
|
+
};
|
|
116
|
+
resolve(result);
|
|
117
|
+
connection.destroy();
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
connection.on(LiveTranscriptionEvents.Error, (err) => {
|
|
121
|
+
logger.warn("error on Deepgram connection", { err });
|
|
122
|
+
reject(err);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
stream.on("end", () => {
|
|
126
|
+
connection.destroy();
|
|
127
|
+
});
|
|
128
|
+
stream.on("error", (err) => {
|
|
129
|
+
connection.destroy();
|
|
130
|
+
reject(err);
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
static getConfigValidationSchema() {
|
|
136
|
+
return z.object({
|
|
137
|
+
languageCode: z.nativeEnum(common_1.VoiceLanguage).optional().nullable(),
|
|
138
|
+
model: z.nativeEnum(types_1.DeepgramModel).optional().nullable()
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
static getCredentialsValidationSchema() {
|
|
142
|
+
return z.object({
|
|
143
|
+
apiKey: z.string()
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
exports.Deepgram = Deepgram;
|
|
148
|
+
function buildTranscribeConfig(config) {
|
|
149
|
+
return {
|
|
150
|
+
model: config.model || types_1.DeepgramModel.NOVA_2_PHONECALL,
|
|
151
|
+
encoding: "linear16",
|
|
152
|
+
sample_rate: 16000,
|
|
153
|
+
language: config.languageCode || common_1.VoiceLanguage.EN_US,
|
|
154
|
+
smart_format: true
|
|
155
|
+
};
|
|
156
|
+
}
|
|
@@ -2,16 +2,15 @@ import { Stream } from "stream";
|
|
|
2
2
|
import { SpeechClient } from "@google-cloud/speech";
|
|
3
3
|
import * as z from "zod";
|
|
4
4
|
import { AbstractSpeechToText } from "./AbstractSpeechToText";
|
|
5
|
-
import { GoogleSttConfig, SpeechResult,
|
|
5
|
+
import { GoogleSttConfig, SpeechResult, StreamSpeech } from "./types";
|
|
6
|
+
import { SpeechToText } from "../types";
|
|
6
7
|
declare const ENGINE_NAME = "stt.google";
|
|
7
|
-
declare class Google extends AbstractSpeechToText<typeof ENGINE_NAME> {
|
|
8
|
+
declare class Google extends AbstractSpeechToText<typeof ENGINE_NAME> implements SpeechToText {
|
|
8
9
|
client: SpeechClient;
|
|
9
|
-
|
|
10
|
+
engineConfig: GoogleSttConfig;
|
|
10
11
|
readonly engineName = "stt.google";
|
|
11
|
-
protected readonly AUDIO_ENCODING = "LINEAR16";
|
|
12
|
-
protected readonly SAMPLE_RATE_HERTZ = 16000;
|
|
13
12
|
constructor(config: GoogleSttConfig);
|
|
14
|
-
streamTranscribe(_: Stream):
|
|
13
|
+
streamTranscribe(_: Stream): StreamSpeech;
|
|
15
14
|
transcribe(stream: Stream): Promise<SpeechResult>;
|
|
16
15
|
static getConfigValidationSchema(): z.Schema;
|
|
17
16
|
static getCredentialsValidationSchema(): z.Schema;
|
package/dist/voice/stt/Google.js
CHANGED
|
@@ -39,32 +39,32 @@ const z = __importStar(require("zod"));
|
|
|
39
39
|
const AbstractSpeechToText_1 = require("./AbstractSpeechToText");
|
|
40
40
|
const ENGINE_NAME = "stt.google";
|
|
41
41
|
exports.ENGINE_NAME = ENGINE_NAME;
|
|
42
|
-
const AUDIO_ENCODING = "LINEAR16";
|
|
43
|
-
const SAMPLE_RATE_HERTZ = 16000;
|
|
44
42
|
class Google extends AbstractSpeechToText_1.AbstractSpeechToText {
|
|
45
43
|
constructor(config) {
|
|
46
44
|
super(config);
|
|
47
45
|
this.engineName = ENGINE_NAME;
|
|
48
|
-
this.AUDIO_ENCODING = AUDIO_ENCODING;
|
|
49
|
-
this.SAMPLE_RATE_HERTZ = SAMPLE_RATE_HERTZ;
|
|
50
46
|
this.client = new speech_1.SpeechClient(config);
|
|
51
|
-
this.
|
|
52
|
-
encoding: AUDIO_ENCODING,
|
|
53
|
-
sampleRateHertz: SAMPLE_RATE_HERTZ,
|
|
54
|
-
interimResults: false,
|
|
55
|
-
languageCode: config.languageCode
|
|
56
|
-
} });
|
|
47
|
+
this.engineConfig = config;
|
|
57
48
|
}
|
|
58
49
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
59
50
|
streamTranscribe(_) {
|
|
60
51
|
// Not implemented
|
|
61
|
-
|
|
52
|
+
throw new Error("Stream Transcribe not implemented for Google Engine");
|
|
62
53
|
}
|
|
63
54
|
transcribe(stream) {
|
|
64
55
|
return __awaiter(this, void 0, void 0, function* () {
|
|
56
|
+
const languageCode = this.engineConfig.config.languageCode || common_1.VoiceLanguage.EN_US;
|
|
57
|
+
const audioConfig = {
|
|
58
|
+
interimResults: false,
|
|
59
|
+
config: {
|
|
60
|
+
encoding: "LINEAR16",
|
|
61
|
+
sampleRateHertz: 16000,
|
|
62
|
+
languageCode
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
65
|
return new Promise((resolve, reject) => {
|
|
66
66
|
const recognizeStream = this.client
|
|
67
|
-
.streamingRecognize(
|
|
67
|
+
.streamingRecognize(audioConfig)
|
|
68
68
|
.on("error", (e) => reject(e))
|
|
69
69
|
.on("data", (data) => {
|
|
70
70
|
var _a;
|
|
@@ -86,7 +86,7 @@ class Google extends AbstractSpeechToText_1.AbstractSpeechToText {
|
|
|
86
86
|
}
|
|
87
87
|
static getConfigValidationSchema() {
|
|
88
88
|
return z.object({
|
|
89
|
-
languageCode: z.nativeEnum(common_1.VoiceLanguage)
|
|
89
|
+
languageCode: z.nativeEnum(common_1.VoiceLanguage).optional().nullable()
|
|
90
90
|
});
|
|
91
91
|
}
|
|
92
92
|
static getCredentialsValidationSchema() {
|
|
@@ -20,6 +20,7 @@ exports.SpeechToTextFactory = void 0;
|
|
|
20
20
|
* limitations under the License.
|
|
21
21
|
*/
|
|
22
22
|
const logger_1 = require("@fonoster/logger");
|
|
23
|
+
const Deepgram_1 = require("./Deepgram");
|
|
23
24
|
const Google_1 = require("./Google");
|
|
24
25
|
const logger = (0, logger_1.getLogger)({ service: "apiserver", filePath: __filename });
|
|
25
26
|
class SpeechToTextFactory {
|
|
@@ -39,3 +40,4 @@ exports.SpeechToTextFactory = SpeechToTextFactory;
|
|
|
39
40
|
SpeechToTextFactory.engines = new Map();
|
|
40
41
|
// Register engines
|
|
41
42
|
SpeechToTextFactory.registerEngine(Google_1.ENGINE_NAME, Google_1.Google);
|
|
43
|
+
SpeechToTextFactory.registerEngine(Deepgram_1.ENGINE_NAME, Deepgram_1.Deepgram);
|
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
import { VoiceLanguage } from "@fonoster/common/src/tts/types";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
declare enum DeepgramModel {
|
|
3
|
+
NOVA_2 = "nova-2",
|
|
4
|
+
NOVA_2_PHONECALL = "nova-2-phonecall",
|
|
5
|
+
NOVA_2_CONVERSATIONALAI = "nova-2-conversationalai"
|
|
6
|
+
}
|
|
5
7
|
type SpeechResult = {
|
|
6
8
|
speech: string;
|
|
7
9
|
isFinal: boolean;
|
|
8
10
|
};
|
|
9
|
-
type
|
|
11
|
+
type StreamSpeech = {
|
|
10
12
|
on(events: string, callback: (result: SpeechResult) => void): void;
|
|
11
|
-
close: () => void;
|
|
12
13
|
};
|
|
13
|
-
type
|
|
14
|
+
type SttConfig = {
|
|
15
|
+
config: {
|
|
16
|
+
languageCode: VoiceLanguage;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
type GoogleSttConfig = {
|
|
14
20
|
config: {
|
|
15
|
-
encoding: "LINEAR16";
|
|
16
|
-
sampleRateHertz: 16000;
|
|
17
|
-
interimResults: boolean;
|
|
18
21
|
languageCode: VoiceLanguage;
|
|
19
22
|
};
|
|
20
23
|
credentials: {
|
|
@@ -22,4 +25,13 @@ type GoogleSttConfig = SttConfig & {
|
|
|
22
25
|
private_key: string;
|
|
23
26
|
};
|
|
24
27
|
};
|
|
25
|
-
|
|
28
|
+
type DeepgramSttConfig = {
|
|
29
|
+
config: {
|
|
30
|
+
languageCode: VoiceLanguage;
|
|
31
|
+
model: DeepgramModel;
|
|
32
|
+
};
|
|
33
|
+
credentials: {
|
|
34
|
+
apiKey: string;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
export { SpeechResult, StreamSpeech, SttConfig, GoogleSttConfig, DeepgramSttConfig, DeepgramModel };
|
package/dist/voice/stt/types.js
CHANGED
|
@@ -1,2 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DeepgramModel = void 0;
|
|
4
|
+
var DeepgramModel;
|
|
5
|
+
(function (DeepgramModel) {
|
|
6
|
+
DeepgramModel["NOVA_2"] = "nova-2";
|
|
7
|
+
DeepgramModel["NOVA_2_PHONECALL"] = "nova-2-phonecall";
|
|
8
|
+
DeepgramModel["NOVA_2_CONVERSATIONALAI"] = "nova-2-conversationalai";
|
|
9
|
+
})(DeepgramModel || (exports.DeepgramModel = DeepgramModel = {}));
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
import { AbstractTextToSpeech } from "./AbstractTextToSpeech";
|
|
3
|
+
import { SynthOptions, TtsConfig } from "./types";
|
|
4
|
+
declare const DeepgramClient: any;
|
|
5
|
+
declare const ENGINE_NAME = "tts.deepgram";
|
|
6
|
+
type DeepgramTtsConfig = TtsConfig & {
|
|
7
|
+
[key: string]: Record<string, string>;
|
|
8
|
+
credentials: {
|
|
9
|
+
apiKey: string;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
declare class Deepgram extends AbstractTextToSpeech<typeof ENGINE_NAME> {
|
|
13
|
+
client: typeof DeepgramClient;
|
|
14
|
+
engineConfig: DeepgramTtsConfig;
|
|
15
|
+
readonly engineName = "tts.deepgram";
|
|
16
|
+
protected readonly OUTPUT_FORMAT = "sln16";
|
|
17
|
+
protected readonly CACHING_FIELDS: string[];
|
|
18
|
+
protected readonly AUDIO_ENCODING: "linear16";
|
|
19
|
+
protected readonly SAMPLE_RATE_HERTZ = 16000;
|
|
20
|
+
constructor(config: DeepgramTtsConfig);
|
|
21
|
+
synthesize(text: string, options: SynthOptions): Promise<string>;
|
|
22
|
+
static getConfigValidationSchema(): z.Schema;
|
|
23
|
+
static getCredentialsValidationSchema(): z.Schema;
|
|
24
|
+
}
|
|
25
|
+
export { Deepgram, ENGINE_NAME };
|