@tiledesk/tiledesk-tybot-connector 0.2.113 → 0.2.116
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 +15 -1
- package/TdCache.js +1 -0
- package/TiledeskExpression.js +2 -2
- package/index.js +114 -1
- package/models/TiledeskChatbot.js +9 -0
- package/package.json +2 -2
- package/tiledeskChatbotPlugs/directives/DirSetAttributeV2.js +147 -16
package/CHANGELOG.md
CHANGED
|
@@ -17,7 +17,21 @@ available on:
|
|
|
17
17
|
- Added flowError on JSONCondition when result = null
|
|
18
18
|
- Added fix on Filler -->
|
|
19
19
|
|
|
20
|
-
# v0.2.
|
|
20
|
+
# v0.2.116 -> test
|
|
21
|
+
- updates @tiledesk/tiledesk-client => v0.10.12
|
|
22
|
+
|
|
23
|
+
# v0.2.115 -> test
|
|
24
|
+
- removed log console.error("TiledeskExpression.evaluate() error:...")
|
|
25
|
+
- Log setting fix in DirectivesChatbotPlug: const tdclient = new TiledeskClient({...
|
|
26
|
+
- SetAttributeV2: added check for action null: if (!action) {...
|
|
27
|
+
- SetAttributeV2:added check with ? operator: if (action.operation?.operators === undefined && ...
|
|
28
|
+
|
|
29
|
+
# v0.2.114 -> test
|
|
30
|
+
- Creating draft webhook endpoint on index.js: router.post('/block/:project_id/:bot_id/:block_id' ...
|
|
31
|
+
- Added check on attribute size < 20Mb
|
|
32
|
+
- SetAttributeV2: added persistency service
|
|
33
|
+
|
|
34
|
+
# v0.2.113 -> prod
|
|
21
35
|
- Fixed DirClose not importing TiledeskChatbotConst
|
|
22
36
|
|
|
23
37
|
# v0.2.112 -> prod
|
package/TdCache.js
CHANGED
package/TiledeskExpression.js
CHANGED
|
@@ -263,7 +263,7 @@ class TiledeskExpression {
|
|
|
263
263
|
// console.log("res=", res)
|
|
264
264
|
}
|
|
265
265
|
catch (err) {
|
|
266
|
-
console.error("(evaluateJavascriptExpression) TiledeskExpression.evaluate() error:", err.message, "- while evaluating the following expression: '" + expression + "'");
|
|
266
|
+
// console.error("(evaluateJavascriptExpression) TiledeskExpression.evaluate() error:", err.message, "- while evaluating the following expression: '" + expression + "'");
|
|
267
267
|
}
|
|
268
268
|
return res;
|
|
269
269
|
}
|
|
@@ -337,7 +337,7 @@ class TiledeskExpression {
|
|
|
337
337
|
res = vm.run(`let $data = this;${expression}`);
|
|
338
338
|
}
|
|
339
339
|
catch (err) {
|
|
340
|
-
console.error("TiledeskExpression.evaluate() error:", err.message, "evaluating expression: '" + expression + "'");
|
|
340
|
+
// console.error("TiledeskExpression.evaluate() error:", err.message, "evaluating expression: '" + expression + "'");
|
|
341
341
|
}
|
|
342
342
|
return res;
|
|
343
343
|
}
|
package/index.js
CHANGED
|
@@ -12,6 +12,8 @@ const { MongodbBotsDataSource } = require('./models/MongodbBotsDataSource.js');
|
|
|
12
12
|
const { MockBotsDataSource } = require('./models/MockBotsDataSource.js');
|
|
13
13
|
const { TiledeskChatbotConst } = require('./models/TiledeskChatbotConst');
|
|
14
14
|
const { IntentsMachineFactory } = require('./models/IntentsMachineFactory');
|
|
15
|
+
const { v4: uuidv4 } = require('uuid');
|
|
16
|
+
let axios = require('axios');
|
|
15
17
|
// let parser = require('accept-language-parser');
|
|
16
18
|
|
|
17
19
|
router.use(bodyParser.json({limit: '50mb'}));
|
|
@@ -208,7 +210,7 @@ router.post('/ext/:botid', async (req, res) => {
|
|
|
208
210
|
TILEBOT_ENDPOINT:process.env.TYBOT_ENDPOINT,
|
|
209
211
|
token: token,
|
|
210
212
|
log: log,
|
|
211
|
-
HELP_CENTER_API_ENDPOINT: process.env.HELP_CENTER_API_ENDPOINT,
|
|
213
|
+
// HELP_CENTER_API_ENDPOINT: process.env.HELP_CENTER_API_ENDPOINT,
|
|
212
214
|
cache: tdcache
|
|
213
215
|
}
|
|
214
216
|
);
|
|
@@ -561,6 +563,41 @@ router.post('/echobot', (req, res) => {
|
|
|
561
563
|
});
|
|
562
564
|
});
|
|
563
565
|
|
|
566
|
+
// draft webhook
|
|
567
|
+
router.post('/block/:project_id/:bot_id/:block_id', async (req, res) => {
|
|
568
|
+
const project_id = req.params['project_id'];
|
|
569
|
+
const bot_id = req.params['bot_id'];
|
|
570
|
+
const block_id = req.params['block_id'];
|
|
571
|
+
const body = req.body;
|
|
572
|
+
console.log('/block/:project_id/:bot_id/:block_id:', project_id, "/", bot_id, "/", block_id);
|
|
573
|
+
console.log('/block/:project_id/:bot_id/:block_id.body', body);
|
|
574
|
+
|
|
575
|
+
// invoke block
|
|
576
|
+
// unique ID for each execution
|
|
577
|
+
const execution_id = uuidv4().replace(/-/g, '');
|
|
578
|
+
const request_id = "automation-request-" + project_id + "-" + execution_id;
|
|
579
|
+
const command = "/" + block_id;
|
|
580
|
+
let request = {
|
|
581
|
+
"payload": {
|
|
582
|
+
"recipient": request_id,
|
|
583
|
+
"text": command,
|
|
584
|
+
"id_project": project_id,
|
|
585
|
+
"request": {
|
|
586
|
+
"request_id": request_id
|
|
587
|
+
},
|
|
588
|
+
"attributes": {
|
|
589
|
+
"payload": body
|
|
590
|
+
}
|
|
591
|
+
}, token: ".."
|
|
592
|
+
}
|
|
593
|
+
console.log("sendMessageToBot()...");
|
|
594
|
+
sendMessageToBot(request, bot_id, async () => {
|
|
595
|
+
console.log("Async webhook message sent:\n", request);
|
|
596
|
+
res.status(200).send({"success":true});
|
|
597
|
+
return;
|
|
598
|
+
});
|
|
599
|
+
});
|
|
600
|
+
|
|
564
601
|
async function startApp(settings, completionCallback) {
|
|
565
602
|
console.log("Starting Tilebot...");
|
|
566
603
|
//console.log("Starting Tilebot with Settings:", settings);
|
|
@@ -677,4 +714,80 @@ async function checkRequest(request_id, id_project) {
|
|
|
677
714
|
// WARNING! Move this function in models/TiledeskChatbotUtil.js
|
|
678
715
|
}
|
|
679
716
|
|
|
717
|
+
/**
|
|
718
|
+
* A stub to send message to the "ext/botId" endpoint, hosted by tilebot on:
|
|
719
|
+
* /${TILEBOT_ROUTE}/ext/${botId}
|
|
720
|
+
*
|
|
721
|
+
* @param {Object} message. The message to send
|
|
722
|
+
* @param {string} botId. Tiledesk botId
|
|
723
|
+
* @param {string} token. User token
|
|
724
|
+
*/
|
|
725
|
+
function sendMessageToBot(message, botId, callback) {
|
|
726
|
+
// const jwt_token = this.fixToken(token);
|
|
727
|
+
const url = `${process.env.TYBOT_ENDPOINT}/ext/${botId}`;
|
|
728
|
+
console.log("sendMessageToBot URL", url);
|
|
729
|
+
const HTTPREQUEST = {
|
|
730
|
+
url: url,
|
|
731
|
+
headers: {
|
|
732
|
+
'Content-Type': 'application/json'
|
|
733
|
+
},
|
|
734
|
+
json: message,
|
|
735
|
+
method: 'POST'
|
|
736
|
+
};
|
|
737
|
+
myrequest(
|
|
738
|
+
HTTPREQUEST,
|
|
739
|
+
function (err, resbody) {
|
|
740
|
+
if (err) {
|
|
741
|
+
if (callback) {
|
|
742
|
+
callback(err);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
else {
|
|
746
|
+
if (callback) {
|
|
747
|
+
callback(null, resbody);
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
}, false
|
|
751
|
+
);
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
function myrequest(options, callback, log) {
|
|
755
|
+
if (log) {
|
|
756
|
+
console.log("API URL:", options.url);
|
|
757
|
+
console.log("** Options:", JSON.stringify(options));
|
|
758
|
+
}
|
|
759
|
+
axios(
|
|
760
|
+
{
|
|
761
|
+
url: options.url,
|
|
762
|
+
method: options.method,
|
|
763
|
+
data: options.json,
|
|
764
|
+
params: options.params,
|
|
765
|
+
headers: options.headers
|
|
766
|
+
})
|
|
767
|
+
.then((res) => {
|
|
768
|
+
if (log) {
|
|
769
|
+
console.log("Response for url:", options.url);
|
|
770
|
+
console.log("Response headers:\n", JSON.stringify(res.headers));
|
|
771
|
+
//console.log("******** Response for url:", res);
|
|
772
|
+
}
|
|
773
|
+
if (res && res.status == 200 && res.data) {
|
|
774
|
+
if (callback) {
|
|
775
|
+
callback(null, res.data);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
else {
|
|
779
|
+
if (callback) {
|
|
780
|
+
callback(TiledeskClient.getErr({ message: "Response status not 200" }, options, res), null, null);
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
})
|
|
784
|
+
.catch((error) => {
|
|
785
|
+
console.error("An error occurred:", error);
|
|
786
|
+
if (callback) {
|
|
787
|
+
callback(error, null, null);
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
);
|
|
791
|
+
}
|
|
792
|
+
|
|
680
793
|
module.exports = { router: router, startApp: startApp};
|
|
@@ -618,8 +618,17 @@ class TiledeskChatbot {
|
|
|
618
618
|
}
|
|
619
619
|
|
|
620
620
|
static async addParameterStatic(_tdcache, requestId, parameter_name, parameter_value) {
|
|
621
|
+
if (parameter_name === null || parameter_name === undefined) {
|
|
622
|
+
// console.error("Error saving key:", parameter_name, "value:", parameter_value);
|
|
623
|
+
return;
|
|
624
|
+
}
|
|
621
625
|
const parameter_key = TiledeskChatbot.requestCacheKey(requestId) + ":parameters";
|
|
622
626
|
const parameter_value_s = JSON.stringify(parameter_value);
|
|
627
|
+
// console.log("saving key:", parameter_name, "value:", parameter_value);
|
|
628
|
+
if (parameter_value_s?.length > 20000000) {
|
|
629
|
+
// console.log("Error. Attribute size too big (> 20mb):", parameter_value_s);
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
623
632
|
await _tdcache.hset(parameter_key, parameter_name, parameter_value_s);
|
|
624
633
|
}
|
|
625
634
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tiledesk/tiledesk-tybot-connector",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.116",
|
|
4
4
|
"description": "Tiledesk Tybot connector",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"@tiledesk/helpcenter-query-client": "^0.1.8",
|
|
15
15
|
"@tiledesk/tiledesk-chatbot-client": "^0.5.30",
|
|
16
16
|
"@tiledesk/tiledesk-chatbot-util": "^0.8.39",
|
|
17
|
-
"@tiledesk/tiledesk-client": "^0.10.
|
|
17
|
+
"@tiledesk/tiledesk-client": "^0.10.12",
|
|
18
18
|
"accept-language-parser": "^1.5.0",
|
|
19
19
|
"axios": "^0.27.2",
|
|
20
20
|
"body-parser": "^1.19.0",
|
|
@@ -97,6 +97,11 @@ class DirSetAttributeV2 {
|
|
|
97
97
|
|
|
98
98
|
async go(action, callback) {
|
|
99
99
|
if (this.log) {console.log("(DirSetAttribute) action before filling:", JSON.stringify(action));}
|
|
100
|
+
if (!action) {
|
|
101
|
+
if (this.log) {console.log("(SetAttributeV2) Error 'action' is missing");}
|
|
102
|
+
callback();
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
100
105
|
if (action && !action.operation) {
|
|
101
106
|
if (this.log) {console.log("(SetAttributeV2) Error operation is mandatory");}
|
|
102
107
|
callback();
|
|
@@ -108,14 +113,16 @@ class DirSetAttributeV2 {
|
|
|
108
113
|
if (this.log) { console.log("action.operation.operands.length", action.operation.operands.length); }
|
|
109
114
|
if (this.log) { console.log("action.operation.operands[0].type", action.operation.operands[0].type); }
|
|
110
115
|
|
|
111
|
-
// FUN FACT: THIS TOOK A LOT OF
|
|
116
|
+
// FUN FACT: THIS TOOK A LOT OF EFFORT BUT IT WAS NEVER USED. YOU CAN SIMPLY CREATE A JSON ATTRIBUTE APPLYING
|
|
112
117
|
// JSONparse FUNCTION TO AN ATTRIBUTE.
|
|
118
|
+
// DEPRECATED because type = json is not available in the UI!
|
|
113
119
|
if (action.operation.operands && action.operation.operands.length === 1 && action.operation.operands[0].type === "json") {
|
|
114
120
|
if (this.log) {console.log("(SetAttributeV2) setting json value...");}
|
|
115
121
|
if (this.log) { console.log("(SetAttributeV2) setting json value... destination:", action.destination); }
|
|
116
122
|
const json_value = JSON.parse(action.operation.operands[0].value);
|
|
117
123
|
if (this.log) { console.log("(SetAttributeV2) json_value:", json_value); }
|
|
118
|
-
await
|
|
124
|
+
await this.saveAttribute(action.destination, json_value);
|
|
125
|
+
// await TiledeskChatbot.addParameterStatic(this.context.tdcache, this.context.requestId, action.destination, json_value);
|
|
119
126
|
callback();
|
|
120
127
|
return; // on json types no operations are permitted beyond assignment
|
|
121
128
|
}
|
|
@@ -130,12 +137,12 @@ class DirSetAttributeV2 {
|
|
|
130
137
|
// callback();
|
|
131
138
|
// return;
|
|
132
139
|
// }
|
|
133
|
-
if (action.operation
|
|
140
|
+
if (action.operation?.operators === undefined && action.operation?.operands?.length !== 1) {
|
|
134
141
|
if (this.log) {console.error("(DirSetAttribute) Invalid action: operators === undefined && operands.length !== 1")};
|
|
135
142
|
callback();
|
|
136
143
|
return;
|
|
137
144
|
}
|
|
138
|
-
if (action.operation
|
|
145
|
+
if (action.operation?.operators !== undefined && action.operation?.operators?.length !== action.operation?.operands?.length - 1) {
|
|
139
146
|
if (this.log) {console.error("(DirSetAttribute) Invalid action: operators.length !== operands.length - 1")};
|
|
140
147
|
callback();
|
|
141
148
|
return;
|
|
@@ -145,21 +152,89 @@ class DirSetAttributeV2 {
|
|
|
145
152
|
// await this.fillValues(action.operation.operands);
|
|
146
153
|
// }
|
|
147
154
|
// console.log("dirsetattribute, action.operation.operands:", action.operation.operands);
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
155
|
+
try {
|
|
156
|
+
const expression = TiledeskExpression.JSONOperationToExpression(action.operation?.operators, action.operation?.operands);
|
|
157
|
+
const attributes = await TiledeskChatbot.allParametersStatic(this.context.tdcache, this.context.requestId);
|
|
158
|
+
// console.log("dirsetattribute, attributes:", attributes);
|
|
159
|
+
if (attributes) {
|
|
160
|
+
attributes.TiledeskMath = TiledeskMath;
|
|
161
|
+
attributes.TiledeskString = TiledeskString;
|
|
162
|
+
const result = new TiledeskExpression().evaluateJavascriptExpression(expression, attributes);
|
|
163
|
+
// console.log("filling in setattribute, result:", result);
|
|
164
|
+
// THE GOAL OF ATTRIBUTE-FILLING THE "DESTINATION" FIELD IS TO SUPPORT DYNAMIC ATTRIBUTES
|
|
165
|
+
// (ATTRS WHOSE NAME IS UNKNOWN AD DESIGN-TIME)
|
|
166
|
+
// STILL UNSUPPORTED IN UI
|
|
167
|
+
let destination = await this.fillDestination(action.destination);
|
|
168
|
+
await this.saveAttribute(destination, result);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
catch(err) {
|
|
172
|
+
console.error("SetAttributeV2 error:", err);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// await TiledeskChatbot.addParameterStatic(this.context.tdcache, this.context.requestId, destination, result);
|
|
160
176
|
callback();
|
|
161
177
|
}
|
|
162
178
|
|
|
179
|
+
async saveAttribute(key, value, persist) {
|
|
180
|
+
if (this.log) {
|
|
181
|
+
console.log("SetAttributeV2 saving attribute:", key, value, persist);
|
|
182
|
+
}
|
|
183
|
+
await TiledeskChatbot.addParameterStatic(this.context.tdcache, this.context.requestId, key, value);
|
|
184
|
+
// if (persist) {
|
|
185
|
+
// console.log("SetAttributeV2 persisting...");
|
|
186
|
+
// await this.persistOnTiledesk(destination, result);
|
|
187
|
+
// }
|
|
188
|
+
|
|
189
|
+
// await make persistent autenticato con "Chatbot Token" (solo il chatbot può usare questo servizio)
|
|
190
|
+
// sarebbe il top che accodasse
|
|
191
|
+
/**
|
|
192
|
+
* ACL ?
|
|
193
|
+
* Solo agents appartenenti a quella conversazione possono accedere agli attibuti. E gli Admin
|
|
194
|
+
* collection flow_attributes
|
|
195
|
+
* {
|
|
196
|
+
* "projectId",
|
|
197
|
+
* "flowId",
|
|
198
|
+
* "requestId",
|
|
199
|
+
* attributes: [
|
|
200
|
+
* {"key": destination, "value": {}, 2, "Andrea"} => In pratica value è un "any"
|
|
201
|
+
* ]
|
|
202
|
+
* }
|
|
203
|
+
*/
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
async persistOnTiledesk(key, value) {
|
|
207
|
+
if (!process.env.PERSIST_API_ENDPOINT) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const HTTPREQUEST = {
|
|
211
|
+
url: process.env.PERSIST_API_ENDPOINT,
|
|
212
|
+
headers: {
|
|
213
|
+
'Content-Type': 'application/json',
|
|
214
|
+
'Authorization': this.fixToken(this.context.token)
|
|
215
|
+
},
|
|
216
|
+
json: json,
|
|
217
|
+
method: 'POST'
|
|
218
|
+
}
|
|
219
|
+
if (this.log) { console.log("SetAttribute. HTTPREQUEST: ", HTTPREQUEST); }
|
|
220
|
+
this.#myrequest(
|
|
221
|
+
HTTPREQUEST, async (err, resbody) => {
|
|
222
|
+
if (err) {
|
|
223
|
+
if (this.log) {
|
|
224
|
+
console.error("SetAttribute. persistOnTiledesk() error:", err);
|
|
225
|
+
}
|
|
226
|
+
// callback();
|
|
227
|
+
// return;
|
|
228
|
+
} else {
|
|
229
|
+
if (this.log) { console.log("SetAttribute. Attributes saved.", JSON.stringify(resbody)); }
|
|
230
|
+
// callback();
|
|
231
|
+
// return;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
);
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
|
|
163
238
|
async fillDestination(destination) {
|
|
164
239
|
if (this.tdcache) {
|
|
165
240
|
// console.log("tdcache in setattribute...", this.tdcache);
|
|
@@ -257,6 +332,62 @@ class DirSetAttributeV2 {
|
|
|
257
332
|
console.error("Error while converting operands:", error);
|
|
258
333
|
}
|
|
259
334
|
}
|
|
335
|
+
|
|
336
|
+
#myrequest(options, callback) {
|
|
337
|
+
if (this.log) {
|
|
338
|
+
console.log("API URL:", options.url);
|
|
339
|
+
console.log("** Options:", JSON.stringify(options));
|
|
340
|
+
}
|
|
341
|
+
let axios_options = {
|
|
342
|
+
url: options.url,
|
|
343
|
+
method: options.method,
|
|
344
|
+
params: options.params,
|
|
345
|
+
headers: options.headers
|
|
346
|
+
}
|
|
347
|
+
if (options.json !== null) {
|
|
348
|
+
axios_options.data = options.json
|
|
349
|
+
}
|
|
350
|
+
if (this.log) {
|
|
351
|
+
console.log("axios_options:", JSON.stringify(axios_options));
|
|
352
|
+
}
|
|
353
|
+
if (options.url.startsWith("https:")) {
|
|
354
|
+
const httpsAgent = new https.Agent({
|
|
355
|
+
rejectUnauthorized: false,
|
|
356
|
+
});
|
|
357
|
+
axios_options.httpsAgent = httpsAgent;
|
|
358
|
+
}
|
|
359
|
+
axios(axios_options)
|
|
360
|
+
.then((res) => {
|
|
361
|
+
if (this.log) {
|
|
362
|
+
console.log("Response for url:", options.url);
|
|
363
|
+
console.log("Response headers:\n", JSON.stringify(res.headers));
|
|
364
|
+
}
|
|
365
|
+
if (res && res.status == 200 && res.data) {
|
|
366
|
+
if (callback) {
|
|
367
|
+
callback(null, res.data);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
if (callback) {
|
|
372
|
+
callback(new Error("Response status is not 200"), null);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
})
|
|
376
|
+
.catch((error) => {
|
|
377
|
+
if (callback) {
|
|
378
|
+
callback(error, null);
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
fixToken(token) {
|
|
384
|
+
if (token.startsWith('JWT ')) {
|
|
385
|
+
return token
|
|
386
|
+
}
|
|
387
|
+
else {
|
|
388
|
+
return 'JWT ' + token
|
|
389
|
+
}
|
|
390
|
+
}
|
|
260
391
|
}
|
|
261
392
|
|
|
262
393
|
module.exports = { DirSetAttributeV2 };
|