@tiledesk/tiledesk-tybot-connector 0.3.4 → 0.3.5-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.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,10 @@
5
5
  available on:
6
6
  ▶️ https://www.npmjs.com/package/@tiledesk/tiledesk-tybot-connector
7
7
 
8
+ # v0.3.5-rc1
9
+ - changed: refactoring web-request-v2
10
+ - bug-fixed: jsonBody parse error in web-request-v2
11
+
8
12
  # v0.3.4
9
13
  -bug-fixed: slit is undefined in TiledeskChatbotUtils
10
14
 
@@ -14,6 +18,18 @@ available on:
14
18
  # v0.3.2
15
19
  - bug-fixed: minor improvement
16
20
 
21
+ # v0.2.153-rc9
22
+ - changed: updated tiledesk-multi-worker to 0.2.1-rc2
23
+
24
+ # v0.2.153-rc8
25
+ - added: fixToken function in TiledeskService utils class
26
+
27
+ # v0.2.153-rc4
28
+ - log added
29
+
30
+ # v0.2.153-rc3
31
+ - added: specchToText function to transcript audio file
32
+
17
33
  # v0.2.153-rc1
18
34
  - changed: context for gpt-40 and gpt-40-mini
19
35
 
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-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",
@@ -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);
@@ -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