@tiledesk/tiledesk-tybot-connector 0.2.66-rc3 → 0.2.66
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/CHANGELOG.md +3 -2
- package/models/TiledeskChatbot.js +1 -0
- package/models/TiledeskChatbotUtil.js +46 -0
- package/package.json +1 -1
- package/tiledeskChatbotPlugs/DirectivesChatbotPlug.js +14 -0
- package/tiledeskChatbotPlugs/directives/DirAssistant.js +1 -1
- package/tiledeskChatbotPlugs/directives/DirReplyV2.js +289 -0
- package/tiledeskChatbotPlugs/directives/Directives.js +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,14 +5,15 @@
|
|
|
5
5
|
available on:
|
|
6
6
|
▶️ https://www.npmjs.com/package/@tiledesk/tiledesk-tybot-connector
|
|
7
7
|
|
|
8
|
-
# v0.2.66
|
|
8
|
+
# v0.2.66
|
|
9
9
|
- changed updateQuotes method
|
|
10
10
|
- fix missing model in updateQuote
|
|
11
|
+
- added ReplyV2
|
|
11
12
|
|
|
12
13
|
# v0.2.66-rc1
|
|
13
14
|
- fix missing model in updateQuote
|
|
14
15
|
|
|
15
|
-
# v0.2.65
|
|
16
|
+
# v0.2.65 - online
|
|
16
17
|
- fix OPENAI_APIKEY: removed Bearer prefix
|
|
17
18
|
|
|
18
19
|
# v0.2.64
|
|
@@ -81,6 +81,7 @@ class TiledeskChatbot {
|
|
|
81
81
|
await this.unlockIntent(this.requestId);
|
|
82
82
|
await this.unlockAction(this.requestId);
|
|
83
83
|
// console.log("RESET LOCKED INTENT.");
|
|
84
|
+
await chatbot.addParameter("userInput", true); // set userInput
|
|
84
85
|
if (this.log) {console.log("RESET LOCKED INTENT. Intent was explicitly invoked with an action:", message.attributes.action);}
|
|
85
86
|
}
|
|
86
87
|
} catch(error) {
|
|
@@ -336,6 +336,51 @@ class TiledeskChatbotUtil {
|
|
|
336
336
|
}
|
|
337
337
|
}
|
|
338
338
|
|
|
339
|
+
static allReplyButtons(message) {
|
|
340
|
+
let all_buttons = [];
|
|
341
|
+
if (message.attributes && message.attributes.commands) {
|
|
342
|
+
// console.log("message.attributes ok")
|
|
343
|
+
let commands = message.attributes.commands;
|
|
344
|
+
if (commands.length > 0) {
|
|
345
|
+
// console.log("commands ok", commands.length)
|
|
346
|
+
for (let i = 0; i < commands.length; i++) {
|
|
347
|
+
let command = commands[i];
|
|
348
|
+
// console.log("got command:", command)s
|
|
349
|
+
if (command.type === 'message' && command.message) {
|
|
350
|
+
if (command.message.attributes && command.message.attributes.attachment && command.message.attributes.attachment.buttons && command.message.attributes.attachment.buttons.length > 0){
|
|
351
|
+
// console.log("command with buttons ok:")
|
|
352
|
+
let buttons = command.message.attributes.attachment.buttons;
|
|
353
|
+
|
|
354
|
+
buttons.forEach(button => {
|
|
355
|
+
if (button.type === "action" || button.type === "text") {
|
|
356
|
+
// console.log("pushing button:", button);
|
|
357
|
+
all_buttons.push(button);
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
return all_buttons;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
static buttonByText(text, buttons) {
|
|
369
|
+
if (buttons === null || text === null) {
|
|
370
|
+
return null;
|
|
371
|
+
}
|
|
372
|
+
let search_text = text.toLowerCase();
|
|
373
|
+
let selected_button = null;
|
|
374
|
+
for (let i = 0; i < buttons.length; i++) {
|
|
375
|
+
const button = buttons[i];
|
|
376
|
+
if (button.value !== null && button.value.toLowerCase() === search_text) {
|
|
377
|
+
selected_button = button;
|
|
378
|
+
break;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
return selected_button;
|
|
382
|
+
}
|
|
383
|
+
|
|
339
384
|
static async updateConversationTranscript(chatbot, message) {
|
|
340
385
|
if (!message || !message.senderFullname) { // not a conversation, can it be an Automation invocation?
|
|
341
386
|
return null;
|
|
@@ -451,6 +496,7 @@ class TiledeskChatbotUtil {
|
|
|
451
496
|
}
|
|
452
497
|
|
|
453
498
|
if (message.text && message.sender !== "_tdinternal") {
|
|
499
|
+
await chatbot.addParameter("userInput", true); // set userInput
|
|
454
500
|
await chatbot.addParameter(TiledeskChatbotConst.REQ_LAST_USER_TEXT_KEY, message.text); // DEPRECATED
|
|
455
501
|
await chatbot.addParameter(TiledeskChatbotConst.REQ_LAST_USER_TEXT_v2_KEY, message.text);
|
|
456
502
|
if (message.channel) {
|
package/package.json
CHANGED
|
@@ -47,6 +47,7 @@ const { DirCustomerio } = require('./directives/DirCustomerio');
|
|
|
47
47
|
const { DirBrevo } = require('./directives/DirBrevo');
|
|
48
48
|
const { DirAskGPTV2 } = require('./directives/DirAskGPTV2');
|
|
49
49
|
const { DirAssistant } = require('./directives/DirAssistant');
|
|
50
|
+
const { DirReplyV2 } = require('./directives/DirReplyV2');
|
|
50
51
|
|
|
51
52
|
class DirectivesChatbotPlug {
|
|
52
53
|
|
|
@@ -293,6 +294,19 @@ class DirectivesChatbotPlug {
|
|
|
293
294
|
this.process(next_dir);
|
|
294
295
|
});
|
|
295
296
|
}
|
|
297
|
+
else if (directive_name === Directives.REPLY_V2) {
|
|
298
|
+
// console.log("...DirReplyV2");
|
|
299
|
+
new DirReplyV2(context).execute(directive, async (stop) => {
|
|
300
|
+
if (stop) {
|
|
301
|
+
if (context.log) { console.log("Stopping Actions on:", JSON.stringify(directive));}
|
|
302
|
+
this.theend();
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
let next_dir = await this.nextDirective(this.directives);
|
|
306
|
+
this.process(next_dir);
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
}
|
|
296
310
|
else if (directive_name === Directives.DTMF_FORM) {
|
|
297
311
|
// console.log("...DirReply");
|
|
298
312
|
new DirReply(context).execute(directive, async () => {
|
|
@@ -125,7 +125,7 @@ class DirAssistant {
|
|
|
125
125
|
let apikey = await this.getGPT_APIKEY();
|
|
126
126
|
if (this.log) {console.log("apikey:", apikey);}
|
|
127
127
|
if (!apikey) {
|
|
128
|
-
const reply = "
|
|
128
|
+
const reply = "OpenAI APIKEY is mandatory for ChatGPT Assistants. Add your personal OpenAI APIKEY in Settings > Integrations";
|
|
129
129
|
if (this.log) { console.error(reply); };
|
|
130
130
|
await TiledeskChatbot.addParameterStatic(this.context.tdcache, this.context.requestId, assignErrorTo, reply);
|
|
131
131
|
if (falseIntent) {
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
const { Filler } = require('../Filler');
|
|
2
|
+
const { TiledeskChatbot } = require('../../models/TiledeskChatbot');
|
|
3
|
+
const { TiledeskChatbotConst } = require('../../models/TiledeskChatbotConst');
|
|
4
|
+
const { TiledeskChatbotUtil } = require('../../models/TiledeskChatbotUtil');
|
|
5
|
+
const { DirIntent } = require("./DirIntent");
|
|
6
|
+
|
|
7
|
+
class DirReplyV2 {
|
|
8
|
+
|
|
9
|
+
constructor(context) {
|
|
10
|
+
if (!context) {
|
|
11
|
+
throw new Error('context object is mandatory.');
|
|
12
|
+
}
|
|
13
|
+
this.context = context;
|
|
14
|
+
this.projectId = context.projectId;
|
|
15
|
+
this.requestId = context.requestId;
|
|
16
|
+
this.token = context.token;
|
|
17
|
+
this.tdcache = context.tdcache;
|
|
18
|
+
this.log = context.log;
|
|
19
|
+
this.intentDir = new DirIntent(context);
|
|
20
|
+
this.chatbot = context.chatbot;
|
|
21
|
+
this.reply = context.reply;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
execute(directive, callback) {
|
|
25
|
+
let action;
|
|
26
|
+
if (directive.action) {
|
|
27
|
+
action = directive.action;
|
|
28
|
+
if (!action.attributes) {
|
|
29
|
+
action.attributes = {}
|
|
30
|
+
}
|
|
31
|
+
action.attributes.fillParams = true;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
console.error("Incorrect directive (no action provided):", directive);
|
|
35
|
+
callback();
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
this.go(action, (stop) => {
|
|
39
|
+
callback(stop);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async go(action, callback) {
|
|
44
|
+
if (this.log) { console.log("ReplyV2 action!", JSON.stringify(action)); }
|
|
45
|
+
const message = action;
|
|
46
|
+
|
|
47
|
+
let current; // debug only
|
|
48
|
+
if (this.log) {
|
|
49
|
+
if (message.attributes.commands[1].message.text) {
|
|
50
|
+
current = message.attributes.commands[1].message.text
|
|
51
|
+
}
|
|
52
|
+
console.log("current:", current);
|
|
53
|
+
}
|
|
54
|
+
let must_stop = false;
|
|
55
|
+
// fill
|
|
56
|
+
let requestAttributes = null;
|
|
57
|
+
if (this.tdcache) {
|
|
58
|
+
requestAttributes =
|
|
59
|
+
await TiledeskChatbot.allParametersStatic(
|
|
60
|
+
this.tdcache, this.requestId
|
|
61
|
+
);
|
|
62
|
+
if (this.log) {
|
|
63
|
+
for (const [key, value] of Object.entries(requestAttributes)) {
|
|
64
|
+
const value_type = typeof value;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
// lock/unlock + no-match
|
|
70
|
+
// get buttons if available
|
|
71
|
+
const buttons = TiledeskChatbotUtil.allReplyButtons(message);
|
|
72
|
+
if (this.log) { console.log("Action Buttons:", JSON.stringify(buttons)); }
|
|
73
|
+
if (buttons && buttons.length > 0) {
|
|
74
|
+
const locked = await this.lockUnlock(action); // first execution returns locked, then unlocked
|
|
75
|
+
if (!locked) {
|
|
76
|
+
if (this.log) { console.log("second pass! unlocked!"); }
|
|
77
|
+
const last_user_text = await this.chatbot.getParameter(TiledeskChatbotConst.REQ_LAST_USER_TEXT_v2_KEY);
|
|
78
|
+
if (this.log) { console.log("got last user text"); }
|
|
79
|
+
const button = TiledeskChatbotUtil.buttonByText(last_user_text, buttons);
|
|
80
|
+
if (this.log) { console.log("button found", JSON.stringify(button)); }
|
|
81
|
+
// invoke button
|
|
82
|
+
if (button && button.action) {
|
|
83
|
+
if (this.log) { console.log("moving to button action", button.action); }
|
|
84
|
+
let button_action = DirIntent.intentDirectiveFor(button.action, null);
|
|
85
|
+
if (this.log) { console.log("action with .intentName:", button_action); }
|
|
86
|
+
this.intentDir.execute(button_action, () => {
|
|
87
|
+
if (this.log) { console.log("action invoked", button_action); }
|
|
88
|
+
});
|
|
89
|
+
if (this.log) { console.log("callback(true) + return", current); }
|
|
90
|
+
callback(true); // must_stop = true
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
else { // no match (treating text buttons as no-match for the moment)
|
|
94
|
+
// if noMatchIntent invoke
|
|
95
|
+
// const button = TiledeskChatbotUtil.buttonByText("nomatch", buttons);
|
|
96
|
+
if (this.log) { console.log("nomatch button found", JSON.stringify(button)); }
|
|
97
|
+
// // invoke button
|
|
98
|
+
// if (button && button.action) {
|
|
99
|
+
// console.log("moving to nomatch action", button.action);
|
|
100
|
+
// let button_action = DirIntent.intentDirectiveFor(button.action, null);
|
|
101
|
+
// this.intentDir.execute(button_action, () => {
|
|
102
|
+
// console.log("nomatch action invoked", button_action);
|
|
103
|
+
// });
|
|
104
|
+
// console.log("callback(true) + return 2", current);
|
|
105
|
+
// callback(true);
|
|
106
|
+
// return;
|
|
107
|
+
// }
|
|
108
|
+
if (action.noMatchIntent) {
|
|
109
|
+
if (this.log) { console.log("moving to nomatch action", action.noMatchIntent); }
|
|
110
|
+
let nomatch_action = DirIntent.intentDirectiveFor(action.noMatchIntent, null);
|
|
111
|
+
this.intentDir.execute(nomatch_action, () => {
|
|
112
|
+
if (this.log) { console.log("nomatch action invoked", nomatch_action); }
|
|
113
|
+
});
|
|
114
|
+
if (this.log) { console.log("callback(true) + return no-match", current); }
|
|
115
|
+
callback(true); // must_stop = true
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
// there is no "no-match", go on...
|
|
120
|
+
if (this.log) { console.log("callback(false) + return 3", current); }
|
|
121
|
+
callback(false);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
if (this.log) { console.log("first time pass!"); }
|
|
128
|
+
must_stop = true; // you must stop after next callbacks (in this flow) if there are buttons
|
|
129
|
+
// console.log("action:", action);
|
|
130
|
+
if (action.noInputIntent) {
|
|
131
|
+
if (this.log) { console.log("NoInputIntent found:", action.noInputIntent); }
|
|
132
|
+
const noInputIntent = action.noInputIntent;
|
|
133
|
+
const noInputTimeout = action.noInputTimeout;
|
|
134
|
+
if (this.log) { console.log("noInputTimeout found:", noInputTimeout); }
|
|
135
|
+
if (noInputTimeout > 0 && noInputTimeout < 300000) {
|
|
136
|
+
await this.chatbot.addParameter("userInput", false); // control variable. On each user input is set to true
|
|
137
|
+
if (this.log) { console.log("Set userInput: false, checking...", await this.chatbot.getParameter("userInput")); }
|
|
138
|
+
setTimeout(async () => {
|
|
139
|
+
if (this.log) { onsole.log("noinput timeout triggered!"); }
|
|
140
|
+
let userInput = await this.chatbot.getParameter("userInput");
|
|
141
|
+
if (!userInput) {
|
|
142
|
+
if (this.log) { console.log("no 'userInput'. Executing noinput action:", noInputIntent); }
|
|
143
|
+
await this.chatbot.unlockIntent(this.requestId);
|
|
144
|
+
await this.chatbot.unlockAction(this.requestId);
|
|
145
|
+
if (this.log) { console.log("unlocked (for noInput) ReplyV2"); }
|
|
146
|
+
let noinput_action = DirIntent.intentDirectiveFor(noInputIntent, null);
|
|
147
|
+
this.intentDir.execute(noinput_action, () => {
|
|
148
|
+
if (this.log) { console.log("noinput action invoked", noinput_action); }
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}, noInputTimeout);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
catch(error) {
|
|
158
|
+
console.error("Error in DirReplyV2:", error);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
if (this.log) { console.log("proceding normally to render and send the reply", current); }
|
|
163
|
+
const filler = new Filler();
|
|
164
|
+
// fill text attribute
|
|
165
|
+
message.text = filler.fill(message.text, requestAttributes);
|
|
166
|
+
if (message.metadata) {
|
|
167
|
+
if (this.log) {console.log("filling message 'metadata':", JSON.stringify(message.metadata));}
|
|
168
|
+
if (message.metadata.src) {
|
|
169
|
+
message.metadata.src = filler.fill(message.metadata.src, requestAttributes);
|
|
170
|
+
}
|
|
171
|
+
if (message.metadata.name) {
|
|
172
|
+
message.metadata.name = filler.fill(message.metadata.name, requestAttributes);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
if (this.log) {console.log("filling commands'. Message:", JSON.stringify(message));}
|
|
176
|
+
if (message.attributes && message.attributes.commands) {
|
|
177
|
+
if (this.log) {console.log("filling commands'. commands found.");}
|
|
178
|
+
let commands = message.attributes.commands;
|
|
179
|
+
if (this.log) {console.log("commands:", JSON.stringify(commands), commands.length);}
|
|
180
|
+
if (commands.length > 0) {
|
|
181
|
+
if (this.log) {console.log("commands' found");}
|
|
182
|
+
for (let i = 0; i < commands.length; i++) {
|
|
183
|
+
let command = commands[i];
|
|
184
|
+
if (command.type === 'message' && command.message && command.message.text) {
|
|
185
|
+
command.message.text = filler.fill(command.message.text, requestAttributes);
|
|
186
|
+
TiledeskChatbotUtil.fillCommandAttachments(command, requestAttributes, this.log);
|
|
187
|
+
if (this.log) {console.log("command filled:", command.message.text);}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// EVALUATE EXPRESSION AND REMOVE BASED ON EVALUATION
|
|
194
|
+
if (this.log) {console.log("message before filters:", JSON.stringify(message));}
|
|
195
|
+
if (message.attributes && message.attributes.commands) {
|
|
196
|
+
if (this.log) {console.log("filterOnVariables...on commands", JSON.stringify(message.attributes.commands));}
|
|
197
|
+
if (this.log) {console.log("filterOnVariables...on attributes", requestAttributes);}
|
|
198
|
+
// TiledeskChatbotUtil.filterOnVariables(message.attributes.commands, requestAttributes);
|
|
199
|
+
TiledeskChatbotUtil.filterOnVariables(message, requestAttributes);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// temporary send back of reserved attributes
|
|
203
|
+
if (!message.attributes) {
|
|
204
|
+
message.attributes = {}
|
|
205
|
+
}
|
|
206
|
+
// Reserved names: userEmail, userFullname
|
|
207
|
+
if (requestAttributes['userEmail']) {
|
|
208
|
+
message.attributes.updateUserEmail = requestAttributes['userEmail'];
|
|
209
|
+
}
|
|
210
|
+
if (requestAttributes['userFullname']) {
|
|
211
|
+
message.attributes.updateUserFullname = requestAttributes['userFullname'];
|
|
212
|
+
}
|
|
213
|
+
// intent_info
|
|
214
|
+
if (this.context.reply && this.context.reply.attributes && this.context.reply.attributes.intent_info) {
|
|
215
|
+
message.attributes.intentName = this.context.reply.attributes.intent_info.intent_name;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// send!
|
|
219
|
+
let cleanMessage = message;
|
|
220
|
+
// cleanMessage = TiledeskChatbotUtil.removeEmptyReplyCommands(message);
|
|
221
|
+
// if (!TiledeskChatbotUtil.isValidReply(cleanMessage)) {
|
|
222
|
+
// console.log("invalid message", cleanMessage);
|
|
223
|
+
// callback(); // cancel reply operation
|
|
224
|
+
// return;
|
|
225
|
+
// }
|
|
226
|
+
// console.log("valid message!", cleanMessage);
|
|
227
|
+
cleanMessage.senderFullname = this.context.chatbot.bot.name;
|
|
228
|
+
if (this.log) {console.log("Reply:", JSON.stringify(cleanMessage))};
|
|
229
|
+
await TiledeskChatbotUtil.updateConversationTranscript(this.context.chatbot, cleanMessage);
|
|
230
|
+
this.context.tdclient.sendSupportMessage(
|
|
231
|
+
this.requestId,
|
|
232
|
+
cleanMessage,
|
|
233
|
+
(err) => {
|
|
234
|
+
if (err) {
|
|
235
|
+
console.error("Error sending reply:", err);
|
|
236
|
+
}
|
|
237
|
+
if (this.log) {console.log("Reply message sent");}
|
|
238
|
+
const delay = TiledeskChatbotUtil.totalMessageWait(cleanMessage);
|
|
239
|
+
// console.log("got total delay:", delay)
|
|
240
|
+
if (delay > 0 && delay <= 30000) { // prevent long delays
|
|
241
|
+
if (this.log) { console.log("start timeout callback(" + must_stop + ") for:", current); }
|
|
242
|
+
setTimeout(async () => {
|
|
243
|
+
if (this.log) { console.log("callback(" + must_stop + ") after delay", current); }
|
|
244
|
+
callback(must_stop);
|
|
245
|
+
}, delay);
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
// console.log("invalid delay.")
|
|
249
|
+
callback(must_stop);
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
async lockUnlock(action, callback) {
|
|
256
|
+
let lockedAction = await this.chatbot.currentLockedAction(this.requestId);
|
|
257
|
+
// console.log("(DirReplyV2) lockedAction:", lockedAction);
|
|
258
|
+
if (!lockedAction) {
|
|
259
|
+
// console.log("(DirReplyV2) !lockedAction");
|
|
260
|
+
const intent_name = this.reply.attributes.intent_info.intent_name
|
|
261
|
+
const actionId = action["_tdActionId"];
|
|
262
|
+
// console.log("(DirReplyV2) intent_name:", intent_name);
|
|
263
|
+
// console.log("(DirReplyV2) actionId:", actionId);
|
|
264
|
+
await this.chatbot.lockIntent(this.requestId, intent_name);
|
|
265
|
+
// console.log("(DirReplyV2) lockIntent");
|
|
266
|
+
await this.chatbot.lockAction(this.requestId, actionId);
|
|
267
|
+
// console.log("(DirReplyV2) lockAction");
|
|
268
|
+
let _lockedAction = await this.chatbot.currentLockedAction(this.requestId);
|
|
269
|
+
let _lockedIntent = await this.chatbot.currentLockedIntent(this.requestId);
|
|
270
|
+
// console.log("(DirReplyV2) _lockedAction", _lockedAction);
|
|
271
|
+
// console.log("(DirReplyV2) _lockedIntent", _lockedIntent);
|
|
272
|
+
// callback();
|
|
273
|
+
return true;
|
|
274
|
+
} else {
|
|
275
|
+
try {
|
|
276
|
+
await this.chatbot.unlockIntent(this.requestId);
|
|
277
|
+
await this.chatbot.unlockAction(this.requestId);
|
|
278
|
+
// console.log("unlocked ReplyV2");
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
catch(e) {
|
|
282
|
+
console.error("Error", e);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
module.exports = { DirReplyV2 };
|
|
@@ -47,6 +47,7 @@ class Directives {
|
|
|
47
47
|
static SPEECH_FORM = 'speech_form';
|
|
48
48
|
static PLAY_PROMPT = 'play_prompt';
|
|
49
49
|
static GPT_ASSISTANT = 'gpt_assistant';
|
|
50
|
+
static REPLY_V2 = 'replyv2';
|
|
50
51
|
|
|
51
52
|
// static WHEN_ONLINE_MOVE_TO_AGENT = "whenonlinemovetoagent"; // DEPRECATED?
|
|
52
53
|
// static WHEN_OFFLINE_HOURS = "whenofflinehours"; // DEPRECATED // adds a message on top of the original message when offline hours opts: --replace
|