@tiledesk/tiledesk-tybot-connector 0.4.1 → 0.5.0-rc1

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.
@@ -349,6 +349,105 @@ class TiledeskChatbotUtil {
349
349
  return all_buttons;
350
350
  }
351
351
 
352
+ static replaceJSONButtons(message, flow_attributes) {
353
+ let all_buttons = [];
354
+ if (message.attributes && message.attributes.commands) {
355
+ let commands = message.attributes.commands;
356
+ if (commands.length > 0) {
357
+ for (let i = 0; i < commands.length; i++) {
358
+ let command = commands[i];
359
+ if (command.type === 'message' && command.message) {
360
+ if (command.message.attributes && command.message.attributes.attachment && command.message.attributes.attachment.json_buttons){
361
+ // console.log("command with buttons ok:")
362
+ let json_buttons_string = command.message.attributes.attachment.json_buttons;
363
+ let json_buttons = null;
364
+ let final_buttons = [];
365
+ try {
366
+ // fill buttons
367
+ const filler = new Filler();
368
+ json_buttons_string = filler.fill(json_buttons_string, flow_attributes);
369
+ console.log("json_buttons_string:", json_buttons_string);
370
+ console.log("type json_buttons_string:", typeof json_buttons_string);
371
+ try {
372
+ json_buttons = JSON.parse(json_buttons_string);
373
+ console.log("json_buttons (parsed): ", json_buttons);
374
+ } catch(err) {
375
+ console.error("Error parsing json_buttons_string: ", err)
376
+ }
377
+
378
+ console.log("after try type json_buttons: ", typeof json_buttons, json_buttons);
379
+ console.log("Array.isArray(json_buttons): ", Array.isArray(json_buttons));
380
+ if (Array.isArray(json_buttons)) {
381
+ console.log("json_buttons is array");
382
+ json_buttons.forEach(button => {
383
+ console.log("analyze button:", button);
384
+ console.log("button.value:", typeof button.value, button.value);
385
+ console.log("button.type:", typeof button.type, button.type);
386
+ console.log("button.action:", typeof button.action, button.action);
387
+ console.log("final_buttons:", final_buttons);
388
+ if (button.value && button.type === "action" && button.action) {
389
+ console.log("Case 1");
390
+ button.show_echo = true;
391
+ // console.log("pushing:", button)
392
+ final_buttons.push(button);
393
+ }
394
+ else if (button.value && button.type === "text") {
395
+ console.log("Case 2");
396
+ button.show_echo = true;
397
+ // console.log("pushing:", button)
398
+ final_buttons.push(button);
399
+ }
400
+ else if (button.value && button.type === "url" && button.link) {
401
+ console.log("Case 3");
402
+ button.show_echo = true;
403
+ // console.log("pushing:", button)
404
+ final_buttons.push(button);
405
+ }
406
+ else {
407
+ console.log("Invalid button. Skipping:", JSON.stringify(button) );
408
+ }
409
+ });
410
+ }
411
+
412
+ // "buttons": [
413
+ // {
414
+ // "type": "action",
415
+ // "value": "Button1", // obbligatorio sempre
416
+ // "action": "#bb347206-d639-4926-94c9-e94930623dce", // mandatory
417
+ // "show_echo": true, // lo inserisco sempre
418
+ // "alias": "button1 alias"
419
+ // },
420
+ // {
421
+ // "type": "text",
422
+ // "value": "Button2 text", // obbligatorio sempre
423
+ // "show_echo": true // lo inserisco sempre
424
+ // },
425
+ // {
426
+ // "type": "url",
427
+ // "value": "Button3 link", // obbligatorio sempre
428
+ // "link": "http://", // obbligatorio
429
+ // "show_echo": true // lo inserisco sempre
430
+ // }
431
+ // ]
432
+ }
433
+ catch(error) {
434
+ console.error("Invalid json_buttons:", error)
435
+ }
436
+ if (final_buttons && final_buttons.length > 0) {
437
+ command.message.attributes.attachment.buttons = final_buttons;
438
+ delete command.message.attributes.attachment.json_buttons;
439
+ }
440
+ else {
441
+ console.log("Invalid json buttons. Skipped:", JSON.stringify(final_buttons));
442
+ }
443
+ }
444
+ }
445
+ }
446
+ }
447
+ }
448
+ return all_buttons;
449
+ }
450
+
352
451
  static buttonByText(text, buttons) {
353
452
  if (buttons === null || text === null) {
354
453
  return null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiledesk/tiledesk-tybot-connector",
3
- "version": "0.4.1",
3
+ "version": "0.5.0-rc1",
4
4
  "description": "Tiledesk Tybot connector",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -15,6 +15,7 @@
15
15
  "@tiledesk/tiledesk-chatbot-client": "^0.5.30",
16
16
  "@tiledesk/tiledesk-chatbot-util": "^0.8.39",
17
17
  "@tiledesk/tiledesk-client": "^0.10.13",
18
+ "@tiledesk/tiledesk-multi-worker": "^0.2.1-rc2",
18
19
  "accept-language-parser": "^1.5.0",
19
20
  "axios": "^1.7.7",
20
21
  "body-parser": "^1.19.0",
@@ -774,6 +774,19 @@ class DirectivesChatbotPlug {
774
774
  }
775
775
  });
776
776
  }
777
+ else if (directive_name === Directives.WEBHOOK) {
778
+ // console.log(".....DirIntent")
779
+ new DirIntent(context).execute(directive, async (stop) => {
780
+ if (stop) {
781
+ if (context.log) { console.log("Stopping Actions on:", JSON.stringify(directive));}
782
+ this.theend();
783
+ }
784
+ else {
785
+ let next_dir = await this.nextDirective(this.directives);
786
+ this.process(next_dir);
787
+ }
788
+ });
789
+ }
777
790
  else if (directive_name === Directives.WEB_RESPONSE) {
778
791
  new DirWebResponse(context).execute(directive, async () => {
779
792
  let next_dir = await this.nextDirective(this.directives);
@@ -596,7 +596,6 @@ class DirAssistant {
596
596
  });
597
597
  console.error("(DirAssistant) An error occurred: ", error_log);
598
598
  // FIX THE STRINGIFY OF CIRCULAR STRUCTURE BUG - END
599
- // console.error("An error occurred:", JSON.stringify(err));
600
599
  }
601
600
  if (callback) {
602
601
  let status = 1000;
@@ -423,7 +423,6 @@ class DirGptTask {
423
423
  }
424
424
  })
425
425
  .catch((error) => {
426
- // console.error("An error occurred:", JSON.stringify(error.data));
427
426
  if (callback) {
428
427
  callback(error, null);
429
428
  }
@@ -71,11 +71,12 @@ class DirIntent {
71
71
  "recipient": requestId,
72
72
  "text": intent_command,
73
73
  "id_project": projectId,
74
- "request": {
75
- "request_id": requestId,
76
- "id_project": projectId
77
- // "bot_id": botId
78
- }
74
+ "request": this.supportRequest,
75
+ // "request": {
76
+ // "request_id": requestId,
77
+ // "id_project": projectId
78
+ // // "bot_id": botId
79
+ // }
79
80
  },
80
81
  "token": this.token
81
82
  }
@@ -243,9 +243,8 @@ class DirMake {
243
243
  }
244
244
  return value;
245
245
  });
246
- console.error("An error occurred: ", error_log);
246
+ console.error("(DirMake) An error occurred: ", error_log);
247
247
  // FIX THE STRINGIFY OF CIRCULAR STRUCTURE BUG - END
248
- // console.error("An error occurred:", JSON.stringify(err));
249
248
  }
250
249
  if (callback) {
251
250
  let status = 1000;
@@ -278,54 +277,6 @@ class DirMake {
278
277
  });
279
278
  }
280
279
 
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
-
329
280
  async #executeCondition(result, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes, callback) {
330
281
  let trueIntentDirective = null;
331
282
  if (trueIntent) {
@@ -3,6 +3,7 @@ const { TiledeskChatbot } = require('../../models/TiledeskChatbot');
3
3
  const { TiledeskChatbotUtil } = require('../../models/TiledeskChatbotUtil');
4
4
  let axios = require('axios');
5
5
  const { TiledeskClient } = require('@tiledesk/tiledesk-client');
6
+ const { Logger } = require('../../Logger');
6
7
 
7
8
  class DirReply {
8
9
 
@@ -16,6 +17,8 @@ class DirReply {
16
17
  this.token = context.token;
17
18
  this.tdcache = context.tdcache;
18
19
  this.log = context.log;
20
+ this.supportRequest = this.context.supportRequest;
21
+ this.logger = new Logger({ request_id: this.requestId, dev: this.context.supportRequest.draft });
19
22
 
20
23
  this.API_ENDPOINT = context.API_ENDPOINT;
21
24
  this.tdClient = new TiledeskClient({
@@ -38,16 +41,21 @@ class DirReply {
38
41
  }
39
42
  else {
40
43
  console.error("Incorrect directive (no action provided):", directive);
44
+ this.logger.error("Incorrect directive (no action provided):", directive);
41
45
  callback();
42
46
  return;
43
47
  }
48
+ this.logger.info("Executing Action Reply ", directive.action)
49
+
44
50
  this.go(action, () => {
51
+ this.logger.info("Action Reply terminated")
45
52
  callback();
46
53
  });
47
54
  }
48
55
 
49
56
  async go(action, callback) {
50
57
  const message = action;
58
+
51
59
  // fill
52
60
  let requestAttributes = null;
53
61
  if (this.tdcache) {
@@ -55,22 +63,22 @@ class DirReply {
55
63
  await TiledeskChatbot.allParametersStatic(
56
64
  this.tdcache, this.requestId
57
65
  );
58
- if (this.log) {
59
- for (const [key, value] of Object.entries(requestAttributes)) {
60
- const value_type = typeof value;
61
- // if (this.log) {console.log("(DirReply) request parameter:", key, "value:", value, "type:", value_type)}
62
- }
63
- }
66
+
67
+ TiledeskChatbotUtil.replaceJSONButtons(message, requestAttributes);
68
+
64
69
  const filler = new Filler();
65
70
  // fill text attribute
66
71
  message.text = filler.fill(message.text, requestAttributes);
72
+
67
73
  if (message.metadata) {
68
74
  if (this.log) {console.log("filling message 'metadata':", JSON.stringify(message.metadata));}
69
75
  if (message.metadata.src) {
70
76
  message.metadata.src = filler.fill(message.metadata.src, requestAttributes);
77
+ this.logger.debug("Filled metadata.src with ", message.metadata.src);
71
78
  }
72
79
  if (message.metadata.name) {
73
80
  message.metadata.name = filler.fill(message.metadata.name, requestAttributes);
81
+ this.logger.debug("Filled metadata.name with ", message.metadata.name);
74
82
  }
75
83
  }
76
84
  if (this.log) {console.log("filling commands'. Message:", JSON.stringify(message));}
@@ -84,6 +92,7 @@ class DirReply {
84
92
  let command = commands[i];
85
93
  if (command.type === 'message' && command.message && command.message.text) {
86
94
  command.message.text = filler.fill(command.message.text, requestAttributes);
95
+ this.logger.debug("Filled message.text with ", command.message.text)
87
96
  TiledeskChatbotUtil.fillCommandAttachments(command, requestAttributes, this.log);
88
97
  if (this.log) {console.log("command filled:", command.message.text);}
89
98
  }
@@ -133,12 +142,14 @@ class DirReply {
133
142
  }
134
143
  catch(err) {
135
144
  console.error("An error occurred while JSON.parse(). Parsed value:" + value + " in allParametersStatic(). Error:", err);
145
+ this.logger.error("An error occurred while JSON.parse(). Parsed value:" + value + " in allParametersStatic(). Error:", err);
136
146
  }
137
147
  }
138
148
  }
139
149
  }
140
150
  // send!
141
151
  let cleanMessage = message;
152
+ this.logger.info("Sending reply with text ", cleanMessage.text);
142
153
  // cleanMessage = TiledeskChatbotUtil.removeEmptyReplyCommands(message);
143
154
  // if (!TiledeskChatbotUtil.isValidReply(cleanMessage)) {
144
155
  // console.log("invalid message", cleanMessage);
@@ -156,8 +167,10 @@ class DirReply {
156
167
  (err) => {
157
168
  if (err) {
158
169
  console.error("Error sending reply:", err);
170
+ this.logger.error("Error sending reply ", err.response.data);
159
171
  }
160
172
  if (this.log) {console.log("Reply message sent:", JSON.stringify(cleanMessage));}
173
+ this.logger.info("Reply message sent!", cleanMessage.text);
161
174
  const delay = TiledeskChatbotUtil.totalMessageWait(cleanMessage);
162
175
  // console.log("got total delay:", delay)
163
176
  if (delay > 0 && delay <= 30000) { // prevent long delays
@@ -79,6 +79,8 @@ class DirReplyV2 {
79
79
  }
80
80
  }
81
81
 
82
+ TiledeskChatbotUtil.replaceJSONButtons(message, requestAttributes);
83
+
82
84
  try {
83
85
  // lock/unlock + no-match
84
86
  // get buttons if available
@@ -359,7 +359,7 @@ class DirWebRequestV2 {
359
359
  }
360
360
  return value;
361
361
  });
362
- console.error("An error occurred: ", error_log);
362
+ console.error("(DirWebRequestv2) An error occurred: ", error_log);
363
363
  // FIX THE STRINGIFY OF CIRCULAR STRUCTURE BUG - END
364
364
  // console.error("An error occurred:", JSON.stringify(err));
365
365
  }
@@ -34,10 +34,10 @@ class DirWebResponse {
34
34
  }
35
35
 
36
36
  async go(action, callback) {
37
- console.log("Web response...");
38
- let payload = action.payload;
39
- let status = action.status;
40
-
37
+ if (this.log) {
38
+ console.log("(DirWebResponse) action:", action);
39
+ }
40
+
41
41
  let requestAttributes = null;
42
42
  if (this.tdcache) {
43
43
  requestAttributes =
@@ -45,7 +45,7 @@ class DirWebResponse {
45
45
  const filler = new Filler();
46
46
 
47
47
  try {
48
- payload = filler.fill(payload, requestAttributes);
48
+ let status = action.status;
49
49
  status = filler.fill(status, requestAttributes);
50
50
  }
51
51
  catch(e) {
@@ -54,16 +54,19 @@ class DirWebResponse {
54
54
 
55
55
  }
56
56
 
57
+ const json = await this.getJsonFromAction(action, filler, requestAttributes)
57
58
  let webResponse = {
58
59
  status: status,
59
- payload: payload
60
+ payload: json
60
61
  }
61
62
 
62
63
  const topic = `/webhooks/${this.requestId}`;
63
64
 
64
65
  try {
65
66
  this.tdcache.publish(topic, JSON.stringify(webResponse));
66
- console.log("Published webresponse:", to_send, "to topic:", topic);
67
+ if (this.log) {
68
+ console.log("(DirWebResponse) Published webresponse to topic:", topic);
69
+ }
67
70
  }
68
71
  catch(e) {
69
72
  console.error(e)
@@ -72,8 +75,32 @@ class DirWebResponse {
72
75
  callback();
73
76
 
74
77
  }
78
+
79
+ async getJsonFromAction(action, filler, requestAttributes) {
80
+
81
+ return new Promise( async (resolve, reject) => {
82
+
83
+ if (action.payload && action.bodyType == "json") {
84
+ let jsonBody = filler.fill(action.payload, requestAttributes);
85
+ try {
86
+ let json = JSON.parse(jsonBody);
87
+ resolve(json);
88
+ }
89
+ catch (err) {
90
+ if (this.log) { console.error("Error parsing webRequest jsonBody:", jsonBody, err) };
91
+ reject("Error parsing jsonBody");
92
+ }
93
+ }
94
+ else {
95
+ resolve(null);
96
+ }
97
+ })
98
+ }
99
+
75
100
  }
76
101
 
102
+
103
+
77
104
  /**
78
105
  * A stub to send message to the "ext/botId" endpoint, hosted by tilebot on:
79
106
  * /${TILEBOT_ROUTE}/ext/${botId}
@@ -58,6 +58,7 @@ class Directives {
58
58
  static MOVE_TO_UNASSIGNED = "move_to_unassigned";
59
59
  static CONNECT_BLOCK = "connect_block";
60
60
  static ADD_TAGS = 'add_tags'
61
+ static WEBHOOK = 'webhook';
61
62
  static WEB_RESPONSE = "web_response";
62
63
 
63
64
  // static WHEN_ONLINE_MOVE_TO_AGENT = "whenonlinemovetoagent"; // DEPRECATED?