@tiledesk/tiledesk-tybot-connector 0.1.55 → 0.1.56
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 +5 -0
- package/TiledeskExpression.js +153 -17
- package/index.js +48 -3
- package/models/{IntentForm_no_prefill.js → DEPRECATED_IntentForm_no_prefill.js} +0 -0
- package/models/IntentForm.js +1 -1
- package/models/MockBotsDataSource.js +19 -0
- package/models/MongodbBotsDataSource.js +90 -3
- package/models/TiledeskChatbot.js +27 -14
- package/models/faqKbService.js +10 -6
- package/models/faq_kb.js +22 -1
- package/package.json +1 -1
- package/test/anomaly-detection-test.js +3 -3
- package/test/condition_json_to_expression_test.js +386 -0
- package/test/conversation-actions-test.js +3 -23
- package/test/conversation-form-test.js +3 -3
- package/test/var_splitter_test.js +70 -0
- package/tiledeskChatbotPlugs/DirectivesChatbotPlug.js +38 -6
- package/tiledeskChatbotPlugs/Filler.js +3 -2
- package/tiledeskChatbotPlugs/TiledeskVarSplitter.js +33 -0
- package/tiledeskChatbotPlugs/directives/DirAssign.js +0 -1
- package/tiledeskChatbotPlugs/directives/DirAssignFromFunction.js +0 -2
- package/tiledeskChatbotPlugs/directives/DirCondition.js +47 -39
- package/tiledeskChatbotPlugs/directives/DirDisableInputText.js +1 -0
- package/tiledeskChatbotPlugs/directives/DirIntent.js +5 -7
- package/tiledeskChatbotPlugs/directives/DirJSONCondition.js +142 -0
- package/tiledeskChatbotPlugs/directives/DirSetAttribute.js +66 -0
- package/tiledeskChatbotPlugs/directives/DirWebRequest.js +141 -0
- package/tiledeskChatbotPlugs/directives/Directives.js +10 -7
package/CHANGELOG.md
CHANGED
package/TiledeskExpression.js
CHANGED
|
@@ -5,33 +5,74 @@ class TiledeskExpression {
|
|
|
5
5
|
// check valid operators (only those in operators are allowed)
|
|
6
6
|
// check valid variable names /^[_0-9a-zA-Z\.]$/
|
|
7
7
|
|
|
8
|
-
static
|
|
9
|
-
"
|
|
10
|
-
|
|
8
|
+
static OPERATORS = {
|
|
9
|
+
"equalAsNumbers" : {
|
|
10
|
+
name: "equalAsNumbers",
|
|
11
|
+
applyPattern: "Number(#1) === Number(#2)"
|
|
11
12
|
},
|
|
12
|
-
"
|
|
13
|
-
|
|
13
|
+
"equalAsStrings" : {
|
|
14
|
+
name: "equalAsStrings",
|
|
15
|
+
applyPattern: "String(#1) === String(#2)"
|
|
14
16
|
},
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
+
"notEqualAsNumbers" : {
|
|
18
|
+
name: "notEqualAsNumbers",
|
|
19
|
+
applyPattern: "Number(#1) !== Number(#2)"
|
|
17
20
|
},
|
|
18
|
-
"
|
|
19
|
-
|
|
21
|
+
"notEqualAsStrings" : {
|
|
22
|
+
name: "notEqualAsStrings",
|
|
23
|
+
applyPattern: "String(#1) !== String(#2)"
|
|
20
24
|
},
|
|
21
|
-
"
|
|
22
|
-
|
|
25
|
+
"greaterThan" : {
|
|
26
|
+
name: "greaterThan",
|
|
27
|
+
applyPattern: "Number(#1) > Number(#2)"
|
|
28
|
+
},
|
|
29
|
+
"greaterThanOrEqual" : {
|
|
30
|
+
name: "greaterThanOrEqual",
|
|
31
|
+
applyPattern: "Number(#1) >= Number(#2)"
|
|
32
|
+
},
|
|
33
|
+
"lessThan" : {
|
|
34
|
+
name: "lessThan",
|
|
35
|
+
applyPattern: "Number(#1) < Number(#2)"
|
|
36
|
+
},
|
|
37
|
+
"lessThanOrEqual" : {
|
|
38
|
+
name: "lessThanOrEqual",
|
|
39
|
+
applyPattern: "Number(#1) <= Number(#2)"
|
|
40
|
+
},
|
|
41
|
+
"AND": {
|
|
42
|
+
name: "AND",
|
|
43
|
+
applyPattern: " && "
|
|
44
|
+
},
|
|
45
|
+
"OR": {
|
|
46
|
+
name: "OR",
|
|
47
|
+
applyPattern: " || "
|
|
23
48
|
},
|
|
24
49
|
"startsWith": {
|
|
25
|
-
|
|
50
|
+
name: "startsWith",
|
|
51
|
+
applyPattern: "String(#1).startsWith(String(#2))"
|
|
52
|
+
},
|
|
53
|
+
"startsWithIgnoreCase": {
|
|
54
|
+
name: "startsWithIgnoreCase",
|
|
55
|
+
applyPattern: "String(#1).toLowerCase().startsWith(String(#2).toLowerCase())"
|
|
26
56
|
},
|
|
27
57
|
"contains": {
|
|
28
|
-
|
|
58
|
+
name: "contains",
|
|
59
|
+
applyPattern: "#1.includes(#2)"
|
|
60
|
+
},
|
|
61
|
+
"containsIgnoreCase": {
|
|
62
|
+
name: "containsIgnoreCase",
|
|
63
|
+
applyPattern: "#1.toLowerCase().includes(#2.toLowerCase())"
|
|
29
64
|
},
|
|
30
65
|
"endsWith": {
|
|
31
|
-
|
|
66
|
+
name: "endsWith",
|
|
67
|
+
applyPattern: "#1.toLowerCase().endsWith(#2.toLowerCase())"
|
|
68
|
+
},
|
|
69
|
+
"isEmpty": {
|
|
70
|
+
name: "isEmpty",
|
|
71
|
+
applyPattern: "#1 === \"\""
|
|
32
72
|
},
|
|
33
73
|
"matches": {
|
|
34
|
-
|
|
74
|
+
name: "matches",
|
|
75
|
+
applyPattern: "#1.matches(/#2/)"
|
|
35
76
|
}
|
|
36
77
|
}
|
|
37
78
|
|
|
@@ -46,6 +87,12 @@ class TiledeskExpression {
|
|
|
46
87
|
return result;
|
|
47
88
|
}
|
|
48
89
|
|
|
90
|
+
// public
|
|
91
|
+
evaluateStaticExpression(expression) {
|
|
92
|
+
const result = new TiledeskExpression().evaluate(expression);
|
|
93
|
+
return result;
|
|
94
|
+
}
|
|
95
|
+
|
|
49
96
|
// private
|
|
50
97
|
// evaluate(expression, context) {
|
|
51
98
|
// let fn;
|
|
@@ -62,6 +109,8 @@ class TiledeskExpression {
|
|
|
62
109
|
// }
|
|
63
110
|
|
|
64
111
|
evaluate(expression, context) {
|
|
112
|
+
// console.log("evaluating:", expression)
|
|
113
|
+
// console.log("context:", context)
|
|
65
114
|
let res;
|
|
66
115
|
try {
|
|
67
116
|
const vm = new VM({
|
|
@@ -77,8 +126,95 @@ class TiledeskExpression {
|
|
|
77
126
|
return res;
|
|
78
127
|
}
|
|
79
128
|
|
|
80
|
-
|
|
81
|
-
|
|
129
|
+
static JSONConditionToExpression(condition, variables) {
|
|
130
|
+
// console.log("condition:", condition);
|
|
131
|
+
// console.log("condition.operand1:", condition.operand1);
|
|
132
|
+
// console.log("condition.operand2:", condition.operand2);
|
|
133
|
+
const operator_name = condition.operator;
|
|
134
|
+
const operator = TiledeskExpression.OPERATORS[operator_name];
|
|
135
|
+
// console.log("operator:", operator);
|
|
136
|
+
const applyPattern = operator.applyPattern;
|
|
137
|
+
// console.log("applyPattern:", applyPattern);
|
|
138
|
+
const operand1_s = TiledeskExpression.stringValueOperand(condition.operand1, variables);
|
|
139
|
+
// console.log("operand1_s:", operand1_s);
|
|
140
|
+
const operand2_s = TiledeskExpression.stringValueOperand(condition.operand2, variables);
|
|
141
|
+
// console.log("operand2_s:", operand2_s);
|
|
142
|
+
const expression =
|
|
143
|
+
applyPattern
|
|
144
|
+
.replace("#1", operand1_s)
|
|
145
|
+
.replace("#2", operand2_s);
|
|
146
|
+
return expression;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
static JSONGroupToExpression(group, variables) {
|
|
150
|
+
let conditions = group.conditions;
|
|
151
|
+
let group_expression = "";
|
|
152
|
+
// console.log("conditions:", conditions)
|
|
153
|
+
for(let i = 0; i < conditions.length; i++) {
|
|
154
|
+
let part = conditions[i];
|
|
155
|
+
if (part.type === "condition") {
|
|
156
|
+
let expression = TiledeskExpression.JSONConditionToExpression(part, variables);
|
|
157
|
+
group_expression += expression;
|
|
158
|
+
}
|
|
159
|
+
else if (part.type === "operator") {
|
|
160
|
+
const operator = TiledeskExpression.OPERATORS[part.operatorName];
|
|
161
|
+
group_expression += operator.applyPattern;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return "(" + group_expression + ")";
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
static JSONGroupsToExpression(groups, variables) {
|
|
168
|
+
let full_expression = "";
|
|
169
|
+
// console.log("groups:", groups)
|
|
170
|
+
for(let i = 0; i < groups.length; i++) {
|
|
171
|
+
let g = groups[i];
|
|
172
|
+
if (g.type === "expression") {
|
|
173
|
+
let group_expression = TiledeskExpression.JSONGroupToExpression(g, variables);
|
|
174
|
+
full_expression += group_expression;
|
|
175
|
+
}
|
|
176
|
+
else if (g.type === "operator") {
|
|
177
|
+
const operator = TiledeskExpression.OPERATORS[g.operatorName];
|
|
178
|
+
full_expression += operator.applyPattern;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return full_expression;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
static stringValueOperand(operand, variables) {
|
|
186
|
+
// return operand;
|
|
187
|
+
if (!operand) {
|
|
188
|
+
return TiledeskExpression.quotedString(""); //"\"\"";
|
|
189
|
+
}
|
|
190
|
+
else if (!variables) {
|
|
191
|
+
// return "\"" + JSON.stringify(operand) + "\"";
|
|
192
|
+
return TiledeskExpression.quotedString(operand);
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
// console.log("vars!", variables)
|
|
196
|
+
let _operand = operand.trim();
|
|
197
|
+
let operandAsString = TiledeskExpression.quotedString(operand); //"\"" + JSON.stringify(operand) + "\"";
|
|
198
|
+
if (_operand.startsWith("$")) {
|
|
199
|
+
// console.log("_operand with $", _operand);
|
|
200
|
+
let varName = _operand.replace(/\$/g, "");
|
|
201
|
+
// console.log("varName:", varName);
|
|
202
|
+
let value = variables[varName];
|
|
203
|
+
if (value) {
|
|
204
|
+
operandAsString = TiledeskExpression.quotedString(value); //'"' + JSON.stringify(value) + '"';
|
|
205
|
+
}
|
|
206
|
+
return operandAsString;
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
// return "\"" + JSON.stringify(operand) + "\"";
|
|
210
|
+
return TiledeskExpression.quotedString(operand);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
static quotedString(s) {
|
|
217
|
+
return JSON.stringify(s);
|
|
82
218
|
}
|
|
83
219
|
|
|
84
220
|
}
|
package/index.js
CHANGED
|
@@ -99,7 +99,9 @@ router.post('/ext/:botid', async (req, res) => {
|
|
|
99
99
|
// get the bot metadata
|
|
100
100
|
let bot = null;
|
|
101
101
|
try {
|
|
102
|
-
bot = await botsDS.getBotById(botId);
|
|
102
|
+
// bot = await botsDS.getBotById(botId);
|
|
103
|
+
// bot = await botById(botId, projectId, tdcache, botsDS);
|
|
104
|
+
bot = botsDS.getBotByIdCache(botId, tdcache);
|
|
103
105
|
}
|
|
104
106
|
catch(error) {
|
|
105
107
|
console.error("Error getting botId:", botId);
|
|
@@ -139,7 +141,8 @@ router.post('/ext/:botid', async (req, res) => {
|
|
|
139
141
|
projectId: projectId,
|
|
140
142
|
log: log
|
|
141
143
|
});
|
|
142
|
-
|
|
144
|
+
// console.log("log:", log)
|
|
145
|
+
// process.exit(1)
|
|
143
146
|
await updateRequestVariables(chatbot, message, projectId, requestId);
|
|
144
147
|
|
|
145
148
|
let reply = await chatbot.replyToMessage(message);
|
|
@@ -198,6 +201,35 @@ router.post('/ext/:botid', async (req, res) => {
|
|
|
198
201
|
|
|
199
202
|
});
|
|
200
203
|
|
|
204
|
+
// async function botById(botId, projectId, tdcache, botsDS) {
|
|
205
|
+
// let bot = null;
|
|
206
|
+
// // let botCacheKey = "cacheman:cachegoose-cache:" + projectId + ":faq_kbs:id:" + botId;
|
|
207
|
+
// let botCacheKey = "cacheman:cachegoose-cache:faq_kbs:id:" + botId;
|
|
208
|
+
// try {
|
|
209
|
+
// let _bot_as_string = await tdcache.get(botCacheKey);
|
|
210
|
+
// const value_type = typeof _bot_as_string;
|
|
211
|
+
// console.log("_bot_as_string found in chache:", _bot_as_string);
|
|
212
|
+
// console.log("value_type:", value_type);
|
|
213
|
+
// if (_bot_as_string) {
|
|
214
|
+
// bot = JSON.parse(_bot_as_string);
|
|
215
|
+
// console.log("got bot from cache:", JSON.stringify(bot));
|
|
216
|
+
// }
|
|
217
|
+
// else {
|
|
218
|
+
// console.log("bot not found, getting from datasource...");
|
|
219
|
+
// bot = await botsDS.getBotById(botId);
|
|
220
|
+
// console.log("bot found in datasource:", JSON.stringify(bot));
|
|
221
|
+
// await tdcache.set(botCacheKey, JSON.stringify(bot));
|
|
222
|
+
// // DEBUG CODE REMOVE
|
|
223
|
+
// let bot_ = await tdcache.get(botCacheKey);
|
|
224
|
+
// console.log("_bot_as_string from cache debug:", bot_)
|
|
225
|
+
// }
|
|
226
|
+
// }
|
|
227
|
+
// catch(err) {
|
|
228
|
+
// console.error("error getting bot by id:", err);
|
|
229
|
+
// }
|
|
230
|
+
// return bot;
|
|
231
|
+
// }
|
|
232
|
+
|
|
201
233
|
async function updateRequestVariables(chatbot, message, projectId, requestId) {
|
|
202
234
|
// update request context
|
|
203
235
|
const messageId = message._id;
|
|
@@ -440,9 +472,22 @@ router.get('/', (req, res) => {
|
|
|
440
472
|
res.send('Hello Tilebot!');
|
|
441
473
|
});
|
|
442
474
|
|
|
475
|
+
router.get('/test/webrequest/get/plain', async (req, res) => {
|
|
476
|
+
res.send("Application var");
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
router.post('/test/webrequest/post/plain', async (req, res) => {
|
|
480
|
+
console.log("/post/plain req.body:", req.body);
|
|
481
|
+
if (req && req.body && req.body.name) {
|
|
482
|
+
res.send("Your name is " + req.body.name);
|
|
483
|
+
}
|
|
484
|
+
else {
|
|
485
|
+
res.send("No HTTP POST provided");
|
|
486
|
+
}
|
|
487
|
+
});
|
|
488
|
+
|
|
443
489
|
async function startApp(settings, completionCallback) {
|
|
444
490
|
// console.log("Starting Tilebot with Settings:", settings);
|
|
445
|
-
|
|
446
491
|
if (settings.bots) { // static bots data source
|
|
447
492
|
staticBots = settings.bots;
|
|
448
493
|
}
|
|
File without changes
|
package/models/IntentForm.js
CHANGED
|
@@ -111,7 +111,7 @@ class IntentForm {
|
|
|
111
111
|
return await this.getMessage(is_current_value);
|
|
112
112
|
}
|
|
113
113
|
if (this.log) {console.log("Form asking fist value. No 'is_current_value' for first form field", is_current_value);}
|
|
114
|
-
if (this.log) {console.log("INTENT_FORM:", this.form);}
|
|
114
|
+
// if (this.log) {console.log("INTENT_FORM:", this.form);}
|
|
115
115
|
if (this.log) {console.log("CURRENT FIELD:", current_field);}
|
|
116
116
|
let message = {
|
|
117
117
|
text: this.form.fields[current_field].label
|
|
@@ -22,6 +22,10 @@ class MockBotsDataSource {
|
|
|
22
22
|
}
|
|
23
23
|
return null;
|
|
24
24
|
}
|
|
25
|
+
|
|
26
|
+
async getBotByIdCache(botId, tdcache) {
|
|
27
|
+
return this.getBotById(botId);
|
|
28
|
+
}
|
|
25
29
|
|
|
26
30
|
/**
|
|
27
31
|
*
|
|
@@ -48,6 +52,21 @@ class MockBotsDataSource {
|
|
|
48
52
|
return intent;
|
|
49
53
|
}
|
|
50
54
|
|
|
55
|
+
async getByIntentDisplayNameCache(botId, key, tdcache) {
|
|
56
|
+
let faq = null;
|
|
57
|
+
if (tdcache) {
|
|
58
|
+
// console.log("mock chache. anyway in mock getting faq from datasource...");
|
|
59
|
+
faq = await this.getByIntentDisplayName(botId, key);
|
|
60
|
+
// console.log("faq found in datasource.:", JSON.stringify(faq));
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
// console.log("mock no chache. getting faq from datasource...");
|
|
64
|
+
faq = await this.getByIntentDisplayName(botId, key);
|
|
65
|
+
// console.log("faq found in datasource..:", JSON.stringify(faq));
|
|
66
|
+
}
|
|
67
|
+
return faq;
|
|
68
|
+
}
|
|
69
|
+
|
|
51
70
|
/**
|
|
52
71
|
* intentsFinder Adapter
|
|
53
72
|
* @param {String} text
|
|
@@ -18,6 +18,41 @@ class MongodbBotsDataSource {
|
|
|
18
18
|
return null;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
async getBotByIdCache(botId, tdcache) {
|
|
22
|
+
let bot = null;
|
|
23
|
+
if (tdcache) {
|
|
24
|
+
let botCacheKey = "cacheman:cachegoose-cache:faq_kbs:id:" + botId;
|
|
25
|
+
try {
|
|
26
|
+
let _bot_as_string = await tdcache.get(botCacheKey);
|
|
27
|
+
const value_type = typeof _bot_as_string;
|
|
28
|
+
console.log("__bot_as_string found in chache:", _bot_as_string);
|
|
29
|
+
console.log("value_type:", value_type);
|
|
30
|
+
if (_bot_as_string) {
|
|
31
|
+
bot = JSON.parse(_bot_as_string);
|
|
32
|
+
console.log("got bot from cache:", JSON.stringify(bot));
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
console.log("bot not found, getting from datasource...");
|
|
36
|
+
bot = await this.getBotById(botId);
|
|
37
|
+
console.log("bot found in datasource:", JSON.stringify(bot));
|
|
38
|
+
await tdcache.set(botCacheKey, JSON.stringify(bot));
|
|
39
|
+
// DEBUG CODE REMOVE
|
|
40
|
+
let bot_ = await tdcache.get(botCacheKey);
|
|
41
|
+
console.log("_bot_as_string from cache debug:", bot_)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch(err) {
|
|
45
|
+
console.error("error getting bot by id:", err);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
console.log("no chache. getting bot from datasource...");
|
|
50
|
+
bot = await this.getBotById(botId);
|
|
51
|
+
console.log("bot found in datasource:", JSON.stringify(bot));
|
|
52
|
+
}
|
|
53
|
+
return bot;
|
|
54
|
+
}
|
|
55
|
+
|
|
21
56
|
/**
|
|
22
57
|
*
|
|
23
58
|
* @param {String} text
|
|
@@ -49,16 +84,27 @@ class MongodbBotsDataSource {
|
|
|
49
84
|
* @param {String} intentName
|
|
50
85
|
* @returns a single Intent
|
|
51
86
|
*/
|
|
52
|
-
async getByIntentDisplayName(botId,
|
|
87
|
+
async getByIntentDisplayName(botId, key) {
|
|
53
88
|
return new Promise((resolve, reject) => {
|
|
54
89
|
// var query = { "id_project": this.projectId, "id_faq_kb": botId, "intent_display_name": name};
|
|
55
|
-
|
|
90
|
+
let query = null;
|
|
91
|
+
key = key.trim();
|
|
92
|
+
if (key.startsWith("#")) {
|
|
93
|
+
let intent_id = key.substring(key.indexOf("#") + 1);
|
|
94
|
+
console.log("Query by intent_id:", intent_id );
|
|
95
|
+
query = { "id_faq_kb": botId, "intent_id": intent_id };
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
console.log("Query by intent name:", key );
|
|
99
|
+
query = { "id_faq_kb": botId, "intent_display_name": key };
|
|
100
|
+
}
|
|
101
|
+
|
|
56
102
|
if (this.log) {console.debug('query', query);}
|
|
57
103
|
Faq.find(query).lean().exec( (err, faqs) => {
|
|
58
104
|
if (err) {
|
|
59
105
|
return reject(err);
|
|
60
106
|
}
|
|
61
|
-
if (this.log) {console.debug("getByIntentDisplayName faqs", faqs);}
|
|
107
|
+
if (this.log) {console.debug("getByIntentDisplayName faqs", JSON.stringify(faqs));}
|
|
62
108
|
if (faqs && faqs.length > 0) {
|
|
63
109
|
const intent = faqs[0];
|
|
64
110
|
return resolve(intent);
|
|
@@ -69,6 +115,47 @@ class MongodbBotsDataSource {
|
|
|
69
115
|
});
|
|
70
116
|
});
|
|
71
117
|
}
|
|
118
|
+
|
|
119
|
+
async getByIntentDisplayNameCache(botId, key, tdcache) {
|
|
120
|
+
let faq = null;
|
|
121
|
+
console.log("botID:", botId);
|
|
122
|
+
console.log("key:", key);
|
|
123
|
+
if (tdcache) {
|
|
124
|
+
console.log("in tdchace");
|
|
125
|
+
let faqCacheKey = "cacheman:cachegoose-cache:faqs:botid:"+ botId + ":faq:id:" + key;
|
|
126
|
+
console.log("Looking in cache for:", faqCacheKey);
|
|
127
|
+
try {
|
|
128
|
+
let _faq_as_string = await tdcache.get(faqCacheKey);
|
|
129
|
+
const value_type = typeof _faq_as_string;
|
|
130
|
+
console.log("_faq_as_string found in chache:", _faq_as_string);
|
|
131
|
+
console.log("value_type:", value_type);
|
|
132
|
+
if (_faq_as_string) {
|
|
133
|
+
faq = JSON.parse(_faq_as_string);
|
|
134
|
+
console.log("got faq from cache:", JSON.stringify(faq));
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
console.log("faq not found, getting from datasource...");
|
|
138
|
+
faq = await this.getByIntentDisplayName(botId, key);
|
|
139
|
+
console.log(".faq found in datasource:", JSON.stringify(faq));
|
|
140
|
+
await tdcache.set(faqCacheKey, JSON.stringify(faq));
|
|
141
|
+
// DEBUG CODE REMOVE
|
|
142
|
+
let faq_ = await tdcache.get(faqCacheKey);
|
|
143
|
+
console.log("_faq_as_string from cache debug:", faq_)
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch(err) {
|
|
147
|
+
console.error("error getting faq by id:", err);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
console.log("no chache. getting faq from datasource...");
|
|
152
|
+
faq = await this.getByIntentDisplayName(botId, key);
|
|
153
|
+
console.log("faq found in datasource:", JSON.stringify(faq));
|
|
154
|
+
}
|
|
155
|
+
return faq;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// query = { "id_project": message.id_project, "id_faq_kb": faq_kb._id, $or:[{"intent_id": action}, {"intent_display_name": action}]};
|
|
72
159
|
|
|
73
160
|
}
|
|
74
161
|
|
|
@@ -43,9 +43,9 @@ class TiledeskChatbot {
|
|
|
43
43
|
async replyToMessage(message, callback) {
|
|
44
44
|
return new Promise( async (resolve, reject) => {
|
|
45
45
|
// get bot info
|
|
46
|
-
if (this.log) {
|
|
47
|
-
|
|
48
|
-
}
|
|
46
|
+
// if (this.log) {
|
|
47
|
+
// console.log("replyToMessage():", JSON.stringify(message));
|
|
48
|
+
// }
|
|
49
49
|
let lead = null;
|
|
50
50
|
if (message.request) {
|
|
51
51
|
this.request = message.request;
|
|
@@ -97,7 +97,8 @@ class TiledeskChatbot {
|
|
|
97
97
|
log: false
|
|
98
98
|
});
|
|
99
99
|
// it only gets the locked_intent
|
|
100
|
-
const faq = await this.botsDataSource.getByIntentDisplayName(this.botId, locked_intent);
|
|
100
|
+
// const faq = await this.botsDataSource.getByIntentDisplayName(this.botId, locked_intent);
|
|
101
|
+
const faq = await this.botsDataSource.getByIntentDisplayNameCache(this.botId, locked_intent, this.tdcache);
|
|
101
102
|
if (this.log) {console.log("locked intent. got faqs", JSON.stringify(faq))}
|
|
102
103
|
let reply;
|
|
103
104
|
if (faq) {
|
|
@@ -156,9 +157,22 @@ class TiledeskChatbot {
|
|
|
156
157
|
}
|
|
157
158
|
}
|
|
158
159
|
else {
|
|
159
|
-
|
|
160
|
+
if (this.log) {console.log("processing intent:", explicit_intent_name);}
|
|
161
|
+
// let faq = await this.botsDataSource.getByIntentDisplayName(this.botId, intent.name);
|
|
162
|
+
if (this.log) {
|
|
163
|
+
console.log("intent this.botId:", this.botId);
|
|
164
|
+
console.log("intent intent.name:", intent.name);
|
|
165
|
+
if (this.tdcache) {
|
|
166
|
+
console.log("intent this.tdcache ok");
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
console.log("no intent this.tdcache");
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
let faq = await this.botsDataSource.getByIntentDisplayNameCache(this.botId, intent.name, this.tdcache);
|
|
160
173
|
if (faq) {
|
|
161
|
-
if (this.log) {
|
|
174
|
+
if (this.log) {
|
|
175
|
+
console.log("Got a reply (faq) by Intent name:", JSON.stringify(faq));}
|
|
162
176
|
try {
|
|
163
177
|
if (intent.parameters) {
|
|
164
178
|
for (const [key, value] of Object.entries(intent.parameters)) {
|
|
@@ -176,7 +190,7 @@ class TiledeskChatbot {
|
|
|
176
190
|
else {
|
|
177
191
|
if (this.log) {console.log("Intent not found:", explicit_intent_name);}
|
|
178
192
|
reply = {
|
|
179
|
-
"text": "Intent not found:
|
|
193
|
+
"text": "Intent not found: " + explicit_intent_name
|
|
180
194
|
}
|
|
181
195
|
}
|
|
182
196
|
}
|
|
@@ -217,7 +231,8 @@ class TiledeskChatbot {
|
|
|
217
231
|
}
|
|
218
232
|
if (this.log) {console.log("NLP decoded found:", intents);}
|
|
219
233
|
if (intents && intents.length > 0) {
|
|
220
|
-
let faq = await this.botsDataSource.getByIntentDisplayName(this.botId, intents[0].intent_display_name);
|
|
234
|
+
// let faq = await this.botsDataSource.getByIntentDisplayName(this.botId, intents[0].intent_display_name);
|
|
235
|
+
let faq = await this.botsDataSource.getByIntentDisplayNameCache(this.botId, intents[0].intent_display_name, this.tdcache);
|
|
221
236
|
let reply;
|
|
222
237
|
try {
|
|
223
238
|
reply = await this.execIntent(faq, message, lead);//, bot);
|
|
@@ -232,12 +247,10 @@ class TiledeskChatbot {
|
|
|
232
247
|
}
|
|
233
248
|
else {
|
|
234
249
|
// fallback
|
|
235
|
-
let fallbackIntent = await this.botsDataSource.getByIntentDisplayName(this.botId, "defaultFallback");
|
|
236
|
-
|
|
237
|
-
// console.log("getByIntentDisplayName(this.botId, 'defaultFallback'):", this.botId, "defaultFallback");
|
|
238
|
-
// console.log("fallbackIntent found!", JSON.stringify(fallbackIntent));
|
|
250
|
+
// let fallbackIntent = await this.botsDataSource.getByIntentDisplayName(this.botId, "defaultFallback");
|
|
251
|
+
let fallbackIntent = await this.botsDataSource.getByIntentDisplayNameCache(this.botId, "defaultFallback", this.tdcache);
|
|
239
252
|
if (!fallbackIntent) {
|
|
240
|
-
console.log("No defaultFallback found!");
|
|
253
|
+
// console.log("No defaultFallback found!");
|
|
241
254
|
resolve(null);
|
|
242
255
|
return;
|
|
243
256
|
}
|
|
@@ -399,7 +412,7 @@ class TiledeskChatbot {
|
|
|
399
412
|
};
|
|
400
413
|
}
|
|
401
414
|
else {
|
|
402
|
-
console.error("
|
|
415
|
+
console.error("Intent with no actions or answer.", JSON.stringify(answerObj) );
|
|
403
416
|
return null;
|
|
404
417
|
}
|
|
405
418
|
|
package/models/faqKbService.js
CHANGED
|
@@ -2,17 +2,21 @@ var Faq_kb = require("./faq_kb");
|
|
|
2
2
|
|
|
3
3
|
class FaqKbService {
|
|
4
4
|
|
|
5
|
-
async getAll(
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
async getAll(_query) {
|
|
6
|
+
let query = _query;
|
|
7
|
+
if (!query) {
|
|
8
|
+
query = {
|
|
8
9
|
public: true,
|
|
9
|
-
certified: true
|
|
10
|
+
certified: true,
|
|
11
|
+
"trashed": { $in: [null, false] }
|
|
10
12
|
}
|
|
11
13
|
}
|
|
14
|
+
var sortQuery = {};
|
|
15
|
+
sortQuery["score"] = -1;
|
|
12
16
|
console.log("(Service) GET ALL FAQ_KBs");
|
|
13
17
|
return new Promise((resolve, reject) => {
|
|
14
|
-
let query = {public: options.public, certified: options.certified};
|
|
15
|
-
Faq_kb.find(query).lean().exec( (err, bots) => {
|
|
18
|
+
// let query = {public: options.public, certified: options.certified};
|
|
19
|
+
Faq_kb.find(query).sort(sortQuery).lean().exec( (err, bots) => {
|
|
16
20
|
if (err) {
|
|
17
21
|
reject(err);
|
|
18
22
|
}
|
package/models/faq_kb.js
CHANGED
|
@@ -58,18 +58,39 @@ var Faq_kbSchema = new Schema({
|
|
|
58
58
|
type: String,
|
|
59
59
|
required: false
|
|
60
60
|
},
|
|
61
|
+
bigImage: {
|
|
62
|
+
type: String,
|
|
63
|
+
required: false
|
|
64
|
+
},
|
|
65
|
+
tags: {
|
|
66
|
+
type: Array,
|
|
67
|
+
required: false
|
|
68
|
+
},
|
|
69
|
+
templateFeatures: {
|
|
70
|
+
type: Array,
|
|
71
|
+
required: false
|
|
72
|
+
},
|
|
61
73
|
attributes: {
|
|
62
74
|
type: Object,
|
|
63
75
|
},
|
|
64
76
|
createdBy: {
|
|
65
77
|
type: String,
|
|
66
78
|
required: true
|
|
67
|
-
}
|
|
79
|
+
},
|
|
80
|
+
score: {
|
|
81
|
+
type: Number,
|
|
82
|
+
required: false,
|
|
83
|
+
index: true,
|
|
84
|
+
default: 0
|
|
85
|
+
},
|
|
68
86
|
},{
|
|
69
87
|
timestamps: true
|
|
70
88
|
}
|
|
71
89
|
);
|
|
72
90
|
|
|
91
|
+
Faq_kbSchema.index({name: 'text', description: 'text', "tags": 'text'},
|
|
92
|
+
{"name":"faqkb_fulltext","default_language": "none","language_override": "language"}); // schema level
|
|
93
|
+
|
|
73
94
|
var faq_kb = mongoose.model('faq_kb', Faq_kbSchema);
|
|
74
95
|
|
|
75
96
|
module.exports = faq_kb
|
package/package.json
CHANGED
|
@@ -38,7 +38,7 @@ describe('Conversation for anomaly detection test', async () => {
|
|
|
38
38
|
console.log("ACTIONS Tilebot route successfully started.");
|
|
39
39
|
var port = process.env.PORT || 10001;
|
|
40
40
|
app_listener = app.listen(port, () => {
|
|
41
|
-
console.log('Tilebot connector listening on port ', port);
|
|
41
|
+
console.log('Tilebot connector listening on port... ', port);
|
|
42
42
|
resolve();
|
|
43
43
|
});
|
|
44
44
|
});
|
|
@@ -52,7 +52,7 @@ describe('Conversation for anomaly detection test', async () => {
|
|
|
52
52
|
});
|
|
53
53
|
|
|
54
54
|
it('/anomaly', (done) => {
|
|
55
|
-
|
|
55
|
+
console.log("/anomaly story...");
|
|
56
56
|
let message_id = uuidv4();
|
|
57
57
|
let listener;
|
|
58
58
|
let endpointServer = express();
|
|
@@ -71,7 +71,7 @@ describe('Conversation for anomaly detection test', async () => {
|
|
|
71
71
|
});
|
|
72
72
|
|
|
73
73
|
listener = endpointServer.listen(10002, '0.0.0.0', () => {
|
|
74
|
-
|
|
74
|
+
console.log('endpointServer started', listener.address());
|
|
75
75
|
let request = {
|
|
76
76
|
"payload": {
|
|
77
77
|
"_id": message_id,
|