@fonoster/apiserver 0.7.24 → 0.7.26
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/createGetFnUtil.d.ts +7 -7
- package/dist/applications/deleteApplication.js +1 -1
- package/dist/applications/getApplication.js +1 -1
- package/dist/applications/utils/getApplicationValidationSchema.d.ts +6 -6
- package/dist/applications/utils/getApplicationValidationSchema.js +3 -1
- package/dist/core/allowList.js +3 -0
- package/dist/core/{filesServer.d.ts → httpBridge.d.ts} +2 -2
- package/dist/core/{filesServer.js → httpBridge.js} +26 -4
- package/dist/core/identityConfig.d.ts +9 -0
- package/dist/core/identityConfig.js +9 -0
- package/dist/core/runServices.js +19 -9
- package/dist/core/services.d.ts +9 -0
- package/dist/envs.d.ts +8 -2
- package/dist/envs.js +21 -9
- package/dist/index.js +17 -7
- package/dist/secrets/createGetFnUtil.d.ts +2 -2
- package/dist/secrets/createGetFnUtil.js +1 -1
- package/dist/secrets/deleteSecret.js +1 -1
- package/dist/secrets/getSecret.js +1 -1
- package/dist/voice/VoiceClientImpl.js +17 -7
- package/dist/voice/handlers/PlaybackControl.js +4 -2
- package/dist/voice/handlers/Say.js +3 -3
- package/dist/voice/handlers/Stream.js +6 -2
- package/dist/voice/handlers/StreamGather.js +3 -1
- package/dist/voice/handlers/dial/Dial.js +4 -3
- package/dist/voice/handlers/dial/handleStasisStart.js +1 -0
- package/dist/voice/handlers/gather/Gather.js +15 -4
- package/dist/voice/handlers/utils/textChunksByClause.d.ts +2 -0
- package/dist/voice/handlers/utils/textChunksByClause.js +42 -0
- package/dist/voice/handlers/utils/textChunksByFirstNaturalPause.d.ts +2 -0
- package/dist/voice/handlers/utils/textChunksByFirstNaturalPause.js +35 -0
- package/dist/voice/handlers/utils/withErrorHandling.js +4 -2
- package/dist/voice/integrations/makeCreateContainer.js +1 -1
- package/dist/voice/stt/Deepgram.js +25 -9
- package/dist/voice/stt/Google.js +20 -8
- package/dist/voice/tts/Azure.js +18 -8
- package/dist/voice/tts/Deepgram.d.ts +3 -2
- package/dist/voice/tts/Deepgram.js +58 -13
- package/dist/voice/tts/ElevenLabs.js +20 -8
- package/dist/voice/tts/Google.js +20 -8
- package/dist/voice/tts/streamToBuffer.d.ts +2 -0
- package/dist/voice/tts/streamToBuffer.js +61 -0
- package/dist/voice/utils/VoiceServiceClientConstructor.js +17 -7
- package/package.json +8 -8
|
@@ -6,28 +6,28 @@ declare function createGetFnUtil(prisma: Prisma): (ref: string) => Promise<{
|
|
|
6
6
|
textToSpeech: {
|
|
7
7
|
ref: string;
|
|
8
8
|
config: import("@prisma/client/runtime/library").JsonValue;
|
|
9
|
-
applicationRef: string;
|
|
10
9
|
productRef: string;
|
|
10
|
+
applicationRef: string;
|
|
11
11
|
};
|
|
12
12
|
speechToText: {
|
|
13
13
|
ref: string;
|
|
14
14
|
config: import("@prisma/client/runtime/library").JsonValue;
|
|
15
|
-
applicationRef: string;
|
|
16
15
|
productRef: string;
|
|
16
|
+
applicationRef: string;
|
|
17
17
|
};
|
|
18
18
|
intelligence: {
|
|
19
19
|
ref: string;
|
|
20
|
-
credentials: string;
|
|
21
20
|
config: import("@prisma/client/runtime/library").JsonValue;
|
|
22
|
-
|
|
21
|
+
credentials: string;
|
|
23
22
|
productRef: string;
|
|
23
|
+
applicationRef: string;
|
|
24
24
|
};
|
|
25
25
|
name: string;
|
|
26
|
-
type: "
|
|
26
|
+
type: import(".prisma/client").$Enums.ApplicationType;
|
|
27
|
+
endpoint: string;
|
|
27
28
|
ref: string;
|
|
29
|
+
accessKeyId: string;
|
|
28
30
|
createdAt: Date;
|
|
29
31
|
updatedAt: Date;
|
|
30
|
-
endpoint: string;
|
|
31
|
-
accessKeyId: string;
|
|
32
32
|
}>;
|
|
33
33
|
export { createGetFnUtil };
|
|
@@ -41,5 +41,5 @@ function deleteApplication(prisma) {
|
|
|
41
41
|
yield prisma.application.delete({ where: { ref } });
|
|
42
42
|
return { ref };
|
|
43
43
|
});
|
|
44
|
-
return (0, common_1.withErrorHandlingAndValidation)((0, identity_1.withAccess)(fn, (ref) => getFn(ref)), common_1.Validators.
|
|
44
|
+
return (0, common_1.withErrorHandlingAndValidation)((0, identity_1.withAccess)(fn, (ref) => getFn(ref)), common_1.Validators.emptySchema);
|
|
45
45
|
}
|
|
@@ -42,5 +42,5 @@ function getApplication(prisma) {
|
|
|
42
42
|
const result = yield getFn(ref);
|
|
43
43
|
return result ? (0, applicationWithEncodedStruct_1.applicationWithEncodedStruct)(result) : null;
|
|
44
44
|
});
|
|
45
|
-
return (0, withErrorHandlingAndValidationAndAccess_1.withErrorHandlingAndValidationAndAccess)(fn, (ref) => getFn(ref), common_1.Validators.
|
|
45
|
+
return (0, withErrorHandlingAndValidationAndAccess_1.withErrorHandlingAndValidationAndAccess)(fn, (ref) => getFn(ref), common_1.Validators.emptySchema);
|
|
46
46
|
}
|
|
@@ -8,7 +8,7 @@ declare function getApplicationValidationSchema(request: {
|
|
|
8
8
|
EXTERNAL: "EXTERNAL";
|
|
9
9
|
}>;
|
|
10
10
|
endpoint: z.ZodEffects<z.ZodOptional<z.ZodString>, string, string>;
|
|
11
|
-
textToSpeech: z.
|
|
11
|
+
textToSpeech: z.ZodObject<{
|
|
12
12
|
productRef: z.ZodString;
|
|
13
13
|
config: any;
|
|
14
14
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -19,7 +19,7 @@ declare function getApplicationValidationSchema(request: {
|
|
|
19
19
|
[x: string]: any;
|
|
20
20
|
productRef?: unknown;
|
|
21
21
|
config?: unknown;
|
|
22
|
-
}
|
|
22
|
+
}> | z.ZodUndefined;
|
|
23
23
|
speechToText: z.ZodUndefined | z.ZodObject<{
|
|
24
24
|
productRef: z.ZodString;
|
|
25
25
|
config: any;
|
|
@@ -33,9 +33,6 @@ declare function getApplicationValidationSchema(request: {
|
|
|
33
33
|
config?: unknown;
|
|
34
34
|
}>;
|
|
35
35
|
}, "strip", z.ZodTypeAny, {
|
|
36
|
-
name?: string;
|
|
37
|
-
type?: "EXTERNAL";
|
|
38
|
-
endpoint?: string;
|
|
39
36
|
textToSpeech?: {
|
|
40
37
|
[x: string]: any;
|
|
41
38
|
productRef?: unknown;
|
|
@@ -46,10 +43,10 @@ declare function getApplicationValidationSchema(request: {
|
|
|
46
43
|
productRef?: unknown;
|
|
47
44
|
config?: unknown;
|
|
48
45
|
};
|
|
49
|
-
}, {
|
|
50
46
|
name?: string;
|
|
51
47
|
type?: "EXTERNAL";
|
|
52
48
|
endpoint?: string;
|
|
49
|
+
}, {
|
|
53
50
|
textToSpeech?: {
|
|
54
51
|
[x: string]: any;
|
|
55
52
|
productRef?: unknown;
|
|
@@ -60,5 +57,8 @@ declare function getApplicationValidationSchema(request: {
|
|
|
60
57
|
productRef?: unknown;
|
|
61
58
|
config?: unknown;
|
|
62
59
|
};
|
|
60
|
+
name?: string;
|
|
61
|
+
type?: "EXTERNAL";
|
|
62
|
+
endpoint?: string;
|
|
63
63
|
}>;
|
|
64
64
|
export { getApplicationValidationSchema };
|
|
@@ -55,7 +55,9 @@ function getApplicationValidationSchema(request) {
|
|
|
55
55
|
const { ttsEngineName, sttEngineName } = request;
|
|
56
56
|
return zod_1.z.object({
|
|
57
57
|
name: zod_1.z.string().max(255, MAX_NAME_MESSAGE),
|
|
58
|
-
type: zod_1.z.nativeEnum(client_1.ApplicationType
|
|
58
|
+
type: zod_1.z.nativeEnum(client_1.ApplicationType, {
|
|
59
|
+
message: "Invalid application type."
|
|
60
|
+
}),
|
|
59
61
|
endpoint: common_1.hostOrHostPortSchema,
|
|
60
62
|
textToSpeech: ttsEngineName
|
|
61
63
|
? zod_1.z.object({
|
package/dist/core/allowList.js
CHANGED
|
@@ -25,7 +25,10 @@ const allowList = [
|
|
|
25
25
|
"/fonoster.identity.v1beta2.Identity/CreateWorkspace",
|
|
26
26
|
"/fonoster.identity.v1beta2.Identity/ExchangeApiKey",
|
|
27
27
|
"/fonoster.identity.v1beta2.Identity/ExchangeCredentials",
|
|
28
|
+
"/fonoster.identity.v1beta2.Identity/ExchangeOauth2Code",
|
|
28
29
|
"/fonoster.identity.v1beta2.Identity/ExchangeRefreshToken",
|
|
30
|
+
"/fonoster.identity.v1beta2.Identity/SendVerificationCode",
|
|
31
|
+
"/fonoster.identity.v1beta2.Identity/VerifyCode",
|
|
29
32
|
"/fonoster.identity.v1beta2.Identity/GetPublicKey"
|
|
30
33
|
];
|
|
31
34
|
exports.allowList = allowList;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Readable } from "stream";
|
|
2
|
-
declare function
|
|
2
|
+
declare function httpBridge(params: {
|
|
3
3
|
port: number;
|
|
4
4
|
}): {
|
|
5
5
|
addStream: (id: string, stream: Readable) => void;
|
|
6
6
|
removeStream: (id: string) => void;
|
|
7
7
|
getStream: (id: string) => Readable;
|
|
8
8
|
};
|
|
9
|
-
export {
|
|
9
|
+
export { httpBridge };
|
|
@@ -1,18 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
2
11
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
13
|
};
|
|
5
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
15
|
+
exports.httpBridge = httpBridge;
|
|
16
|
+
const identity_1 = require("@fonoster/identity");
|
|
7
17
|
const logger_1 = require("@fonoster/logger");
|
|
8
18
|
const express_1 = __importDefault(require("express"));
|
|
19
|
+
const identityConfig_1 = require("./identityConfig");
|
|
20
|
+
const envs_1 = require("../envs");
|
|
9
21
|
const logger = (0, logger_1.getLogger)({ service: "apiserver", filePath: __filename });
|
|
10
22
|
const CONTENT_TYPE = "audio/L16;rate=16000;channels=1";
|
|
11
|
-
function
|
|
23
|
+
function httpBridge(params) {
|
|
12
24
|
const { port } = params;
|
|
13
25
|
const app = (0, express_1.default)();
|
|
14
26
|
const streamMap = new Map();
|
|
15
|
-
app.get("/sounds/:id", (req, res) => {
|
|
27
|
+
app.get("/api/sounds/:id", (req, res) => {
|
|
16
28
|
const idWithoutExtension = req.params.id.split(".")[0];
|
|
17
29
|
const stream = streamMap.get(idWithoutExtension);
|
|
18
30
|
if (!stream) {
|
|
@@ -32,8 +44,18 @@ function filesServer(params) {
|
|
|
32
44
|
});
|
|
33
45
|
stream.pipe(res);
|
|
34
46
|
});
|
|
47
|
+
app.get("/api/identity/accept-invite", (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
48
|
+
try {
|
|
49
|
+
yield (0, identity_1.updateMembershipStatus)(identityConfig_1.identityConfig)(req.query.token);
|
|
50
|
+
res.redirect(envs_1.APP_URL);
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
logger.verbose("error updating membership status", error);
|
|
54
|
+
res.redirect(envs_1.IDENTITY_WORKSPACE_INVITATION_FAIL_URL);
|
|
55
|
+
}
|
|
56
|
+
}));
|
|
35
57
|
app.listen(port, () => {
|
|
36
|
-
logger.info(`
|
|
58
|
+
logger.info(`HTTP bridge is running on port ${port}`);
|
|
37
59
|
});
|
|
38
60
|
return {
|
|
39
61
|
addStream: (id, stream) => {
|
|
@@ -17,5 +17,14 @@ declare const identityConfig: {
|
|
|
17
17
|
pass: string;
|
|
18
18
|
};
|
|
19
19
|
};
|
|
20
|
+
twilioSmsConfig: {
|
|
21
|
+
accountSid: string;
|
|
22
|
+
authToken: string;
|
|
23
|
+
sender: string;
|
|
24
|
+
};
|
|
25
|
+
githubOauth2Config: {
|
|
26
|
+
clientId: string;
|
|
27
|
+
clientSecret: string;
|
|
28
|
+
};
|
|
20
29
|
};
|
|
21
30
|
export { identityConfig };
|
|
@@ -38,6 +38,15 @@ const identityConfig = {
|
|
|
38
38
|
user: envs_1.SMTP_AUTH_USER,
|
|
39
39
|
pass: envs_1.SMTP_AUTH_PASS
|
|
40
40
|
}
|
|
41
|
+
},
|
|
42
|
+
twilioSmsConfig: {
|
|
43
|
+
accountSid: envs_1.TWILIO_ACCOUNT_SID,
|
|
44
|
+
authToken: envs_1.TWILIO_AUTH_TOKEN,
|
|
45
|
+
sender: envs_1.TWILIO_PHONE_NUMBER
|
|
46
|
+
},
|
|
47
|
+
githubOauth2Config: {
|
|
48
|
+
clientId: envs_1.IDENTITY_OAUTH2_GITHUB_CLIENT_ID,
|
|
49
|
+
clientSecret: envs_1.IDENTITY_OAUTH2_GITHUB_CLIENT_SECRET
|
|
41
50
|
}
|
|
42
51
|
};
|
|
43
52
|
exports.identityConfig = identityConfig;
|
package/dist/core/runServices.js
CHANGED
|
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
36
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
37
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -59,7 +69,7 @@ const logger_1 = require("@fonoster/logger");
|
|
|
59
69
|
const grpc = __importStar(require("@grpc/grpc-js"));
|
|
60
70
|
const grpc_health_check_1 = require("grpc-health-check");
|
|
61
71
|
const allowList_1 = require("./allowList");
|
|
62
|
-
const
|
|
72
|
+
const httpBridge_1 = require("./httpBridge");
|
|
63
73
|
const loadServices_1 = __importDefault(require("./loadServices"));
|
|
64
74
|
const services_1 = __importDefault(require("./services"));
|
|
65
75
|
const runCallManager_1 = require("../calls/runCallManager");
|
|
@@ -79,7 +89,7 @@ function runServices() {
|
|
|
79
89
|
// Load the remaining services
|
|
80
90
|
(0, loadServices_1.default)(server, yield services_1.default);
|
|
81
91
|
// Connecting to Asterisk ARI
|
|
82
|
-
yield (0, connectToAri_1.connectToAri)((0,
|
|
92
|
+
yield (0, connectToAri_1.connectToAri)((0, httpBridge_1.httpBridge)({ port: envs_1.HTTP_BRIDGE_PORT }));
|
|
83
93
|
// Additional Call Managers subscriber may be added here to handle call events
|
|
84
94
|
yield (0, runCallManager_1.createCreateCallSubscriber)({
|
|
85
95
|
natsUrl: envs_1.NATS_URL,
|
package/dist/core/services.d.ts
CHANGED
|
@@ -129,12 +129,21 @@ declare const services: Promise<[{
|
|
|
129
129
|
exchangeCredentials: (call: {
|
|
130
130
|
request: unknown;
|
|
131
131
|
}, callback: (error?: import("@fonoster/common").GrpcErrorMessage, response?: unknown) => void) => Promise<void>;
|
|
132
|
+
exchangeOauth2Code: (call: {
|
|
133
|
+
request: unknown;
|
|
134
|
+
}, callback: (error?: import("@fonoster/common").GrpcErrorMessage, response?: unknown) => void) => Promise<void>;
|
|
132
135
|
exchangeRefreshToken: (call: {
|
|
133
136
|
request: unknown;
|
|
134
137
|
}, callback: (error?: import("@fonoster/common").GrpcErrorMessage, response?: unknown) => void) => Promise<void>;
|
|
135
138
|
getPublicKey: (_: unknown, callback: (error: import("@fonoster/common").GrpcErrorMessage, response?: {
|
|
136
139
|
publicKey: string;
|
|
137
140
|
}) => void) => Promise<void>;
|
|
141
|
+
sendVerificationCode: (call: {
|
|
142
|
+
request: unknown;
|
|
143
|
+
}, callback: (error?: import("@fonoster/common").GrpcErrorMessage, response?: unknown) => void) => Promise<void>;
|
|
144
|
+
verifyCode: (call: {
|
|
145
|
+
request: unknown;
|
|
146
|
+
}, callback: (error?: import("@fonoster/common").GrpcErrorMessage, response?: unknown) => void) => Promise<void>;
|
|
138
147
|
};
|
|
139
148
|
}, {
|
|
140
149
|
definition: {
|
package/dist/envs.d.ts
CHANGED
|
@@ -10,15 +10,17 @@ export declare const CALLS_CREATE_SUBJECT = "calls.create";
|
|
|
10
10
|
export declare const CALLS_TRACK_CALL_SUBJECT = "calls.track";
|
|
11
11
|
export declare const CLOAK_ENCRYPTION_KEY: string;
|
|
12
12
|
export declare const DEFAULT_NATS_QUEUE_GROUP = "apiserver";
|
|
13
|
-
export declare const
|
|
14
|
-
export declare const FILES_SERVER_PORT: number;
|
|
13
|
+
export declare const HTTP_BRIDGE_PORT: number;
|
|
15
14
|
export declare const IDENTITY_ACCESS_TOKEN_EXPIRES_IN: string;
|
|
16
15
|
export declare const IDENTITY_AUDIENCE: string;
|
|
17
16
|
export declare const IDENTITY_ID_TOKEN_EXPIRES_IN: string;
|
|
18
17
|
export declare const IDENTITY_ISSUER: string;
|
|
18
|
+
export declare const IDENTITY_OAUTH2_GITHUB_CLIENT_ID: string;
|
|
19
|
+
export declare const IDENTITY_OAUTH2_GITHUB_CLIENT_SECRET: string;
|
|
19
20
|
export declare const IDENTITY_PRIVATE_KEY: string;
|
|
20
21
|
export declare const IDENTITY_PUBLIC_KEY: string;
|
|
21
22
|
export declare const IDENTITY_REFRESH_TOKEN_EXPIRES_IN: string;
|
|
23
|
+
export declare const IDENTITY_WORKSPACE_INVITATION_FAIL_URL: string;
|
|
22
24
|
export declare const INFLUXDB_BUCKET: string;
|
|
23
25
|
export declare const INFLUXDB_ORG: string;
|
|
24
26
|
export declare const INFLUXDB_PASSWORD: string;
|
|
@@ -41,3 +43,7 @@ export declare const SMTP_HOST: string;
|
|
|
41
43
|
export declare const SMTP_PORT: number;
|
|
42
44
|
export declare const SMTP_SECURE: boolean;
|
|
43
45
|
export declare const SMTP_SENDER: string;
|
|
46
|
+
export declare const TEMPLATES_DIR: string;
|
|
47
|
+
export declare const TWILIO_ACCOUNT_SID: string;
|
|
48
|
+
export declare const TWILIO_AUTH_TOKEN: string;
|
|
49
|
+
export declare const TWILIO_PHONE_NUMBER: string;
|
package/dist/envs.js
CHANGED
|
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
var _a;
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.SMTP_SENDER = exports.SMTP_SECURE = exports.SMTP_PORT = exports.SMTP_HOST = exports.SMTP_AUTH_USER = exports.SMTP_AUTH_PASS = exports.ROUTR_DEFAULT_PEER_USERNAME = exports.ROUTR_DEFAULT_PEER_PASSWORD = exports.ROUTR_DEFAULT_PEER_NAME = exports.ROUTR_DEFAULT_PEER_AOR = exports.ROUTR_API_ENDPOINT = exports.OWNER_PASSWORD = exports.OWNER_NAME = exports.OWNER_EMAIL = exports.NATS_URL = exports.INTEGRATIONS_FILE = exports.INFLUXDB_USERNAME = exports.INFLUXDB_URL = exports.INFLUXDB_TOKEN = exports.INFLUXDB_PASSWORD = exports.INFLUXDB_ORG = exports.INFLUXDB_BUCKET = exports.IDENTITY_REFRESH_TOKEN_EXPIRES_IN = exports.IDENTITY_PUBLIC_KEY = exports.IDENTITY_PRIVATE_KEY = exports.
|
|
7
|
+
exports.TWILIO_PHONE_NUMBER = exports.TWILIO_AUTH_TOKEN = exports.TWILIO_ACCOUNT_SID = exports.TEMPLATES_DIR = exports.SMTP_SENDER = exports.SMTP_SECURE = exports.SMTP_PORT = exports.SMTP_HOST = exports.SMTP_AUTH_USER = exports.SMTP_AUTH_PASS = exports.ROUTR_DEFAULT_PEER_USERNAME = exports.ROUTR_DEFAULT_PEER_PASSWORD = exports.ROUTR_DEFAULT_PEER_NAME = exports.ROUTR_DEFAULT_PEER_AOR = exports.ROUTR_API_ENDPOINT = exports.OWNER_PASSWORD = exports.OWNER_NAME = exports.OWNER_EMAIL = exports.NATS_URL = exports.INTEGRATIONS_FILE = exports.INFLUXDB_USERNAME = exports.INFLUXDB_URL = exports.INFLUXDB_TOKEN = exports.INFLUXDB_PASSWORD = exports.INFLUXDB_ORG = exports.INFLUXDB_BUCKET = exports.IDENTITY_WORKSPACE_INVITATION_FAIL_URL = exports.IDENTITY_REFRESH_TOKEN_EXPIRES_IN = exports.IDENTITY_PUBLIC_KEY = exports.IDENTITY_PRIVATE_KEY = exports.IDENTITY_OAUTH2_GITHUB_CLIENT_SECRET = exports.IDENTITY_OAUTH2_GITHUB_CLIENT_ID = exports.IDENTITY_ISSUER = exports.IDENTITY_ID_TOKEN_EXPIRES_IN = exports.IDENTITY_AUDIENCE = exports.IDENTITY_ACCESS_TOKEN_EXPIRES_IN = exports.HTTP_BRIDGE_PORT = exports.DEFAULT_NATS_QUEUE_GROUP = exports.CLOAK_ENCRYPTION_KEY = exports.CALLS_TRACK_CALL_SUBJECT = exports.CALLS_CREATE_SUBJECT = exports.ASTERISK_TRUNK = exports.ASTERISK_SYSTEM_DOMAIN = exports.ASTERISK_ARI_USERNAME = exports.ASTERISK_ARI_SECRET = exports.ASTERISK_ARI_PROXY_URL = exports.APP_URL = exports.APISERVER_HOST = exports.APISERVER_BIND_ADDR = void 0;
|
|
8
8
|
/*
|
|
9
9
|
* Copyright (C) 2024 by Fonoster Inc (https://fonoster.com)
|
|
10
10
|
* http://github.com/fonoster/fonoster
|
|
@@ -39,6 +39,7 @@ const e = process.env;
|
|
|
39
39
|
"SMTP_AUTH_USER",
|
|
40
40
|
"SMTP_AUTH_PASS",
|
|
41
41
|
"IDENTITY_DATABASE_URL",
|
|
42
|
+
"IDENTITY_WORKSPACE_INVITATION_FAIL_URL",
|
|
42
43
|
"DATABASE_URL",
|
|
43
44
|
"INFLUXDB_URL",
|
|
44
45
|
"INFLUXDB_INIT_USERNAME",
|
|
@@ -53,8 +54,6 @@ const e = process.env;
|
|
|
53
54
|
]);
|
|
54
55
|
const IDENTITY_PRIVATE_KEY_PATH = e.IDENTITY_PRIVATE_KEY_PATH || "/opt/fonoster/keys/private.pem";
|
|
55
56
|
const IDENTITY_PUBLIC_KEY_PATH = e.IDENTITY_PUBLIC_KEY_PATH || "/opt/fonoster/keys/public.pem";
|
|
56
|
-
(0, common_1.assertFileExists)(IDENTITY_PRIVATE_KEY_PATH);
|
|
57
|
-
(0, common_1.assertFileExists)(IDENTITY_PUBLIC_KEY_PATH);
|
|
58
57
|
exports.APISERVER_BIND_ADDR = e.APISERVER_BIND_ADDR || "0.0.0.0:50051";
|
|
59
58
|
exports.APISERVER_HOST = e.APISERVER_HOST || "apiserver";
|
|
60
59
|
// Frontend configurations
|
|
@@ -69,24 +68,31 @@ exports.CALLS_TRACK_CALL_SUBJECT = "calls.track";
|
|
|
69
68
|
// Other configurations
|
|
70
69
|
exports.CLOAK_ENCRYPTION_KEY = e.CLOAK_ENCRYPTION_KEY;
|
|
71
70
|
exports.DEFAULT_NATS_QUEUE_GROUP = "apiserver";
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
exports.FILES_SERVER_PORT = e.FILES_SERVER_PORT
|
|
75
|
-
? parseInt(e.FILES_SERVER_PORT)
|
|
71
|
+
exports.HTTP_BRIDGE_PORT = e.HTTP_BRIDGE_PORT
|
|
72
|
+
? parseInt(e.HTTP_BRIDGE_PORT)
|
|
76
73
|
: 9876;
|
|
74
|
+
// Identity configurations
|
|
77
75
|
exports.IDENTITY_ACCESS_TOKEN_EXPIRES_IN = e.IDENTITY_ACCESS_TOKEN_EXPIRES_IN || "15m";
|
|
78
76
|
exports.IDENTITY_AUDIENCE = e.IDENTITY_AUDIENCE || "api";
|
|
79
77
|
exports.IDENTITY_ID_TOKEN_EXPIRES_IN = e.IDENTITY_ID_TOKEN_EXPIRES_IN || "15m";
|
|
80
|
-
// Identity configurations
|
|
81
78
|
exports.IDENTITY_ISSUER = e.IDENTITY_ISSUER || "https://fonoster.local";
|
|
79
|
+
exports.IDENTITY_OAUTH2_GITHUB_CLIENT_ID = e.IDENTITY_OAUTH2_GITHUB_CLIENT_ID;
|
|
80
|
+
exports.IDENTITY_OAUTH2_GITHUB_CLIENT_SECRET = e.IDENTITY_OAUTH2_GITHUB_CLIENT_SECRET;
|
|
82
81
|
exports.IDENTITY_PRIVATE_KEY = fs_1.default.readFileSync(IDENTITY_PRIVATE_KEY_PATH, "utf8");
|
|
83
82
|
exports.IDENTITY_PUBLIC_KEY = fs_1.default.readFileSync(IDENTITY_PUBLIC_KEY_PATH, "utf8");
|
|
84
83
|
exports.IDENTITY_REFRESH_TOKEN_EXPIRES_IN = e.IDENTITY_REFRESH_TOKEN_EXPIRES_IN || "24h";
|
|
84
|
+
exports.IDENTITY_WORKSPACE_INVITATION_FAIL_URL = e.IDENTITY_WORKSPACE_INVITATION_FAIL_URL;
|
|
85
|
+
if (e.IDENTITY_OAUTH2_GITHUB_ENABLED === "true") {
|
|
86
|
+
(0, common_1.assertEnvsAreSet)([
|
|
87
|
+
"IDENTITY_OAUTH2_GITHUB_CLIENT_ID",
|
|
88
|
+
"IDENTITY_OAUTH2_GITHUB_CLIENT_SECRET"
|
|
89
|
+
]);
|
|
90
|
+
}
|
|
91
|
+
// InfluxDB configurations
|
|
85
92
|
exports.INFLUXDB_BUCKET = e.INFLUXDB_INIT_BUCKET;
|
|
86
93
|
exports.INFLUXDB_ORG = e.INFLUXDB_INIT_ORG;
|
|
87
94
|
exports.INFLUXDB_PASSWORD = e.INFLUXDB_INIT_PASSWORD;
|
|
88
95
|
exports.INFLUXDB_TOKEN = e.INFLUXDB_INIT_TOKEN;
|
|
89
|
-
// InfluxDB configurations
|
|
90
96
|
exports.INFLUXDB_URL = e.INFLUXDB_URL;
|
|
91
97
|
exports.INFLUXDB_USERNAME = e.INFLUXDB_INIT_USERNAME;
|
|
92
98
|
exports.INTEGRATIONS_FILE = e.INTEGRATIONS_FILE || "/opt/fonoster/integrations.json";
|
|
@@ -107,3 +113,9 @@ exports.SMTP_HOST = e.SMTP_HOST;
|
|
|
107
113
|
exports.SMTP_PORT = e.SMTP_PORT ? parseInt(e.SMTP_PORT) : 587;
|
|
108
114
|
exports.SMTP_SECURE = ((_a = e.SMTP_SECURE) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === "true";
|
|
109
115
|
exports.SMTP_SENDER = e.SMTP_SENDER;
|
|
116
|
+
// Custom templates
|
|
117
|
+
exports.TEMPLATES_DIR = e.TEMPLATES_DIR;
|
|
118
|
+
// Twilio configurations
|
|
119
|
+
exports.TWILIO_ACCOUNT_SID = e.TWILIO_ACCOUNT_SID;
|
|
120
|
+
exports.TWILIO_AUTH_TOKEN = e.TWILIO_AUTH_TOKEN;
|
|
121
|
+
exports.TWILIO_PHONE_NUMBER = e.TWILIO_PHONE_NUMBER;
|
package/dist/index.js
CHANGED
|
@@ -16,13 +16,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
16
16
|
}) : function(o, v) {
|
|
17
17
|
o["default"] = v;
|
|
18
18
|
});
|
|
19
|
-
var __importStar = (this && this.__importStar) || function (
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
};
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
26
36
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
27
37
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
28
38
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -3,12 +3,12 @@ declare function createGetFnUtil(prisma: Prisma): (ref: string) => Promise<{
|
|
|
3
3
|
extended: {
|
|
4
4
|
accessKeyId: string;
|
|
5
5
|
};
|
|
6
|
-
name: string;
|
|
7
6
|
secret: string;
|
|
7
|
+
name: string;
|
|
8
8
|
ref: string;
|
|
9
|
+
accessKeyId: string;
|
|
9
10
|
createdAt: Date;
|
|
10
11
|
updatedAt: Date;
|
|
11
|
-
accessKeyId: string;
|
|
12
12
|
} & {
|
|
13
13
|
createdAt: number;
|
|
14
14
|
updatedAt: number;
|
|
@@ -36,7 +36,7 @@ function createGetFnUtil(prisma) {
|
|
|
36
36
|
where: { ref }
|
|
37
37
|
});
|
|
38
38
|
if (!response) {
|
|
39
|
-
throw (0, notFoundError_1.notFoundError)(`
|
|
39
|
+
throw (0, notFoundError_1.notFoundError)(`Resource not found: ${ref}`);
|
|
40
40
|
}
|
|
41
41
|
return (0, common_1.datesMapper)(Object.assign(Object.assign({}, response), { extended: {
|
|
42
42
|
accessKeyId: response.accessKeyId
|
|
@@ -41,5 +41,5 @@ function deleteSecret(prisma) {
|
|
|
41
41
|
yield prisma.secret.delete({ where: { ref } });
|
|
42
42
|
return { ref };
|
|
43
43
|
});
|
|
44
|
-
return (0, withErrorHandlingAndValidationAndAccess_1.withErrorHandlingAndValidationAndAccess)(fn, (ref) => getFn(ref), common_1.Validators.
|
|
44
|
+
return (0, withErrorHandlingAndValidationAndAccess_1.withErrorHandlingAndValidationAndAccess)(fn, (ref) => getFn(ref), common_1.Validators.emptySchema);
|
|
45
45
|
}
|
|
@@ -40,5 +40,5 @@ function getSecret(prisma) {
|
|
|
40
40
|
logger.verbose("call to getSecret", { ref });
|
|
41
41
|
return yield getFn(ref);
|
|
42
42
|
});
|
|
43
|
-
return (0, withErrorHandlingAndValidationAndAccess_1.withErrorHandlingAndValidationAndAccess)(fn, (ref) => getFn(ref), common_1.Validators.
|
|
43
|
+
return (0, withErrorHandlingAndValidationAndAccess_1.withErrorHandlingAndValidationAndAccess)(fn, (ref) => getFn(ref), common_1.Validators.emptySchema);
|
|
44
44
|
}
|
|
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
36
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
37
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -33,8 +33,10 @@ const zod_1 = require("zod");
|
|
|
33
33
|
const withErrorHandling_1 = require("./utils/withErrorHandling");
|
|
34
34
|
const requestSchema = zod_1.z.object({
|
|
35
35
|
sessionRef: zod_1.z.string(),
|
|
36
|
-
playbackRef: zod_1.z.string().optional()
|
|
37
|
-
action: zod_1.z.nativeEnum(common_1.PlaybackControlAction
|
|
36
|
+
playbackRef: zod_1.z.string().optional(),
|
|
37
|
+
action: zod_1.z.nativeEnum(common_1.PlaybackControlAction, {
|
|
38
|
+
message: "Invalid playback control action."
|
|
39
|
+
})
|
|
38
40
|
});
|
|
39
41
|
function playbackControlHandler(ari, voiceClient) {
|
|
40
42
|
return (0, withErrorHandling_1.withErrorHandling)((playbackControlReq) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -19,10 +19,10 @@ const envs_1 = require("../../envs");
|
|
|
19
19
|
const sayRequestSchema = zod_1.z.object({
|
|
20
20
|
text: zod_1.z.string(),
|
|
21
21
|
sessionRef: zod_1.z.string(),
|
|
22
|
-
playbackRef: zod_1.z.string().optional()
|
|
23
|
-
options: zod_1.z.record(zod_1.z.unknown()).optional()
|
|
22
|
+
playbackRef: zod_1.z.string().optional(),
|
|
23
|
+
options: zod_1.z.record(zod_1.z.unknown()).optional()
|
|
24
24
|
});
|
|
25
|
-
const getMediaUrl = (filename) => `sound:http://${envs_1.APISERVER_HOST}:${envs_1.
|
|
25
|
+
const getMediaUrl = (filename) => `sound:http://${envs_1.APISERVER_HOST}:${envs_1.HTTP_BRIDGE_PORT}/api/sounds/${filename}.sln16`;
|
|
26
26
|
function sayHandler(ari, voiceClient) {
|
|
27
27
|
return (0, withErrorHandling_1.withErrorHandling)((request) => __awaiter(this, void 0, void 0, function* () {
|
|
28
28
|
const { sessionRef: channelId } = request;
|
|
@@ -32,8 +32,12 @@ const common_1 = require("@fonoster/common");
|
|
|
32
32
|
const zod_1 = require("zod");
|
|
33
33
|
const withErrorHandling_1 = require("./utils/withErrorHandling");
|
|
34
34
|
const streamRequestSchema = zod_1.z.object({
|
|
35
|
-
direction: zod_1.z
|
|
36
|
-
|
|
35
|
+
direction: zod_1.z
|
|
36
|
+
.nativeEnum(common_1.StreamDirection, { message: "Invalid stream direction" })
|
|
37
|
+
.optional(),
|
|
38
|
+
format: zod_1.z
|
|
39
|
+
.nativeEnum(common_1.StreamAudioFormat, { message: "Invalid stream audio format" })
|
|
40
|
+
.optional()
|
|
37
41
|
});
|
|
38
42
|
function streamHandler(voiceClient) {
|
|
39
43
|
return (0, withErrorHandling_1.withErrorHandling)((request) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -32,7 +32,9 @@ const common_1 = require("@fonoster/common");
|
|
|
32
32
|
const zod_1 = require("zod");
|
|
33
33
|
const withErrorHandling_1 = require("./utils/withErrorHandling");
|
|
34
34
|
const gatherRequestSchema = zod_1.z.object({
|
|
35
|
-
source: zod_1.z.optional(zod_1.z.nativeEnum(common_1.StreamGatherSource
|
|
35
|
+
source: zod_1.z.optional(zod_1.z.nativeEnum(common_1.StreamGatherSource, {
|
|
36
|
+
message: "Invalid stream gather source."
|
|
37
|
+
}))
|
|
36
38
|
});
|
|
37
39
|
function streamGatherHandler(voiceClient) {
|
|
38
40
|
return (0, withErrorHandling_1.withErrorHandling)((request) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -40,14 +40,14 @@ const makeGetChannelVar_1 = require("../../utils/makeGetChannelVar");
|
|
|
40
40
|
// TODO: Needs request validation
|
|
41
41
|
function dialHandler(ari, voiceClient) {
|
|
42
42
|
return (request) => __awaiter(this, void 0, void 0, function* () {
|
|
43
|
-
const { sessionRef, destination, timeout } = request;
|
|
43
|
+
const { sessionRef: channelId, destination, timeout } = request;
|
|
44
44
|
const bridge = yield ari.bridges.create({
|
|
45
45
|
type: "mixing"
|
|
46
46
|
});
|
|
47
47
|
// eslint-disable-next-line new-cap
|
|
48
48
|
const dialed = ari.Channel();
|
|
49
|
-
yield bridge.addChannel({ channel:
|
|
50
|
-
const callerChannel = yield ari.channels.get({ channelId
|
|
49
|
+
yield bridge.addChannel({ channel: channelId });
|
|
50
|
+
const callerChannel = yield ari.channels.get({ channelId });
|
|
51
51
|
const getChannelVar = (0, makeGetChannelVar_1.makeGetChannelVar)(callerChannel);
|
|
52
52
|
const ingressNumber = (yield getChannelVar(types_1.ChannelVar.INGRESS_NUMBER))
|
|
53
53
|
.value;
|
|
@@ -62,6 +62,7 @@ function dialHandler(ari, voiceClient) {
|
|
|
62
62
|
"PJSIP_HEADER(add,X-Is-Api-Originated-Type)": "true"
|
|
63
63
|
}
|
|
64
64
|
});
|
|
65
|
+
yield ari.channels.ring({ channelId });
|
|
65
66
|
dialed.once(types_1.AriEvent.STASIS_START, (0, handleStasisStart_1.handleStasisStart)({ ari, request, bridge, dialed }));
|
|
66
67
|
dialed.once(types_1.AriEvent.CHANNEL_LEFT_BRIDGE, (0, handleChannelLeftBridge_1.handleChannelLeftBridge)({ bridge, dialed }));
|
|
67
68
|
dialed.once(types_1.AriEvent.STASIS_END, (0, handleStasisEnd_1.handleStasisEnd)(request));
|
|
@@ -36,6 +36,7 @@ function handleStasisStart(params) {
|
|
|
36
36
|
return (_, channel) => __awaiter(this, void 0, void 0, function* () {
|
|
37
37
|
try {
|
|
38
38
|
yield bridge.addChannel({ channel: dialed.id });
|
|
39
|
+
yield ari.channels.ringStop({ channelId: channel.id });
|
|
39
40
|
if ([common_1.DialRecordDirection.IN, common_1.DialRecordDirection.BOTH].includes(recordDirection)) {
|
|
40
41
|
(0, recordChannel_1.recordChannel)(ari, common_1.DialRecordDirection.IN, channel.id);
|
|
41
42
|
}
|
|
@@ -29,17 +29,28 @@ exports.gatherHandler = gatherHandler;
|
|
|
29
29
|
* limitations under the License.
|
|
30
30
|
*/
|
|
31
31
|
const common_1 = require("@fonoster/common");
|
|
32
|
+
const messages_1 = require("@fonoster/common/src/messages");
|
|
32
33
|
const zod_1 = require("zod");
|
|
33
34
|
const getTimeoutPromise_1 = require("./getTimeoutPromise");
|
|
34
35
|
const utils_1 = require("../utils");
|
|
35
36
|
const withErrorHandling_1 = require("../utils/withErrorHandling");
|
|
36
37
|
const gatherRequestSchema = zod_1.z.object({
|
|
37
|
-
source: zod_1.z
|
|
38
|
-
|
|
38
|
+
source: zod_1.z
|
|
39
|
+
.optional(zod_1.z.nativeEnum(common_1.GatherSource, { message: "Invalid gather source" }))
|
|
40
|
+
.optional(),
|
|
41
|
+
maxDigits: zod_1.z
|
|
42
|
+
.number()
|
|
43
|
+
.int({
|
|
44
|
+
message: messages_1.POSITIVE_INTEGER_MESSAGE
|
|
45
|
+
})
|
|
46
|
+
.positive({
|
|
47
|
+
message: messages_1.POSITIVE_INTEGER_MESSAGE
|
|
48
|
+
})
|
|
49
|
+
.optional(),
|
|
39
50
|
finishOnKey: zod_1.z
|
|
40
51
|
.string()
|
|
41
|
-
.regex(/^[0-9*#]$/)
|
|
42
|
-
.max(1)
|
|
52
|
+
.regex(/^[0-9*#]$/)
|
|
53
|
+
.max(1, { message: messages_1.MUST_BE_A_SINGLE_CHARACTER })
|
|
43
54
|
.optional()
|
|
44
55
|
});
|
|
45
56
|
function gatherHandler(voiceClient) {
|