@tiledesk/tiledesk-tybot-connector 0.2.39 → 0.2.41

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 CHANGED
@@ -5,6 +5,15 @@
5
5
  available on:
6
6
  ▶️ https://www.npmjs.com/package/@tiledesk/tiledesk-tybot-connector
7
7
 
8
+ # v0.2.41
9
+ - added attribute currentPhoneNumber
10
+ - added attribute tickeId
11
+
12
+ # v0.2.40
13
+ - refactorized Make action
14
+ - added support for public gptkey for GptTask and AskGPT actions
15
+ - fixes bug: AskGPT action not working
16
+
8
17
  # v0.2.39
9
18
  - fixed bug: wrong update of userFullname based on lead.fullname
10
19
 
@@ -453,18 +453,13 @@ class TiledeskChatbotUtil {
453
453
  await chatbot.addParameter("userEmail", message.request.lead.email);
454
454
  }
455
455
  if (message.request.lead.fullname) {
456
- console.log("got lead.fullname:", message.request.lead.fullname);
457
456
  try {
458
457
  const current_userFullname = await chatbot.getParameter("userFullname");
459
- console.log("current_userFullname:", current_userFullname);
460
458
  if (current_userFullname && current_userFullname.startsWith("guest#")) {
461
- console.log("current_userFullname && current_userFullname.startsWith('guest#')");
462
459
  await chatbot.addParameter("userFullname", message.request.lead.fullname);
463
460
  }
464
461
  else if (!current_userFullname) {
465
- console.log("no current_userFullname");
466
462
  await chatbot.addParameter("userFullname", message.request.lead.fullname);
467
- console.log("it was null, set to the incoming one");
468
463
  }
469
464
  }
470
465
  catch(error) {
@@ -474,15 +469,25 @@ class TiledeskChatbotUtil {
474
469
  else {
475
470
  console.log("!lead.fullname");
476
471
  }
472
+ // console.log("Getting userPhone:", JSON.stringify(message.request));
477
473
  if (message.request.lead.phone) {
478
474
  await chatbot.addParameter("userPhone", message.request.lead.phone);
479
475
  }
476
+ if (message.request.lead.lead_id && message.request.lead.lead_id.startsWith("wab-")) {
477
+ const splits = message.request.lead.lead_id.split("-");
478
+ if (splits && splits.length > 1) {
479
+ await chatbot.addParameter("currentPhoneNumber",splits[1]);
480
+ }
481
+ }
480
482
  if (message.request.lead.lead_id) {
481
483
  await chatbot.addParameter("userLeadId", message.request.lead.lead_id);
482
484
  }
483
485
  if (message.request.lead.company) {
484
486
  await chatbot.addParameter("userCompany", message.request.lead.company);
485
487
  }
488
+ if (message.request.ticket_id) {
489
+ await chatbot.addParameter("ticketId", message.request.ticket_id);
490
+ }
486
491
  }
487
492
  }
488
493
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiledesk/tiledesk-tybot-connector",
3
- "version": "0.2.39",
3
+ "version": "0.2.41",
4
4
  "description": "Tiledesk Tybot connector",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -632,9 +632,16 @@ class DirectivesChatbotPlug {
632
632
  })
633
633
  }
634
634
  else if (directive_name === Directives.MAKE) {
635
- new DirMake(context).execute(directive, async () => {
636
- let next_dir = await this.nextDirective(this.directives);
637
- this.process(next_dir);
635
+ new DirMake(context).execute(directive, async (stop) => {
636
+ if (context.log) { console.log("DirMake stop?", stop);}
637
+ if (stop == true) {
638
+ if (context.log) { console.log("Stopping Actions on:", JSON.stringify(directive));}
639
+ this.theend();
640
+ }
641
+ else {
642
+ let next_dir = await this.nextDirective(this.directives);
643
+ this.process(next_dir);
644
+ }
638
645
  })
639
646
  }
640
647
  else {
@@ -100,6 +100,11 @@ class DirAskGPT {
100
100
  key = await this.getKeyFromKbSettings(server_base_url);
101
101
  }
102
102
 
103
+ if (!key) {
104
+ if (this.log) { console.log("DirGptTask - Retrieve public gptkey")}
105
+ key = process.env.GPTKEY;
106
+ }
107
+
103
108
  if (!key) {
104
109
  console.error("Error: DirAskGPT gptkey is mandatory");
105
110
  await this.#assignAttributes(action, answer);
@@ -299,7 +304,7 @@ class DirAskGPT {
299
304
  this.#myrequest(
300
305
  INTEGRATIONS_HTTPREQUEST, async (err, integration) => {
301
306
  if (err) {
302
- console.error("DirAskGPT Get integrations error ", JSON.stringify(err));
307
+ if (this.log) { console.error("DirAskGPT Get integrations error ", err); }
303
308
  resolve(null);
304
309
  } else {
305
310
 
@@ -331,7 +336,7 @@ class DirAskGPT {
331
336
  this.#myrequest(
332
337
  KB_HTTPREQUEST, async (err, resbody) => {
333
338
  if (err) {
334
- console.error("DirGptTask Get kb settings error ", JSON.stringify(err));
339
+ if (this.log) { console.error("DirGptTask Get kb settings error ", err); }
335
340
  resolve(null);
336
341
  } else {
337
342
  if (!resbody.gptkey) {
@@ -99,6 +99,11 @@ class DirGptTask {
99
99
  key = await this.getKeyFromKbSettings(server_base_url);
100
100
  }
101
101
 
102
+ if (!key) {
103
+ if (this.log) { console.log("DirGptTask - Retrieve public gptkey")}
104
+ key = process.env.GPTKEY;
105
+ }
106
+
102
107
  if (!key) {
103
108
  console.error("DirGptTask gptkey is mandatory");
104
109
  await this.#assignAttributes(action, answer);
@@ -5,7 +5,6 @@ const { DirIntent } = require("./DirIntent");
5
5
  let https = require("https");
6
6
  require('dotenv').config();
7
7
 
8
-
9
8
  class DirMake {
10
9
 
11
10
  constructor(context) {
@@ -15,9 +14,8 @@ class DirMake {
15
14
  this.context = context;
16
15
  this.tdcache = this.context.tdcache;
17
16
  this.requestId = this.context.requestId;
18
- this.log = context.log;
19
17
  this.intentDir = new DirIntent(context);
20
- if (this.log) {console.log('LOG: ', this.log)};
18
+ this.log = context.log;
21
19
  }
22
20
 
23
21
  execute(directive, callback) {
@@ -31,80 +29,97 @@ class DirMake {
31
29
  callback();
32
30
  return;
33
31
  }
34
- this.go(action, () => {
35
- callback();
32
+ this.go(action, (stop) => {
33
+ callback(stop);
36
34
  })
37
35
  }
38
36
 
39
37
  async go(action, callback) {
40
38
  if (this.log) { console.log("DirMake action:", JSON.stringify(action)); }
41
- let trueIntent = action.trueIntent;
42
- let falseIntent = action.falseIntent;
43
- if (this.log) {console.log('DirMake trueIntent',trueIntent)}
44
39
  if (!this.tdcache) {
45
40
  console.error("Error: DirMake tdcache is mandatory");
46
41
  callback();
47
42
  return;
48
43
  }
49
- //console.log('DirMake work!');
44
+
45
+ let trueIntent = action.trueIntent;
46
+ let falseIntent = action.falseIntent;
47
+ let trueIntentAttributes = action.trueIntentAttributes;
48
+ let falseIntentAttributes = action.falseIntentAttributes;
49
+
50
+ if (this.log) {
51
+ console.log("DirAskGPT trueIntent", trueIntent)
52
+ console.log("DirAskGPT falseIntent", falseIntent)
53
+ console.log("DirAskGPT trueIntentAttributes", trueIntentAttributes)
54
+ console.log("DirAskGPT falseIntentAttributes", falseIntentAttributes)
55
+ }
56
+
57
+ // default values?
58
+ let status = null;
59
+ let error = null;
60
+
50
61
  let requestVariables = null;
51
62
  requestVariables =
52
63
  await TiledeskChatbot.allParametersStatic(
53
64
  this.tdcache, this.requestId
54
65
  )
55
66
 
56
- if (this.log) {
57
- const all_parameters = await TiledeskChatbot.allParametersStatic(this.context.tdcache, this.context.requestId);
58
- for (const [key, value] of Object.entries(all_parameters)) {
59
- if (this.log) { console.log("DirMake request parameter:", key, "value:", value, "type:", typeof value) }
60
- }
61
- }
62
-
63
67
  let webhook_url = action.url;
64
68
  let bodyParameters = action.bodyParameters;
69
+
65
70
  if (this.log) {
66
71
  console.log("DirMake webhook_url: ", webhook_url);
67
- console.log("DirMake bodyParameters: ", bodyParameters);
72
+ console.log("DirMake bodyParameters: ", JSON.stringify(bodyParameters));
68
73
  }
69
- if (!bodyParameters || bodyParameters === '') {
70
- if (this.log) {console.error("DirMake ERROR - bodyParameters is undefined or null or empty string")};
74
+
75
+ if (!bodyParameters) {
76
+ console.error("Error: DirMake bodyParameters is undefined");
77
+ error = "Missing body parameters";
78
+ await this.#assignAttributes(action, status, error);
79
+ if (falseIntent) {
80
+ await this.#executeCondition(false, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes);
81
+ callback(true);
82
+ return;
83
+ }
71
84
  callback();
72
85
  return;
73
86
  }
87
+
74
88
  if (!webhook_url || webhook_url === '') {
75
- if (this.log) {console.error("DirMake ERROR - webhook_url is undefined or null or empty string:")};
76
- let status = 422;
89
+ console.error("Error: DirMake Webhook Url is not defined");
90
+ let status = 422;
77
91
  let error = 'Missing make webhook url';
78
92
  await this.#assignAttributes(action, status, error);
79
- this.#executeCondition(false, trueIntent, null, falseIntent, null, () => {
80
- callback(); // stop the flow
81
- });
93
+ if (falseIntent) {
94
+ await this.#executeCondition(false, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes);
95
+ callback(true);
96
+ return;
97
+ }
98
+ callback();
82
99
  return;
83
100
  }
84
- let url;
85
- try {
101
+
102
+ /**
103
+ * process.env.MAKE_ENDPOINT is used for testing purposes only.
104
+ * This variable must be not defined in Production Env.
105
+ */
86
106
  let make_base_url = process.env.MAKE_ENDPOINT;
87
- if (make_base_url) {
88
- url = make_base_url + "/make/";
89
- } else {
90
- url = action.url;
91
- }
92
- const filler = new Filler();
93
- for (const [key, value] of Object.entries(bodyParameters)) {
94
- //if (this.log) {console.log("bodyParam:", key, "value:", value)}
95
- let filled_value = filler.fill(value, requestVariables);
96
- bodyParameters[key] = filled_value;
97
- }
98
- if (this.log) {console.log('DirMake bodyParameters filler: ',bodyParameters)}
99
-
107
+ let url;
100
108
 
101
-
102
- // Condition branches
103
- //let trueIntent = action.trueIntent;
104
- //let falseIntent = action.falseIntent;
105
- //console.log('DirMake trueIntent',trueIntent)
106
-
109
+ if (make_base_url) {
110
+ url = make_base_url + "/make/";
111
+ } else {
112
+ url = action.url;
113
+ }
107
114
  if (this.log) { console.log("DirMake MakeEndpoint URL: ", url); }
115
+
116
+ const filler = new Filler();
117
+ for (const [key, value] of Object.entries(bodyParameters)) {
118
+ let filled_value = filler.fill(value, requestVariables);
119
+ bodyParameters[key] = filled_value;
120
+ }
121
+ if (this.log) { console.log('DirMake bodyParameters filler: ', bodyParameters) }
122
+
108
123
  const MAKE_HTTPREQUEST = {
109
124
  url: url,
110
125
  headers: {
@@ -113,37 +128,46 @@ class DirMake {
113
128
  json: bodyParameters,
114
129
  method: "POST"
115
130
  }
116
-
117
- if (this.log) { console.log("myrequest/DirMake MAKE_HTTPREQUEST", MAKE_HTTPREQUEST); }
131
+ if (this.log) { console.log("DirMake MAKE_HTTPREQUEST", MAKE_HTTPREQUEST); }
118
132
  this.#myrequest(
119
- MAKE_HTTPREQUEST, async (err, resbody) => {
133
+ MAKE_HTTPREQUEST, async (err, res) => {
120
134
  if (err) {
121
135
  if (callback) {
122
- if (this.log) {console.error("myrequest/(httprequest) DirMake make err:", err)};
123
- let status = 404;
124
- let error = 'Make url not found';
136
+ console.error("(httprequest) DirMake err:", err);
137
+ // let status = 404;
138
+ // let error = 'Make url not found';
139
+ status = res.status;
140
+ error = res.error;
125
141
  await this.#assignAttributes(action, status, error);
126
- this.#executeCondition(false, trueIntent, null, falseIntent, null, () => {
127
- callback(false); // continue the flow
128
- });
142
+ if (falseIntent) {
143
+ await this.#executeCondition(false, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes);
144
+ callback(true);
145
+ return;
146
+ }
129
147
  callback();
148
+ return;
130
149
  }
131
150
  } else if (callback) {
132
- if (this.log) { console.log("myrequest/DirMake Make resbody: ", resbody); }
133
- let status = 200;
134
- let error = null;
135
- await this.#assignAttributes(action, status, error);
136
- await this.#executeCondition(true, trueIntent, null, falseIntent, null, () => {
137
- callback(); // stop the flow
138
- });
139
- if (this.log) {console.log('myrequest/status: ',status)}
140
- //callback();
151
+ if (this.log) { console.log("(httprequest) DirMake resbody ", res); }
152
+ // let status = 200;
153
+ // let error = null;
154
+ status = res.status;
155
+ error = null;
156
+ if (res.error) {
157
+ error = res.error
158
+ }
159
+ await this.#assignAttributes(action, status, error);
160
+ if (trueIntent) {
161
+ await this.#executeCondition(true, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes);
162
+ callback(true);
163
+ return;
164
+ }
165
+ callback();
166
+ return;
141
167
  }
142
168
  }
143
169
  );
144
- } catch(e) {
145
- console.error('error: ', e)
146
- }
170
+
147
171
  }
148
172
 
149
173
  async #assignAttributes(action, status, error) {
@@ -170,6 +194,7 @@ class DirMake {
170
194
  }
171
195
  }
172
196
 
197
+ // Advanced #myrequest function
173
198
  #myrequest(options, callback) {
174
199
  if (this.log) {
175
200
  console.log("API URL:", options.url);
@@ -179,7 +204,8 @@ class DirMake {
179
204
  url: options.url,
180
205
  method: options.method,
181
206
  params: options.params,
182
- headers: options.headers
207
+ headers: options.headers,
208
+ timeout: 20000
183
209
  }
184
210
  if (options.json !== null) {
185
211
  axios_options.data = options.json
@@ -197,61 +223,146 @@ class DirMake {
197
223
  .then((res) => {
198
224
  if (this.log) {
199
225
  console.log("Response for url:", options.url);
200
- console.log("Response status:", res.status);
201
226
  console.log("Response headers:\n", JSON.stringify(res.headers));
202
227
  }
203
- if (res && res.status == 200 && res.data) {
204
- if (callback) {
205
- callback(null, res.data);
206
- }
207
- }
208
- else {
209
- if (callback) {
210
- callback(new Error("Response status is not 200"), null);
211
- }
228
+ if (callback) {
229
+ callback(null, res);
212
230
  }
231
+
213
232
  })
214
- .catch((error) => {
215
- if (this.log) {console.error("An error occurred:", JSON.stringify(error.message))};
233
+ .catch((err) => {
234
+ if (this.log) {
235
+ // FIX THE STRINGIFY OF CIRCULAR STRUCTURE BUG - START
236
+ let cache = [];
237
+ let error_log = JSON.stringify(err, function (key, value) { // try to use a separate function
238
+ if (typeof value === 'object' && value != null) {
239
+ if (cache.indexOf(value) !== -1) {
240
+ return;
241
+ }
242
+ cache.push(value);
243
+ }
244
+ return value;
245
+ });
246
+ console.error("An error occurred: ", error_log);
247
+ // FIX THE STRINGIFY OF CIRCULAR STRUCTURE BUG - END
248
+ // console.error("An error occurred:", JSON.stringify(err));
249
+ }
216
250
  if (callback) {
217
- callback(error, null);
251
+ let status = 1000;
252
+ let cache = [];
253
+ let str_error = JSON.stringify(err, function (key, value) { // try to use a separate function
254
+ if (typeof value === 'object' && value != null) {
255
+ if (cache.indexOf(value) !== -1) {
256
+ return;
257
+ }
258
+ cache.push(value);
259
+ }
260
+ return value;
261
+ });
262
+ let error = JSON.parse(str_error) // "status" disappears without this trick
263
+ let errorMessage = JSON.stringify(error);
264
+ if (error.status) {
265
+ status = error.status;
266
+ }
267
+ if (error.message) {
268
+ errorMessage = error.message;
269
+ }
270
+ callback(
271
+ null, {
272
+ status: status,
273
+ data: null,
274
+ error: errorMessage
275
+ }
276
+ );
218
277
  }
219
278
  });
220
279
  }
280
+
281
+ // #myrequest(options, callback) {
282
+ // if (this.log) {
283
+ // console.log("API URL:", options.url);
284
+ // console.log("** Options:", JSON.stringify(options));
285
+ // }
286
+ // let axios_options = {
287
+ // url: options.url,
288
+ // method: options.method,
289
+ // params: options.params,
290
+ // headers: options.headers
291
+ // }
292
+ // if (options.json !== null) {
293
+ // axios_options.data = options.json
294
+ // }
295
+ // if (this.log) {
296
+ // console.log("axios_options:", JSON.stringify(axios_options));
297
+ // }
298
+ // if (options.url.startsWith("https:")) {
299
+ // const httpsAgent = new https.Agent({
300
+ // rejectUnauthorized: false,
301
+ // });
302
+ // axios_options.httpsAgent = httpsAgent;
303
+ // }
304
+ // axios(axios_options)
305
+ // .then((res) => {
306
+ // if (this.log) {
307
+ // console.log("Response for url:", options.url);
308
+ // console.log("Response headers:\n", JSON.stringify(res.headers));
309
+ // }
310
+ // if (res && res.status == 200 && res.data) {
311
+ // if (callback) {
312
+ // callback(null, res.data);
313
+ // }
314
+ // }
315
+ // else {
316
+ // if (callback) {
317
+ // callback(new Error("Response status is not 200"), null);
318
+ // }
319
+ // }
320
+ // })
321
+ // .catch((error) => {
322
+ // if (this.log) { console.error("An error occurred:", JSON.stringify(error.message)) };
323
+ // if (callback) {
324
+ // callback(error, null);
325
+ // }
326
+ // });
327
+ // }
328
+
221
329
  async #executeCondition(result, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes, callback) {
222
330
  let trueIntentDirective = null;
223
-
224
331
  if (trueIntent) {
225
- //console.log('executeCondition/trueIntent',trueIntent)
226
332
  trueIntentDirective = DirIntent.intentDirectiveFor(trueIntent, trueIntentAttributes);
227
- //console.log('executeCondition/trueIntentDirective',trueIntentDirective)
228
- //console.log('executeCondition/trueIntentAttributes',trueIntentAttributes)
229
333
  }
230
334
  let falseIntentDirective = null;
231
335
  if (falseIntent) {
232
336
  falseIntentDirective = DirIntent.intentDirectiveFor(falseIntent, falseIntentAttributes);
233
337
  }
234
- if (this.log) {console.log('DirMake executeCondition/result',result)}
235
338
  if (result === true) {
236
339
  if (trueIntentDirective) {
237
340
  this.intentDir.execute(trueIntentDirective, () => {
238
- callback();
341
+ if (callback) {
342
+ callback();
343
+ }
239
344
  });
240
345
  }
241
346
  else {
242
- if (this.log) {console.log("No trueIntentDirective specified");}
243
- callback();
347
+ if (this.log) { console.log("No trueIntentDirective specified"); }
348
+ if (callback) {
349
+ callback();
350
+ }
244
351
  }
245
352
  }
246
353
  else {
247
354
  if (falseIntentDirective) {
248
355
  this.intentDir.execute(falseIntentDirective, () => {
249
- callback();
356
+ if (callback) {
357
+ callback();
358
+ }
250
359
  });
251
360
  }
252
361
  else {
253
- if (this.log) {console.log("No falseIntentDirective specified");}
254
- callback();
362
+ if (this.log) { console.log("No falseIntentDirective specified"); }
363
+ if (callback) {
364
+ callback();
365
+ }
255
366
  }
256
367
  }
257
368
  }
@@ -54,7 +54,7 @@ class DirQapla {
54
54
  console.log("DirAskGPT falseIntentAttributes", falseIntentAttributes)
55
55
  }
56
56
 
57
- // let default values??
57
+ // Set default values
58
58
  let status = null;
59
59
  let result = null;
60
60
  let error;