@tiledesk/tiledesk-tybot-connector 0.2.601-rc1 → 0.3.1
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 +387 -1
- package/ExtApi.js +6 -7
- package/Logger.js +74 -0
- package/TdCache.js +81 -176
- package/TdCache_v3.js +261 -0
- package/TiledeskExpression.js +7 -3
- package/TiledeskServices/AIService.js +43 -0
- package/TiledeskServices/utils.js +99 -0
- package/index.js +305 -50
- package/logs/app.log +279 -0
- package/models/IntentsMachineFactory.js +5 -2
- package/models/MockBotsDataSource.js +19 -11
- package/models/TiledeskChatbot.js +97 -79
- package/models/TiledeskChatbotConst.js +12 -17
- package/models/TiledeskChatbotUtil.js +359 -109
- package/models/TiledeskIntentsMachine.js +1 -1
- package/models/faqKbService.js +1 -1
- package/package.json +8 -6
- package/tiledeskChatbotPlugs/DirectivesChatbotPlug.js +172 -106
- package/tiledeskChatbotPlugs/Filler.js +13 -2
- package/tiledeskChatbotPlugs/TildeskContextForCodeOrchestrator.js +8 -0
- package/tiledeskChatbotPlugs/WebhookChatbotPlug.js +13 -7
- package/tiledeskChatbotPlugs/directives/DirAddTags.js +374 -0
- package/tiledeskChatbotPlugs/directives/DirAiPrompt.js +476 -0
- package/tiledeskChatbotPlugs/directives/DirAskGPT.js +16 -19
- package/tiledeskChatbotPlugs/directives/DirAskGPTV2.js +221 -34
- package/tiledeskChatbotPlugs/directives/DirAssign.js +0 -11
- package/tiledeskChatbotPlugs/directives/DirAssignFromFunction.js +11 -21
- package/tiledeskChatbotPlugs/directives/DirAssistant.js +728 -0
- package/tiledeskChatbotPlugs/directives/DirBrevo.js +353 -0
- package/tiledeskChatbotPlugs/directives/DirCaptureUserReply.js +3 -30
- package/tiledeskChatbotPlugs/directives/DirClearTranscript.js +22 -0
- package/tiledeskChatbotPlugs/directives/DirClose.js +16 -3
- package/tiledeskChatbotPlugs/directives/DirCode.js +1 -1
- package/tiledeskChatbotPlugs/directives/DirCondition.js +0 -26
- package/tiledeskChatbotPlugs/directives/DirConnectBlock.js +182 -0
- package/tiledeskChatbotPlugs/directives/DirContactUpdate.js +121 -0
- package/tiledeskChatbotPlugs/directives/DirCustomerio.js +5 -8
- package/tiledeskChatbotPlugs/directives/DirDeflectToHelpCenter.js +11 -1
- package/tiledeskChatbotPlugs/directives/DirDepartment.js +15 -6
- package/tiledeskChatbotPlugs/directives/DirFireTiledeskEvent.js +17 -6
- package/tiledeskChatbotPlugs/directives/DirForm.js +12 -2
- package/tiledeskChatbotPlugs/directives/DirGptTask.js +83 -38
- package/tiledeskChatbotPlugs/directives/DirGptTask_OLD.js +4 -7
- package/tiledeskChatbotPlugs/directives/DirHubspot.js +5 -8
- package/tiledeskChatbotPlugs/directives/DirIfOnlineAgents.js +14 -27
- package/tiledeskChatbotPlugs/directives/DirIfOnlineAgentsV2.js +278 -0
- package/tiledeskChatbotPlugs/directives/DirIfOpenHours.js +147 -51
- package/tiledeskChatbotPlugs/directives/DirIfOpenHours_OLD.js +125 -0
- package/tiledeskChatbotPlugs/directives/DirIntent.js +8 -37
- package/tiledeskChatbotPlugs/directives/DirJSONCondition.js +5 -26
- package/tiledeskChatbotPlugs/directives/DirMessage.js +19 -17
- package/tiledeskChatbotPlugs/directives/DirMessageToBot.js +135 -0
- package/tiledeskChatbotPlugs/directives/DirMoveToAgent.js +20 -87
- package/tiledeskChatbotPlugs/directives/DirMoveToUnassigned.js +59 -0
- package/tiledeskChatbotPlugs/directives/DirQapla.js +6 -9
- package/tiledeskChatbotPlugs/directives/DirRandomReply.js +17 -7
- package/tiledeskChatbotPlugs/directives/DirRemoveCurrentBot.js +17 -7
- package/tiledeskChatbotPlugs/directives/DirReplaceBot.js +11 -2
- package/tiledeskChatbotPlugs/directives/DirReplaceBotV2.js +135 -21
- package/tiledeskChatbotPlugs/directives/DirReplaceBotV3.js +163 -0
- package/tiledeskChatbotPlugs/directives/DirReply.js +53 -9
- package/tiledeskChatbotPlugs/directives/DirReplyV2.js +347 -0
- package/tiledeskChatbotPlugs/directives/DirSendEmail.js +13 -23
- package/tiledeskChatbotPlugs/directives/DirSendWhatsapp.js +247 -0
- package/tiledeskChatbotPlugs/directives/DirSetAttributeV2.js +202 -15
- package/tiledeskChatbotPlugs/directives/DirSetConversationTags.js +13 -4
- package/tiledeskChatbotPlugs/directives/DirWait.js +21 -4
- package/tiledeskChatbotPlugs/directives/DirWebRequest.js +1 -2
- package/tiledeskChatbotPlugs/directives/DirWebRequestV2.js +166 -103
- package/tiledeskChatbotPlugs/directives/DirWhatsappByAttribute.js +2 -60
- package/tiledeskChatbotPlugs/directives/Directives.js +16 -1
- /package/tiledeskChatbotPlugs/directives/{DirOfflineHours.js → DEPRECATED_DirOfflineHours.js} +0 -0
|
@@ -0,0 +1,347 @@
|
|
|
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
|
+
// const { defaultOptions } = require('liquidjs');
|
|
7
|
+
const { DirMessageToBot } = require('./DirMessageToBot');
|
|
8
|
+
const { v4: uuidv4 } = require('uuid');
|
|
9
|
+
const { TiledeskClient } = require('@tiledesk/tiledesk-client');
|
|
10
|
+
|
|
11
|
+
class DirReplyV2 {
|
|
12
|
+
|
|
13
|
+
constructor(context) {
|
|
14
|
+
if (!context) {
|
|
15
|
+
throw new Error('context object is mandatory.');
|
|
16
|
+
}
|
|
17
|
+
this.context = context;
|
|
18
|
+
this.projectId = context.projectId;
|
|
19
|
+
this.requestId = context.requestId;
|
|
20
|
+
this.token = context.token;
|
|
21
|
+
this.tdcache = context.tdcache;
|
|
22
|
+
this.log = context.log;
|
|
23
|
+
this.intentDir = new DirIntent(context);
|
|
24
|
+
this.chatbot = context.chatbot;
|
|
25
|
+
this.reply = context.reply;
|
|
26
|
+
this.originalMessage = context.message;
|
|
27
|
+
|
|
28
|
+
this.API_ENDPOINT = context.API_ENDPOINT;
|
|
29
|
+
this.tdClient = new TiledeskClient({
|
|
30
|
+
projectId: this.context.projectId,
|
|
31
|
+
token: this.context.token,
|
|
32
|
+
APIURL: this.API_ENDPOINT,
|
|
33
|
+
APIKEY: "___",
|
|
34
|
+
log: this.log
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
execute(directive, callback) {
|
|
39
|
+
let action;
|
|
40
|
+
if (directive.action) {
|
|
41
|
+
action = directive.action;
|
|
42
|
+
if (!action.attributes) {
|
|
43
|
+
action.attributes = {}
|
|
44
|
+
}
|
|
45
|
+
action.attributes.fillParams = true;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
console.error("Incorrect directive (no action provided):", directive);
|
|
49
|
+
callback();
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
this.go(action, (stop) => {
|
|
53
|
+
callback(stop);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async go(action, callback) {
|
|
58
|
+
if (this.log) { console.log("ReplyV2 action!", JSON.stringify(action)); }
|
|
59
|
+
const message = action;
|
|
60
|
+
|
|
61
|
+
let current; // debug only
|
|
62
|
+
if (this.log) {
|
|
63
|
+
if (message.attributes.commands[1].message.text) {
|
|
64
|
+
current = message.attributes.commands[1].message.text
|
|
65
|
+
}
|
|
66
|
+
console.log("current:", current);
|
|
67
|
+
}
|
|
68
|
+
let must_stop = false;
|
|
69
|
+
// fill
|
|
70
|
+
let requestAttributes = null;
|
|
71
|
+
if (this.tdcache) {
|
|
72
|
+
requestAttributes =
|
|
73
|
+
await TiledeskChatbot.allParametersStatic(
|
|
74
|
+
this.tdcache, this.requestId
|
|
75
|
+
);
|
|
76
|
+
if (this.log) {
|
|
77
|
+
for (const [key, value] of Object.entries(requestAttributes)) {
|
|
78
|
+
const value_type = typeof value;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
try {
|
|
83
|
+
// lock/unlock + no-match
|
|
84
|
+
// get buttons if available
|
|
85
|
+
const buttons = TiledeskChatbotUtil.allReplyButtons(message);
|
|
86
|
+
if (this.log) { console.log("Action Buttons:", JSON.stringify(buttons)); }
|
|
87
|
+
if (buttons && buttons.length > 0) {
|
|
88
|
+
const locked = await this.lockUnlock(action); // first execution returns locked, then unlocked
|
|
89
|
+
if (locked) { // fist execution returns (just) locked
|
|
90
|
+
if (this.log) { console.log("first time pass!"); }
|
|
91
|
+
must_stop = true; // you must stop after next callbacks (in this flow) if there are buttons
|
|
92
|
+
// console.log("action:", action);
|
|
93
|
+
if (action.noInputIntent) {
|
|
94
|
+
if (this.log) { console.log("NoInputIntent found:", action.noInputIntent); }
|
|
95
|
+
const noInputIntent = action.noInputIntent;
|
|
96
|
+
const noInputTimeout = action.noInputTimeout;
|
|
97
|
+
if (this.log) { console.log("noInputTimeout found:", noInputTimeout); }
|
|
98
|
+
if (noInputTimeout > 0 && noInputTimeout < 7776000) {
|
|
99
|
+
const timeout_id = uuidv4();
|
|
100
|
+
await this.chatbot.addParameter(TiledeskChatbotConst.USER_INPUT, timeout_id); // control variable. On each user input is removed
|
|
101
|
+
if (this.log) { console.log("Set userInput: false, checking...", await this.chatbot.getParameter(TiledeskChatbotConst.USER_INPUT)); }
|
|
102
|
+
setTimeout(async () => {
|
|
103
|
+
if (this.log) { console.log("noinput timeout triggered!"); }
|
|
104
|
+
const userInput = await this.chatbot.getParameter(TiledeskChatbotConst.USER_INPUT);
|
|
105
|
+
if (this.log) { console.log("got 'userInput':", userInput); }
|
|
106
|
+
if (userInput && userInput === timeout_id) {
|
|
107
|
+
if (this.log) { console.log("no 'userInput'. Executing noinput action:", noInputIntent); }
|
|
108
|
+
await this.chatbot.unlockIntent(this.requestId);
|
|
109
|
+
await this.chatbot.unlockAction(this.requestId);
|
|
110
|
+
if (this.log) { console.log("unlocked (for noInput) ReplyV2"); }
|
|
111
|
+
let noinput_action = DirIntent.intentDirectiveFor(noInputIntent, null);
|
|
112
|
+
this.intentDir.execute(noinput_action, () => {
|
|
113
|
+
if (this.log) { console.log("noinput action invoked", noinput_action); }
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
if (this.log) { console.log("skipping noinput action because of userInput", userInput); }
|
|
118
|
+
}
|
|
119
|
+
}, noInputTimeout);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
else { // second execution
|
|
124
|
+
if (this.log) { console.log("second pass! unlocked!"); }
|
|
125
|
+
const last_user_text = await this.chatbot.getParameter(TiledeskChatbotConst.REQ_LAST_USER_TEXT_v2_KEY);
|
|
126
|
+
if (this.log) { console.log("got last user text"); }
|
|
127
|
+
const button = TiledeskChatbotUtil.buttonByText(last_user_text, buttons);
|
|
128
|
+
if (this.log) { console.log("button found", JSON.stringify(button)); }
|
|
129
|
+
// invoke button
|
|
130
|
+
if (button && button.action) {
|
|
131
|
+
if (this.log) { console.log("moving to button action", button.action); }
|
|
132
|
+
let button_action = DirIntent.intentDirectiveFor(button.action, null);
|
|
133
|
+
if (this.log) { console.log("action with .intentName:", button_action); }
|
|
134
|
+
this.intentDir.execute(button_action, () => {
|
|
135
|
+
if (this.log) { console.log("action invoked", button_action); }
|
|
136
|
+
});
|
|
137
|
+
if (this.log) { console.log("callback(true) + return", current); }
|
|
138
|
+
callback(true); // must_stop = true
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
else { // no match (treating text buttons as no-match for the moment)
|
|
142
|
+
// if noMatchIntent invoke
|
|
143
|
+
// const button = TiledeskChatbotUtil.buttonByText("nomatch", buttons);
|
|
144
|
+
if (this.log) { console.log("nomatch button found", JSON.stringify(button)); }
|
|
145
|
+
// // invoke button
|
|
146
|
+
// if (button && button.action) {
|
|
147
|
+
// console.log("moving to nomatch action", button.action);
|
|
148
|
+
// let button_action = DirIntent.intentDirectiveFor(button.action, null);
|
|
149
|
+
// this.intentDir.execute(button_action, () => {
|
|
150
|
+
// console.log("nomatch action invoked", button_action);
|
|
151
|
+
// });
|
|
152
|
+
// console.log("callback(true) + return 2", current);
|
|
153
|
+
// callback(true);
|
|
154
|
+
// return;
|
|
155
|
+
// }
|
|
156
|
+
if (action.noMatchIntent) {
|
|
157
|
+
if (this.log) { console.log("moving to nomatch action", action.noMatchIntent); }
|
|
158
|
+
let nomatch_action = DirIntent.intentDirectiveFor(action.noMatchIntent, null);
|
|
159
|
+
this.intentDir.execute(nomatch_action, () => {
|
|
160
|
+
if (this.log) { console.log("nomatch action invoked", nomatch_action); }
|
|
161
|
+
});
|
|
162
|
+
if (this.log) { console.log("callback(true) + return no-match", current); }
|
|
163
|
+
callback(true); // must_stop = true
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
// const defaultFallbackAction = { action: { intentName: "defaultFallback" } };
|
|
168
|
+
|
|
169
|
+
// console.log("re-send original message:",JSON.stringify(this.originalMessage));
|
|
170
|
+
const messageDir = new DirMessageToBot(this.context);
|
|
171
|
+
messageDir.execute( { action: { message: this.originalMessage } }, () => {
|
|
172
|
+
if (this.log) { console.log("messageDir invoked"); }
|
|
173
|
+
});
|
|
174
|
+
if (this.log) { console.log("callback(true) + return no-match", current); }
|
|
175
|
+
callback(true); // must_stop = true
|
|
176
|
+
return;
|
|
177
|
+
|
|
178
|
+
// const textAction = { action: { text: last_user_text } };
|
|
179
|
+
// console.log("textAction invoked:",textAction ); //, defaultFallbackAction);
|
|
180
|
+
// this.intentDir.execute( textAction, () => {
|
|
181
|
+
// if (this.log) { console.log("textAction invoked", textAction); }
|
|
182
|
+
// });
|
|
183
|
+
// if (this.log) { console.log("callback(true) + return no-match", current); }
|
|
184
|
+
// callback(true); // must_stop = true
|
|
185
|
+
// return;
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
// // there is no "no-match", go on...
|
|
189
|
+
// if (this.log) { console.log("callback(false) + return 3", current); }
|
|
190
|
+
// callback(false);
|
|
191
|
+
// return;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
catch(error) {
|
|
198
|
+
console.error("Error in DirReplyV2:", error);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
if (this.log) { console.log("proceding normally to render and send the reply", current); }
|
|
203
|
+
const filler = new Filler();
|
|
204
|
+
// fill text attribute
|
|
205
|
+
message.text = filler.fill(message.text, requestAttributes);
|
|
206
|
+
if (message.metadata) {
|
|
207
|
+
if (this.log) {console.log("filling message 'metadata':", JSON.stringify(message.metadata));}
|
|
208
|
+
if (message.metadata.src) {
|
|
209
|
+
message.metadata.src = filler.fill(message.metadata.src, requestAttributes);
|
|
210
|
+
}
|
|
211
|
+
if (message.metadata.name) {
|
|
212
|
+
message.metadata.name = filler.fill(message.metadata.name, requestAttributes);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (this.log) {console.log("filling commands'. Message:", JSON.stringify(message));}
|
|
216
|
+
if (message.attributes && message.attributes.commands) {
|
|
217
|
+
if (this.log) {console.log("filling commands'. commands found.");}
|
|
218
|
+
let commands = message.attributes.commands;
|
|
219
|
+
if (this.log) {console.log("commands:", JSON.stringify(commands), commands.length);}
|
|
220
|
+
if (commands.length > 0) {
|
|
221
|
+
if (this.log) {console.log("commands' found");}
|
|
222
|
+
for (let i = 0; i < commands.length; i++) {
|
|
223
|
+
let command = commands[i];
|
|
224
|
+
if (command.type === 'message' && command.message && command.message.text) {
|
|
225
|
+
command.message.text = filler.fill(command.message.text, requestAttributes);
|
|
226
|
+
TiledeskChatbotUtil.fillCommandAttachments(command, requestAttributes, this.log);
|
|
227
|
+
if (this.log) {console.log("command filled:", command.message.text);}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// EVALUATE EXPRESSION AND REMOVE BASED ON EVALUATION
|
|
234
|
+
if (this.log) {console.log("message before filters:", JSON.stringify(message));}
|
|
235
|
+
if (message.attributes && message.attributes.commands) {
|
|
236
|
+
if (this.log) {console.log("filterOnVariables...on commands", JSON.stringify(message.attributes.commands));}
|
|
237
|
+
if (this.log) {console.log("filterOnVariables...on attributes", requestAttributes);}
|
|
238
|
+
// TiledeskChatbotUtil.filterOnVariables(message.attributes.commands, requestAttributes);
|
|
239
|
+
TiledeskChatbotUtil.filterOnVariables(message, requestAttributes);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// temporary send back of reserved attributes
|
|
243
|
+
if (!message.attributes) {
|
|
244
|
+
message.attributes = {}
|
|
245
|
+
}
|
|
246
|
+
// Reserved names: userEmail, userFullname
|
|
247
|
+
// if (requestAttributes['userEmail']) {
|
|
248
|
+
// message.attributes.updateUserEmail = requestAttributes['userEmail'];
|
|
249
|
+
// }
|
|
250
|
+
// if (requestAttributes['userFullname']) {
|
|
251
|
+
// message.attributes.updateUserFullname = requestAttributes['userFullname'];
|
|
252
|
+
// }
|
|
253
|
+
// intent_info
|
|
254
|
+
if (this.context.reply && this.context.reply.attributes && this.context.reply.attributes.intent_info) {
|
|
255
|
+
message.attributes.intentName = this.context.reply.attributes.intent_info.intent_name;
|
|
256
|
+
}
|
|
257
|
+
// userFlowAttributes
|
|
258
|
+
let userFlowAttributes = TiledeskChatbotUtil.userFlowAttributes(requestAttributes);
|
|
259
|
+
if (this.log) { console.log("userFlowAttributes:", userFlowAttributes); }
|
|
260
|
+
if (userFlowAttributes) {
|
|
261
|
+
message.attributes["flowAttributes"] = {};
|
|
262
|
+
for (const [key, value] of Object.entries(userFlowAttributes)) {
|
|
263
|
+
try {
|
|
264
|
+
if(typeof value === 'string' && value.length <= 1000){
|
|
265
|
+
message.attributes["flowAttributes"][key] = value;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
catch(err) {
|
|
269
|
+
console.error("An error occurred while JSON.parse(). Parsed value:" + value + " in allParametersStatic(). Error:", err);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
}
|
|
275
|
+
// send!
|
|
276
|
+
let cleanMessage = message;
|
|
277
|
+
// cleanMessage = TiledeskChatbotUtil.removeEmptyReplyCommands(message);
|
|
278
|
+
// if (!TiledeskChatbotUtil.isValidReply(cleanMessage)) {
|
|
279
|
+
// console.log("invalid message", cleanMessage);
|
|
280
|
+
// callback(); // cancel reply operation
|
|
281
|
+
// return;
|
|
282
|
+
// }
|
|
283
|
+
// console.log("valid message!", cleanMessage);
|
|
284
|
+
cleanMessage.senderFullname = this.context.chatbot.bot.name;
|
|
285
|
+
if (this.log) {console.log("Reply:", JSON.stringify(cleanMessage))};
|
|
286
|
+
await TiledeskChatbotUtil.updateConversationTranscript(this.context.chatbot, cleanMessage);
|
|
287
|
+
this.tdClient.sendSupportMessage(
|
|
288
|
+
this.requestId,
|
|
289
|
+
cleanMessage,
|
|
290
|
+
(err) => {
|
|
291
|
+
if (err) {
|
|
292
|
+
console.error("Error sending reply:", err);
|
|
293
|
+
}
|
|
294
|
+
if (this.log) {console.log("Reply message sent");}
|
|
295
|
+
const delay = TiledeskChatbotUtil.totalMessageWait(cleanMessage);
|
|
296
|
+
// console.log("got total delay:", delay)
|
|
297
|
+
if (delay > 0 && delay <= 30000) { // prevent long delays
|
|
298
|
+
if (this.log) { console.log("start timeout callback(" + must_stop + ") for:", current); }
|
|
299
|
+
setTimeout(async () => {
|
|
300
|
+
if (this.log) { console.log("callback(" + must_stop + ") after delay", current); }
|
|
301
|
+
callback(must_stop);
|
|
302
|
+
}, delay);
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
// console.log("invalid delay.")
|
|
306
|
+
callback(must_stop);
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
async lockUnlock(action, callback) {
|
|
314
|
+
let lockedAction = await this.chatbot.currentLockedAction(this.requestId);
|
|
315
|
+
// console.log("(DirReplyV2) lockedAction:", lockedAction);
|
|
316
|
+
if (!lockedAction) {
|
|
317
|
+
// console.log("(DirReplyV2) !lockedAction");
|
|
318
|
+
const intent_name = this.reply.attributes.intent_info.intent_name
|
|
319
|
+
const actionId = action["_tdActionId"];
|
|
320
|
+
// console.log("(DirReplyV2) intent_name:", intent_name);
|
|
321
|
+
// console.log("(DirReplyV2) actionId:", actionId);
|
|
322
|
+
await this.chatbot.lockIntent(this.requestId, intent_name);
|
|
323
|
+
// console.log("(DirReplyV2) lockIntent");
|
|
324
|
+
await this.chatbot.lockAction(this.requestId, actionId);
|
|
325
|
+
// console.log("(DirReplyV2) lockAction");
|
|
326
|
+
let _lockedAction = await this.chatbot.currentLockedAction(this.requestId);
|
|
327
|
+
let _lockedIntent = await this.chatbot.currentLockedIntent(this.requestId);
|
|
328
|
+
// console.log("(DirReplyV2) _lockedAction", _lockedAction);
|
|
329
|
+
// console.log("(DirReplyV2) _lockedIntent", _lockedIntent);
|
|
330
|
+
// callback();
|
|
331
|
+
return true;
|
|
332
|
+
} else {
|
|
333
|
+
try {
|
|
334
|
+
await this.chatbot.unlockIntent(this.requestId);
|
|
335
|
+
await this.chatbot.unlockAction(this.requestId);
|
|
336
|
+
// console.log("unlocked ReplyV2");
|
|
337
|
+
return false;
|
|
338
|
+
}
|
|
339
|
+
catch(e) {
|
|
340
|
+
console.error("Error", e);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
module.exports = { DirReplyV2 };
|
|
@@ -2,6 +2,7 @@ const { param } = require('express/lib/request');
|
|
|
2
2
|
const ms = require('minimist-string');
|
|
3
3
|
const { TiledeskChatbot } = require('../../models/TiledeskChatbot');
|
|
4
4
|
const { Filler } = require('../Filler');
|
|
5
|
+
const { TiledeskClient } = require('@tiledesk/tiledesk-client');
|
|
5
6
|
// const { TiledeskClient } = require('@tiledesk/tiledesk-client');
|
|
6
7
|
|
|
7
8
|
class DirSendEmail {
|
|
@@ -11,29 +12,18 @@ class DirSendEmail {
|
|
|
11
12
|
throw new Error('context object is mandatory.');
|
|
12
13
|
}
|
|
13
14
|
this.context = context;
|
|
14
|
-
this.tdclient = context.tdclient;
|
|
15
15
|
this.tdcache = context.tdcache;
|
|
16
16
|
this.requestId = context.requestId;
|
|
17
|
-
this.log = context.log;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
// log: false
|
|
28
|
-
// }
|
|
29
|
-
// this.tdclient = new TiledeskClient({
|
|
30
|
-
// projectId: context.projectId,
|
|
31
|
-
// token: context.token,
|
|
32
|
-
// APIURL: context.TILEDESK_APIURL,
|
|
33
|
-
// APIKEY: "___",
|
|
34
|
-
// log: context.log
|
|
35
|
-
// });
|
|
36
|
-
|
|
17
|
+
this.log = context.log;
|
|
18
|
+
|
|
19
|
+
this.API_ENDPOINT = context.API_ENDPOINT;
|
|
20
|
+
this.tdClient = new TiledeskClient({
|
|
21
|
+
projectId: this.context.projectId,
|
|
22
|
+
token: this.context.token,
|
|
23
|
+
APIURL: this.API_ENDPOINT,
|
|
24
|
+
APIKEY: "___",
|
|
25
|
+
log: this.log
|
|
26
|
+
});
|
|
37
27
|
}
|
|
38
28
|
|
|
39
29
|
execute(directive, callback) {
|
|
@@ -82,8 +72,8 @@ class DirSendEmail {
|
|
|
82
72
|
to: filled_to,
|
|
83
73
|
replyto: reply_to
|
|
84
74
|
}
|
|
85
|
-
console.log("email message:", JSON.stringify(message));
|
|
86
|
-
const message_echo = await this.
|
|
75
|
+
// console.log("email message:", JSON.stringify(message));
|
|
76
|
+
const message_echo = await this.tdClient.sendEmail(message);
|
|
87
77
|
if (this.log) {console.log("email sent. filled_subject:", filled_subject);}
|
|
88
78
|
if (this.log) {console.log("email sent. filled_text:", filled_text);}
|
|
89
79
|
if (this.log) {console.log("email sent. filled_to:", filled_to);}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
const axios = require("axios").default;
|
|
2
|
+
const { TiledeskChatbot } = require('../../models/TiledeskChatbot');
|
|
3
|
+
const { Filler } = require("../Filler");
|
|
4
|
+
const { DirIntent } = require("./DirIntent");
|
|
5
|
+
|
|
6
|
+
let whatsapp_api_url;
|
|
7
|
+
|
|
8
|
+
class DirSendWhatsapp {
|
|
9
|
+
|
|
10
|
+
constructor(context) {
|
|
11
|
+
if (!context) {
|
|
12
|
+
throw new Error('context object is mandatory');
|
|
13
|
+
}
|
|
14
|
+
this.context = context;
|
|
15
|
+
this.chatbot = context.chatbot;
|
|
16
|
+
this.tdcache = this.context.tdcache;
|
|
17
|
+
this.requestId = this.context.requestId;
|
|
18
|
+
this.intentDir = new DirIntent(context);
|
|
19
|
+
this.API_ENDPOINT = this.context.API_ENDPOINT;
|
|
20
|
+
this.log = context.log;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
execute(directive, callback) {
|
|
24
|
+
if (this.log) { console.log("DirWhatsappStatic directive: ", directive); }
|
|
25
|
+
let action;
|
|
26
|
+
if (directive.action) {
|
|
27
|
+
action = directive.action;
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
console.error("Incorrect directive: ", JSON.stringify(directive));
|
|
31
|
+
callback();
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
this.go(action, (stop) => {
|
|
35
|
+
callback(stop);
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async go(action, callback) {
|
|
40
|
+
|
|
41
|
+
if (this.log) { console.log("DirWhatsappStatic action: ", JSON.stringify(action)) }
|
|
42
|
+
if (!this.tdcache) {
|
|
43
|
+
console.error("Error: DirAskGPT tdcache is mandatory");
|
|
44
|
+
callback();
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let trueIntent = action.trueIntent;
|
|
49
|
+
let falseIntent = action.falseIntent;
|
|
50
|
+
|
|
51
|
+
let requestVariables = null;
|
|
52
|
+
requestVariables =
|
|
53
|
+
await TiledeskChatbot.allParametersStatic(
|
|
54
|
+
this.tdcache, this.requestId
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
// Declarations
|
|
58
|
+
let payload = action.payload;
|
|
59
|
+
|
|
60
|
+
const filler = new Filler();
|
|
61
|
+
|
|
62
|
+
// receiver_list will be of just one element, so we can pick up only the first element, if exists.
|
|
63
|
+
let receiver = payload.receiver_list[0];
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
//header_params: text, image, document. NO: location
|
|
67
|
+
//body_params: text
|
|
68
|
+
//button_params: text
|
|
69
|
+
//footer_paramas: non supportati
|
|
70
|
+
|
|
71
|
+
receiver = await this.fillWholeReceiver(receiver, requestVariables);
|
|
72
|
+
payload.receiver_list[0] = receiver;
|
|
73
|
+
payload.transaction_id = this.context.requestId;
|
|
74
|
+
payload.broadcast = false;
|
|
75
|
+
|
|
76
|
+
const whatsapp_api_url_pre = process.env.WHATSAPP_ENDPOINT;
|
|
77
|
+
|
|
78
|
+
if (whatsapp_api_url_pre) {
|
|
79
|
+
whatsapp_api_url = whatsapp_api_url_pre;
|
|
80
|
+
} else {
|
|
81
|
+
whatsapp_api_url = this.API_ENDPOINT + "/modules/whatsapp/api"
|
|
82
|
+
}
|
|
83
|
+
if (this.log) { console.log("DirSendWhatsapp whatsapp_api_url: ", whatsapp_api_url); };
|
|
84
|
+
|
|
85
|
+
const HTTPREQUEST = {
|
|
86
|
+
url: whatsapp_api_url + "/tiledesk/broadcast",
|
|
87
|
+
headers: {
|
|
88
|
+
'Content-Type': 'application/json'
|
|
89
|
+
},
|
|
90
|
+
json: payload,
|
|
91
|
+
method: 'POST'
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (this.log) { console.log("DirSendWhatsapp HTTPREQUEST: ", HTTPREQUEST); }
|
|
95
|
+
|
|
96
|
+
this.#myrequest(
|
|
97
|
+
HTTPREQUEST, async (err, resbody) => {
|
|
98
|
+
if (err) {
|
|
99
|
+
console.error("DirSendWhatsapp error: ", err);
|
|
100
|
+
await this.chatbot.addParameter("flowError", "SendWhatsapp Error: " + err);
|
|
101
|
+
if (callback) {
|
|
102
|
+
if (falseIntent) {
|
|
103
|
+
await this.#executeCondition(false, trueIntent, null, falseIntent, null);
|
|
104
|
+
callback(true);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
callback();
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
} else if (resbody.success === true) {
|
|
111
|
+
if (callback) {
|
|
112
|
+
if (trueIntent) {
|
|
113
|
+
await this.#executeCondition(true, trueIntent, null, falseIntent, null);
|
|
114
|
+
callback(true);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
callback();
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
} else {
|
|
121
|
+
if (this.log) { console.log("DirSendWhatsapp unexpected resbody: ", resbody); }
|
|
122
|
+
if (callback) {
|
|
123
|
+
if (falseIntent) {
|
|
124
|
+
await this.#executeCondition(false, trueIntent, null, falseIntent, null);
|
|
125
|
+
callback(true);
|
|
126
|
+
return
|
|
127
|
+
}
|
|
128
|
+
callback();
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async #executeCondition(result, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes, callback) {
|
|
137
|
+
let trueIntentDirective = null;
|
|
138
|
+
if (trueIntent) {
|
|
139
|
+
trueIntentDirective = DirIntent.intentDirectiveFor(trueIntent, trueIntentAttributes);
|
|
140
|
+
}
|
|
141
|
+
let falseIntentDirective = null;
|
|
142
|
+
if (falseIntent) {
|
|
143
|
+
falseIntentDirective = DirIntent.intentDirectiveFor(falseIntent, falseIntentAttributes);
|
|
144
|
+
}
|
|
145
|
+
if (result === true) {
|
|
146
|
+
if (trueIntentDirective) {
|
|
147
|
+
this.intentDir.execute(trueIntentDirective, () => {
|
|
148
|
+
if (callback) {
|
|
149
|
+
callback();
|
|
150
|
+
}
|
|
151
|
+
})
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
if (this.log) { console.log("No trueIntentDirective specified"); }
|
|
155
|
+
if (callback) {
|
|
156
|
+
callback();
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
if (falseIntentDirective) {
|
|
162
|
+
this.intentDir.execute(falseIntentDirective, () => {
|
|
163
|
+
if (callback) {
|
|
164
|
+
callback();
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
if (this.log) { console.log("No falseIntentDirective specified"); }
|
|
170
|
+
if (callback) {
|
|
171
|
+
callback();
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
async fillWholeReceiver(receiver, requestVariables) {
|
|
178
|
+
return new Promise((resolve) => {
|
|
179
|
+
|
|
180
|
+
const filler = new Filler();
|
|
181
|
+
try {
|
|
182
|
+
receiver.phone_number = filler.fill(receiver.phone_number, requestVariables);
|
|
183
|
+
if (receiver.header_params) {
|
|
184
|
+
receiver.header_params.forEach(p => {
|
|
185
|
+
if (p.type === 'TEXT') {
|
|
186
|
+
p.text = filler.fill(p.text, requestVariables)
|
|
187
|
+
}
|
|
188
|
+
else if (p.type === 'IMAGE') {
|
|
189
|
+
p.image.link = filler.fill(p.image.link, requestVariables)
|
|
190
|
+
}
|
|
191
|
+
else if (p.type === 'DOCUMENT') {
|
|
192
|
+
p.document.link = filler.fill(p.document.link, requestVariables)
|
|
193
|
+
}
|
|
194
|
+
})
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (receiver.body_params) {
|
|
198
|
+
receiver.body_params.forEach(p => {
|
|
199
|
+
p.text = filler.fill(p.text, requestVariables)
|
|
200
|
+
})
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (receiver.buttons_params) {
|
|
204
|
+
receiver.buttons_params.forEach(p => {
|
|
205
|
+
p.text = filler.fill(p.text, requestVariables)
|
|
206
|
+
})
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
resolve(receiver);
|
|
210
|
+
|
|
211
|
+
} catch(err) {
|
|
212
|
+
console.error("DirSendWhatsapp fillWholeReceiver error: ", err)
|
|
213
|
+
resolve(null);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
})
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// HTTP REQUEST
|
|
220
|
+
async #myrequest(options, callback, log) {
|
|
221
|
+
return await axios({
|
|
222
|
+
url: options.url,
|
|
223
|
+
method: options.method,
|
|
224
|
+
data: options.json,
|
|
225
|
+
params: options.params,
|
|
226
|
+
headers: options.headers
|
|
227
|
+
}).then((res) => {
|
|
228
|
+
if (res && res.status == 200 && res.data) {
|
|
229
|
+
if (callback) {
|
|
230
|
+
callback(null, res.data);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
if (callback) {
|
|
235
|
+
callback(TiledeskClient.getErr({ message: "Response status not 200" }, options, res), null, null);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}).catch((err) => {
|
|
239
|
+
console.error("(tybot request) An error occured: ", err);
|
|
240
|
+
if (callback) {
|
|
241
|
+
callback(err, null, null);
|
|
242
|
+
}
|
|
243
|
+
})
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
module.exports = { DirSendWhatsapp }
|