@fonoster/voice 0.27.0 → 0.31.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/README.md +32 -419
- package/dist/Session.d.ts +161 -0
- package/dist/Session.js +576 -0
- package/dist/VoiceServer.d.ts +70 -5
- package/dist/VoiceServer.js +149 -43
- package/dist/{verbs/Dial.d.ts → errors.d.ts} +9 -13
- package/dist/{verbs/Answer.js → errors.js} +18 -7
- package/dist/index.d.ts +4 -6
- package/dist/index.js +4 -15
- package/dist/signature.d.ts +31 -0
- package/dist/signature.js +93 -0
- package/dist/types.d.ts +88 -10
- package/dist/types.js +0 -21
- package/package.json +13 -19
- package/session.d.ts +1 -0
- package/session.js +2 -0
- package/dist/VoiceResponse.d.ts +0 -304
- package/dist/VoiceResponse.js +0 -461
- package/dist/createSession.d.ts +0 -22
- package/dist/createSession.js +0 -66
- package/dist/defaultServerConfig.d.ts +0 -21
- package/dist/defaultServerConfig.js +0 -10
- package/dist/demo.d.ts +0 -1
- package/dist/demo.js +0 -83
- package/dist/filters.d.ts +0 -44
- package/dist/filters.js +0 -17
- package/dist/serviceDefinition.d.ts +0 -2
- package/dist/serviceDefinition.js +0 -29
- package/dist/verbs/Answer.d.ts +0 -24
- package/dist/verbs/Dial.js +0 -60
- package/dist/verbs/Gather.d.ts +0 -25
- package/dist/verbs/Gather.js +0 -57
- package/dist/verbs/Hangup.d.ts +0 -24
- package/dist/verbs/Hangup.js +0 -29
- package/dist/verbs/Mute.d.ts +0 -25
- package/dist/verbs/Mute.js +0 -36
- package/dist/verbs/Play.d.ts +0 -25
- package/dist/verbs/Play.js +0 -33
- package/dist/verbs/PlayDtmf.d.ts +0 -25
- package/dist/verbs/PlayDtmf.js +0 -32
- package/dist/verbs/PlaybackControl.d.ts +0 -25
- package/dist/verbs/PlaybackControl.js +0 -35
- package/dist/verbs/Record.d.ts +0 -25
- package/dist/verbs/Record.js +0 -49
- package/dist/verbs/Say.d.ts +0 -25
- package/dist/verbs/Say.js +0 -33
- package/dist/verbs/SetAudioFilters.d.ts +0 -25
- package/dist/verbs/SetAudioFilters.js +0 -16
- package/dist/verbs/StopSay.d.ts +0 -25
- package/dist/verbs/StopSay.js +0 -11
- package/dist/verbs/Stream.d.ts +0 -39
- package/dist/verbs/Stream.js +0 -80
- package/dist/verbs/StreamGather.d.ts +0 -37
- package/dist/verbs/StreamGather.js +0 -66
- package/dist/verbs/Unmute.d.ts +0 -22
- package/dist/verbs/Unmute.js +0 -26
- package/dist/verbs/Verb.d.ts +0 -28
- package/dist/verbs/Verb.js +0 -103
- package/dist/verbs/getExpectedContent.d.ts +0 -2
- package/dist/verbs/getExpectedContent.js +0 -32
- package/dist/verbs/index.d.ts +0 -35
- package/dist/verbs/index.js +0 -51
- package/dist/verbs/validateRequest.d.ts +0 -20
- package/dist/verbs/validateRequest.js +0 -13
package/dist/VoiceResponse.js
DELETED
|
@@ -1,461 +0,0 @@
|
|
|
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.VoiceResponse = void 0;
|
|
13
|
-
/**
|
|
14
|
-
* Copyright (C) 2025 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 pb_util_1 = require("pb-util");
|
|
33
|
-
const verbs_1 = require("./verbs");
|
|
34
|
-
/**
|
|
35
|
-
* @classdesc Use the VoiceResponse object, to construct advance Interactive
|
|
36
|
-
* Voice Response (IVR) applications.
|
|
37
|
-
*
|
|
38
|
-
* @extends Verb
|
|
39
|
-
* @example
|
|
40
|
-
*
|
|
41
|
-
* import { VoiceServer } from "@fonoster/voice";
|
|
42
|
-
*
|
|
43
|
-
* async function handler (request, response) {
|
|
44
|
-
* await response.answer();
|
|
45
|
-
* await response.play("https://soundsserver:9000/sounds/hello-world.wav");
|
|
46
|
-
* }
|
|
47
|
-
*
|
|
48
|
-
* new VoiceServer().listen(handler, { port: 3000 })
|
|
49
|
-
*/
|
|
50
|
-
class VoiceResponse {
|
|
51
|
-
/**
|
|
52
|
-
* Constructs a new VoiceResponse object.
|
|
53
|
-
*
|
|
54
|
-
* @param {VoiceRequest} request - Options to indicate the objects endpoint
|
|
55
|
-
* @param {VoiceSessionStream} voice - The voice session stream
|
|
56
|
-
* @see module:core:APIClient
|
|
57
|
-
*/
|
|
58
|
-
constructor(request, voice) {
|
|
59
|
-
this.voice = voice;
|
|
60
|
-
this.request = request;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Answer the call. Before running any other verb you
|
|
64
|
-
* must run the answer command.
|
|
65
|
-
* @example
|
|
66
|
-
*
|
|
67
|
-
* async function handler (request, response) {
|
|
68
|
-
* await response.answer();
|
|
69
|
-
* }
|
|
70
|
-
*/
|
|
71
|
-
answer() {
|
|
72
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
73
|
-
yield new verbs_1.Answer(this.request, this.voice).run();
|
|
74
|
-
return { mediaSessionRef: this.request.mediaSessionRef };
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Hangup the call.
|
|
79
|
-
* @example
|
|
80
|
-
*
|
|
81
|
-
* async function handler (request, response) {
|
|
82
|
-
* await response.hangup();
|
|
83
|
-
* }
|
|
84
|
-
*/
|
|
85
|
-
hangup() {
|
|
86
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
87
|
-
yield new verbs_1.Hangup(this.request, this.voice).run();
|
|
88
|
-
return { mediaSessionRef: this.request.mediaSessionRef };
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Play an audio in the call.
|
|
93
|
-
*
|
|
94
|
-
* @param {string} url - The URL of the media to play
|
|
95
|
-
* @param {PlayOptions} options - Options to control the playback
|
|
96
|
-
* @param {string} options.playbackRef - Playback identifier to use in Playback operations
|
|
97
|
-
* @see Playback
|
|
98
|
-
* @example
|
|
99
|
-
*
|
|
100
|
-
* async function handler (request, response) {
|
|
101
|
-
* await response.answer();
|
|
102
|
-
* await response.play("https://soundsserver:9000/sounds/hello-world.wav");
|
|
103
|
-
* }
|
|
104
|
-
*/
|
|
105
|
-
play(url, options) {
|
|
106
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
107
|
-
const response = yield new verbs_1.Play(this.request, this.voice).run(Object.assign(Object.assign({}, options), { mediaSessionRef: this.request.mediaSessionRef, url }));
|
|
108
|
-
return response.playResponse;
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Play a series of DTMF digits in a call.
|
|
113
|
-
*
|
|
114
|
-
* @param {string} digits -The DTMF digits to play (0-9, #, or *)
|
|
115
|
-
* @example
|
|
116
|
-
*
|
|
117
|
-
* async function handler (request, response) {
|
|
118
|
-
* await response.answer();
|
|
119
|
-
* await response.playDtmf("1234");
|
|
120
|
-
* }
|
|
121
|
-
*/
|
|
122
|
-
playDtmf(digits) {
|
|
123
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
124
|
-
yield new verbs_1.PlayDtmf(this.request, this.voice).run({
|
|
125
|
-
mediaSessionRef: this.request.mediaSessionRef,
|
|
126
|
-
digits
|
|
127
|
-
});
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Control the playback of the currently playing media.
|
|
132
|
-
*
|
|
133
|
-
* @param {string} playbackRef - The playback identifier
|
|
134
|
-
* @param {PlaybackControlAction} action - The action to perform (STOP, RESTART, PAUSE, UNPAUSE, FORWARD)
|
|
135
|
-
* @see play
|
|
136
|
-
* @example
|
|
137
|
-
*
|
|
138
|
-
* async function handler (request, response) {
|
|
139
|
-
* await response.answer();
|
|
140
|
-
* await response.play("https://s3.fonoster.io/uuid/hello-world.wav", { playbackRef: "playback-01" });
|
|
141
|
-
*
|
|
142
|
-
* // Pause the media
|
|
143
|
-
* await response.playbackControl("playback-01", PlaybackControlAction.PAUSE);
|
|
144
|
-
* }
|
|
145
|
-
*/
|
|
146
|
-
playbackControl(playbackRef, action) {
|
|
147
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
148
|
-
yield new verbs_1.PlaybackControl(this.request, this.voice).run({
|
|
149
|
-
mediaSessionRef: this.request.mediaSessionRef,
|
|
150
|
-
playbackRef,
|
|
151
|
-
action
|
|
152
|
-
});
|
|
153
|
-
return { mediaSessionRef: this.request.mediaSessionRef };
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Waits for data entry from the user's keypad or from a speech provider.
|
|
158
|
-
*
|
|
159
|
-
* @param {GatherOptions} options - Options to select the maximum number of digits, final character, and timeout
|
|
160
|
-
* @param {number} options.maxDigits - Maximum number of digits to collect. Defaults to 1
|
|
161
|
-
* @param {number} options.timeout - Milliseconds to wait before timeout. Defaults to 4000. Use zero for no timeout.
|
|
162
|
-
* @param {string} options.finishOnKey - Optional last character to wait for. Defaults to '#'. It will not be included in the returned digits
|
|
163
|
-
* @param {GatherSource} options.source - Where to listen as input source. This option accepts `DTMF` and `SPEECH`. A speech provider must be configure
|
|
164
|
-
* when including the `SPEECH` source. You might include both with `SPEECH_AND_DTMF`. Defaults to `SPEECH_AND_DTMF`
|
|
165
|
-
* @note When including `SPEECH` the default timeout is 10000 (10s).
|
|
166
|
-
* @example
|
|
167
|
-
*
|
|
168
|
-
* async function handler (request, response) {
|
|
169
|
-
* await response.answer();
|
|
170
|
-
* const speech = await response.gather({ source: GatherSource.SPEECH, numDigits: 3 });
|
|
171
|
-
* console.log("speech: " + speech);
|
|
172
|
-
* await response.hangup();
|
|
173
|
-
* }
|
|
174
|
-
*/
|
|
175
|
-
gather() {
|
|
176
|
-
return __awaiter(this, arguments, void 0, function* (options = { source: common_1.GatherSource.SPEECH_AND_DTMF }) {
|
|
177
|
-
const response = yield new verbs_1.Gather(this.request, this.voice).run(Object.assign({ mediaSessionRef: this.request.mediaSessionRef }, options));
|
|
178
|
-
return response.gatherResponse;
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Send a text for a TTS engine to convert to speech.
|
|
183
|
-
*
|
|
184
|
-
* @param {string} text - The text to convert to speech
|
|
185
|
-
* @param {SayOptions} options - Options to control the TTS engine
|
|
186
|
-
* @param {string} options.playbackRef - Playback identifier to use in Playback operations
|
|
187
|
-
* @param {TTSOptions} options.ttsOptions - Options to control the TTS engine (specific to the TTS engine)
|
|
188
|
-
* @see Say
|
|
189
|
-
* @example
|
|
190
|
-
*
|
|
191
|
-
* async function handler (request, response) {
|
|
192
|
-
* await response.answer();
|
|
193
|
-
* const playbackRef = await response.say("Hello World");
|
|
194
|
-
*
|
|
195
|
-
* // Like the play verb, you can control the playback
|
|
196
|
-
* await response.playbackControl(playbackRef, PlaybackControlAction.STOP);
|
|
197
|
-
* }
|
|
198
|
-
*/
|
|
199
|
-
say(text, options) {
|
|
200
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
201
|
-
yield new verbs_1.Say(this.request, this.voice).run({
|
|
202
|
-
options: options ? pb_util_1.struct.encode(options) : undefined,
|
|
203
|
-
mediaSessionRef: this.request.mediaSessionRef,
|
|
204
|
-
text
|
|
205
|
-
});
|
|
206
|
-
return { mediaSessionRef: this.request.mediaSessionRef };
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
/**
|
|
210
|
-
* Stop the current TTS operation.
|
|
211
|
-
* @example
|
|
212
|
-
*
|
|
213
|
-
* async function handler (request, response) {
|
|
214
|
-
* await response.answer();
|
|
215
|
-
*
|
|
216
|
-
* // Some async operation
|
|
217
|
-
* setTimeout(() => {
|
|
218
|
-
* // Will stop the current TTS operation
|
|
219
|
-
* response.stopSay();
|
|
220
|
-
* }, 10000);
|
|
221
|
-
*
|
|
222
|
-
* await response.say("Long text to say...");
|
|
223
|
-
* }
|
|
224
|
-
*/
|
|
225
|
-
stopSay() {
|
|
226
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
227
|
-
yield new verbs_1.StopSay(this.request, this.voice).run();
|
|
228
|
-
return { mediaSessionRef: this.request.mediaSessionRef };
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
/**
|
|
232
|
-
* Record the audio of the call.
|
|
233
|
-
*
|
|
234
|
-
* @param {RecordOptions} options - Options to control the record operation
|
|
235
|
-
* @param {number} options.maxDuration - The maximum duration of the recording in seconds. Default is 60
|
|
236
|
-
* @param {number} options.maxSilence - The maximum duration of silence in seconds. Default is 5
|
|
237
|
-
* @param {boolean} options.beep - Play a beep before recording. Default is true
|
|
238
|
-
* @param {string} options.finishOnKey - Stop recording when a DTMF digit is received. Default is '#'
|
|
239
|
-
* @return {RecordResponse} The record response
|
|
240
|
-
* @example
|
|
241
|
-
*
|
|
242
|
-
* async function handler (request, response) {
|
|
243
|
-
* await response.answer();
|
|
244
|
-
* const record = await response.record();
|
|
245
|
-
* console.log("Recording: %s", record.name);
|
|
246
|
-
* }
|
|
247
|
-
*/
|
|
248
|
-
record(options) {
|
|
249
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
250
|
-
const response = yield new verbs_1.Record(this.request, this.voice).run(Object.assign({ mediaSessionRef: this.request.mediaSessionRef }, options));
|
|
251
|
-
return response.recordResponse;
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
/**
|
|
255
|
-
* Dials a destination and returns a stream of status.
|
|
256
|
-
*
|
|
257
|
-
* @param {string} destination - The destination to dial
|
|
258
|
-
* @param {DialOptions} options - Options to control the dial operation
|
|
259
|
-
* @param {number} options.timeout - The timeout in seconds. Default is 60
|
|
260
|
-
* @param {RecordDirection} options.recordDirection - The direction to record the call (IN, OUT, BOTH). Default is BOTH
|
|
261
|
-
* @return {Promise<DialStatusStream>} The dial status stream
|
|
262
|
-
*/
|
|
263
|
-
dial(destination, options) {
|
|
264
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
265
|
-
const stream = new verbs_1.DialStatusStream();
|
|
266
|
-
yield new verbs_1.Dial(this.request, this.voice).run(Object.assign({ mediaSessionRef: this.request.mediaSessionRef, destination }, options));
|
|
267
|
-
this.voice.on(common_1.StreamEvent.DATA, (result) => {
|
|
268
|
-
if (result.dialResponse) {
|
|
269
|
-
stream.emit(result.dialResponse.status);
|
|
270
|
-
}
|
|
271
|
-
});
|
|
272
|
-
return stream;
|
|
273
|
-
});
|
|
274
|
-
}
|
|
275
|
-
/**
|
|
276
|
-
* Starts a bidirectional audio stream between the call and the application.
|
|
277
|
-
*
|
|
278
|
-
* @param {StreamOptions} options - Options to control the stream operation
|
|
279
|
-
* @param {StreamDirection} options.direction - The direction to stream the audio (IN, OUT, BOTH). Default is BOTH
|
|
280
|
-
* @param {StreamAudioFormat} options.format - The audio format to stream (WAV). Default is WAV
|
|
281
|
-
* @return {Promise<Stream>} The stream object
|
|
282
|
-
* @example
|
|
283
|
-
*
|
|
284
|
-
* async function handler (request, response) {
|
|
285
|
-
* await response.answer();
|
|
286
|
-
*
|
|
287
|
-
* const stream = await response.stream({
|
|
288
|
-
* direction: StreamDirection.BOTH
|
|
289
|
-
* });
|
|
290
|
-
*
|
|
291
|
-
* stream.onPayload((payload) => {
|
|
292
|
-
* // Use the payload
|
|
293
|
-
* });
|
|
294
|
-
*
|
|
295
|
-
* // Or write to the stream
|
|
296
|
-
* // stream.write({ type: StreamMessageType.AUDIO_OUT, payload: "\x00\x01\x02" });
|
|
297
|
-
* }
|
|
298
|
-
*/
|
|
299
|
-
stream(options) {
|
|
300
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
301
|
-
const stream = new verbs_1.Stream();
|
|
302
|
-
const startStream = new verbs_1.StartStream(this.request, this.voice);
|
|
303
|
-
const stopStream = new verbs_1.StopStream(this.request, this.voice);
|
|
304
|
-
const { startStreamResponse } = yield startStream.run(Object.assign({ mediaSessionRef: this.request.mediaSessionRef }, options));
|
|
305
|
-
this.voice.on(common_1.StreamEvent.DATA, (result) => {
|
|
306
|
-
if (result.streamPayload) {
|
|
307
|
-
stream.emit("payloadOut", result.streamPayload);
|
|
308
|
-
}
|
|
309
|
-
});
|
|
310
|
-
stream.onPayloadIn((payload) => {
|
|
311
|
-
this.voice.write({
|
|
312
|
-
streamPayload: payload
|
|
313
|
-
});
|
|
314
|
-
});
|
|
315
|
-
stream.cleanup(() => {
|
|
316
|
-
stopStream.run({
|
|
317
|
-
mediaSessionRef: this.request.mediaSessionRef,
|
|
318
|
-
streamRef: startStreamResponse === null || startStreamResponse === void 0 ? void 0 : startStreamResponse.streamRef
|
|
319
|
-
});
|
|
320
|
-
});
|
|
321
|
-
return stream;
|
|
322
|
-
});
|
|
323
|
-
}
|
|
324
|
-
/**
|
|
325
|
-
* Starts a server-side stream gather operation which sends transcription data to the voice server.
|
|
326
|
-
*
|
|
327
|
-
* @param {StreamGatherOptions} options - Options to control the stream gather operation
|
|
328
|
-
* @param {StreamGatherSource} options.source - The source to gather data from (DTMF, SPEECH, SPEECH_AND_DTMF). Default is SPEECH
|
|
329
|
-
* @return {Promise<StreamGatherStream>} The stream gather object
|
|
330
|
-
* @see Gather
|
|
331
|
-
* @example
|
|
332
|
-
*
|
|
333
|
-
* async function handler (request, response) {
|
|
334
|
-
* await response.answer();
|
|
335
|
-
* const sGather = await response.sgather({ source: StreamGatherSource.SPEECH });
|
|
336
|
-
* sGather.onPayload((payload) => {
|
|
337
|
-
* console.log("Payload: %s", payload);
|
|
338
|
-
* });
|
|
339
|
-
* }
|
|
340
|
-
*/
|
|
341
|
-
sgather(options) {
|
|
342
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
343
|
-
const stream = new verbs_1.StreamGatherStream();
|
|
344
|
-
const startStreamGather = new verbs_1.StartStreamGather(this.request, this.voice);
|
|
345
|
-
const stopStreamGather = new verbs_1.StopStreamGather(this.request, this.voice);
|
|
346
|
-
yield startStreamGather.run(Object.assign({ mediaSessionRef: this.request.mediaSessionRef }, options));
|
|
347
|
-
this.voice.on(common_1.StreamEvent.DATA, (result) => {
|
|
348
|
-
if (result.streamGatherPayload) {
|
|
349
|
-
stream.emit("data", result.streamGatherPayload);
|
|
350
|
-
}
|
|
351
|
-
});
|
|
352
|
-
stream.cleanup(() => {
|
|
353
|
-
stopStreamGather.run();
|
|
354
|
-
});
|
|
355
|
-
return stream;
|
|
356
|
-
});
|
|
357
|
-
}
|
|
358
|
-
/**
|
|
359
|
-
* Sets the audio filters for this session. Filters run in the Media Server,
|
|
360
|
-
* on the caller's audio, before it reaches speech recognition and the
|
|
361
|
-
* application's media stream. Call it before answering.
|
|
362
|
-
*
|
|
363
|
-
* Sending a new list replaces the previous one; an empty list removes all
|
|
364
|
-
* filters. If a filter cannot be created — an unknown name, invalid options,
|
|
365
|
-
* a missing SDK or license — the verb fails and the call continues with
|
|
366
|
-
* unfiltered audio.
|
|
367
|
-
*
|
|
368
|
-
* @param {AudioFilterConfig[]} filters - The filters to run, in order
|
|
369
|
-
* @return {Promise<void>}
|
|
370
|
-
* @see aiCoustics
|
|
371
|
-
* @example
|
|
372
|
-
*
|
|
373
|
-
* async function handler (request, response) {
|
|
374
|
-
* await response.setAudioFilters([aiCoustics({ enhancementLevel: 0.8 })]);
|
|
375
|
-
* await response.answer();
|
|
376
|
-
* }
|
|
377
|
-
*/
|
|
378
|
-
setAudioFilters(filters) {
|
|
379
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
380
|
-
var _a;
|
|
381
|
-
const result = yield new verbs_1.SetAudioFilters(this.request, this.voice).run({
|
|
382
|
-
mediaSessionRef: this.request.mediaSessionRef,
|
|
383
|
-
filters: filters.map((filter) => {
|
|
384
|
-
var _a;
|
|
385
|
-
return ({
|
|
386
|
-
name: filter.name,
|
|
387
|
-
options: pb_util_1.struct.encode(((_a = filter.options) !== null && _a !== void 0 ? _a : {}))
|
|
388
|
-
});
|
|
389
|
-
})
|
|
390
|
-
});
|
|
391
|
-
// The Media Server applies what it can and keeps the call alive; anything
|
|
392
|
-
// it refused comes back here so the application can log or react to it.
|
|
393
|
-
if ((_a = result.setAudioFiltersResponse) === null || _a === void 0 ? void 0 : _a.error) {
|
|
394
|
-
throw new Error(result.setAudioFiltersResponse.error);
|
|
395
|
-
}
|
|
396
|
-
});
|
|
397
|
-
}
|
|
398
|
-
/**
|
|
399
|
-
* Mutes a call.
|
|
400
|
-
*
|
|
401
|
-
* @param {MuteOptions} options - Options to control the mute operation
|
|
402
|
-
* @param {MuteDirection} options.direction - The direction to mute the channel (IN, OUT, BOTH). Default is BOTH
|
|
403
|
-
* @see unmute
|
|
404
|
-
* @example
|
|
405
|
-
*
|
|
406
|
-
* async function handler (request, response) {
|
|
407
|
-
* await response.answer();
|
|
408
|
-
* await response.mute(); // Will mute both directions
|
|
409
|
-
* }
|
|
410
|
-
*/
|
|
411
|
-
mute() {
|
|
412
|
-
return __awaiter(this, arguments, void 0, function* (options = { direction: common_1.MuteDirection.BOTH }) {
|
|
413
|
-
const { direction } = options;
|
|
414
|
-
yield new verbs_1.Mute(this.request, this.voice).run({
|
|
415
|
-
mediaSessionRef: this.request.mediaSessionRef,
|
|
416
|
-
direction
|
|
417
|
-
});
|
|
418
|
-
});
|
|
419
|
-
}
|
|
420
|
-
/**
|
|
421
|
-
* Unmute a call.
|
|
422
|
-
*
|
|
423
|
-
* @param {MuteOptions} options - Options to control the unmute operation
|
|
424
|
-
* @param {MuteDirection} options.direction - The direction to unmute the call (IN, OUT, BOTH). Default is BOTH
|
|
425
|
-
* @see mute
|
|
426
|
-
* @example
|
|
427
|
-
*
|
|
428
|
-
* async function handler (request, response) {
|
|
429
|
-
* await response.answer();
|
|
430
|
-
* await response.unmute(); // Will unmute both directions
|
|
431
|
-
* }
|
|
432
|
-
*/
|
|
433
|
-
unmute() {
|
|
434
|
-
return __awaiter(this, arguments, void 0, function* (options = { direction: common_1.MuteDirection.BOTH }) {
|
|
435
|
-
const { direction } = options;
|
|
436
|
-
yield new verbs_1.Unmute(this.request, this.voice).run({
|
|
437
|
-
mediaSessionRef: this.request.mediaSessionRef,
|
|
438
|
-
direction
|
|
439
|
-
});
|
|
440
|
-
});
|
|
441
|
-
}
|
|
442
|
-
/**
|
|
443
|
-
* Register a listener for the given event.
|
|
444
|
-
*
|
|
445
|
-
* @param {StreamEvent} event - The event to listen for
|
|
446
|
-
* @param {Function} listener - The callback function
|
|
447
|
-
* @example
|
|
448
|
-
*
|
|
449
|
-
* async function handler (request, response) {
|
|
450
|
-
* ...
|
|
451
|
-
*
|
|
452
|
-
* response.on(StreamEvent.END, () => {
|
|
453
|
-
* console.log("Call ended");
|
|
454
|
-
* });
|
|
455
|
-
* }
|
|
456
|
-
*/
|
|
457
|
-
on(event, listener) {
|
|
458
|
-
this.voice.on(event, listener);
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
exports.VoiceResponse = VoiceResponse;
|
package/dist/createSession.d.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
3
|
-
* http://github.com/fonoster/fonoster
|
|
4
|
-
*
|
|
5
|
-
* This file is part of Fonoster
|
|
6
|
-
*
|
|
7
|
-
* Licensed under the MIT License (the "License");
|
|
8
|
-
* you may not use this file except in compliance with
|
|
9
|
-
* the License. You may obtain a copy of the License at
|
|
10
|
-
*
|
|
11
|
-
* https://opensource.org/licenses/MIT
|
|
12
|
-
*
|
|
13
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
-
* See the License for the specific language governing permissions and
|
|
17
|
-
* limitations under the License.
|
|
18
|
-
*/
|
|
19
|
-
import { VoiceSessionStreamServer } from "@fonoster/common";
|
|
20
|
-
import { VoiceHandler } from "./types";
|
|
21
|
-
declare function createSession(handler: VoiceHandler): (voice: VoiceSessionStreamServer) => Promise<void>;
|
|
22
|
-
export { createSession };
|
package/dist/createSession.js
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
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.createSession = createSession;
|
|
13
|
-
/**
|
|
14
|
-
* Copyright (C) 2025 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 logger_1 = require("@fonoster/logger");
|
|
33
|
-
const VoiceResponse_1 = require("./VoiceResponse");
|
|
34
|
-
const logger = (0, logger_1.getLogger)({ service: "voice", filePath: __filename });
|
|
35
|
-
function createSession(handler) {
|
|
36
|
-
return (voice) => new Promise((resolve) => {
|
|
37
|
-
let mediaSessionRef;
|
|
38
|
-
voice.once(common_1.StreamEvent.DATA, (params) => __awaiter(this, void 0, void 0, function* () {
|
|
39
|
-
const { request } = params;
|
|
40
|
-
if (request) {
|
|
41
|
-
mediaSessionRef = request.mediaSessionRef;
|
|
42
|
-
const response = new VoiceResponse_1.VoiceResponse(request, voice);
|
|
43
|
-
// EventEmitter ignores the promise this callback returns, so an error
|
|
44
|
-
// escaping the handler becomes an unhandled rejection and, under Node's
|
|
45
|
-
// default policy, takes the whole voice server down with it. Verbs now
|
|
46
|
-
// reject when the session ends mid-call, which makes reaching here an
|
|
47
|
-
// ordinary occurrence rather than a defect in the application.
|
|
48
|
-
try {
|
|
49
|
-
yield handler(request, response);
|
|
50
|
-
}
|
|
51
|
-
catch (e) {
|
|
52
|
-
logger.warn("voice handler did not complete", {
|
|
53
|
-
mediaSessionRef,
|
|
54
|
-
error: e instanceof Error ? e.message : e
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
resolve();
|
|
58
|
-
}
|
|
59
|
-
}));
|
|
60
|
-
voice.once(common_1.StreamEvent.END, () => {
|
|
61
|
-
logger.verbose("session ended", { mediaSessionRef });
|
|
62
|
-
voice.end();
|
|
63
|
-
resolve();
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
3
|
-
* http://github.com/fonoster/fonoster
|
|
4
|
-
*
|
|
5
|
-
* This file is part of Fonoster
|
|
6
|
-
*
|
|
7
|
-
* Licensed under the MIT License (the "License");
|
|
8
|
-
* you may not use this file except in compliance with
|
|
9
|
-
* the License. You may obtain a copy of the License at
|
|
10
|
-
*
|
|
11
|
-
* https://opensource.org/licenses/MIT
|
|
12
|
-
*
|
|
13
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
-
* See the License for the specific language governing permissions and
|
|
17
|
-
* limitations under the License.
|
|
18
|
-
*/
|
|
19
|
-
import { ServerConfig } from "./types";
|
|
20
|
-
declare const defaultServerConfig: ServerConfig;
|
|
21
|
-
export { defaultServerConfig };
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.defaultServerConfig = void 0;
|
|
4
|
-
const defaultServerConfig = {
|
|
5
|
-
port: 50061,
|
|
6
|
-
bind: "0.0.0.0",
|
|
7
|
-
identityAddress: "api.fonoster.com",
|
|
8
|
-
skipIdentity: false
|
|
9
|
-
};
|
|
10
|
-
exports.defaultServerConfig = defaultServerConfig;
|
package/dist/demo.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/demo.js
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
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 () {
|
|
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
|
-
})();
|
|
35
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
-
});
|
|
43
|
-
};
|
|
44
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
-
/**
|
|
46
|
-
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
47
|
-
* http://github.com/fonoster/fonoster
|
|
48
|
-
*
|
|
49
|
-
* This file is part of Fonoster
|
|
50
|
-
*
|
|
51
|
-
* Licensed under the MIT License (the "License");
|
|
52
|
-
* you may not use this file except in compliance with
|
|
53
|
-
* the License. You may obtain a copy of the License at
|
|
54
|
-
*
|
|
55
|
-
* https://opensource.org/licenses/MIT
|
|
56
|
-
*
|
|
57
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
58
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
59
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
60
|
-
* See the License for the specific language governing permissions and
|
|
61
|
-
* limitations under the License.
|
|
62
|
-
*/
|
|
63
|
-
const logger_1 = require("@fonoster/logger");
|
|
64
|
-
const _1 = __importStar(require("."));
|
|
65
|
-
const logger = (0, logger_1.getLogger)({ service: "voice", filePath: __filename });
|
|
66
|
-
const skipIdentity = process.env.NODE_ENV === "development";
|
|
67
|
-
// Only skip identity for local development
|
|
68
|
-
new _1.default({ skipIdentity }).listen((req, res) => __awaiter(void 0, void 0, void 0, function* () {
|
|
69
|
-
logger.verbose("voice request", Object.assign({}, req));
|
|
70
|
-
yield res.answer();
|
|
71
|
-
yield res.say("Hi there! What's your name?");
|
|
72
|
-
const { speech: name } = yield res.gather({
|
|
73
|
-
source: _1.GatherSource.SPEECH
|
|
74
|
-
});
|
|
75
|
-
yield res.say("Nice to meet you " + name + "!");
|
|
76
|
-
yield res.say("Please enter your 4 digit pin.");
|
|
77
|
-
const { digits } = yield res.gather({
|
|
78
|
-
maxDigits: 4,
|
|
79
|
-
finishOnKey: "#"
|
|
80
|
-
});
|
|
81
|
-
yield res.say("Your pin is " + digits);
|
|
82
|
-
yield res.hangup();
|
|
83
|
-
}));
|