@tiledesk/tiledesk-tybot-connector 0.3.4 → 0.3.5-rc2

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.
@@ -5,6 +5,7 @@ const { TiledeskChatbot } = require('../../models/TiledeskChatbot');
5
5
  const { DirIntent } = require('./DirIntent');
6
6
 
7
7
  class DirWebRequestV2 {
8
+
8
9
  constructor(context) {
9
10
  if (!context) {
10
11
  throw new Error('context object is mandatory.');
@@ -12,6 +13,7 @@ class DirWebRequestV2 {
12
13
  this.context = context;
13
14
  this.tdcache = context.tdcache;
14
15
  this.requestId = context.requestId;
16
+ this.chatbot = context.chatbot;
15
17
  this.intentDir = new DirIntent(context);
16
18
  this.log = context.log;
17
19
  }
@@ -27,106 +29,65 @@ class DirWebRequestV2 {
27
29
  return;
28
30
  }
29
31
  this.go(action, (stop) => {
30
- if (this.log) {console.log("(webrequestv2, stop?", stop); }
31
32
  callback(stop);
32
33
  });
33
34
  }
34
35
 
35
36
  async go(action, callback) {
36
- if (this.log) {console.log("webRequest action:", JSON.stringify(action));}
37
+ if (this.log) { console.log("DirWebRequest action:", JSON.stringify(action)); }
38
+ if (!this.tdcache) {
39
+ console.error("Error: DirWebRequest tdcache is mandatory");
40
+ callback();
41
+ return;
42
+ }
43
+
44
+ let trueIntent = action.trueIntent;
45
+ let falseIntent = action.falseIntent;
46
+ let trueIntentAttributes = action.trueIntentAttributes;
47
+ let falseIntentAttributes = action.falseIntentAttributes;
48
+
49
+ if (this.log) {
50
+ console.log("DirWebRequest trueIntent", trueIntent)
51
+ console.log("DirWebRequest falseIntent", falseIntent)
52
+ console.log("DirWebRequest trueIntentAttributes", trueIntentAttributes)
53
+ console.log("DirWebRequest falseIntentAttributes", falseIntentAttributes)
54
+ }
55
+
37
56
  let requestAttributes = null;
38
- if (this.tdcache) {
39
- requestAttributes =
57
+ requestAttributes =
40
58
  await TiledeskChatbot.allParametersStatic(
41
59
  this.tdcache, this.requestId
42
60
  );
43
- }
61
+
44
62
  const filler = new Filler();
45
63
  const url = filler.fill(action.url, requestAttributes);
46
64
 
47
- let headers = {};
48
- if (action.headersString) {
49
- let headersDict = action.headersString
50
- for (const [key, value] of Object.entries(headersDict)) {
51
- if (this.log) {console.log("header:", key, "value:", value)}
52
- let filled_value = filler.fill(value, requestAttributes);
53
- headers[key] = filled_value;
65
+ let headers = await this.getHeadersFromAction(action, filler, requestAttributes).catch( async (err) => {
66
+ await this.chatbot.addParameter("flowError", "Error getting headers");
67
+ if (falseIntent) {
68
+ await this.#executeCondition(false, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes);
69
+ callback(true);
70
+ return Promise.reject(err);;
54
71
  }
55
- }
72
+ callback();
73
+ return Promise.reject(err);
74
+ });
56
75
 
57
- let json = null;
58
- try {
59
- if (action.jsonBody && action.bodyType == "json") {
60
- if (this.log) {console.log("action.body is:", action.jsonBody);}
61
- let jsonBody = filler.fill(action.jsonBody, requestAttributes);
62
- try {
63
- json = JSON.parse(jsonBody);
64
- if (this.log) {console.log("json is:", json);}
65
- }
66
- catch(err) {
67
- console.error("Error parsing webRequest jsonBody:", jsonBody);
68
- }
76
+ let json = await this.getJsonFromAction(action, filler, requestAttributes).catch( async (err) => {
77
+ await this.chatbot.addParameter("flowError", "Error parsing json body");
78
+ if (falseIntent) {
79
+ await this.#executeCondition(false, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes);
80
+ callback(true);
81
+ return Promise.reject(err);;
69
82
  }
70
- else if (action.formData && action.bodyType == "form-data") {
71
- let formData = filler.fill(action.formData, requestAttributes);
72
- if (this.log) {console.log("action.body is form-data:", formData);}
73
- // // fill
74
- if (formData && formData.length > 0) {
75
- for (let i = 0; i < formData.length; i++) {
76
- let field = formData[i];
77
- if (field.value) {
78
- field.value = filler.fill(field.value, requestAttributes);
79
- if (this.log) {console.log("field filled:", field.value);}
80
- }
81
- }
82
- }
83
- json = {};
84
- for (let i = 0; i < formData.length; i++) {
85
- let field = formData[i];
86
- if (field.enabled && field.value && field.type === "URL") {
87
- if (this.log) {console.log("Getting file:", field.value);}
88
- let response = await axios.get(field.value,
89
- {
90
- responseType: 'stream'
91
- }
92
- );
93
- let stream = response.data;
94
- // if (this.log) {console.log("Stream data:", stream);}
95
- json[field.name] = stream;
96
- // process.exit(0);
97
- }
98
- else if (field.enabled && field.value && field.type === "Text") {
99
- json[field.name] = field.value;
100
- }
101
- }
102
- if (this.log) {console.log("final json:", json);}
103
- }
104
- else {
105
- if (this.log) {console.log("no action upload parts");}
106
- }
107
-
108
- }
109
- catch(error) {
110
- console.error("Error", error);
111
- }
112
-
113
- // Condition branches
114
- let trueIntent = action.trueIntent;
115
- let falseIntent = action.falseIntent;
116
- const trueIntentAttributes = action.trueIntentAttributes;
117
- const falseIntentAttributes = action.falseIntentAttributes;
118
- let stopOnConditionMet = action.stopOnConditionMet;
119
- if (trueIntent && trueIntent.trim() === "") {
120
- trueIntent = null;
121
- }
122
- if (falseIntent && falseIntent.trim() === "") {
123
- falseIntent = null;
124
- }
83
+ callback();
84
+ return Promise.reject(err);
85
+ });
125
86
 
126
87
  let timeout = this.#webrequest_timeout(action, 20000, 1, 300000);
127
-
88
+
128
89
  if (this.log) {console.log("webRequest URL", url);}
129
-
90
+
130
91
  const HTTPREQUEST = {
131
92
  url: url,
132
93
  headers: headers,
@@ -134,56 +95,129 @@ class DirWebRequestV2 {
134
95
  method: action.method,
135
96
  timeout: timeout
136
97
  };
137
-
138
- if (this.log) {console.log("webRequest HTTPREQUEST", HTTPREQUEST);}
98
+ if (this.log) { console.log("webRequest HTTPREQUEST", HTTPREQUEST); }
99
+
139
100
  this.#myrequest(
140
101
  HTTPREQUEST, async (err, res) => {
141
102
  if (this.log && err) {
142
103
  console.log("webRequest error:", err);
143
104
  }
144
- if (this.log) {console.log("got res:", res);}
105
+ if (this.log) { console.log("DirWebRequest res:", res); }
145
106
  let resbody = res.data;
146
107
  let status = res.status;
147
108
  let error = res.error;
148
109
  await this.#assignAttributes(action, resbody, status, error)
149
- if (this.log) {console.log("webRequest resbody:", resbody);}
110
+ if (this.log) { console.log("webRequest resbody:", resbody); }
111
+
150
112
  if (err) {
151
- if (this.log) {console.error("webRequest error:", err);}
113
+ if (this.log) { console.error("webRequest error:", err); }
152
114
  if (callback) {
153
115
  if (falseIntent) {
154
- this.#executeCondition(false, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes, () => {
155
- callback(true); // stop the flow
156
- });
157
- }
158
- else {
159
- callback(false); // continue the flow
116
+ await this.#executeCondition(false, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes);
117
+ callback(true);
118
+ return;
160
119
  }
120
+ callback();
121
+ return;
161
122
  }
162
123
  }
163
- else if(res.status >= 200 && res.status <= 299) {
124
+ else if (res.status >= 200 && res.status <= 299) {
164
125
  if (trueIntent) {
165
- await this.#executeCondition(true, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes, () => {
166
- callback(true); // stop the flow
167
- });
168
- }
169
- else {
170
- callback(false); // continue the flow
126
+ await this.#executeCondition(true, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes);
127
+ callback(true);
128
+ return;
171
129
  }
130
+ callback();
131
+ return;
172
132
  }
173
133
  else {
174
134
  if (falseIntent) {
175
- this.#executeCondition(false, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes, () => {
176
- callback(true); // stop the flow
177
- });
178
- }
179
- else {
180
- callback(false); // continue the flow
135
+ await this.#executeCondition(false, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes);
136
+ callback(true);
137
+ return;
181
138
  }
139
+ callback();
140
+ return;
182
141
  }
183
142
  }
184
143
  );
185
144
  }
186
145
 
146
+
147
+ async getHeadersFromAction(action, filler, requestAttributes) {
148
+ return new Promise((resolve, reject) => {
149
+ let headers = {};
150
+ if (action.headersString) {
151
+ try {
152
+ let headersDict = action.headersString
153
+ for (const [key, value] of Object.entries(headersDict)) {
154
+ let filled_value = filler.fill(value, requestAttributes);
155
+ headers[key] = filled_value;
156
+ }
157
+ resolve(headers)
158
+ } catch(err) {
159
+ reject("Error getting headers");
160
+ }
161
+ } else {
162
+ resolve(headers)
163
+ }
164
+
165
+ })
166
+ }
167
+ async getJsonFromAction(action, filler, requestAttributes) {
168
+
169
+ return new Promise( async (resolve, reject) => {
170
+
171
+ if (action.jsonBody && action.bodyType == "json") {
172
+ let jsonBody = filler.fill(action.jsonBody, requestAttributes);
173
+ try {
174
+ let json = JSON.parse(jsonBody);
175
+ resolve(json);
176
+ }
177
+ catch (err) {
178
+ if (this.log) { console.error("Error parsing webRequest jsonBody:", jsonBody, err) };
179
+ reject("Error parsing jsonBody");
180
+ }
181
+ }
182
+ else if (action.formData && action.bodyType == "form-data") {
183
+ let formData = filler.fill(action.formData, requestAttributes);
184
+ try {
185
+ if (formData && formData.length > 0) {
186
+ for (let i = 0; i < formData.length; i++) {
187
+ let field = formData[i];
188
+ if (field.value) {
189
+ field.value = filler.fill(field.value, requestAttributes);
190
+ }
191
+ }
192
+ }
193
+ let json = {};
194
+ for (let i = 0; i < formData.length; i++) {
195
+ let field = formData[i];
196
+ if (field.enabled && field.value && field.type === "URL") {
197
+ let response = await axios.get(field.value,
198
+ {
199
+ responseType: 'stream'
200
+ }
201
+ );
202
+ let stream = response.data;
203
+ json[field.name] = stream;
204
+ }
205
+ else if (field.enabled && field.value && field.type === "Text") {
206
+ json[field.name] = field.value;
207
+ }
208
+ }
209
+ resolve(json);
210
+ } catch (err) {
211
+ if (this.log) { console.error("Error parsing webRequest formData:", formData, err) };
212
+ reject("Error parsing formData");
213
+ }
214
+ }
215
+ else {
216
+ resolve(null);
217
+ }
218
+ })
219
+ }
220
+
187
221
  async #executeCondition(result, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes, callback) {
188
222
  let trueIntentDirective = null;
189
223
  if (trueIntent) {
@@ -196,23 +230,31 @@ class DirWebRequestV2 {
196
230
  if (result === true) {
197
231
  if (trueIntentDirective) {
198
232
  this.intentDir.execute(trueIntentDirective, () => {
199
- callback();
233
+ if (callback) {
234
+ callback();
235
+ }
200
236
  });
201
237
  }
202
238
  else {
203
- if (this.log) {console.log("No trueIntentDirective specified");}
204
- callback();
239
+ if (this.log) { console.log("No trueIntentDirective specified"); }
240
+ if (callback) {
241
+ callback();
242
+ }
205
243
  }
206
244
  }
207
245
  else {
208
246
  if (falseIntentDirective) {
209
247
  this.intentDir.execute(falseIntentDirective, () => {
210
- callback();
248
+ if (callback) {
249
+ callback();
250
+ }
211
251
  });
212
252
  }
213
253
  else {
214
- if (this.log) {console.log("No falseIntentDirective specified");}
215
- callback();
254
+ if (this.log) { console.log("No falseIntentDirective specified"); }
255
+ if (callback) {
256
+ callback();
257
+ }
216
258
  }
217
259
  }
218
260
  }
@@ -226,22 +268,22 @@ class DirWebRequestV2 {
226
268
  }
227
269
  if (this.context.tdcache) {
228
270
  if (action.assignResultTo && resbody) {
229
- if (this.log) {console.log("assign assignResultTo:", resbody);}
271
+ if (this.log) { console.log("assign assignResultTo:", resbody); }
230
272
  await TiledeskChatbot.addParameterStatic(this.context.tdcache, this.context.requestId, action.assignResultTo, resbody);
231
273
  }
232
274
  if (action.assignErrorTo && error) {
233
- if (this.log) {console.log("assign assignResultTo:", error);}
275
+ if (this.log) { console.log("assign assignResultTo:", error); }
234
276
  await TiledeskChatbot.addParameterStatic(this.context.tdcache, this.context.requestId, action.assignErrorTo, error);
235
277
  }
236
278
  if (action.assignStatusTo && status) {
237
- if (this.log) {console.log("assign assignStatusTo:", status);}
279
+ if (this.log) { console.log("assign assignStatusTo:", status); }
238
280
  await TiledeskChatbot.addParameterStatic(this.context.tdcache, this.context.requestId, action.assignStatusTo, status);
239
281
  }
240
282
  // Debug log
241
283
  if (this.log) {
242
284
  const all_parameters = await TiledeskChatbot.allParametersStatic(this.context.tdcache, this.context.requestId);
243
285
  for (const [key, value] of Object.entries(all_parameters)) {
244
- if (this.log) {console.log("(webRequest) request parameter:", key, "value:", value, "type:", typeof value)}
286
+ if (this.log) { console.log("(webRequest) request parameter:", key, "value:", value, "type:", typeof value) }
245
287
  }
246
288
  }
247
289
  }
@@ -254,7 +296,7 @@ class DirWebRequestV2 {
254
296
  //console.log("** Options:", JSON.stringify(options));
255
297
  // Stringify "options". FIX THE STRINGIFY OF CIRCULAR STRUCTURE BUG - START
256
298
  let cache = [];
257
- let str_Options = JSON.stringify(options, function(key, value) { // try to use a separate function
299
+ let str_Options = JSON.stringify(options, function (key, value) { // try to use a separate function
258
300
  if (typeof value === 'object' && value != null) {
259
301
  if (cache.indexOf(value) !== -1) {
260
302
  return;
@@ -274,7 +316,7 @@ class DirWebRequestV2 {
274
316
  maxContentLength: 10000000, // max 10mb response size
275
317
  maxBodyLength: 10000000 // max 10mb request body size
276
318
  }
277
-
319
+
278
320
  if (options.json !== null) {
279
321
  axios_options.data = options.json
280
322
  }
@@ -287,73 +329,73 @@ class DirWebRequestV2 {
287
329
  });
288
330
  axios_options.httpsAgent = httpsAgent;
289
331
  }
290
-
332
+
291
333
  axios(axios_options)
292
- .then((res) => {
293
- if (this.log) {
294
- console.log("Success Response:", res);
295
- console.log("Response for url:", options.url);
296
- console.log("Response headers:\n", JSON.stringify(res.headers));
297
- }
298
- if (callback) {
299
- callback(null, res);
300
- }
301
- })
302
- .catch( (err) => {
303
- if (this.log) {
304
- if (err.response) {
305
- console.log("Error Response data:", err.response.data);
334
+ .then((res) => {
335
+ if (this.log) {
336
+ console.log("Success Response:", res);
337
+ console.log("Response for url:", options.url);
338
+ console.log("Response headers:\n", JSON.stringify(res.headers));
306
339
  }
307
- // FIX THE STRINGIFY OF CIRCULAR STRUCTURE BUG - START
308
- let cache = [];
309
- let error_log = JSON.stringify(err, function(key, value) { // try to use a separate function
310
- if (typeof value === 'object' && value != null) {
311
- if (cache.indexOf(value) !== -1) {
312
- return;
313
- }
314
- cache.push(value);
340
+ if (callback) {
341
+ callback(null, res);
342
+ }
343
+ })
344
+ .catch((err) => {
345
+ if (this.log) {
346
+ if (err.response) {
347
+ console.log("Error Response data:", err.response.data);
315
348
  }
316
- return value;
317
- });
318
- console.error("An error occurred: ", error_log);
319
- // FIX THE STRINGIFY OF CIRCULAR STRUCTURE BUG - END
320
- // console.error("An error occurred:", JSON.stringify(err));
321
- }
322
- if (callback) {
323
- let status = 1000;
324
- let cache = [];
325
- let str_error = JSON.stringify(err, function(key, value) { // try to use a separate function
326
- if (typeof value === 'object' && value != null) {
327
- if (cache.indexOf(value) !== -1) {
328
- return;
349
+ // FIX THE STRINGIFY OF CIRCULAR STRUCTURE BUG - START
350
+ let cache = [];
351
+ let error_log = JSON.stringify(err, function (key, value) { // try to use a separate function
352
+ if (typeof value === 'object' && value != null) {
353
+ if (cache.indexOf(value) !== -1) {
354
+ return;
355
+ }
356
+ cache.push(value);
329
357
  }
330
- cache.push(value);
331
- }
332
- return value;
333
- });
334
- let error = JSON.parse(str_error) // "status" disappears without this trick
335
- let errorMessage = JSON.stringify(error);
336
- if (error.status) {
337
- status = error.status;
338
- }
339
- if (error.message) {
340
- errorMessage = error.message;
341
- }
342
- let data = null;
343
- if (err.response) {
344
- data = err.response.data;
358
+ return value;
359
+ });
360
+ console.error("An error occurred: ", error_log);
361
+ // FIX THE STRINGIFY OF CIRCULAR STRUCTURE BUG - END
362
+ // console.error("An error occurred:", JSON.stringify(err));
345
363
  }
346
- callback(
347
- null, {
364
+ if (callback) {
365
+ let status = 1000;
366
+ let cache = [];
367
+ let str_error = JSON.stringify(err, function (key, value) { // try to use a separate function
368
+ if (typeof value === 'object' && value != null) {
369
+ if (cache.indexOf(value) !== -1) {
370
+ return;
371
+ }
372
+ cache.push(value);
373
+ }
374
+ return value;
375
+ });
376
+ let error = JSON.parse(str_error) // "status" disappears without this trick
377
+ let errorMessage = JSON.stringify(error);
378
+ if (error.status) {
379
+ status = error.status;
380
+ }
381
+ if (error.message) {
382
+ errorMessage = error.message;
383
+ }
384
+ let data = null;
385
+ if (err.response) {
386
+ data = err.response.data;
387
+ }
388
+ callback(
389
+ null, {
348
390
  status: status,
349
391
  data: data,
350
392
  error: errorMessage
351
393
  }
352
- );
353
- }
354
- });
394
+ );
395
+ }
396
+ });
355
397
  }
356
- catch(error) {
398
+ catch (error) {
357
399
  console.error("Error:", error);
358
400
  }
359
401
  }
@@ -369,7 +411,7 @@ class DirWebRequestV2 {
369
411
  // console.log("typeof action.settings.timeout:", typeof action.settings.timeout);
370
412
  // console.log("action.settings.timeout > min", action.settings.timeout > min)
371
413
  // console.log("action.settings.timeout < max", action.settings.timeout < max)
372
-
414
+
373
415
  if (action.settings.timeout) {
374
416
  if ((typeof action.settings.timeout === "number") && action.settings.timeout > min && action.settings.timeout < max) {
375
417
  timeout = Math.round(action.settings.timeout)