@onereach/step-voice 5.0.9-fixsubflow.9 → 6.0.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/dst/Cancel.js CHANGED
@@ -11,7 +11,7 @@ class VoiceCancel extends voice_1.default {
11
11
  // return
12
12
  // }
13
13
  const call = await this.fetchData();
14
- this.triggers.local(`in/voice/${call.id}/event`, async (event) => {
14
+ this.triggers.local(`in/voice/${call.id}`, async (event) => {
15
15
  switch (event.params.type) {
16
16
  case 'hangup':
17
17
  await this.handleHangup(call);
package/dst/Choice.js CHANGED
@@ -93,7 +93,7 @@ class Choice extends voice_1.default {
93
93
  }
94
94
  };
95
95
  // There's a specific need to do so. There might be ${variable} section
96
- this.triggers.local(`in/voice/${call.id}/event`, async (event) => {
96
+ this.triggers.local(`in/voice/${call.id}`, async (event) => {
97
97
  const reportingSettingsKey = this.rptsStarted ? 'transcriptRepromptResponse' : 'transcriptResponse';
98
98
  switch (event.params.type) {
99
99
  case 'digit':
@@ -232,7 +232,7 @@ class Choice extends voice_1.default {
232
232
  return await this.waitConvEnd();
233
233
  }
234
234
  case 'cancel': {
235
- return this.data.handleCancel === true && this.exitStep('cancel');
235
+ return this.handleCancel();
236
236
  }
237
237
  case 'error':
238
238
  return this.throwError(event.params.error);
@@ -7,7 +7,7 @@ class ConferenceDial extends voice_1.default {
7
7
  async runStep() {
8
8
  const call = await this.fetchData();
9
9
  this.triggers
10
- .local(`in/voice/${call.id}/event`, async (event) => {
10
+ .local(`in/voice/${call.id}`, async (event) => {
11
11
  switch (event.params.type) {
12
12
  case 'hangup':
13
13
  await this.handleHangup(call);
@@ -84,7 +84,7 @@ class CustomVoiceInput extends voice_1.default {
84
84
  }
85
85
  };
86
86
  // There's a specific need to do so. There might be ${variable} section
87
- this.triggers.local(`in/voice/${call.id}/event`, async (event) => {
87
+ this.triggers.local(`in/voice/${call.id}`, async (event) => {
88
88
  const reportingSettingsKey = this.rptsStarted ? 'transcriptRepromptResponse' : 'transcriptResponse';
89
89
  switch (event.params.type) {
90
90
  // digit recognition removed
@@ -178,7 +178,7 @@ class CustomVoiceInput extends voice_1.default {
178
178
  return await this.waitConvEnd();
179
179
  }
180
180
  case 'cancel': {
181
- return this.data.handleCancel === true && this.exitStep('cancel');
181
+ return this.handleCancel();
182
182
  }
183
183
  case 'error':
184
184
  return this.throwError(event.params.error);
@@ -32,7 +32,7 @@ export default class GlobalCommand extends VoiceStep<Partial<INPUT>, OUTPUT, EVE
32
32
  get useQueue(): boolean;
33
33
  runStep(): Promise<void>;
34
34
  initGrammar(): Promise<void>;
35
- _worker(): Promise<void>;
35
+ worker(): Promise<void>;
36
36
  hangup(call: IVoiceCall): Promise<unknown>;
37
37
  exitThread(event: ITypedEvent<EVENT>, type: string, stepExit: string): Promise<void>;
38
38
  onAwake(): Promise<void>;
@@ -13,7 +13,22 @@ class GlobalCommand extends voice_1.default {
13
13
  return this.isWorker;
14
14
  }
15
15
  async runStep() {
16
- await this.initGrammar();
16
+ const worker = this.process.newThread(this.workerThreadId, thread => {
17
+ thread.state = {
18
+ name: 'worker',
19
+ step: this.step.id,
20
+ thread: this.dataThreadId
21
+ };
22
+ });
23
+ if (worker.isNewThread) {
24
+ worker.activate();
25
+ await worker.run();
26
+ await this._refreshCache();
27
+ }
28
+ else {
29
+ worker.state.step = this.step.id;
30
+ await this.initGrammar();
31
+ }
17
32
  this.exitStep('no commands');
18
33
  }
19
34
  async initGrammar() {
@@ -46,14 +61,18 @@ class GlobalCommand extends voice_1.default {
46
61
  }
47
62
  ]);
48
63
  }
49
- async _worker() {
64
+ async worker() {
50
65
  const call = await this.fetchData();
51
- this.triggers.hook({ name: 'end', thread: 'main' }, async () => {
66
+ this.triggers.otherwise(async () => {
67
+ await this.initGrammar();
68
+ });
69
+ this.triggers.hook({ name: 'waitEnd', thread: 'main', sync: true }, async () => {
70
+ delete this.waits['@waitEnd']; // TODO is there beter way to unsubscribe?
52
71
  await this.sendCommands(call, [{ name: 'grammar', params: {} }]);
53
- if (!this.thread.ending)
72
+ if (this.thread.background)
54
73
  this.end();
55
74
  });
56
- this.triggers.local(`in/voice/${call.id}/event`, async (event) => {
75
+ this.triggers.local(`in/voice/${call.id}`, async (event) => {
57
76
  event.processed = undefined;
58
77
  switch (event.params.type) {
59
78
  case 'hangup': {
@@ -118,8 +137,7 @@ class GlobalCommand extends voice_1.default {
118
137
  }
119
138
  case 'cancel': {
120
139
  this.event.processed = true;
121
- this.end();
122
- break;
140
+ return this.handleCancel();
123
141
  }
124
142
  case 'background': {
125
143
  this.event.processed = true;
package/dst/Hangup.js CHANGED
@@ -5,7 +5,7 @@ const voice_1 = tslib_1.__importDefault(require("./voice"));
5
5
  class Hangup extends voice_1.default {
6
6
  async runStep() {
7
7
  const call = await this.fetchData();
8
- this.triggers.local(`in/voice/${call.id}/event`, async (event) => {
8
+ this.triggers.local(`in/voice/${call.id}`, async (event) => {
9
9
  switch (event.params.type) {
10
10
  case 'hangup':
11
11
  await this.handleHangup(call);
@@ -13,7 +13,7 @@ class Hangup extends voice_1.default {
13
13
  case 'error':
14
14
  return this.throwError(event.params.error);
15
15
  case 'cancel': {
16
- return this.data.handleCancel === true && this.exitStep('cancel');
16
+ return this.handleCancel();
17
17
  }
18
18
  default:
19
19
  return this.exitFlow();
@@ -49,7 +49,7 @@ class InitiateCall extends voice_1.default {
49
49
  async waitForCall() {
50
50
  const { asr, tts, from: botNumber, endUserNumber, sipHost, sipUser, sipPassword, timeout, headers, enableSpoofCallerId, spoofCallerId, isAMD, otherCallRef, otherCallRefThread } = this.data;
51
51
  const call = await this.fetchData();
52
- this.triggers.local(`in/voice/${call.id}/event`, async (event) => {
52
+ this.triggers.once(`in/voice/${call.id}/event`, async (event) => {
53
53
  switch (event.params.type) {
54
54
  case 'is_flow_ready': {
55
55
  // TODO this.exitFlow({is_ready : true}) should be enough
@@ -7,7 +7,7 @@ class JoinConference extends voice_1.default {
7
7
  async runStep() {
8
8
  const call = await this.fetchData();
9
9
  const { conferenceName, stayInConference } = this.data;
10
- this.triggers.local(`in/voice/${call.id}/event`, async (event) => {
10
+ this.triggers.local(`in/voice/${call.id}`, async (event) => {
11
11
  switch (event.params.type) {
12
12
  case 'hangup':
13
13
  await this.handleHangup(call);
@@ -66,7 +66,7 @@ class KeypadInput extends voice_1.default {
66
66
  }
67
67
  const repromptsList = this.buildReprompts({ prompts: this.data.prompts, allowKeypadBargeIn: keypadBargeIn });
68
68
  const speechSections = this.buildSections({ sections: this.data.audio, textType, ttsSettings, allowKeypadBargeIn: keypadBargeIn });
69
- this.triggers.local(`in/voice/${call.id}/event`, async (event) => {
69
+ this.triggers.local(`in/voice/${call.id}`, async (event) => {
70
70
  const reportingSettingsKey = this.rptsStarted ? 'transcriptRepromptResponse' : 'transcriptResponse';
71
71
  switch (event.params.type) {
72
72
  case 'digits': {
@@ -149,7 +149,7 @@ class KeypadInput extends voice_1.default {
149
149
  return await this.waitConvEnd();
150
150
  }
151
151
  case 'cancel': {
152
- return this.data.handleCancel === true && this.exitStep('cancel');
152
+ return this.handleCancel();
153
153
  }
154
154
  case 'error':
155
155
  return this.throwError(event.params.error);
@@ -7,7 +7,7 @@ class KickFromConference extends voice_1.default {
7
7
  async runStep() {
8
8
  const call = await this.fetchData();
9
9
  const { room, user } = this.data;
10
- this.triggers.local(`in/voice/${call.id}/event`, async (event) => {
10
+ this.triggers.local(`in/voice/${call.id}`, async (event) => {
11
11
  switch (event.params.type) {
12
12
  case 'hangup':
13
13
  await this.handleHangup(call);
@@ -8,7 +8,7 @@ class SayMessage extends voice_1.default {
8
8
  async runStep() {
9
9
  const { audio, textType, tts, sensitiveData } = this.data;
10
10
  const call = await this.fetchData();
11
- this.triggers.local(`in/voice/${call.id}/event`, async (event) => {
11
+ this.triggers.local(`in/voice/${call.id}`, async (event) => {
12
12
  switch (event.params.type) {
13
13
  case 'hangup':
14
14
  await this.handleHangup(call);
@@ -19,7 +19,7 @@ class SayMessage extends voice_1.default {
19
19
  case 'error':
20
20
  return this.throwError(event.params.error);
21
21
  case 'cancel': {
22
- return this.data.handleCancel === true && this.exitStep('cancel');
22
+ return this.handleCancel();
23
23
  }
24
24
  default:
25
25
  return this.exitFlow();
@@ -46,7 +46,7 @@ class SendDTMF extends voice_1.default {
46
46
  afterDelay: +afterDelay
47
47
  }
48
48
  };
49
- this.triggers.local(`in/voice/${call.id}/event`, async (event) => {
49
+ this.triggers.local(`in/voice/${call.id}`, async (event) => {
50
50
  // if (channel.callback.id)
51
51
  // await this.mergeFields[_conversation].set(
52
52
  // this.takeCallback(),
package/dst/Transfer.js CHANGED
@@ -6,7 +6,7 @@ const voice_1 = tslib_1.__importDefault(require("./voice"));
6
6
  class Transfer extends voice_1.default {
7
7
  async runStep() {
8
8
  const call = await this.fetchData();
9
- this.triggers.local(`in/voice/${call.id}/event`, async (event) => {
9
+ this.triggers.local(`in/voice/${call.id}`, async (event) => {
10
10
  switch (event.params.type) {
11
11
  case 'bridge': {
12
12
  await this.transcript(call, {
@@ -23,7 +23,7 @@ class Recording extends voice_1.default {
23
23
  sections
24
24
  }
25
25
  };
26
- this.triggers.local(`in/voice/${call.id}/event`, async (event) => {
26
+ this.triggers.local(`in/voice/${call.id}`, async (event) => {
27
27
  const url = event.params.mediaPath;
28
28
  switch (event.params.type) {
29
29
  case 'hangup':
package/dst/step.d.ts CHANGED
@@ -17,7 +17,6 @@ export declare const enum ConvThreadType {
17
17
  }
18
18
  export default class ConvStep<TData extends IConversationData, TIn = unknown, TOut = unknown, TParams = any> extends Step<TIn & ConvStepDataIn, TOut, TParams> {
19
19
  private convDataCache?;
20
- _worker(_data: IConversationData): Promise<void>;
21
20
  get cache(): TData | undefined;
22
21
  get conversation(): string | IMergeField;
23
22
  get conversationId(): string;
@@ -32,9 +31,7 @@ export default class ConvStep<TData extends IConversationData, TIn = unknown, TO
32
31
  getConversation(): Promise<IConversation>;
33
32
  updateData(): Promise<void>;
34
33
  hasConversation(): Promise<boolean>;
35
- protected worker(): Promise<void>;
36
34
  runBefore(): Promise<void>;
37
- runAfter(): Promise<void>;
38
35
  waitForConversation(): Promise<void>;
39
36
  protected onSkipEvent(): Promise<void>;
40
37
  cancel(): Promise<void>;
@@ -51,8 +48,6 @@ export default class ConvStep<TData extends IConversationData, TIn = unknown, TO
51
48
  onConvEnd(): Promise<void>;
52
49
  pause(): Promise<void>;
53
50
  resume(): Promise<void>;
54
- /** @returns true if current conv is active */
55
- /** @returns true if current conv was active */
56
51
  startConversation(data: TData, { thread }?: {
57
52
  thread?: IThreadId;
58
53
  }): Promise<void>;
package/dst/step.js CHANGED
@@ -13,7 +13,6 @@ const step_1 = tslib_1.__importDefault(require("@onereach/flow-sdk/dst/step"));
13
13
  // step?: string // for debug
14
14
  // }
15
15
  class ConvStep extends step_1.default {
16
- async _worker(_data) { }
17
16
  get cache() {
18
17
  return this.convDataCache;
19
18
  }
@@ -76,16 +75,11 @@ class ConvStep extends step_1.default {
76
75
  async hasConversation() {
77
76
  return (await this._fetchCache())?._conv != null;
78
77
  }
79
- async worker() {
80
- this.triggers.local('_conv');
81
- if (this.cache == null)
82
- return;
83
- await this._worker(this.cache);
84
- }
85
78
  async runBefore() {
86
79
  await super.runBefore();
87
80
  if (this.thread.ending)
88
81
  return;
82
+ this.triggers.local('_conv');
89
83
  // ensure cache is reset between step runs, just in case
90
84
  this._clearCache();
91
85
  if (!await this.hasConversation())
@@ -97,79 +91,8 @@ class ConvStep extends step_1.default {
97
91
  this.event.processed = true;
98
92
  this.state.prevName = this.state.name;
99
93
  this.state.name = this.event.action;
100
- return;
101
94
  }
102
- console.log('BEFORE', {
103
- event: this.event,
104
- state: this.state,
105
- name: this.constructor.name,
106
- thread: this.thread.id,
107
- ...this.cache?._conv
108
- });
109
- // if (this.useQueue && !await this.pushConvStep()) {
110
- // return await this.waitForConversation()
111
- // }
112
- if (this.cache == null)
113
- return;
114
- // const glb = this.cache._conv.glb
115
- // if (!this.isGlobal && glb.length > 0 && glb[glb.length - 1].typ !== ConvThreadType.wrk) return
116
- if (!this.isGlobal)
117
- return;
118
- if (this.thread.id !== this.workerThreadId) {
119
- const worker = this.process.newThread(this.workerThreadId, thread => {
120
- thread.state = {
121
- name: 'worker',
122
- step: this.step.id,
123
- thread: this.dataThreadId
124
- };
125
- });
126
- if (worker.isNewThread) {
127
- worker.activate();
128
- await worker.run();
129
- await this._refreshCache();
130
- }
131
- else {
132
- worker.state.step = this.step.id;
133
- }
134
- }
135
- }
136
- // public async runHandle (): Promise<unknown> {
137
- // if (this.thread.ending || this.state.name === 'onConvEnd') {
138
- // return await super.runHandle()
139
- // }
140
- // // const sid = this.cache?._conv.sid
141
- // // if (sid != null && sid !== this.session.sessionId) {
142
- // // this.triggers.refreshAll()
143
- // // }
144
- // return await super.runHandle()
145
- // }
146
- async runAfter() {
147
- console.log('AFTER', {
148
- name: this.constructor.name,
149
- thread: this.thread.id,
150
- ...this.cache?._conv
151
- });
152
- // if (this.thread.ending || this.state.name === 'onConvEnd') {
153
- // return await super.runAfter()
154
- // }
155
- // if (!await this.hasConversation()) return await super.runAfter()
156
- // if (this.thread.hasControlAction()) {
157
- // // await this.popConvStep()
158
- // if (await this.popConvStep()) {
159
- // // TODO: this seems not to be necessary now or not?
160
- // await this.sendEventToStep({ toGlobal: this.isGlobal, action: 'onAwake' })
161
- // }
162
- // }
163
- // if (this.isGlobal && !this.event.processed) {
164
- // await this.sendEventToStep({ toGlobal: false, event: { ...this.event, processed: undefined, action: 'lcl' } })
165
- // }
166
- await super.runAfter();
167
95
  }
168
- // public async setLocalTriggers (): Promise<void> {
169
- // if (!this.isGlobal && await this.hasActiveGlobal()) {
170
- // this.triggers.config({ target: 'session' })
171
- // }
172
- // }
173
96
  async waitForConversation() {
174
97
  if (this.state.name !== 'waitForConversation') {
175
98
  this.log.debug(this.state, 'conv.begin waitForConversation');
@@ -286,92 +209,6 @@ class ConvStep extends step_1.default {
286
209
  // this.log.debug('conv.nothing to resume')
287
210
  // }
288
211
  }
289
- // protected async sendEventToStep ({
290
- // toGlobal = false,
291
- // toStep,
292
- // action,
293
- // event = { name: '_conv', action }
294
- // }: {
295
- // action?: string
296
- // event?: IEvent
297
- // toStep?: IConversationStep
298
- // toGlobal?: boolean
299
- // }): Promise<IStepResult | undefined> {
300
- // toStep ||= await this.activeStep(toGlobal)
301
- // if (toStep != null) {
302
- // const target = { type: 'session' as any, name: toStep.key, id: toStep.trd }
303
- // return await this.thread.eventManager.emit(
304
- // event,
305
- // { invocationType: 'async', target }
306
- // )
307
- // }
308
- // return undefined
309
- // }
310
- // async activeStep (toGlobal: boolean): Promise<IConversationStep | undefined> {
311
- // const conv = await this.getConversation()
312
- // const que = toGlobal ? conv.glb : conv.lcl
313
- // if (que == null) return
314
- // const lastItem = que[que.length - 1]
315
- // if (toGlobal && lastItem?.typ === ConvThreadType.wrk) return undefined
316
- // return que[que.length - 1]
317
- // }
318
- /** @returns true if current conv is active */
319
- // protected async pushConvStep (): Promise<boolean> {
320
- // const conv = await this.getConversation()
321
- // const sessionKey = this.session.key
322
- // if (sessionKey == null) throw new Error('session is required')
323
- // const que = this.isWorker ? conv.glb : conv.lcl
324
- // const lastItem = que[que.length - 1]
325
- // const lastItemType = lastItem?.typ
326
- // if (lastItemType === ConvThreadType.wrk) {
327
- // console.log('POP', lastItem)
328
- // que.pop() // remove last item, since it's temporary
329
- // // TODO triggers.refreshAll!
330
- // }
331
- // const queIndex = que.findIndex(stp => stp.key === sessionKey && this.thread.id === stp.trd)
332
- // if (queIndex < 0) {
333
- // if (que.length > 0) {
334
- // await this.sendEventToStep({ toGlobal: this.isGlobal, event: { name: '_conv', action: 'onPause', params: { byStep: this.step.label } } })
335
- // }
336
- // const type = this.threadType === ConvThreadType.wrk ? this.threadType : undefined
337
- // que.push({ key: sessionKey, trd: this.thread.id, typ: type, name: this.constructor.name, label: this.label, step: this.id })
338
- // console.log('PUSH', que[que.length - 1])
339
- // await this.updateData()
340
- // return true
341
- // }
342
- // // refresh data on step change
343
- // que[queIndex].name = this.constructor.name
344
- // que[queIndex].label = this.label
345
- // que[queIndex].step = this.id
346
- // return queIndex === que.length - 1
347
- // }
348
- /** @returns true if current conv was active */
349
- // protected async popConvStep (popStep?: IConversationStep): Promise<boolean> {
350
- // const conv = await this.getConversation()
351
- // const sessionKey = this.session.key
352
- // if (sessionKey == null) throw new Error('session is required')
353
- // popStep ||= { key: sessionKey, trd: this.thread.id }
354
- // const que = this.isWorker ? conv.glb : conv.lcl
355
- // const queIndex = que.findIndex(stp => stp.key === popStep?.key && stp.trd === popStep.trd)
356
- // if (queIndex >= 0) {
357
- // // console.log('SPLICE1', this.thread.id, this.step.label, que)
358
- // que.splice(queIndex, 1)
359
- // // conv.sid = this.session.sessionId
360
- // await this.updateData()
361
- // return queIndex === que.length
362
- // }
363
- // // let updated = false
364
- // // conv.stk.forEach((steps, stepsIdx) => {
365
- // // const stpIdx = steps.findIndex(stp => stp.key === sessionKey && this.thread.id === stp.thread)
366
- // // if (stpIdx>= 0) {
367
- // // if (steps.length> 1) steps.splice(stpIdx, 1)
368
- // // else conv.stk.splice(stepsIdx, 1)
369
- // // updated = true
370
- // // }
371
- // // })
372
- // // if (updated) await this.updateData()
373
- // return false
374
- // }
375
212
  async startConversation(data, { thread: _thread } = {}) {
376
213
  this.convDataCache = {
377
214
  ...data,
package/dst/voice.d.ts CHANGED
@@ -47,6 +47,7 @@ export default class VoiceStep<TIn = unknown, TOut = unknown, TParams extends Vo
47
47
  runBefore(): Promise<void>;
48
48
  sendCommands({ id, type, callback }: IVoiceCall, commands: TODO[]): Promise<void>;
49
49
  handleHeartbeat(call: IVoiceCall): Promise<void>;
50
+ handleCancel(): void;
50
51
  extractSectionMessages(sections: IPromtpSection[]): string;
51
52
  extractSectionFiles(sections: IPromtpSection[]): Array<{
52
53
  fileUrl: string;
package/dst/voice.js CHANGED
@@ -65,6 +65,12 @@ class VoiceStep extends step_1.default {
65
65
  await this.updateData();
66
66
  }
67
67
  }
68
+ handleCancel() {
69
+ if (this.data.handleCancel === true)
70
+ this.exitStep('cancel');
71
+ else
72
+ this.end();
73
+ }
68
74
  extractSectionMessages(sections) {
69
75
  return lodash_1.default.chain(sections)
70
76
  .filter(s => Boolean(s.text))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onereach/step-voice",
3
- "version": "5.0.9-fixsubflow.9",
3
+ "version": "6.0.0",
4
4
  "author": "Roman Zolotarov <roman.zolotarov@onereach.com>",
5
5
  "contributors": [
6
6
  "Roman Zolotarov",