@fonoster/apiserver 0.6.6 → 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.
Files changed (105) hide show
  1. package/dist/applications/createGetFnUtil.d.ts +1 -1
  2. package/dist/applications/getApplication.js +1 -3
  3. package/dist/applications/types.d.ts +1 -1
  4. package/dist/applications/utils/applicationWithEncodedStruct.js +20 -1
  5. package/dist/applications/utils/convertToApplicationData.js +1 -1
  6. package/dist/applications/utils/getApplicationValidationSchema.d.ts +3 -3
  7. package/dist/applications/utils/getApplicationValidationSchema.js +6 -3
  8. package/dist/applications/utils/prepareForValidation.js +1 -1
  9. package/dist/calls/ListCallsRequestSchema.d.ts +1 -4
  10. package/dist/calls/ListCallsRequestSchema.js +0 -4
  11. package/dist/calls/buildService.d.ts +2 -2
  12. package/dist/calls/buildService.js +6 -5
  13. package/dist/calls/createCall.d.ts +6 -4
  14. package/dist/calls/createCall.js +18 -8
  15. package/dist/calls/createFetchCalls.js +3 -7
  16. package/dist/calls/createFetchSingleCall.js +9 -2
  17. package/dist/calls/{trackCall.d.ts → makeTrackCall.d.ts} +3 -3
  18. package/dist/calls/makeTrackCall.js +67 -0
  19. package/dist/calls/runCallManager.js +12 -13
  20. package/dist/calls/types.d.ts +8 -42
  21. package/dist/calls/types.js +5 -38
  22. package/dist/core/seed.js +20 -0
  23. package/dist/core/services.d.ts +2 -2
  24. package/dist/envs.d.ts +0 -2
  25. package/dist/envs.js +1 -3
  26. package/dist/events/createInfluxDbPub.js +2 -1
  27. package/dist/events/mapCallDirectionToEnum.d.ts +3 -0
  28. package/dist/events/mapCallDirectionToEnum.js +37 -0
  29. package/dist/events/nats.js +5 -6
  30. package/dist/events/transformEvent.d.ts +2 -0
  31. package/dist/events/transformEvent.js +72 -0
  32. package/dist/index.js +4 -5
  33. package/dist/utils/index.d.ts +2 -0
  34. package/dist/utils/index.js +2 -0
  35. package/dist/utils/makeHandleDialEventsWithNats.d.ts +5 -0
  36. package/dist/{voice/handlers/StasisEnd.js → utils/makeHandleDialEventsWithNats.js} +10 -15
  37. package/dist/utils/makeHandleDialEventsWithVoiceClient.d.ts +5 -0
  38. package/dist/{voice/handlers/dial/handleDialEvents.js → utils/makeHandleDialEventsWithVoiceClient.js} +6 -17
  39. package/dist/utils/mapDialStatus.d.ts +3 -0
  40. package/dist/utils/mapDialStatus.js +38 -0
  41. package/dist/voice/VoiceClientImpl.d.ts +10 -1
  42. package/dist/voice/VoiceClientImpl.js +47 -7
  43. package/dist/voice/VoiceDispatcher.d.ts +6 -2
  44. package/dist/voice/VoiceDispatcher.js +50 -37
  45. package/dist/voice/connectToAri.js +3 -1
  46. package/dist/voice/createExternalMediaConfig.d.ts +3 -0
  47. package/dist/voice/createExternalMediaConfig.js +4 -1
  48. package/dist/voice/handlers/Answer.js +1 -1
  49. package/dist/voice/handlers/Hangup.js +1 -1
  50. package/dist/voice/handlers/Mute.js +1 -1
  51. package/dist/voice/handlers/Play.js +2 -2
  52. package/dist/voice/handlers/PlayDtmf.js +1 -1
  53. package/dist/voice/handlers/PlaybackControl.js +1 -1
  54. package/dist/voice/handlers/Record.js +2 -2
  55. package/dist/voice/handlers/Say.js +2 -2
  56. package/dist/voice/handlers/StreamGather.d.ts +3 -0
  57. package/dist/voice/handlers/StreamGather.js +66 -0
  58. package/dist/voice/handlers/Unmute.js +1 -1
  59. package/dist/voice/handlers/dial/Dial.js +10 -6
  60. package/dist/voice/handlers/gather/Gather.js +5 -4
  61. package/dist/voice/handlers/index.d.ts +12 -0
  62. package/dist/voice/handlers/index.js +46 -0
  63. package/dist/voice/handlers/{awaitForPlaybackFinished.js → utils/awaitForPlaybackFinished.js} +1 -1
  64. package/dist/voice/handlers/{awaitForRecordingFinished.js → utils/awaitForRecordingFinished.js} +1 -1
  65. package/dist/voice/handlers/utils/index.d.ts +3 -0
  66. package/dist/voice/handlers/utils/index.js +37 -0
  67. package/dist/voice/handlers/utils/isDtmf.d.ts +2 -0
  68. package/dist/voice/handlers/utils/isDtmf.js +24 -0
  69. package/dist/voice/integrations/findIntegrationsCredentials.d.ts +1 -1
  70. package/dist/voice/integrations/findIntegrationsCredentials.js +2 -1
  71. package/dist/voice/integrations/getSttConfig.d.ts +4 -2
  72. package/dist/voice/integrations/getSttConfig.js +4 -1
  73. package/dist/voice/integrations/getTtsConfig.d.ts +2 -1
  74. package/dist/voice/integrations/getTtsConfig.js +5 -1
  75. package/dist/voice/integrations/makeCreateContainer.js +1 -1
  76. package/dist/voice/integrations/types.d.ts +1 -1
  77. package/dist/voice/makeCreateVoiceClient.js +4 -10
  78. package/dist/voice/makeGetChannelVar.d.ts +2 -1
  79. package/dist/voice/makeGetChannelVar.js +13 -0
  80. package/dist/voice/stt/AbstractSpeechToText.d.ts +4 -3
  81. package/dist/voice/stt/Deepgram.d.ts +18 -0
  82. package/dist/voice/stt/Deepgram.js +156 -0
  83. package/dist/voice/stt/Google.d.ts +5 -6
  84. package/dist/voice/stt/Google.js +13 -13
  85. package/dist/voice/stt/SpeechToTextFactory.js +2 -0
  86. package/dist/voice/stt/types.d.ts +22 -10
  87. package/dist/voice/stt/types.js +7 -0
  88. package/dist/voice/tts/Deepgram.d.ts +25 -0
  89. package/dist/voice/tts/Deepgram.js +122 -0
  90. package/dist/voice/tts/Google.d.ts +2 -1
  91. package/dist/voice/tts/Google.js +7 -8
  92. package/dist/voice/tts/TextToSpeechFactory.js +2 -0
  93. package/dist/voice/types/ari.d.ts +2 -1
  94. package/dist/voice/types/ari.js +1 -0
  95. package/dist/voice/types/voice.d.ts +9 -1
  96. package/package.json +9 -8
  97. package/dist/calls/createTrackCallSubscriber.d.ts +0 -5
  98. package/dist/calls/createTrackCallSubscriber.js +0 -52
  99. package/dist/calls/trackCall.js +0 -63
  100. package/dist/voice/handlers/StasisEnd.d.ts +0 -4
  101. package/dist/voice/handlers/dial/handleDialEvents.d.ts +0 -5
  102. /package/dist/voice/handlers/{awaitForPlaybackFinished.d.ts → utils/awaitForPlaybackFinished.d.ts} +0 -0
  103. /package/dist/voice/handlers/{awaitForRecordingFinished.d.ts → utils/awaitForRecordingFinished.d.ts} +0 -0
  104. /package/dist/voice/handlers/{withErrorHandling.d.ts → utils/withErrorHandling.d.ts} +0 -0
  105. /package/dist/voice/handlers/{withErrorHandling.js → utils/withErrorHandling.js} +0 -0
@@ -30,58 +30,59 @@ exports.VoiceDispatcher = void 0;
30
30
  */
31
31
  const common_1 = require("@fonoster/common");
32
32
  const logger_1 = require("@fonoster/logger");
33
- const Answer_1 = require("./handlers/Answer");
34
- const Dial_1 = require("./handlers/dial/Dial");
35
- const Gather_1 = require("./handlers/gather/Gather");
36
- const Hangup_1 = require("./handlers/Hangup");
37
- const Mute_1 = require("./handlers/Mute");
38
- const Play_1 = require("./handlers/Play");
39
- const PlaybackControl_1 = require("./handlers/PlaybackControl");
40
- const PlayDtmf_1 = require("./handlers/PlayDtmf");
41
- const Say_1 = require("./handlers/Say");
42
- const Unmute_1 = require("./handlers/Unmute");
33
+ const handlers_1 = require("./handlers");
34
+ const makeGetChannelVar_1 = require("./makeGetChannelVar");
43
35
  const types_1 = require("./types");
36
+ const utils_1 = require("../utils");
44
37
  const logger = (0, logger_1.getLogger)({ service: "apiserver", filePath: __filename });
45
38
  class VoiceDispatcher {
46
- constructor(ari, createVoiceClient) {
39
+ constructor(ari, nc, createVoiceClient) {
47
40
  this.ari = ari;
41
+ this.nc = nc;
48
42
  this.voiceClients = new Map();
49
43
  this.createVoiceClient = createVoiceClient;
50
44
  }
51
45
  start() {
52
46
  // Initialize the ARI client
53
- this.ari.start(common_1.STASIS_APP_NAME);
54
- this.ari.on(types_1.AriEvent.STASIS_START, this.handleStasisStart.bind(this));
55
- this.ari.on(types_1.AriEvent.STASIS_END, this.handleStasisEnd.bind(this));
47
+ const { ari, handleStasisStart, handleStasisEnd, handleDial } = this;
48
+ ari.start(common_1.STASIS_APP_NAME);
49
+ ari.on(types_1.AriEvent.STASIS_START, handleStasisStart.bind(this));
50
+ ari.on(types_1.AriEvent.STASIS_END, handleStasisEnd.bind(this));
51
+ ari.on(types_1.AriEvent.DIAL, handleDial.bind(this));
56
52
  }
57
53
  handleStasisStart(event, channel) {
58
54
  return __awaiter(this, void 0, void 0, function* () {
59
- // TODO: This is a temporary fix. We need to find a better way to handle external media channels
60
- if (channel.id.length > 15) {
61
- logger.verbose("skipping statis start for external media channel", {
62
- channel: channel.id
63
- });
55
+ var _a;
56
+ const { ari, voiceClients, createVoiceClient, isHandledElsewhere } = this;
57
+ const getChannelVar = (0, makeGetChannelVar_1.makeGetChannelVarWithoutThrow)(channel);
58
+ const appRef = (_a = (yield getChannelVar(types_1.ChannelVar.APP_REF))) === null || _a === void 0 ? void 0 : _a.value;
59
+ // This check feels strange but is necessary as ARI calls this event twice
60
+ if (!appRef) {
61
+ logger.silly("no appRef found, ignoring handleStasisStart event");
62
+ return;
63
+ }
64
+ if (yield isHandledElsewhere(channel)) {
64
65
  return;
65
66
  }
66
67
  try {
67
- const vc = yield this.createVoiceClient({
68
- ari: this.ari,
69
- event,
70
- channel
71
- });
68
+ const vc = yield createVoiceClient({ ari, event, channel });
72
69
  // Connect to voice server
73
70
  vc.connect();
74
- this.voiceClients.set(channel.id, vc);
75
- vc.on(common_1.StreamContent.ANSWER_REQUEST, (0, Answer_1.answerHandler)(this.ari, vc).bind(this));
76
- vc.on(common_1.StreamContent.HANGUP_REQUEST, (0, Hangup_1.hangupHandler)(this.ari, vc).bind(this));
77
- vc.on(common_1.StreamContent.MUTE_REQUEST, (0, Mute_1.muteHandler)(this.ari, vc).bind(this));
78
- vc.on(common_1.StreamContent.UNMUTE_REQUEST, (0, Unmute_1.unmuteHandler)(this.ari, vc).bind(this));
79
- vc.on(common_1.StreamContent.PLAY_REQUEST, (0, Play_1.playHandler)(this.ari, vc).bind(this));
80
- vc.on(common_1.StreamContent.PLAY_DTMF_REQUEST, (0, PlayDtmf_1.playDtmfHandler)(this.ari, vc).bind(this));
81
- vc.on(common_1.StreamContent.PLAYBACK_CONTROL_REQUEST, (0, PlaybackControl_1.playbackControlHandler)(this.ari, vc).bind(this));
82
- vc.on(common_1.StreamContent.SAY_REQUEST, (0, Say_1.sayHandler)(this.ari, vc).bind(this));
83
- vc.on(common_1.StreamContent.GATHER_REQUEST, (0, Gather_1.gatherHandler)(vc).bind(this));
84
- vc.on(common_1.StreamContent.DIAL_REQUEST, (0, Dial_1.dialHandler)(this.ari, vc).bind(this));
71
+ voiceClients.set(channel.id, vc);
72
+ vc.on(common_1.StreamContent.ANSWER_REQUEST, (0, handlers_1.answerHandler)(ari, vc).bind(this));
73
+ vc.on(common_1.StreamContent.HANGUP_REQUEST, (0, handlers_1.hangupHandler)(ari, vc).bind(this));
74
+ vc.on(common_1.StreamContent.MUTE_REQUEST, (0, handlers_1.muteHandler)(ari, vc).bind(this));
75
+ vc.on(common_1.StreamContent.UNMUTE_REQUEST, (0, handlers_1.unmuteHandler)(ari, vc).bind(this));
76
+ vc.on(common_1.StreamContent.PLAY_REQUEST, (0, handlers_1.playHandler)(ari, vc).bind(this));
77
+ vc.on(common_1.StreamContent.PLAY_DTMF_REQUEST, (0, handlers_1.playDtmfHandler)(ari, vc).bind(this));
78
+ vc.on(common_1.StreamContent.SAY_REQUEST, (0, handlers_1.sayHandler)(ari, vc).bind(this));
79
+ vc.on(common_1.StreamContent.GATHER_REQUEST, (0, handlers_1.gatherHandler)(vc).bind(this));
80
+ vc.on(common_1.StreamContent.DIAL_REQUEST, (0, handlers_1.dialHandler)(ari, vc).bind(this));
81
+ vc.on(common_1.StreamContent.PLAYBACK_CONTROL_REQUEST, (0, handlers_1.playbackControlHandler)(ari, vc).bind(this));
82
+ vc.on(common_1.StreamContent.START_STREAM_GATHER_REQUEST, (0, handlers_1.streamGatherHandler)(vc).bind(this));
83
+ vc.on(common_1.StreamContent.STOP_STREAM_GATHER_REQUEST, () => {
84
+ vc.stopStreamGather();
85
+ });
85
86
  }
86
87
  catch (err) {
87
88
  logger.error("error handling stasis start", { error: err.message });
@@ -89,11 +90,23 @@ class VoiceDispatcher {
89
90
  });
90
91
  }
91
92
  handleStasisEnd(_, channel) {
92
- const voiceClient = this.voiceClients.get(channel.id);
93
+ const { voiceClients } = this;
94
+ const voiceClient = voiceClients.get(channel.id);
93
95
  if (voiceClient) {
94
96
  voiceClient.close();
95
- this.voiceClients.delete(channel.id);
97
+ voiceClients.delete(channel.id);
96
98
  }
97
99
  }
100
+ handleDial(event, channel) {
101
+ return __awaiter(this, void 0, void 0, function* () {
102
+ (0, utils_1.makeHandleDialEventsWithNats)(this.nc)(channel.id, event);
103
+ });
104
+ }
105
+ isHandledElsewhere(channel) {
106
+ return __awaiter(this, void 0, void 0, function* () {
107
+ var _a;
108
+ return (((_a = (yield (0, makeGetChannelVar_1.makeGetChannelVarWithoutThrow)(channel)(types_1.ChannelVar.FROM_EXTERNAL_MEDIA))) === null || _a === void 0 ? void 0 : _a.value) === "true");
109
+ });
110
+ }
98
111
  }
99
112
  exports.VoiceDispatcher = VoiceDispatcher;
@@ -33,6 +33,7 @@ exports.connectToAri = connectToAri;
33
33
  */
34
34
  const logger_1 = require("@fonoster/logger");
35
35
  const ari_client_1 = __importDefault(require("ari-client"));
36
+ const nats_1 = require("nats");
36
37
  const wait_port_1 = __importDefault(require("wait-port"));
37
38
  const integrations_1 = require("./integrations");
38
39
  const makeCreateVoiceClient_1 = require("./makeCreateVoiceClient");
@@ -62,7 +63,8 @@ function connectToAri() {
62
63
  });
63
64
  logger.info("asterisk is ready");
64
65
  const createContainer = (0, integrations_1.makeCreateContainer)(db_1.prisma, envs_1.INTEGRATIONS_FILE);
65
- const dispatcher = new VoiceDispatcher_1.VoiceDispatcher(ari, (0, makeCreateVoiceClient_1.makeCreateVoiceClient)(createContainer));
66
+ const nats = yield (0, nats_1.connect)({ servers: envs_1.NATS_URL });
67
+ const dispatcher = new VoiceDispatcher_1.VoiceDispatcher(ari, nats, (0, makeCreateVoiceClient_1.makeCreateVoiceClient)(createContainer));
66
68
  dispatcher.start();
67
69
  }
68
70
  else {
@@ -5,5 +5,8 @@ declare function createExternalMediaConfig(port: number): {
5
5
  transport: string;
6
6
  data: string;
7
7
  encapsulation: string;
8
+ variables: {
9
+ FROM_EXTERNAL_MEDIA: string;
10
+ };
8
11
  };
9
12
  export { createExternalMediaConfig };
@@ -29,6 +29,9 @@ function createExternalMediaConfig(port) {
29
29
  format: "slin16",
30
30
  transport: "tcp",
31
31
  data: (0, uuid_1.v4)(),
32
- encapsulation: "audiosocket"
32
+ encapsulation: "audiosocket",
33
+ variables: {
34
+ FROM_EXTERNAL_MEDIA: "true"
35
+ }
33
36
  };
34
37
  }
@@ -10,7 +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.answerHandler = answerHandler;
13
- const withErrorHandling_1 = require("./withErrorHandling");
13
+ const withErrorHandling_1 = require("./utils/withErrorHandling");
14
14
  function answerHandler(ari, voiceClient) {
15
15
  return (0, withErrorHandling_1.withErrorHandling)((request) => __awaiter(this, void 0, void 0, function* () {
16
16
  const { sessionRef } = request;
@@ -10,7 +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.hangupHandler = hangupHandler;
13
- const withErrorHandling_1 = require("./withErrorHandling");
13
+ const withErrorHandling_1 = require("./utils/withErrorHandling");
14
14
  function hangupHandler(ari, voiceClient) {
15
15
  return (0, withErrorHandling_1.withErrorHandling)((request) => __awaiter(this, void 0, void 0, function* () {
16
16
  const { sessionRef } = request;
@@ -10,7 +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.muteHandler = muteHandler;
13
- const withErrorHandling_1 = require("./withErrorHandling");
13
+ const withErrorHandling_1 = require("./utils/withErrorHandling");
14
14
  function muteHandler(ari, voiceClient) {
15
15
  return (0, withErrorHandling_1.withErrorHandling)((request) => __awaiter(this, void 0, void 0, function* () {
16
16
  const { sessionRef, direction } = request;
@@ -11,8 +11,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.playHandler = playHandler;
13
13
  const nanoid_1 = require("nanoid");
14
- const awaitForPlaybackFinished_1 = require("./awaitForPlaybackFinished");
15
- const withErrorHandling_1 = require("./withErrorHandling");
14
+ const awaitForPlaybackFinished_1 = require("./utils/awaitForPlaybackFinished");
15
+ const withErrorHandling_1 = require("./utils/withErrorHandling");
16
16
  function playHandler(ari, voiceClient) {
17
17
  return (0, withErrorHandling_1.withErrorHandling)((request) => __awaiter(this, void 0, void 0, function* () {
18
18
  const { sessionRef } = request;
@@ -10,7 +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.playDtmfHandler = playDtmfHandler;
13
- const withErrorHandling_1 = require("./withErrorHandling");
13
+ const withErrorHandling_1 = require("./utils/withErrorHandling");
14
14
  function playDtmfHandler(ari, voiceClient) {
15
15
  return (0, withErrorHandling_1.withErrorHandling)((request) => __awaiter(this, void 0, void 0, function* () {
16
16
  const { sessionRef, digits } = request;
@@ -10,7 +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.playbackControlHandler = playbackControlHandler;
13
- const withErrorHandling_1 = require("./withErrorHandling");
13
+ const withErrorHandling_1 = require("./utils/withErrorHandling");
14
14
  function playbackControlHandler(ari, voiceClient) {
15
15
  return (0, withErrorHandling_1.withErrorHandling)((playbackControlReq) => __awaiter(this, void 0, void 0, function* () {
16
16
  const { sessionRef, playbackRef, action } = playbackControlReq;
@@ -30,8 +30,8 @@ exports.recordHandler = recordHandler;
30
30
  */
31
31
  const common_1 = require("@fonoster/common");
32
32
  const nanoid_1 = require("nanoid");
33
- const awaitForRecordingFinished_1 = require("./awaitForRecordingFinished");
34
- const withErrorHandling_1 = require("./withErrorHandling");
33
+ const awaitForRecordingFinished_1 = require("./utils/awaitForRecordingFinished");
34
+ const withErrorHandling_1 = require("./utils/withErrorHandling");
35
35
  function recordHandler(ari, voiceClient) {
36
36
  return (0, withErrorHandling_1.withErrorHandling)((request) => __awaiter(this, void 0, void 0, function* () {
37
37
  const { sessionRef, maxDuration, maxSilence, beep, finishOnKey } = request;
@@ -13,8 +13,8 @@ exports.sayHandler = sayHandler;
13
13
  const nanoid_1 = require("nanoid");
14
14
  const pb_util_1 = require("pb-util");
15
15
  const zod_1 = require("zod");
16
- const awaitForPlaybackFinished_1 = require("./awaitForPlaybackFinished");
17
- const withErrorHandling_1 = require("./withErrorHandling");
16
+ const awaitForPlaybackFinished_1 = require("./utils/awaitForPlaybackFinished");
17
+ const withErrorHandling_1 = require("./utils/withErrorHandling");
18
18
  const envs_1 = require("../../envs");
19
19
  const sayRequestSchema = zod_1.z.object({
20
20
  text: zod_1.z.string(),
@@ -0,0 +1,3 @@
1
+ import { VoiceClient } from "../types";
2
+ declare function streamGatherHandler(voiceClient: VoiceClient): (request: import("@fonoster/common").VerbRequest) => Promise<void>;
3
+ export { streamGatherHandler };
@@ -0,0 +1,66 @@
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
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.streamGatherHandler = streamGatherHandler;
13
+ /*
14
+ * Copyright (C) 2024 by Fonoster Inc (https://fonoster.com)
15
+ * http://github.com/fonoster/fonoster
16
+ *
17
+ * This file is part of Fonoster
18
+ *
19
+ * Licensed under the MIT License (the "License");
20
+ * you may not use this file except in compliance with
21
+ * the License. You may obtain a copy of the License at
22
+ *
23
+ * https://opensource.org/licenses/MIT
24
+ *
25
+ * Unless required by applicable law or agreed to in writing, software
26
+ * distributed under the License is distributed on an "AS IS" BASIS,
27
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
28
+ * See the License for the specific language governing permissions and
29
+ * limitations under the License.
30
+ */
31
+ const common_1 = require("@fonoster/common");
32
+ const zod_1 = require("zod");
33
+ const withErrorHandling_1 = require("./utils/withErrorHandling");
34
+ const gatherRequestSchema = zod_1.z.object({
35
+ source: zod_1.z.optional(zod_1.z.nativeEnum(common_1.StreamGatherSource))
36
+ });
37
+ function streamGatherHandler(voiceClient) {
38
+ return (0, withErrorHandling_1.withErrorHandling)((request) => __awaiter(this, void 0, void 0, function* () {
39
+ const { sessionRef, source } = request;
40
+ // Error handled by withErrorHandling
41
+ gatherRequestSchema.parse(request);
42
+ const effectiveSource = source || common_1.StreamGatherSource.SPEECH_AND_DTMF;
43
+ if (effectiveSource.includes(common_1.StreamGatherSource.DTMF)) {
44
+ voiceClient.startDtmfGather(sessionRef, (event) => {
45
+ const { digit } = event;
46
+ voiceClient.sendResponse({
47
+ streamGatherPayload: {
48
+ sessionRef,
49
+ digit
50
+ }
51
+ });
52
+ });
53
+ }
54
+ if (effectiveSource.includes(common_1.StreamGatherSource.SPEECH)) {
55
+ voiceClient.startSpeechGather((event) => {
56
+ const { speech } = event;
57
+ voiceClient.sendResponse({
58
+ streamGatherPayload: {
59
+ sessionRef,
60
+ speech
61
+ }
62
+ });
63
+ });
64
+ }
65
+ }));
66
+ }
@@ -10,7 +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.unmuteHandler = unmuteHandler;
13
- const withErrorHandling_1 = require("./withErrorHandling");
13
+ const withErrorHandling_1 = require("./utils/withErrorHandling");
14
14
  function unmuteHandler(ari, voiceClient) {
15
15
  return (0, withErrorHandling_1.withErrorHandling)((request) => __awaiter(this, void 0, void 0, function* () {
16
16
  const { sessionRef, direction } = request;
@@ -29,11 +29,12 @@ exports.dialHandler = dialHandler;
29
29
  * limitations under the License.
30
30
  */
31
31
  const common_1 = require("@fonoster/common");
32
+ const uuid_1 = require("uuid");
32
33
  const handleChannelLeftBridge_1 = require("./handleChannelLeftBridge");
33
- const handleDialEvents_1 = require("./handleDialEvents");
34
34
  const handleStasisEnd_1 = require("./handleStasisEnd");
35
35
  const handleStasisStart_1 = require("./handleStasisStart");
36
36
  const envs_1 = require("../../../envs");
37
+ const utils_1 = require("../../../utils");
37
38
  const makeGetChannelVar_1 = require("../../makeGetChannelVar");
38
39
  const types_1 = require("../../types");
39
40
  // TODO: Needs request validation
@@ -50,18 +51,21 @@ function dialHandler(ari, voiceClient) {
50
51
  const getChannelVar = (0, makeGetChannelVar_1.makeGetChannelVar)(callerChannel);
51
52
  const ingressNumber = (yield getChannelVar(types_1.ChannelVar.INGRESS_NUMBER))
52
53
  .value;
54
+ const ref = (0, uuid_1.v4)();
53
55
  yield dialed.originate({
54
56
  app: common_1.STASIS_APP_NAME,
55
57
  endpoint: `PJSIP/${envs_1.ASTERISK_TRUNK}/sip:${destination}@${envs_1.ASTERISK_SYSTEM_DOMAIN}`,
56
58
  timeout,
57
59
  variables: {
58
- "PJSIP_HEADER(add,X-DOD-Number)": ingressNumber
60
+ "PJSIP_HEADER(add,X-Call-Ref)": ref,
61
+ "PJSIP_HEADER(add,X-Dod-Number)": ingressNumber,
62
+ "PJSIP_HEADER(add,X-Is-Api-Originated-Type)": "true"
59
63
  }
60
64
  });
61
- dialed.on(types_1.AriEvent.STASIS_START, (0, handleStasisStart_1.handleStasisStart)({ ari, request, bridge, dialed }));
62
- dialed.on(types_1.AriEvent.CHANNEL_LEFT_BRIDGE, (0, handleChannelLeftBridge_1.handleChannelLeftBridge)({ bridge, dialed }));
63
- dialed.on(types_1.AriEvent.STASIS_END, (0, handleStasisEnd_1.handleStasisEnd)(request));
64
- dialed.on(types_1.AriEvent.DIAL, (0, handleDialEvents_1.handleDialEvents)(voiceClient));
65
+ dialed.once(types_1.AriEvent.STASIS_START, (0, handleStasisStart_1.handleStasisStart)({ ari, request, bridge, dialed }));
66
+ dialed.once(types_1.AriEvent.CHANNEL_LEFT_BRIDGE, (0, handleChannelLeftBridge_1.handleChannelLeftBridge)({ bridge, dialed }));
67
+ dialed.once(types_1.AriEvent.STASIS_END, (0, handleStasisEnd_1.handleStasisEnd)(request));
68
+ dialed.on(types_1.AriEvent.DIAL, (0, utils_1.makeHandleDialEventsWithVoiceClient)(voiceClient));
65
69
  voiceClient.sendResponse({
66
70
  dialResponse: {
67
71
  status: common_1.DialStatus.TRYING
@@ -31,9 +31,10 @@ exports.gatherHandler = gatherHandler;
31
31
  const common_1 = require("@fonoster/common");
32
32
  const zod_1 = require("zod");
33
33
  const getTimeoutPromise_1 = require("./getTimeoutPromise");
34
- const withErrorHandling_1 = require("../withErrorHandling");
35
- const isDtmf = (digit) => /^[0-9*#]+$/.test(digit);
34
+ const utils_1 = require("../utils");
35
+ const withErrorHandling_1 = require("../utils/withErrorHandling");
36
36
  const gatherRequestSchema = zod_1.z.object({
37
+ source: zod_1.z.optional(zod_1.z.nativeEnum(common_1.GatherSource)),
37
38
  maxDigits: zod_1.z.number().optional().nullable(),
38
39
  // TODO: Ensure it is a dtmf character
39
40
  finishOnKey: zod_1.z.string().max(1).optional().nullable()
@@ -64,8 +65,8 @@ function gatherHandler(voiceClient) {
64
65
  voiceClient.sendResponse({
65
66
  gatherResponse: {
66
67
  sessionRef,
67
- speech: isDtmf(result) ? null : result,
68
- digits: isDtmf(result) ? result : null
68
+ speech: (0, utils_1.isDtmf)(result) ? null : result,
69
+ digits: (0, utils_1.isDtmf)(result) ? result : null
69
70
  }
70
71
  });
71
72
  }));
@@ -0,0 +1,12 @@
1
+ export * from "./Answer";
2
+ export * from "./Hangup";
3
+ export * from "./Mute";
4
+ export * from "./Unmute";
5
+ export * from "./dial/Dial";
6
+ export * from "./gather/Gather";
7
+ export * from "./StreamGather";
8
+ export * from "./Play";
9
+ export * from "./PlaybackControl";
10
+ export * from "./PlayDtmf";
11
+ export * from "./Record";
12
+ export * from "./Say";
@@ -0,0 +1,46 @@
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("./Answer"), exports);
36
+ __exportStar(require("./Hangup"), exports);
37
+ __exportStar(require("./Mute"), exports);
38
+ __exportStar(require("./Unmute"), exports);
39
+ __exportStar(require("./dial/Dial"), exports);
40
+ __exportStar(require("./gather/Gather"), exports);
41
+ __exportStar(require("./StreamGather"), exports);
42
+ __exportStar(require("./Play"), exports);
43
+ __exportStar(require("./PlaybackControl"), exports);
44
+ __exportStar(require("./PlayDtmf"), exports);
45
+ __exportStar(require("./Record"), exports);
46
+ __exportStar(require("./Say"), exports);
@@ -10,7 +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.awaitForPlaybackFinished = void 0;
13
- const types_1 = require("../types");
13
+ const types_1 = require("../../types");
14
14
  const awaitForPlaybackFinished = (ari, playbackRef) => __awaiter(void 0, void 0, void 0, function* () {
15
15
  return new Promise((resolve) => {
16
16
  const listener = (_, playback) => {
@@ -30,7 +30,7 @@ exports.awaitForRecordingFinished = awaitForRecordingFinished;
30
30
  */
31
31
  const common_1 = require("@fonoster/common");
32
32
  const grpc_js_1 = require("@grpc/grpc-js");
33
- const types_1 = require("../types");
33
+ const types_1 = require("../../types");
34
34
  function awaitForRecordingFinished(ari, name) {
35
35
  return __awaiter(this, void 0, void 0, function* () {
36
36
  return new Promise((resolve, reject) => {
@@ -0,0 +1,3 @@
1
+ export * from "./awaitForPlaybackFinished";
2
+ export * from "./awaitForRecordingFinished";
3
+ export * from "./isDtmf";
@@ -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,2 @@
1
+ declare function isDtmf(digit: string): boolean;
2
+ export { isDtmf };
@@ -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): IntegrationConfig;
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
- return integrations.find((i) => i.productRef === engine);
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
- credentials: IntegrationConfig;
6
- languageCode: VoiceLanguage;
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 Object.assign(Object.assign({}, config), { credentials });
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
- credentials: IntegrationConfig;
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 Object.assign(Object.assign({}, config), { credentials, pathToFiles: envs_1.TTS_PATH_TO_FILES });
9
+ return {
10
+ config,
11
+ credentials,
12
+ pathToFiles: envs_1.TTS_PATH_TO_FILES
13
+ };
10
14
  }
@@ -80,7 +80,7 @@ function makeCreateContainer(prisma, pathToIntegrations) {
80
80
  return {
81
81
  ref: appRef,
82
82
  accessKeyId: app.accessKeyId,
83
- appEndpoint: app.appEndpoint,
83
+ endpoint: app.endpoint,
84
84
  tts,
85
85
  stt
86
86
  };