@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.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,13 @@
5
5
  available on:
6
6
  ▶️ https://www.npmjs.com/package/@tiledesk/tiledesk-tybot-connector
7
7
 
8
+ # v0.3.5-rc2
9
+ - bug-fixed: cannot set status of undefined reading res.status in DirAssistant
10
+
11
+ # v0.3.5-rc1
12
+ - changed: refactoring web-request-v2
13
+ - bug-fixed: jsonBody parse error in web-request-v2
14
+
8
15
  # v0.3.4
9
16
  -bug-fixed: slit is undefined in TiledeskChatbotUtils
10
17
 
@@ -14,6 +21,18 @@ available on:
14
21
  # v0.3.2
15
22
  - bug-fixed: minor improvement
16
23
 
24
+ # v0.2.153-rc9
25
+ - changed: updated tiledesk-multi-worker to 0.2.1-rc2
26
+
27
+ # v0.2.153-rc8
28
+ - added: fixToken function in TiledeskService utils class
29
+
30
+ # v0.2.153-rc4
31
+ - log added
32
+
33
+ # v0.2.153-rc3
34
+ - added: specchToText function to transcript audio file
35
+
17
36
  # v0.2.153-rc1
18
37
  - changed: context for gpt-40 and gpt-40-mini
19
38
 
package/Logger.js ADDED
@@ -0,0 +1,86 @@
1
+ let { Publisher } = require("@tiledesk/tiledesk-multi-worker");
2
+
3
+ const AMQP_MANAGER_URL = process.env.AMQP_MANAGER_URL;
4
+ let publisher = new Publisher(AMQP_MANAGER_URL, {
5
+ debug: false,
6
+ queueName: "logs_queue",
7
+ exchange: "tiledesk-multi",
8
+ topic: "logs",
9
+ })
10
+
11
+ class Logger {
12
+
13
+ constructor(config) {
14
+
15
+ if (!config) {
16
+ throw new Error('config is mandatory');
17
+ }
18
+
19
+ if (!config.request_id) {
20
+ console.error('config.request_id is mandatory');
21
+ //throw new Error('config.request_id is mandatory');
22
+ }
23
+
24
+ this.request_id = config.request_id;
25
+ this.dev = false;
26
+ if (config.dev && config.dev === true) {
27
+ this.dev = true;
28
+ }
29
+
30
+ if (!AMQP_MANAGER_URL) {
31
+ console.error('AMQP_MANAGER_URL is undefined. Logger not available...');
32
+ return;
33
+ //throw new Error("Error starting logger: AMQP_MANAGER_URL is undefined.")
34
+ }
35
+
36
+ }
37
+
38
+ error(...args) {
39
+ let log = this.formatLog(args);
40
+ return this.base('error', log);
41
+ }
42
+
43
+ warn(...args) {
44
+ let log = this.formatLog(args);
45
+ return this.base('warn', log);
46
+ }
47
+
48
+ info(...args) {
49
+ let log = this.formatLog(args);
50
+ return this.base('info', log);
51
+ }
52
+
53
+ debug(...args) {
54
+ let log = this.formatLog(args);
55
+ return this.base('debug', log);
56
+ }
57
+
58
+ base(level, text) {
59
+ if (!this.request_id || !publisher) {
60
+ console.log("Return because request or publisher is undefined", this.request_id, publisher);
61
+ return;
62
+ }
63
+
64
+ let data = {
65
+ request_id: this.request_id,
66
+ text: text,
67
+ level: level,
68
+ timestamp: new Date(),
69
+ dev: this.dev
70
+ }
71
+
72
+ publisher.publish(data, (err, ok) => {
73
+ if (err) console.warn("publish log fail: ", err);
74
+ return;
75
+ })
76
+ }
77
+
78
+ formatLog(args) {
79
+ return args
80
+ .map(arg => (typeof arg === "object" ? JSON.stringify(arg, null, 2) : arg ))
81
+ .join(" ")
82
+ }
83
+
84
+ }
85
+
86
+ module.exports = { Logger }
package/TdCache.js CHANGED
@@ -3,15 +3,12 @@ const redis = require('redis');
3
3
  class TdCache {
4
4
 
5
5
  constructor(config) {
6
- console.log("TdCache config: ", config);
6
+
7
7
  this.redis_host = config.host;
8
8
  this.redis_port = config.port;
9
9
  this.redis_password = config.password;
10
- console.log("TdCache this.redis_host: ", this.redis_host);
11
- console.log("TdCache this.redis_port: ", this.redis_port);
12
- console.log("TdCache this.redis_password: ", this.redis_password);
13
10
  this.client = null;
14
- this.redis_sub = null;
11
+ this.subscriberClient = null;
15
12
  }
16
13
 
17
14
  async connect(callback) {
@@ -42,24 +39,24 @@ class TdCache {
42
39
  /**
43
40
  * Connect redis subscription client
44
41
  */
45
- this.redis_sub = redis.createClient(
42
+ this.subscriberClient = redis.createClient(
46
43
  {
47
44
  url: `redis://${this.redis_host}:${this.redis_port}`,
48
45
  password: this.redis_password
49
46
  });
50
- this.redis_sub.on('error', err => {
47
+ this.subscriberClient.on('error', err => {
51
48
  reject(err);
52
49
  if (callback) {
53
50
  callback(err);
54
51
  }
55
52
  });
56
- this.redis_sub.on('ready',function() {
53
+ this.subscriberClient.on('ready',function() {
57
54
  resolve();
58
55
  if (callback) {
59
56
  callback();
60
57
  }
61
58
  });
62
- await this.redis_sub.connect();
59
+ await this.subscriberClient.connect();
63
60
  });
64
61
  }
65
62
 
@@ -133,7 +130,25 @@ class TdCache {
133
130
  }
134
131
 
135
132
  async publish(key, value) {
136
- await this.redis_sub.publish(key, value);
133
+ await this.client.publish(key, value);
134
+ }
135
+
136
+ async subscribe(topic, callback) {
137
+ if (!this.subscriberClient) {
138
+ throw new Error("Redis subscriber not connected");
139
+ }
140
+
141
+ if (!callback || typeof callback !== 'function') {
142
+ throw new Error("Callback is mandatory for subscribe")
143
+ }
144
+
145
+ await this.subscriberClient.subscribe(topic, (message) => {
146
+ callback(message, topic);
147
+ })
148
+ }
149
+
150
+ async unsubscribe(topic, listener) {
151
+ await this.subscriberClient.unsubscribe(topic, listener);
137
152
  }
138
153
 
139
154
  // subscribe(key, callback) {
package/index.js CHANGED
@@ -20,6 +20,7 @@ router.use(bodyParser.json({limit: '50mb'}));
20
20
  router.use(bodyParser.urlencoded({ extended: true , limit: '50mb'}));
21
21
 
22
22
  let log = false;
23
+ /** @type {TdCache} */
23
24
  let tdcache = null;
24
25
  let MAX_STEPS = 1000;
25
26
  let MAX_EXECUTION_TIME = 1000 * 3600 * 8;
@@ -581,46 +582,117 @@ router.post('/echobot', (req, res) => {
581
582
  });
582
583
  });
583
584
 
584
- // draft webhook
585
585
  router.post('/block/:project_id/:bot_id/:block_id', async (req, res) => {
586
- const project_id = req.params['project_id'];
587
- const bot_id = req.params['bot_id'];
588
- const block_id = req.params['block_id'];
586
+
587
+ const project_id = req.params.project_id;
588
+ const bot_id = req.params.bot_id;
589
+ const block_id = req.params.block_id;
589
590
  const body = req.body;
590
- if (this.log) {
591
- console.log("/block/ .heders:", JSON.stringify(req.headers));
592
- console.log("/block/ .body:", JSON.stringify(body));
593
- }
594
-
595
- // console.log('/block/:project_id/:bot_id/:block_id:', project_id, "/", bot_id, "/", block_id);
596
- // console.log('/block/:project_id/:bot_id/:block_id.body', body);
591
+ const async = body.async;
592
+ const token = body.token;
593
+ delete body.async;
594
+ delete body.token;
597
595
 
598
596
  // invoke block
599
597
  // unique ID for each execution
600
598
  const execution_id = uuidv4().replace(/-/g, '');
601
599
  const request_id = "automation-request-" + project_id + "-" + execution_id;
602
- const command = "/" + block_id;
603
- let request = {
604
- "payload": {
605
- "recipient": request_id,
606
- "text": command,
607
- "id_project": project_id,
608
- "request": {
609
- "request_id": request_id
600
+ const command = "/#" + block_id;
601
+ let message = {
602
+ payload: {
603
+ recipient: request_id,
604
+ text: command,
605
+ id_project: project_id,
606
+ request: {
607
+ request_id: request_id
610
608
  },
611
- "attributes": {
612
- "payload": body
609
+ attributes: {
610
+ payload: body
613
611
  }
614
612
  },
615
- "token": "NO-TOKEN"
613
+ token: token
616
614
  }
617
- if (this.log) {console.log("sendMessageToBot()...", JSON.stringify(request));}
618
- sendMessageToBot(TILEBOT_ENDPOINT, request, bot_id, async () => {
619
- res.status(200).send({"success":true});
620
- return;
621
- });
615
+
616
+ if (async) {
617
+ console.log("Async webhook");
618
+ sendMessageToBot(TILEBOT_ENDPOINT, message, bot_id, (err, resbody) => {
619
+ if (err) {
620
+ console.error("Async err:\n", err);
621
+ return res.status(500).send({ success: false, error: err });
622
+ }
623
+ return res.status(200).send({ success: true });
624
+ })
625
+ } else {
626
+
627
+ console.log("Sync webhook. Subscribe and await for reply...")
628
+ const topic = `/webhooks/${request_id}`;
629
+
630
+ try {
631
+
632
+ const listener = async (message, topic) => {
633
+ console.log("Web response is: ", message, "for topic", topic);
634
+ await tdcache.unsubscribe(topic, listener);
635
+
636
+ let json = JSON.parse(message);
637
+ let status = json.status ? json.status : 200;
638
+ console.log("Web response status: ", status);
639
+
640
+ return res.status(status).send(json.payload);
641
+ }
642
+ await tdcache.subscribe(topic, listener);
643
+
644
+ } catch(err) {
645
+ console.error("Error cache subscribe ", err);
646
+ return res.status(500).send({ success: false, error: "Error during cache subscription"})
647
+ }
648
+
649
+ sendMessageToBot(TILEBOT_ENDPOINT, message, bot_id, () => {
650
+ console.log("Sync webhook message sent: ", message);
651
+ })
652
+ }
653
+
622
654
  });
623
655
 
656
+ // draft webhook
657
+ // router.post('/block/:project_id/:bot_id/:block_id', async (req, res) => {
658
+ // const project_id = req.params['project_id'];
659
+ // const bot_id = req.params['bot_id'];
660
+ // const block_id = req.params['block_id'];
661
+ // const body = req.body;
662
+ // if (this.log) {
663
+ // console.log("/block/ .heders:", JSON.stringify(req.headers));
664
+ // console.log("/block/ .body:", JSON.stringify(body));
665
+ // }
666
+
667
+ // // console.log('/block/:project_id/:bot_id/:block_id:', project_id, "/", bot_id, "/", block_id);
668
+ // // console.log('/block/:project_id/:bot_id/:block_id.body', body);
669
+
670
+ // // invoke block
671
+ // // unique ID for each execution
672
+ // const execution_id = uuidv4().replace(/-/g, '');
673
+ // const request_id = "automation-request-" + project_id + "-" + execution_id;
674
+ // const command = "/" + block_id;
675
+ // let request = {
676
+ // "payload": {
677
+ // "recipient": request_id,
678
+ // "text": command,
679
+ // "id_project": project_id,
680
+ // "request": {
681
+ // "request_id": request_id
682
+ // },
683
+ // "attributes": {
684
+ // "payload": body
685
+ // }
686
+ // },
687
+ // "token": "NO-TOKEN"
688
+ // }
689
+ // if (this.log) {console.log("sendMessageToBot()...", JSON.stringify(request));}
690
+ // sendMessageToBot(TILEBOT_ENDPOINT, request, bot_id, async () => {
691
+ // res.status(200).send({"success":true});
692
+ // return;
693
+ // });
694
+ // });
695
+
624
696
  async function startApp(settings, completionCallback) {
625
697
  console.log("Starting Tilebot...");
626
698
  // console.log("Starting Tilebot with Settings:", settings);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiledesk/tiledesk-tybot-connector",
3
- "version": "0.3.4",
3
+ "version": "0.3.5-rc2",
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",
@@ -55,6 +55,7 @@ const { DirAddTags } = require('./directives/DirAddTags');
55
55
  const { DirSendWhatsapp } = require('./directives/DirSendWhatsapp');
56
56
  const { DirReplaceBotV3 } = require('./directives/DirReplaceBotV3');
57
57
  const { DirAiTask, DirAiPrompt } = require('./directives/DirAiPrompt');
58
+ const { DirWebResponse } = require('./directives/DirWebResponse');
58
59
 
59
60
  class DirectivesChatbotPlug {
60
61
 
@@ -772,6 +773,12 @@ class DirectivesChatbotPlug {
772
773
  }
773
774
  });
774
775
  }
776
+ else if (directive_name === Directives.WEB_RESPONSE) {
777
+ new DirWebResponse(context).execute(directive, async () => {
778
+ let next_dir = await this.nextDirective(this.directives);
779
+ this.process(next_dir);
780
+ });
781
+ }
775
782
  else {
776
783
  //console.log("Unhandled Post-message Directive:", directive_name);
777
784
  let next_dir = await this.nextDirective(this.directives);
@@ -407,17 +407,17 @@ class DirAssistant {
407
407
  if (this.log) {console.log("DirAssistant HTTPREQUEST", HTTPREQUEST);}
408
408
  this.#myrequest(
409
409
  HTTPREQUEST, async (err, res) => {
410
- let status = res.status;
411
410
  if (err) {
412
411
  if (this.log) {console.error("DirAssistant error:", err);}
413
412
  reject(err);
414
413
  }
415
- else if(res.status >= 200 && res.status <= 299) {
414
+ else if(res?.status >= 200 && res?.status <= 299) {
416
415
  if (this.log) {console.log("got response data:", res.data);}
417
416
  // let return_body = res.data;
418
417
  resolve(res.data);
419
418
  }
420
419
  else {
420
+ let status = res?.status;
421
421
  reject(new Error("Message add status != 200:", status));
422
422
  }
423
423
  }
@@ -442,17 +442,17 @@ class DirAssistant {
442
442
  if (this.log) {console.log("DirAssistant HTTPREQUEST", HTTPREQUEST);}
443
443
  this.#myrequest(
444
444
  HTTPREQUEST, async (err, res) => {
445
- let status = res.status;
446
445
  if (err) {
447
446
  if (this.log) {console.error("DirAssistant error:", err);}
448
447
  reject(err);
449
448
  }
450
- else if(res.status >= 200 && res.status <= 299) {
449
+ else if(res?.status >= 200 && res?.status <= 299) {
451
450
  if (this.log) {console.log("got response data:", res.data);}
452
451
  // let return_body = res.data;
453
452
  resolve(res.data);
454
453
  }
455
454
  else {
455
+ let status = res?.status;
456
456
  reject(new Error("Message add status != 200:", status));
457
457
  }
458
458
  }
@@ -477,17 +477,17 @@ class DirAssistant {
477
477
  if (this.log) {console.log("DirAssistant HTTPREQUEST", HTTPREQUEST);}
478
478
  this.#myrequest(
479
479
  HTTPREQUEST, async (err, res) => {
480
- let status = res.status;
481
480
  if (err) {
482
481
  if (this.log) {console.error("DirAssistant error:", err);}
483
482
  reject(err);
484
483
  }
485
- else if(res.status >= 200 && res.status <= 299) {
484
+ else if(res?.status >= 200 && res?.status <= 299) {
486
485
  if (this.log) {console.log("got response data:", res.data);}
487
486
  // let return_body = res.data;
488
487
  resolve(res.data);
489
488
  }
490
489
  else {
490
+ let status = res?.status;
491
491
  reject(new Error("Message add status != 200:", status));
492
492
  }
493
493
  }
@@ -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
  }
@@ -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,10 +41,14 @@ 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
  }
@@ -64,13 +71,16 @@ class DirReply {
64
71
  const filler = new Filler();
65
72
  // fill text attribute
66
73
  message.text = filler.fill(message.text, requestAttributes);
74
+
67
75
  if (message.metadata) {
68
76
  if (this.log) {console.log("filling message 'metadata':", JSON.stringify(message.metadata));}
69
77
  if (message.metadata.src) {
70
78
  message.metadata.src = filler.fill(message.metadata.src, requestAttributes);
79
+ this.logger.debug("Filled metadata.src with ", message.metadata.src);
71
80
  }
72
81
  if (message.metadata.name) {
73
82
  message.metadata.name = filler.fill(message.metadata.name, requestAttributes);
83
+ this.logger.debug("Filled metadata.name with ", message.metadata.name);
74
84
  }
75
85
  }
76
86
  if (this.log) {console.log("filling commands'. Message:", JSON.stringify(message));}
@@ -84,6 +94,7 @@ class DirReply {
84
94
  let command = commands[i];
85
95
  if (command.type === 'message' && command.message && command.message.text) {
86
96
  command.message.text = filler.fill(command.message.text, requestAttributes);
97
+ this.logger.debug("Filled message.text with ", command.message.text)
87
98
  TiledeskChatbotUtil.fillCommandAttachments(command, requestAttributes, this.log);
88
99
  if (this.log) {console.log("command filled:", command.message.text);}
89
100
  }
@@ -133,12 +144,14 @@ class DirReply {
133
144
  }
134
145
  catch(err) {
135
146
  console.error("An error occurred while JSON.parse(). Parsed value:" + value + " in allParametersStatic(). Error:", err);
147
+ this.logger.error("An error occurred while JSON.parse(). Parsed value:" + value + " in allParametersStatic(). Error:", err);
136
148
  }
137
149
  }
138
150
  }
139
151
  }
140
152
  // send!
141
153
  let cleanMessage = message;
154
+ this.logger.info("Sending reply with text ", cleanMessage.text);
142
155
  // cleanMessage = TiledeskChatbotUtil.removeEmptyReplyCommands(message);
143
156
  // if (!TiledeskChatbotUtil.isValidReply(cleanMessage)) {
144
157
  // console.log("invalid message", cleanMessage);
@@ -156,8 +169,10 @@ class DirReply {
156
169
  (err) => {
157
170
  if (err) {
158
171
  console.error("Error sending reply:", err);
172
+ this.logger.error("Error sending reply ", err.response.data);
159
173
  }
160
174
  if (this.log) {console.log("Reply message sent:", JSON.stringify(cleanMessage));}
175
+ this.logger.info("Reply message sent!", cleanMessage.text);
161
176
  const delay = TiledeskChatbotUtil.totalMessageWait(cleanMessage);
162
177
  // console.log("got total delay:", delay)
163
178
  if (delay > 0 && delay <= 30000) { // prevent long delays