@onereach/step-voice 6.0.2 → 6.0.3

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.
@@ -35,9 +35,9 @@ export default class GlobalCommand extends VoiceStep<Partial<INPUT>, OUTPUT, EVE
35
35
  worker(): Promise<void>;
36
36
  hangup(call: IVoiceCall): Promise<unknown>;
37
37
  exitThread(event: ITypedEvent<EVENT>, type: string, stepExit: string): Promise<void>;
38
- onAwake(): Promise<void>;
39
38
  exitToThread(): void;
40
39
  buildGrammar(call: IVoiceCall, choices: TODO[]): Promise<any>;
41
40
  exitFlow(): unknown;
41
+ sleepUntilHangup(): void;
42
42
  }
43
43
  export {};
@@ -2,9 +2,14 @@
2
2
  /* eslint-disable @typescript-eslint/strict-boolean-expressions, @typescript-eslint/explicit-function-return-type */
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  const tslib_1 = require("tslib");
5
+ const types_1 = require("@onereach/flow-sdk/dst/types");
5
6
  const lodash_1 = tslib_1.__importDefault(require("lodash"));
6
7
  const nanoid_1 = require("nanoid");
7
8
  const voice_1 = tslib_1.__importDefault(require("./voice"));
9
+ var LocalEvents;
10
+ (function (LocalEvents) {
11
+ LocalEvents["hangup"] = "hangup";
12
+ })(LocalEvents || (LocalEvents = {}));
8
13
  class GlobalCommand extends voice_1.default {
9
14
  get isGlobal() {
10
15
  return true;
@@ -15,7 +20,7 @@ class GlobalCommand extends voice_1.default {
15
20
  async runStep() {
16
21
  const worker = this.process.newThread(this.workerThreadId, thread => {
17
22
  thread.state = {
18
- name: 'worker',
23
+ name: this.worker.name,
19
24
  step: this.step.id,
20
25
  thread: this.dataThreadId
21
26
  };
@@ -66,7 +71,19 @@ class GlobalCommand extends voice_1.default {
66
71
  this.triggers.otherwise(async () => {
67
72
  await this.initGrammar();
68
73
  });
69
- this.triggers.hook({ name: 'waitEnd', thread: 'main', sync: true }, async () => {
74
+ if (this.dataThreadId !== types_1.MAIN_THREAD_ID) {
75
+ this.triggers.hook({ name: "ending" /* ACTION.ending */, thread: this.dataThreadId, sync: true }, async () => {
76
+ this.log.debug('sleep data thread', { thread: this.dataThreadId });
77
+ delete this.waits['@ending'];
78
+ const dataThread = this.process.getThread(this.dataThreadId);
79
+ dataThread?.gotoState({
80
+ direct: true,
81
+ step: this.currentStepId,
82
+ name: this.sleepUntilHangup.name
83
+ });
84
+ });
85
+ }
86
+ this.triggers.hook({ name: "waitEnd" /* ACTION.waitEnd */, thread: types_1.MAIN_THREAD_ID, sync: true }, async () => {
70
87
  delete this.waits['@waitEnd']; // TODO is there beter way to unsubscribe?
71
88
  await this.sendCommands(call, [{ name: 'grammar', params: {} }]);
72
89
  if (this.thread.background)
@@ -77,12 +94,14 @@ class GlobalCommand extends voice_1.default {
77
94
  switch (event.params.type) {
78
95
  case 'hangup': {
79
96
  await this.hangup(call);
80
- // await this.popConvStep()
81
- await this.notifyConvEnd();
82
- return this.end();
97
+ this.log.debug('wake data thread', { thread: this.dataThreadId });
98
+ this.process.enqueue({
99
+ thread: this.dataThreadId,
100
+ name: LocalEvents.hangup
101
+ });
102
+ return;
83
103
  }
84
104
  case 'avm-detected':
85
- // this.event = {};
86
105
  return await this.exitThread(event, 'AMD', 'AMD');
87
106
  case 'digit':
88
107
  case 'digits': {
@@ -128,10 +147,10 @@ class GlobalCommand extends voice_1.default {
128
147
  return {};
129
148
  }
130
149
  case 'error': {
131
- // const localHandler = await this.sendEventToStep({ toWorker: false, event: { ...this.event, processed: undefined, action: 'lcl' } })
132
- // if (!localHandler) {
133
- // this.throwError(event.params.error)
134
- // }
150
+ if (event.params.error) {
151
+ this.log.error('gc.error', event.params.error);
152
+ // TODO throw it?
153
+ }
135
154
  this.event.processed = true;
136
155
  break;
137
156
  }
@@ -154,25 +173,32 @@ class GlobalCommand extends voice_1.default {
154
173
  await this.handleHangup(call);
155
174
  const isHangedUpByBot = call.sessionEndedBy === 'Bot';
156
175
  const hangUpType = isHangedUpByBot ? 'bot hang up' : 'user hang up';
176
+ let processHangUp = this.data.processHangUp;
157
177
  // process call recording in hangup event
158
178
  if (call.recordCall && this.event.params.callRecording != null) {
159
- return await this.exitThread(this.event, hangUpType, 'hang up');
179
+ processHangUp = 'both';
160
180
  }
161
- switch (this.data.processHangUp) {
181
+ switch (processHangUp) {
162
182
  case 'user':
163
- return isHangedUpByBot
164
- ? this.end()
165
- : await this.exitThread(this.event, hangUpType, 'hang up');
183
+ if (isHangedUpByBot)
184
+ return this.end();
185
+ break;
166
186
  case 'bot':
167
- return isHangedUpByBot
168
- ? await this.exitThread(this.event, hangUpType, 'hang up')
169
- : this.end();
187
+ if (!isHangedUpByBot)
188
+ return this.end();
189
+ break;
170
190
  case 'both':
171
- return await this.exitThread(this.event, hangUpType, 'hang up');
172
- case 'none':
191
+ break;
192
+ // case 'none':
173
193
  default:
174
194
  return this.end();
175
195
  }
196
+ return this.exitStep('hangup', {
197
+ type: hangUpType,
198
+ callRecording: this.event.params?.callRecording,
199
+ conversation: this.conversation,
200
+ conversationThreadId: this.dataThreadId
201
+ });
176
202
  }
177
203
  async exitThread(event, type, stepExit) {
178
204
  this.log.debug('exitThread', type, stepExit);
@@ -198,15 +224,11 @@ class GlobalCommand extends voice_1.default {
198
224
  if (!lodash_1.default.isEmpty(params.callRecording)) {
199
225
  result.callRecording = params.callRecording;
200
226
  }
201
- if (!this.data.autoPause) {
202
- await this.notifyConvEnd({ onlyLocal: true });
203
- await this._refreshCache();
204
- }
205
227
  const exitLabel = lodash_1.default.replace(this.getExitStepLabel(stepExit) ?? stepExit, /\W+/g, '');
206
228
  await this.process.runThread({
207
229
  id: `${exitLabel}_${(0, nanoid_1.nanoid)(8)}`,
208
230
  state: {
209
- name: 'exitToThread',
231
+ name: this.exitToThread.name,
210
232
  direct: true,
211
233
  result: {
212
234
  conversation: this.conversation,
@@ -218,14 +240,6 @@ class GlobalCommand extends voice_1.default {
218
240
  }
219
241
  });
220
242
  event.processed = true;
221
- // this is required to mark event as handled
222
- // this.gotoState(this.state, { name: 'exiting' })
223
- }
224
- async onAwake() {
225
- await super.onAwake();
226
- await this.initGrammar();
227
- await this.worker();
228
- this.triggers.refreshAll();
229
243
  }
230
244
  exitToThread() {
231
245
  this.thread.exitStep(this.state.exitStep, this.state.result);
@@ -242,5 +256,10 @@ class GlobalCommand extends voice_1.default {
242
256
  this.event.processed = false;
243
257
  return super.exitFlow();
244
258
  }
259
+ sleepUntilHangup() {
260
+ this.triggers.local(LocalEvents.hangup, () => {
261
+ this.end();
262
+ });
263
+ }
245
264
  }
246
265
  exports.default = GlobalCommand;
package/dst/step.d.ts CHANGED
@@ -34,9 +34,6 @@ export default class ConvStep<TData extends IConversationData, TIn = unknown, TO
34
34
  onAwake(): Promise<void>;
35
35
  onPause(): Promise<void>;
36
36
  onResume(): Promise<void>;
37
- notifyConvEnd({ onlyLocal }?: {
38
- onlyLocal?: boolean;
39
- }): Promise<void>;
40
37
  waitConvEnd(): Promise<void>;
41
38
  waitGlobEnd(): Promise<void>;
42
39
  onConvEnd(): Promise<void>;
package/dst/step.js CHANGED
@@ -80,10 +80,10 @@ class ConvStep extends step_1.default {
80
80
  }
81
81
  }
82
82
  async waitForConversation() {
83
- if (this.state.name !== 'waitForConversation') {
83
+ if (this.state.name !== this.waitForConversation.name) {
84
84
  this.log.debug(this.state, 'conv.begin waitForConversation');
85
85
  this.state.prevWaitName = this.state.name;
86
- this.state.name = 'waitForConversation';
86
+ this.state.name = this.waitForConversation.name;
87
87
  }
88
88
  else if (this.event.name === '_conv') {
89
89
  this.log.debug(this.state, 'conv.end waitForConversation');
@@ -128,15 +128,12 @@ class ConvStep extends step_1.default {
128
128
  this.state.name = this.state.resumeState;
129
129
  this.state.resumeState = undefined;
130
130
  }
131
- async notifyConvEnd({ onlyLocal } = {}) {
132
- this.log.debug('notifyConvEnd', { onlyLocal });
133
- }
134
131
  async waitConvEnd() {
135
132
  const workerThread = this.process.getThread(this.workerThreadId);
136
- const workerState = await workerThread?.state;
133
+ const workerState = workerThread?.state;
137
134
  if (!this.isGlobal && this.thread.id !== 'main' && this.thread.id === workerState?.thread) {
138
135
  this.log.debug('conv.wait for end', this.conversation);
139
- this.gotoState({ ...this.state, name: 'waitGlobEnd', direct: true });
136
+ this.gotoState({ ...this.state, name: this.waitGlobEnd.name, direct: true });
140
137
  }
141
138
  else {
142
139
  this.log.debug('conv.end', this.conversation);
@@ -146,7 +143,7 @@ class ConvStep extends step_1.default {
146
143
  async waitGlobEnd() {
147
144
  const gcThreadId = this.workerThreadId;
148
145
  // wait for glob thread end (if exists)
149
- this.triggers.hook({ name: 'end', thread: gcThreadId }, async () => await this.onConvEnd());
146
+ this.triggers.hook({ name: "end" /* ACTION.end */, thread: gcThreadId }, async () => await this.onConvEnd());
150
147
  if (!this.process.getThread(gcThreadId))
151
148
  await this.onConvEnd();
152
149
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onereach/step-voice",
3
- "version": "6.0.2",
3
+ "version": "6.0.3",
4
4
  "author": "Roman Zolotarov <roman.zolotarov@onereach.com>",
5
5
  "contributors": [
6
6
  "Roman Zolotarov",