@fonoster/voice 0.2.22 → 0.2.29

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/server.d.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  import { ServerConfig } from "./types";
2
2
  import { Plugin } from "@fonoster/common";
3
+ import { VoiceTracer } from "./tracer";
3
4
  export default class VoiceServer {
4
5
  config: ServerConfig;
5
6
  plugins: {};
7
+ voiceTracer: VoiceTracer;
6
8
  constructor(config?: ServerConfig);
7
9
  /**
8
10
  * Add tts or asr plugin.
package/dist/server.js CHANGED
@@ -10,6 +10,7 @@ const path_1 = require("path");
10
10
  const fs_1 = __importDefault(require("fs"));
11
11
  const os_1 = __importDefault(require("os"));
12
12
  const pubsub_js_1 = __importDefault(require("pubsub-js"));
13
+ const tracer_1 = require("./tracer");
13
14
  const merge = require("deepmerge");
14
15
  const app = (0, express_1.default)();
15
16
  app.use(express_1.default.json());
@@ -54,7 +55,9 @@ class VoiceServer {
54
55
  res.send("pong");
55
56
  });
56
57
  app.post(path_1.posix.join(this.config.base), async (req, res) => {
57
- const response = new voice_1.default(req.body);
58
+ this.voiceTracer = new tracer_1.VoiceTracer(this.config.otlSpanExporters);
59
+ this.voiceTracer.init();
60
+ const response = new voice_1.default(req.body, this.voiceTracer);
58
61
  response.plugins = this.plugins;
59
62
  handler(req.body, response);
60
63
  res.end();
@@ -0,0 +1,10 @@
1
+ import { Context, Span, Tracer } from "@opentelemetry/api";
2
+ export declare class VoiceTracer {
3
+ callTracer: Tracer;
4
+ parentSpan: Span;
5
+ ctx: Context;
6
+ constructor(otlSpanExporters: Array<any>);
7
+ init(): void;
8
+ close(): void;
9
+ createSpan(name: string): Span;
10
+ }
package/dist/tracer.js ADDED
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.VoiceTracer = void 0;
7
+ /*
8
+ * Copyright (C) 2021 by Fonoster Inc (https://fonoster.com)
9
+ * http://github.com/fonoster/fonoster
10
+ *
11
+ * This file is part of Fonoster
12
+ *
13
+ * Licensed under the MIT License (the "License");
14
+ * you may not use this file except in compliance with
15
+ * the License. You may obtain a copy of the License at
16
+ *
17
+ * https://opensource.org/licenses/MIT
18
+ *
19
+ * Unless required by applicable law or agreed to in writing, software
20
+ * distributed under the License is distributed on an "AS IS" BASIS,
21
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22
+ * See the License for the specific language governing permissions and
23
+ * limitations under the License.
24
+ */
25
+ const api_1 = __importDefault(require("@opentelemetry/api"));
26
+ const resources_1 = require("@opentelemetry/resources");
27
+ const semantic_conventions_1 = require("@opentelemetry/semantic-conventions");
28
+ const sdk_trace_base_1 = require("@opentelemetry/sdk-trace-base");
29
+ const { NodeTracerProvider } = require("@opentelemetry/node");
30
+ class VoiceTracer {
31
+ constructor(otlSpanExporters) {
32
+ // Configure span processor to send spans to the exporter
33
+ const provider = new NodeTracerProvider({
34
+ resource: new resources_1.Resource({
35
+ [semantic_conventions_1.SemanticResourceAttributes.SERVICE_NAME]: "voice-service"
36
+ })
37
+ });
38
+ for (const exp of otlSpanExporters) {
39
+ const exporter = new exp.exporter(exp.config);
40
+ provider.addSpanProcessor(new sdk_trace_base_1.BatchSpanProcessor(exporter));
41
+ }
42
+ provider.register();
43
+ this.callTracer = api_1.default.trace.getTracer("call_tracer");
44
+ }
45
+ init() {
46
+ this.parentSpan = this.callTracer.startSpan("call");
47
+ this.ctx = api_1.default.trace.setSpan(api_1.default.context.active(), this.parentSpan);
48
+ }
49
+ close() {
50
+ this.parentSpan.end();
51
+ }
52
+ createSpan(name) {
53
+ return this.callTracer.startSpan(name, undefined, this.ctx);
54
+ }
55
+ }
56
+ exports.VoiceTracer = VoiceTracer;
package/dist/types.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { MeterProvider } from "@opentelemetry/sdk-metrics-base";
1
2
  export interface VoiceRequest {
2
3
  accessKeyId: string;
3
4
  sessionToken: string;
@@ -13,6 +14,8 @@ export interface ServerConfig {
13
14
  port?: number;
14
15
  base?: string;
15
16
  pathToFiles?: string;
17
+ otlSpanExporters?: Array<any>;
18
+ meterProvider?: MeterProvider;
16
19
  }
17
20
  export interface VoiceEventData {
18
21
  type: string;
package/dist/voice.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { GatherOptions } from "./gather/gather";
1
2
  import { MuteOptions } from "./mute/mute";
2
3
  import { PlayOptions } from "./play/play";
3
4
  import { RecordOptions, RecordResult } from "./record/record";
@@ -10,6 +11,7 @@ import { SGatherStream } from "./sgather/types";
10
11
  import { DtmfOptions } from "./dtmf/types";
11
12
  import { DialOptions } from "./dial/types";
12
13
  import StreamStatus from "./dial/status_stream";
14
+ import { VoiceTracer } from "./tracer";
13
15
  /**
14
16
  * @classdesc Use the VoiceResponse object, to construct advance Interactive
15
17
  * Voice Response (IVR) applications.
@@ -30,13 +32,14 @@ import StreamStatus from "./dial/status_stream";
30
32
  export default class VoiceResponse {
31
33
  request: VoiceRequest;
32
34
  plugins: {};
35
+ voiceTracer: VoiceTracer;
33
36
  /**
34
37
  * Constructs a new VoiceResponse object.
35
38
  *
36
39
  * @param {VoiceRequest} request - Options to indicate the objects endpoint
37
40
  * @see module:core:APIClient
38
41
  */
39
- constructor(request: VoiceRequest);
42
+ constructor(request: VoiceRequest, voiceTracer: VoiceTracer);
40
43
  /**
41
44
  * Adds a tts or asr plugin. Only one type of plugin can be attached.
42
45
  *
@@ -103,9 +106,7 @@ export default class VoiceResponse {
103
106
  * console.log("digits: " + digits);
104
107
  * }
105
108
  */
106
- gather(options: {
107
- source: "speech,dtmf";
108
- }): Promise<string>;
109
+ gather(options?: GatherOptions): Promise<string>;
109
110
  /**
110
111
  * Waits for data entry from the user's keypad or from a stream speech provider. This command is different from `gather`
111
112
  * in that it returns a stream of results instead of a single result. You can think of it as active listening.
package/dist/voice.js CHANGED
@@ -60,8 +60,9 @@ class VoiceResponse {
60
60
  * @param {VoiceRequest} request - Options to indicate the objects endpoint
61
61
  * @see module:core:APIClient
62
62
  */
63
- constructor(request) {
63
+ constructor(request, voiceTracer) {
64
64
  this.request = request;
65
+ this.voiceTracer = voiceTracer;
65
66
  this.plugins = {};
66
67
  }
67
68
  /**
@@ -92,7 +93,9 @@ class VoiceResponse {
92
93
  * }
93
94
  */
94
95
  async play(media, options = {}) {
96
+ const span = this.voiceTracer.createSpan("play");
95
97
  await new play_1.default(this.request).run(media, options);
98
+ span.end();
96
99
  }
97
100
  /**
98
101
  * Converts a text into a sound and sends sound to media server. To use this verb, you must
@@ -118,9 +121,17 @@ class VoiceResponse {
118
121
  (0, asserts_1.assertPluginExist)(this, "tts");
119
122
  const tts = this.plugins["tts"];
120
123
  // It should return the filename and the generated file location
124
+ const main = this.voiceTracer.createSpan("play");
125
+ const span = this.voiceTracer.createSpan("synthetize");
121
126
  const result = await tts.synthetize(text, options);
127
+ span.setAttribute("text", text);
128
+ span.setAttribute("options", JSON.stringify(options));
129
+ span.end();
122
130
  const media = `sound:${this.request.selfEndpoint}/tts/${result.filename}`;
123
131
  await new play_1.default(this.request).run(media, options);
132
+ main.setAttribute("media", media);
133
+ main.setAttribute("options", JSON.stringify(options));
134
+ main.end();
124
135
  }
125
136
  /**
126
137
  * Waits for data entry from the user's keypad or from a speech provider.
@@ -141,13 +152,17 @@ class VoiceResponse {
141
152
  * console.log("digits: " + digits);
142
153
  * }
143
154
  */
144
- async gather(options) {
155
+ async gather(options = { source: "speech,dtmf" }) {
145
156
  let asr = null;
146
157
  if (options.source.includes("speech")) {
147
158
  (0, asserts_1.assertPluginExist)(this, "asr");
148
159
  asr = this.plugins["asr"];
149
160
  }
150
- return await new gather_1.default(this.request, asr).run(options);
161
+ const span = this.voiceTracer.createSpan("gather");
162
+ const result = await new gather_1.default(this.request, asr).run(options);
163
+ span.setAttribute("options", JSON.stringify(options));
164
+ span.end();
165
+ return result;
151
166
  }
152
167
  /**
153
168
  * Waits for data entry from the user's keypad or from a stream speech provider. This command is different from `gather`
@@ -197,7 +212,11 @@ class VoiceResponse {
197
212
  * }
198
213
  */
199
214
  async dtmf(options) {
200
- return await new dtmf_1.default(this.request).run(options);
215
+ const span = this.voiceTracer.createSpan("dtmf");
216
+ const result = await new dtmf_1.default(this.request).run(options);
217
+ span.setAttribute("options", JSON.stringify(options));
218
+ span.end();
219
+ return result;
201
220
  }
202
221
  /**
203
222
  * Forwards the call to an Agent or the PSTN.
@@ -219,7 +238,12 @@ class VoiceResponse {
219
238
  * }
220
239
  */
221
240
  async dial(destination, options) {
222
- return await new dial_1.default(this.request).run(destination, options);
241
+ const span = this.voiceTracer.createSpan("dial");
242
+ const result = await new dial_1.default(this.request).run(destination, options);
243
+ span.setAttribute("destination", destination);
244
+ span.setAttribute("options", JSON.stringify(options));
245
+ span.end();
246
+ return result;
223
247
  }
224
248
  /**
225
249
  * Returns a PlaybackControl control object.
@@ -243,7 +267,11 @@ class VoiceResponse {
243
267
  * }
244
268
  */
245
269
  playback(playbackId) {
246
- return new playback_1.PlaybackControl(this.request, playbackId);
270
+ const span = this.voiceTracer.createSpan("playback");
271
+ const result = new playback_1.PlaybackControl(this.request, playbackId);
272
+ span.setAttribute("playbackId", playbackId);
273
+ span.end();
274
+ return result;
247
275
  }
248
276
  /**
249
277
  * Listens event publication.
@@ -284,7 +312,11 @@ class VoiceResponse {
284
312
  * }
285
313
  */
286
314
  async mute(options) {
287
- await new mute_1.default(this.request).run(options);
315
+ const span = this.voiceTracer.createSpan("mute");
316
+ const result = new mute_1.default(this.request).run(options);
317
+ span.setAttribute("options", JSON.stringify(options));
318
+ span.end();
319
+ await result;
288
320
  }
289
321
  /**
290
322
  * Unmutes a channel.
@@ -300,7 +332,11 @@ class VoiceResponse {
300
332
  * }
301
333
  */
302
334
  async unmute(options) {
303
- await new unmute_1.default(this.request).run(options);
335
+ const span = this.voiceTracer.createSpan("unmute");
336
+ const result = new unmute_1.default(this.request).run(options);
337
+ span.setAttribute("options", JSON.stringify(options));
338
+ span.end();
339
+ await result;
304
340
  }
305
341
  /**
306
342
  * Answer the communication channel. Before running any other verb you
@@ -314,7 +350,10 @@ class VoiceResponse {
314
350
  * }
315
351
  */
316
352
  async answer() {
317
- await new answer_1.default(this.request).run();
353
+ const span = this.voiceTracer.createSpan("answer");
354
+ const result = new answer_1.default(this.request).run();
355
+ span.end();
356
+ await result;
318
357
  }
319
358
  /**
320
359
  * Terminates the communication channel.
@@ -327,7 +366,12 @@ class VoiceResponse {
327
366
  * }
328
367
  */
329
368
  async hangup() {
330
- await new hangup_1.default(this.request).run();
369
+ const span = this.voiceTracer.createSpan("hangup");
370
+ const result = new hangup_1.default(this.request).run();
371
+ span.end();
372
+ // Need to close or the span will be lost
373
+ this.voiceTracer.close();
374
+ await result;
331
375
  }
332
376
  /**
333
377
  * Records the current channel and uploads the file to the storage subsystem.
@@ -348,17 +392,24 @@ class VoiceResponse {
348
392
  * }
349
393
  */
350
394
  async record(options) {
351
- return await new record_1.default(this.request).run(options);
395
+ const span = this.voiceTracer.createSpan("record");
396
+ const result = await new record_1.default(this.request).run(options);
397
+ span.end();
398
+ return result;
352
399
  }
353
400
  // Requests media from Media server
354
401
  async openMediaPipe() {
402
+ const span = this.voiceTracer.createSpan("openMediaPipe");
355
403
  const genericVerb = new verb_1.Verb(this.request);
356
404
  await (0, utils_1.startMediaTransfer)(genericVerb, this.request.sessionId);
405
+ span.end();
357
406
  }
358
407
  // Requests media stop from Media server
359
408
  async closeMediaPipe() {
409
+ const span = this.voiceTracer.createSpan("stopMediaTransfer");
360
410
  const genericVerb = new verb_1.Verb(this.request);
361
411
  await (0, utils_1.stopMediaTransfer)(genericVerb, this.request.sessionId);
412
+ span.end();
362
413
  }
363
414
  }
364
415
  exports.default = VoiceResponse;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fonoster/voice",
3
- "version": "0.2.22",
3
+ "version": "0.2.29",
4
4
  "description": "Voice verbs",
5
5
  "author": "Pedro Sanders <psanders@fonoster.com>",
6
6
  "homepage": "https://github.com/fonoster/fonoster#readme",
@@ -29,8 +29,18 @@
29
29
  "url": "https://github.com/fonoster/fonoster/issues"
30
30
  },
31
31
  "dependencies": {
32
- "@fonoster/common": "^0.2.21",
33
- "@fonoster/logger": "^0.2.21",
32
+ "@fonoster/common": "^0.2.29",
33
+ "@fonoster/logger": "^0.2.29",
34
+ "@opentelemetry/api": "^1.0.2",
35
+ "@opentelemetry/node": "^0.24.0",
36
+ "@opentelemetry/plugin-express": "^0.15.0",
37
+ "@opentelemetry/plugin-http": "^0.18.2",
38
+ "@opentelemetry/plugin-https": "^0.18.2",
39
+ "@opentelemetry/resources": "0.25.0",
40
+ "@opentelemetry/sdk-metrics-base": "0.25.0",
41
+ "@opentelemetry/sdk-trace-base": "0.25.0",
42
+ "@opentelemetry/semantic-conventions": "0.25.0",
43
+ "@opentelemetry/tracing": "^0.24.0",
34
44
  "axios": "^0.21.1",
35
45
  "deepmerge": "^4.2.2",
36
46
  "express": "^4.17.1",
@@ -39,7 +49,7 @@
39
49
  "pubsub-js": "^1.9.3",
40
50
  "sync": "^0.2.5"
41
51
  },
42
- "gitHead": "255c8a0950b19565a2e11c56612d8696afaa322f",
52
+ "gitHead": "622d59a103faddb8e1ea721091ae58370102e764",
43
53
  "devDependencies": {
44
54
  "@types/pubsub-js": "^1.8.2"
45
55
  }