@onereach/step-voice 7.0.9-processttschunk.0 → 7.0.9-processttschunk.10
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/Global Command.d.ts +2 -0
- package/dst/Global Command.js +8 -0
- package/dst/Initiate Call.d.ts +17 -0
- package/dst/Initiate Call.js +25 -12
- package/dst/Join Conference.d.ts +1 -0
- package/dst/Join Conference.js +5 -2
- package/dst/Say Message.js +2 -1
- package/dst/Start TTS Chunks Processing.js +9 -0
- package/dst/Transfer.d.ts +16 -1
- package/dst/Transfer.js +60 -16
- package/dst/step.d.ts +1 -0
- package/dst/step.js +4 -0
- package/dst/voice.d.ts +1 -1
- package/dst/voice.js +2 -0
- package/package.json +1 -1
package/dst/Global Command.d.ts
CHANGED
package/dst/Global Command.js
CHANGED
|
@@ -93,6 +93,14 @@ class GlobalCommand extends voice_1.default {
|
|
|
93
93
|
await this.initGrammar(call);
|
|
94
94
|
}
|
|
95
95
|
});
|
|
96
|
+
// Set loop prevention settings on call object
|
|
97
|
+
if (this.data.loopPrevention_enabled) {
|
|
98
|
+
this.session.data.loopPrevention = {
|
|
99
|
+
enabled: this.data.loopPrevention_enabled,
|
|
100
|
+
maxLoops: this.data.loopPrevention_maxLoops
|
|
101
|
+
};
|
|
102
|
+
await this.updateData();
|
|
103
|
+
}
|
|
96
104
|
if (allowAck) {
|
|
97
105
|
this.triggers.local('ack', ({ params: { ack } }) => {
|
|
98
106
|
const worker = this.process.getThread(this.workerThreadId);
|
package/dst/Initiate Call.d.ts
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
import VoiceStep, { CallStartEvent, TODO } from './voice';
|
|
2
|
+
declare const enum GATEWAY_SETTINGS_MODE {
|
|
3
|
+
DEFAULT = "default",
|
|
4
|
+
CUSTOM = "custom",
|
|
5
|
+
INHERIT = "inherit",
|
|
6
|
+
PROFILE = "profile"
|
|
7
|
+
}
|
|
8
|
+
declare const enum SIP_PROFILE {
|
|
9
|
+
DEFAULT = "default",
|
|
10
|
+
INTERNAL = "internal",
|
|
11
|
+
EXTERNAL = "external"
|
|
12
|
+
}
|
|
2
13
|
interface INPUT {
|
|
3
14
|
callId?: string;
|
|
4
15
|
sessionTimeout?: number | string;
|
|
@@ -8,9 +19,11 @@ interface INPUT {
|
|
|
8
19
|
tts: TODO;
|
|
9
20
|
from: string;
|
|
10
21
|
endUserNumber: string;
|
|
22
|
+
gatewaySettingsMode?: GATEWAY_SETTINGS_MODE;
|
|
11
23
|
sipHost?: string;
|
|
12
24
|
sipUser?: string;
|
|
13
25
|
sipPassword?: string;
|
|
26
|
+
sipProfile?: SIP_PROFILE;
|
|
14
27
|
timeout?: number | string;
|
|
15
28
|
headers?: Array<{
|
|
16
29
|
name: string;
|
|
@@ -19,6 +32,10 @@ interface INPUT {
|
|
|
19
32
|
enableSpoofCallerId?: boolean;
|
|
20
33
|
spoofCallerId?: string;
|
|
21
34
|
isAMD?: boolean;
|
|
35
|
+
enableWhisperTransfer?: boolean;
|
|
36
|
+
whisperAnnounceAudio?: TODO[];
|
|
37
|
+
whisperCustomerConversation?: string;
|
|
38
|
+
whisperCustomerConversationThread?: string;
|
|
22
39
|
}
|
|
23
40
|
export default class InitiateCall extends VoiceStep<INPUT, TODO, CallStartEvent> {
|
|
24
41
|
get conversation(): string | import("@onereach/flow-sdk/types").IMergeField;
|
package/dst/Initiate Call.js
CHANGED
|
@@ -47,7 +47,7 @@ class InitiateCall extends voice_1.default {
|
|
|
47
47
|
this.exitStep('cancel');
|
|
48
48
|
}
|
|
49
49
|
async waitForCall() {
|
|
50
|
-
const { asr, tts, from: botNumber, endUserNumber, sipHost, sipUser, sipPassword, timeout, headers, enableSpoofCallerId, spoofCallerId, isAMD, otherCallRef, otherCallRefThread, handleCancel } = this.data;
|
|
50
|
+
const { asr, tts, from: botNumber, endUserNumber, gatewaySettingsMode, sipHost, sipUser, sipPassword, sipProfile, timeout, headers, enableSpoofCallerId, spoofCallerId, isAMD, otherCallRef, otherCallRefThread, handleCancel, } = this.data;
|
|
51
51
|
const call = await this.fetchData();
|
|
52
52
|
this.triggers.once(`in/voice/${call.id}/event`, async (event) => {
|
|
53
53
|
switch (event.params.type) {
|
|
@@ -84,7 +84,7 @@ class InitiateCall extends voice_1.default {
|
|
|
84
84
|
reportingSettingsKey: 'transcript',
|
|
85
85
|
actionFromBot: true
|
|
86
86
|
});
|
|
87
|
-
|
|
87
|
+
const commands = [
|
|
88
88
|
...isAMD
|
|
89
89
|
? [{
|
|
90
90
|
name: 'start-avmd',
|
|
@@ -100,8 +100,9 @@ class InitiateCall extends voice_1.default {
|
|
|
100
100
|
type: asr.serverSettings.engine
|
|
101
101
|
}
|
|
102
102
|
}]
|
|
103
|
-
: []
|
|
104
|
-
]
|
|
103
|
+
: [],
|
|
104
|
+
];
|
|
105
|
+
await this.sendCommands(newCall, commands);
|
|
105
106
|
return this.exitStep('success');
|
|
106
107
|
}
|
|
107
108
|
case 'hangup': {
|
|
@@ -160,6 +161,23 @@ class InitiateCall extends voice_1.default {
|
|
|
160
161
|
memo[header.name] = `${header.value}`;
|
|
161
162
|
return memo;
|
|
162
163
|
}, {});
|
|
164
|
+
// GET SIP PROFILE SETTINGS
|
|
165
|
+
let gateway;
|
|
166
|
+
const profile = sipProfile !== "default" /* SIP_PROFILE.DEFAULT */ ? sipProfile : undefined;
|
|
167
|
+
switch (gatewaySettingsMode) {
|
|
168
|
+
case "custom" /* GATEWAY_SETTINGS_MODE.CUSTOM */:
|
|
169
|
+
gateway = {
|
|
170
|
+
host: sipHost,
|
|
171
|
+
user: sipUser,
|
|
172
|
+
username: sipUser,
|
|
173
|
+
password: sipPassword,
|
|
174
|
+
profile
|
|
175
|
+
};
|
|
176
|
+
break;
|
|
177
|
+
case "profile" /* GATEWAY_SETTINGS_MODE.PROFILE */:
|
|
178
|
+
gateway = gateway = profile != null ? { profile } : undefined;
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
163
181
|
const params = {
|
|
164
182
|
id: call.id,
|
|
165
183
|
from: botNumber,
|
|
@@ -169,16 +187,11 @@ class InitiateCall extends voice_1.default {
|
|
|
169
187
|
enableSpoofCallerId,
|
|
170
188
|
spoofCallerId
|
|
171
189
|
},
|
|
172
|
-
gateway: sipHost
|
|
173
|
-
? {
|
|
174
|
-
host: sipHost,
|
|
175
|
-
username: sipUser,
|
|
176
|
-
password: sipPassword
|
|
177
|
-
}
|
|
178
|
-
: undefined,
|
|
179
190
|
timeout: originateTimeout,
|
|
180
191
|
version: 2,
|
|
181
|
-
sessionExpireTime: this.session.expireTime
|
|
192
|
+
sessionExpireTime: this.session.expireTime,
|
|
193
|
+
gateway,
|
|
194
|
+
maxLoops: this.session.data?.loopPrevention?.enabled && this.session.data.loopPrevention.maxLoops,
|
|
182
195
|
};
|
|
183
196
|
if (otherCallRef) {
|
|
184
197
|
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
package/dst/Join Conference.d.ts
CHANGED
package/dst/Join Conference.js
CHANGED
|
@@ -6,7 +6,7 @@ const voice_1 = tslib_1.__importDefault(require("./voice"));
|
|
|
6
6
|
class JoinConference extends voice_1.default {
|
|
7
7
|
async runStep() {
|
|
8
8
|
const call = await this.fetchData();
|
|
9
|
-
const { conferenceName, stayInConference, volumeIn, volumeOut } = this.data;
|
|
9
|
+
const { conferenceName, stayInConference, volumeIn, volumeOut, mute } = this.data;
|
|
10
10
|
this.triggers.local(`in/voice/${call.id}`, async (event) => {
|
|
11
11
|
switch (event.params.type) {
|
|
12
12
|
case 'hangup':
|
|
@@ -49,7 +49,10 @@ class JoinConference extends voice_1.default {
|
|
|
49
49
|
name: 'conference.start',
|
|
50
50
|
params: {
|
|
51
51
|
room: conferenceName,
|
|
52
|
-
flags: [
|
|
52
|
+
flags: [
|
|
53
|
+
call.vv >= 3 ? 'mandatory_member_endconf' : 'endconf',
|
|
54
|
+
...mute ? ['mute'] : []
|
|
55
|
+
],
|
|
53
56
|
stayInConference,
|
|
54
57
|
volumeIn,
|
|
55
58
|
volumeOut
|
package/dst/Say Message.js
CHANGED
|
@@ -37,6 +37,15 @@ class StartTTSChunksProcessing extends voice_1.default {
|
|
|
37
37
|
this.log.info('tts-chunks-playback-done', event.params);
|
|
38
38
|
return this.exitStep('next', {}, false);
|
|
39
39
|
}
|
|
40
|
+
case 'tts-audio/started':
|
|
41
|
+
case 'tts-audio/finished':
|
|
42
|
+
case 'tts-audio/interrupted':
|
|
43
|
+
case 'asr-input/started':
|
|
44
|
+
case 'asr-input/ended':
|
|
45
|
+
case 'asr-input/processed': {
|
|
46
|
+
this.log.warn('Received asr/tts status event', event.params);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
40
49
|
case 'timeout': {
|
|
41
50
|
this.log.info('timeout', event.params);
|
|
42
51
|
return this.exitStep(event.params.type, {}, false);
|
package/dst/Transfer.d.ts
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
import VoiceStep, { VoiceEvent } from './voice';
|
|
2
|
+
declare const enum GATEWAY_SETTINGS_MODE {
|
|
3
|
+
DEFAULT = "default",
|
|
4
|
+
CUSTOM = "custom",
|
|
5
|
+
INHERIT = "inherit",
|
|
6
|
+
PROFILE = "profile"
|
|
7
|
+
}
|
|
8
|
+
declare const enum SIP_PROFILE {
|
|
9
|
+
DEFAULT = "default",
|
|
10
|
+
INTERNAL = "internal",
|
|
11
|
+
EXTERNAL = "external"
|
|
12
|
+
}
|
|
2
13
|
interface INPUT {
|
|
3
14
|
destination: string;
|
|
4
15
|
phoneNumber: string;
|
|
@@ -8,11 +19,15 @@ interface INPUT {
|
|
|
8
19
|
value: string;
|
|
9
20
|
}>;
|
|
10
21
|
refer: boolean;
|
|
11
|
-
|
|
22
|
+
withReplaces: boolean;
|
|
23
|
+
replacesConversation?: string;
|
|
24
|
+
replacesConversationThread?: string;
|
|
12
25
|
from?: string;
|
|
26
|
+
gatewaySettingsMode?: GATEWAY_SETTINGS_MODE;
|
|
13
27
|
sipHost?: string;
|
|
14
28
|
sipUser?: string;
|
|
15
29
|
sipPassword?: string;
|
|
30
|
+
sipProfile?: SIP_PROFILE;
|
|
16
31
|
muteRecording?: boolean;
|
|
17
32
|
}
|
|
18
33
|
interface EVENT extends VoiceEvent {
|
package/dst/Transfer.js
CHANGED
|
@@ -52,33 +52,77 @@ class Transfer extends voice_1.default {
|
|
|
52
52
|
return this.exitFlow();
|
|
53
53
|
});
|
|
54
54
|
this.triggers.otherwise(async () => {
|
|
55
|
-
const { phoneNumber, sessionTimeout, destination, sipHeaders = [], sipHost, sipUser, sipPassword, refer,
|
|
55
|
+
const { phoneNumber, sessionTimeout, destination, sipHeaders = [], sipHost, sipUser, sipPassword, sipProfile, refer, withReplaces, replacesConversation, replacesConversationThread, gatewaySettingsMode, from, muteRecording, } = this.data;
|
|
56
56
|
const destinationIsSip = (/^sip:/i).test(destination);
|
|
57
57
|
const destinationIsUser = (/^user:/i).test(destination);
|
|
58
58
|
const callerID = phoneNumber;
|
|
59
59
|
const timeout = Number(sessionTimeout);
|
|
60
|
-
const inheritGatewaySetting =
|
|
60
|
+
const inheritGatewaySetting = gatewaySettingsMode === 'inherit';
|
|
61
61
|
const headers = Object.fromEntries(sipHeaders.map(({ name, value }) => [name, value]));
|
|
62
|
+
let transferFrom = callerID;
|
|
63
|
+
let transferTo = destination;
|
|
64
|
+
let replacesDialog;
|
|
65
|
+
if (refer && withReplaces && replacesConversation) {
|
|
66
|
+
const replacesCall = replacesConversationThread
|
|
67
|
+
? await this.process.getSafeThread(replacesConversationThread).get(replacesConversation)
|
|
68
|
+
: await this.getConversationByName(replacesConversation);
|
|
69
|
+
// For attended transfer: transferFrom becomes current call's ID,
|
|
70
|
+
// and replacesDialog carries the dialog identifiers for Replaces header
|
|
71
|
+
transferFrom = call.id;
|
|
72
|
+
replacesDialog = {
|
|
73
|
+
callId: replacesCall['toCallId'],
|
|
74
|
+
toTag: replacesCall['toTag'],
|
|
75
|
+
fromTag: replacesCall['fromTag'],
|
|
76
|
+
uri: replacesCall['toUri'],
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
// GET SIP PROFILE SETTINGS
|
|
80
|
+
let gateway;
|
|
81
|
+
const profile = sipProfile !== "default" /* SIP_PROFILE.DEFAULT */ ? sipProfile : undefined;
|
|
82
|
+
switch (gatewaySettingsMode) {
|
|
83
|
+
case "custom" /* GATEWAY_SETTINGS_MODE.CUSTOM */:
|
|
84
|
+
gateway = {
|
|
85
|
+
host: sipHost,
|
|
86
|
+
user: sipUser,
|
|
87
|
+
username: sipUser,
|
|
88
|
+
password: sipPassword,
|
|
89
|
+
profile
|
|
90
|
+
};
|
|
91
|
+
break;
|
|
92
|
+
case "profile" /* GATEWAY_SETTINGS_MODE.PROFILE */:
|
|
93
|
+
gateway = gateway = profile != null ? { profile } : undefined;
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
let commandName = 'bridge';
|
|
97
|
+
if (destinationIsSip) {
|
|
98
|
+
commandName = refer ? 'refer' : 'bridge_sip';
|
|
99
|
+
}
|
|
100
|
+
else if (destinationIsUser) {
|
|
101
|
+
commandName = 'bridge_user';
|
|
102
|
+
}
|
|
103
|
+
const botNumber = inheritGatewaySetting ? from : call.botNumber;
|
|
104
|
+
const maxLoops = this.session.data?.loopPrevention?.enabled
|
|
105
|
+
? this.session.data.loopPrevention.maxLoops
|
|
106
|
+
: undefined;
|
|
62
107
|
const command = {
|
|
63
|
-
name:
|
|
108
|
+
name: commandName,
|
|
64
109
|
params: {
|
|
65
|
-
botNumber
|
|
66
|
-
transferFrom
|
|
67
|
-
transferTo
|
|
110
|
+
botNumber,
|
|
111
|
+
transferFrom,
|
|
112
|
+
transferTo,
|
|
68
113
|
headers,
|
|
69
|
-
gateway
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
username: sipUser,
|
|
74
|
-
password: sipPassword
|
|
75
|
-
}
|
|
76
|
-
: undefined,
|
|
77
|
-
timeout
|
|
114
|
+
gateway,
|
|
115
|
+
timeout,
|
|
116
|
+
maxLoops,
|
|
117
|
+
...(replacesDialog && { replacesDialog }),
|
|
78
118
|
}
|
|
79
119
|
};
|
|
80
120
|
const muteAfterTransfer = !!muteRecording;
|
|
81
|
-
await this.pauseRecording(call, command, {
|
|
121
|
+
await this.pauseRecording(call, command, {
|
|
122
|
+
muteStep: muteAfterTransfer,
|
|
123
|
+
muteBot: muteAfterTransfer,
|
|
124
|
+
muteUser: muteAfterTransfer
|
|
125
|
+
});
|
|
82
126
|
await this.transcript(call, {
|
|
83
127
|
action: 'Transfer Start',
|
|
84
128
|
actionFromBot: true,
|
package/dst/step.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ export default class ConvStep<TData extends IConversationData, TIn = unknown, TO
|
|
|
25
25
|
get useQueue(): boolean;
|
|
26
26
|
fetchData(): Promise<TData>;
|
|
27
27
|
getConversation(): Promise<IConversation>;
|
|
28
|
+
getConversationByName(conversation: string): Promise<IConversation>;
|
|
28
29
|
updateData(): Promise<void>;
|
|
29
30
|
hasConversation(): Promise<boolean>;
|
|
30
31
|
runBefore(): Promise<void>;
|
package/dst/step.js
CHANGED
|
@@ -51,6 +51,10 @@ class ConvStep extends step_1.default {
|
|
|
51
51
|
async getConversation() {
|
|
52
52
|
return (await this.fetchData())._conv;
|
|
53
53
|
}
|
|
54
|
+
async getConversationByName(conversation) {
|
|
55
|
+
const convDataThread = this.process.getSafeThread(this.dataThreadId);
|
|
56
|
+
return await convDataThread.get(conversation);
|
|
57
|
+
}
|
|
54
58
|
async updateData() {
|
|
55
59
|
if (this.convDataCache == null)
|
|
56
60
|
throw new Error(`missing conversation cache in state ${this.state.name}`);
|
package/dst/voice.d.ts
CHANGED
|
@@ -33,7 +33,7 @@ export interface IVoiceCall extends IConversationData {
|
|
|
33
33
|
user: string;
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
|
-
export type EventType = 'hangup' | 'ack' | 'error' | 'cancel' | 'background' | 'avm-detected' | 'recognition' | 'digit' | 'digits' | 'conference-start' | 'conference-end' | 'playback' | 'timeout' | 'record' | 'bridge' | 'bridge/ended' | 'is_flow_ready' | 'call' | 'dtmf-sent' | 'tts-chunks-playback-done';
|
|
36
|
+
export type EventType = 'hangup' | 'ack' | 'error' | 'cancel' | 'background' | 'avm-detected' | 'recognition' | 'digit' | 'digits' | 'conference-start' | 'conference-end' | 'playback' | 'timeout' | 'record' | 'bridge' | 'bridge/ended' | 'is_flow_ready' | 'call' | 'dtmf-sent' | 'tts-chunks-playback-done' | 'tts-audio/started' | 'tts-audio/finished' | 'tts-audio/interrupted' | 'asr-input/started' | 'asr-input/ended' | 'asr-input/processed';
|
|
37
37
|
export declare class VoiceStepError extends BasicError {
|
|
38
38
|
}
|
|
39
39
|
export type VoicerError = Error & {
|
package/dst/voice.js
CHANGED
|
@@ -76,12 +76,14 @@ class VoiceStep extends step_1.default {
|
|
|
76
76
|
}
|
|
77
77
|
async handleHeartbeat(call) {
|
|
78
78
|
const allowHeartbeat = this.canVoicerHeartbeat(call);
|
|
79
|
+
this.log.debug('handleHeartbeat', { allowHeartbeat });
|
|
79
80
|
if (allowHeartbeat) {
|
|
80
81
|
if (this.thread.background) {
|
|
81
82
|
delete this.waits.timeout;
|
|
82
83
|
return;
|
|
83
84
|
}
|
|
84
85
|
const expectHeartbeatBefore = Date.now() + 290000;
|
|
86
|
+
this.log.debug('expectHeartbeatBefore', { expectHeartbeatBefore });
|
|
85
87
|
this.triggers.deadline(expectHeartbeatBefore, () => {
|
|
86
88
|
this.thread.background = true;
|
|
87
89
|
if (call.ended) {
|