@tiledesk/tiledesk-tybot-connector 0.1.27 → 0.1.28

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/.env ADDED
@@ -0,0 +1,11 @@
1
+ API_ENDPOINT=http://localhost:10002
2
+ mongoUrl=mongodb://tiledesk-user1:YB62b7gQNGg3G9OW@tiledesk-prod-shard-00-00-vmvst.mongodb.net:27017,tiledesk-prod-shard-00-01-vmvst.mongodb.net:27017,tiledesk-prod-shard-00-02-vmvst.mongodb.net:27017/tiledesk-pre?ssl=true&replicaSet=tiledesk-prod-shard-0&authSource=admin&retryWrites=true
3
+ REDIS_HOST=redis-17533.c135.eu-central-1-1.ec2.cloud.redislabs.com
4
+ REDIS_PASSWORD=ZSKKrWfnR6o5Gkt17ZgPkKGu1DcrUTge
5
+ REDIS_PORT=17533
6
+ TYBOT_ENDPOINT=http://localhost:10001
7
+ CHATBOT_TOKEN=JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3ZWJob29rX2VuYWJsZWQiOmZhbHNlLCJ0eXBlIjoiZXh0ZXJuYWwiLCJsYW5ndWFnZSI6ImVuIiwicHVibGljIjpmYWxzZSwiX2lkIjoiNjM4Yzc5MDQxZGI0NDkwMDM1MTEwMjYwIiwibmFtZSI6IlRoZSBGb3JtIHYyIC0gZXh0IiwidXJsIjoiaHR0cHM6Ly90aWxlYm90LWRldi5oZXJva3VhcHAuY29tL2V4dC82MzhjNzhkNzFkYjQ0OTAwMzUxMTAxYzIiLCJpZF9wcm9qZWN0IjoiNjM4Yzc4YTYxZGI0NDkwMDM1MTBmZjkxIiwidHJhc2hlZCI6ZmFsc2UsImNyZWF0ZWRCeSI6IjVlMDlkMTZkNGQzNjExMDAxNzUwNmQ3ZiIsImNyZWF0ZWRBdCI6IjIwMjItMTItMDRUMTA6NDA6MDQuMjA3WiIsInVwZGF0ZWRBdCI6IjIwMjItMTItMDVUMDc6MjE6MDIuOTIxWiIsIl9fdiI6MCwiZGVzY3JpcHRpb24iOiJPbiBIZXJva3UiLCJpYXQiOjE2NzA2NzE4ODksImF1ZCI6Imh0dHBzOi8vdGlsZWRlc2suY29tL2JvdHMvNjM4Yzc5MDQxZGI0NDkwMDM1MTEwMjYwIiwiaXNzIjoiaHR0cHM6Ly90aWxlZGVzay5jb20iLCJzdWIiOiJib3QiLCJqdGkiOiJmNDVlZGIwYS0zNzVhLTQ0NjMtYjFhZi1jM2ZiZDg4YmE3ZGQifQ.FbW3csHl1sQgSyRz5Jg0qaTvvpXWXgWHlJ1JWoVbv3s
8
+ CHATBOT_ENDPOINT=http://localhost:10001
9
+ _API_LOG=1
10
+ TEST_PROJECT_ID=638c78a61db449003510ff91
11
+ TEST_BOT_ID=638c78d71db44900351101c2
package/CHANGELOG.md CHANGED
@@ -5,6 +5,11 @@
5
5
  available on:
6
6
  ▶️ https://www.npmjs.com/package/@tiledesk/tiledesk-tybot-connector
7
7
 
8
+ ### 0.1.28 - online
9
+ - Added a 'serious' integration test for chatbot
10
+ - Removed reference to requestId and depId from processInlineDirectives()
11
+ - Added id_project to the 'minimum' request object used in directives not accessing Tiledesk APIs
12
+
8
13
  ### 0.1.27 - online
9
14
  - log fix
10
15
 
package/index.js CHANGED
@@ -149,26 +149,48 @@ router.post('/ext/:projectId/requests/:requestId/messages', async (req, res) =>
149
149
  APIKEY: "___",
150
150
  log: false
151
151
  });
152
-
153
152
  let request;
154
153
  const request_key = "tilebot:" + requestId;
154
+ if (log) {console.log("request_key:", request_key);}
155
155
  if (tdcache) {
156
156
  request = await tdcache.getJSON(request_key)
157
- if (log) {console.log("HIT! Request from cache:", request.request_id);}
157
+ if (log) {console.log("Request from cache:", request);}
158
158
  if (!request) {
159
159
  if (log) {console.log("!Request from cache", requestId);}
160
- request = await tdclient.getRequestById(requestId);
160
+ try {
161
+ request = await tdclient.getRequestById(requestId);
162
+ }
163
+ catch(err) {
164
+ console.error("Error getting the request:", err)
165
+ }
161
166
  if (log) {console.log("Got request with APIs (after no cache hit)");}
162
167
  }
163
168
  }
164
169
  else {
165
170
  if (log) {console.log("No tdcache. Getting request with APIs", requestId);}
166
- request = await tdclient.getRequestById(requestId);
171
+ try {
172
+ request = await tdclient.getRequestById(requestId);
173
+ }
174
+ catch(err) {
175
+ console.log("Request not found.");
176
+ }
167
177
  if (log) {console.log("(No tdcache) Got request with APIs");}
168
178
  }
179
+ if (!request) {
180
+ // chatbot-pure directives still work. Tiledesk specific directives don't
181
+ request = {
182
+ request_id: requestId,
183
+ id_project: projectId
184
+ }
185
+ }
186
+ else {
187
+ if (log) {console.log("request", request);}
188
+ }
189
+ if (log) {console.log("request...", request);}
169
190
  let directivesPlug = new DirectivesChatbotPlug({supportRequest: request, TILEDESK_API_ENDPOINT: APIURL, TILEBOT_ENDPOINT:process.env.TYBOT_ENDPOINT, token: token, log: log, HELP_CENTER_API_ENDPOINT: process.env.HELP_CENTER_API_ENDPOINT, cache: tdcache});
170
191
  // PIPELINE-EXT
171
192
  const bot_answer = await ExtUtil.execPipelineExt(request, answer, directivesPlug, tdcache, log);
193
+ // console.log("bot_answer", bot_answer)
172
194
  //const bot_answer = answer;
173
195
  // console.log("bot_answer to send:", bot_answer);
174
196
  // empty answer
@@ -193,6 +215,7 @@ router.post('/ext/:projectId/requests/:requestId/messages', async (req, res) =>
193
215
  // triggeredByMessageId: '6392e5e8408e0000437aa383'
194
216
  // }
195
217
  if (bot_answer) {
218
+ bot_answer["_raw_message"] = answer.text;
196
219
  tdclient.sendSupportMessage(requestId, bot_answer, (err, response) => {
197
220
  if (err) {
198
221
  console.error("Error sending message", err);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiledesk/tiledesk-tybot-connector",
3
- "version": "0.1.27",
3
+ "version": "0.1.28",
4
4
  "description": "Tiledesk Tybot connector",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -14,7 +14,7 @@
14
14
  "@tiledesk/helpcenter-query-client": "^0.1.8",
15
15
  "@tiledesk/tiledesk-chatbot-client": "^0.5.30",
16
16
  "@tiledesk/tiledesk-chatbot-util": "^0.8.38",
17
- "@tiledesk/tiledesk-client": "^0.8.39",
17
+ "@tiledesk/tiledesk-client": "^0.8.41",
18
18
  "axios": "^0.27.2",
19
19
  "body-parser": "^1.19.0",
20
20
  "cors": "^2.8.5",
@@ -24,6 +24,7 @@
24
24
  "mongoose": "^6.3.5",
25
25
  "nanoid": "^3.1.25",
26
26
  "redis": "^3.1.2",
27
- "uuid": "^3.3.3"
27
+ "uuid": "^3.3.3",
28
+ "dotenv": "^16.0.3"
28
29
  }
29
30
  }
@@ -0,0 +1,277 @@
1
+ var assert = require('assert');
2
+ let axios = require('axios');
3
+ const tybot = require("../");
4
+ const tybotRoute = tybot.router;
5
+ var express = require('express');
6
+ var app = express();
7
+ app.use("/", tybotRoute);
8
+ require('dotenv').config();
9
+ const bodyParser = require('body-parser');
10
+
11
+ const REQUEST_ID = "support-group-" + process.env.TEST_PROJECT_ID + "-" + Date.now();
12
+ console.log("REQUEST_ID:", REQUEST_ID);
13
+ let app_listener;
14
+
15
+ before( () => {
16
+ return new Promise( async (resolve, reject) => {
17
+ console.log("Starting tilebot server...");
18
+ tybot.startApp(
19
+ {
20
+ MONGODB_URI: process.env.mongoUrl,
21
+ API_ENDPOINT: process.env.API_ENDPOINT,
22
+ REDIS_HOST: process.env.REDIS_HOST,
23
+ REDIS_PORT: process.env.REDIS_PORT,
24
+ REDIS_PASSWORD: process.env.REDIS_PASSWORD,
25
+ log: process.env.API_LOG
26
+ }, () => {
27
+ console.log("Tilebot route successfully started.");
28
+ var port = process.env.PORT || 10001;
29
+ app_listener = app.listen(port, () => {
30
+ console.log('Tilebot connector listening on port ', port);
31
+ resolve();
32
+ // var listener = endpointServer.listen(10002, '0.0.0.0', function () {
33
+ // console.log('endpointServer started', listener.address());
34
+ // resolve();
35
+ // });
36
+ });
37
+ });
38
+ })
39
+ });
40
+
41
+ after(function(done) {
42
+ app_listener.close( () => {
43
+ console.log('app_listener closed.');
44
+ done();
45
+ });
46
+ });
47
+
48
+ describe('Conversation1', async() => {
49
+
50
+ it('/start', (done) => {
51
+ console.log("/start...ing story...");
52
+ let listener;
53
+ let endpointServer = express();
54
+ endpointServer.use(bodyParser.json());
55
+ endpointServer.post('/:projectId/requests/:requestId/messages', function (req, res) {
56
+ // console.log("req.body:", JSON.stringify(req.body));
57
+ res.send({success: true});
58
+ const message = req.body;
59
+ assert(message.text === "Hello");
60
+ assert(message.attributes.commands !== null);
61
+ assert(message.attributes.commands.length === 3);
62
+ const command1 = message.attributes.commands[0];
63
+ const command2 = message.attributes.commands[1];
64
+ const command3 = message.attributes.commands[2];
65
+
66
+ assert(command1.type === "message");
67
+ assert(command1.message.text === "");
68
+ assert(command1.message.type === "image");
69
+ assert(command1.message.metadata.src !== null);
70
+
71
+ assert(command2.type === "wait");
72
+ assert(command2.time === 500);
73
+
74
+ listener.close( () => {
75
+ // console.log('closed.');
76
+ done();
77
+ });
78
+
79
+ });
80
+
81
+ listener = endpointServer.listen(10002, '0.0.0.0', function () {
82
+ // console.log('endpointServer started', listener.address());
83
+ });
84
+
85
+ const botId = process.env.TEST_BOT_ID;
86
+ // console.log("botId:", botId);
87
+ let request = {
88
+ "payload": {
89
+ "_id": "ID",
90
+ "senderFullname": "guest#367e",
91
+ "type": "text",
92
+ "sender": "A-SENDER",
93
+ "recipient": REQUEST_ID,
94
+ "text": "/start",
95
+ "id_project": process.env.TEST_PROJECT_ID,
96
+ "metadata": "",
97
+ "request": {
98
+ "request_id": REQUEST_ID
99
+ }
100
+ },
101
+ "token": process.env.CHATBOT_TOKEN
102
+ }
103
+ sendMessageToBot(request, botId, process.env.CHATBOT_TOKEN, () => {
104
+ // console.log("Message sent.");
105
+ });
106
+ });
107
+
108
+ it('/disable_input', (done) => {
109
+ console.log("/disable_input...");
110
+ let listener;
111
+ let endpointServer = express();
112
+ endpointServer.use(bodyParser.json());
113
+ endpointServer.post('/:projectId/requests/:requestId/messages', function (req, res) {
114
+ // console.log("req.body:", JSON.stringify(req.body));
115
+ res.send({success: true});
116
+ const message = req.body;
117
+
118
+ assert(message["text"] !== "");
119
+ assert(message["attributes"] !== "");
120
+ assert(message["attributes"]["disableInputMessage"] === true);
121
+
122
+ listener.close( () => {
123
+ // console.log('closed.');
124
+ done();
125
+ });
126
+
127
+ });
128
+
129
+ listener = endpointServer.listen(10002, '0.0.0.0', function () {
130
+ // console.log('endpointServer started', listener.address());
131
+ const botId = process.env.TEST_BOT_ID;
132
+ const PROJECT_ID = process.env.TEST_PROJECT_ID;
133
+ console.log("botId:", botId);
134
+ console.log("REQUEST_ID:", REQUEST_ID);
135
+ let request = {
136
+ "payload": {
137
+ "_id": "ID",
138
+ "senderFullname": "guest#367e",
139
+ "type": "text",
140
+ "sender": "A-SENDER",
141
+ "recipient": REQUEST_ID,
142
+ "text": "/disable_input",
143
+ "id_project": PROJECT_ID,
144
+ "metadata": "",
145
+ "request": {
146
+ "request_id": REQUEST_ID,
147
+ "id_project": PROJECT_ID
148
+ }
149
+ },
150
+ "token": process.env.CHATBOT_TOKEN
151
+ }
152
+ sendMessageToBot(request, botId, process.env.CHATBOT_TOKEN, () => {
153
+ // console.log("Message sent.");
154
+ });
155
+ });
156
+ });
157
+
158
+ });
159
+
160
+ // function createRequest(projectId, callback) {
161
+
162
+ // const tdclient = new TiledeskClient({
163
+ // APIKEY: "___",
164
+ // APIURL: "",
165
+ // projectId: projectId,
166
+ // token: ANONYM_USER_TOKEN,
167
+ // log: false
168
+ // });
169
+ // if (tdclient) {
170
+ // assert(tdclient != null);
171
+ // const text_value = 'test message';
172
+ // const request_id = TiledeskClient.newRequestId(PROJECT_ID);
173
+ // tdclient.sendSupportMessage(request_id, {text: text_value}, function(err, result) {
174
+ // assert(err === null);
175
+ // assert(result != null);
176
+ // assert(result.text === text_value);
177
+ // done();
178
+ // });
179
+ // }
180
+ // else {
181
+ // assert.ok(false);
182
+ // }
183
+ // }
184
+
185
+ // function createAnonyUser(projecId, callback) {
186
+ // TiledeskClient.anonymousAuthentication(
187
+ // projecId,
188
+ // "_",
189
+ // {
190
+ // APIURL: API_ENDPOINT,
191
+ // log: false
192
+ // },
193
+ // function(err, result) {
194
+ // if (!err && result) {
195
+ // callback(result.token)
196
+ // }
197
+ // else {
198
+ // callback(null);
199
+ // }
200
+ // }
201
+ // );
202
+ // }
203
+
204
+ /**
205
+ * A stub to send message to the "ext/botId" endpoint, hosted by tilebot on:
206
+ * /${TILEBOT_ROUTE}/ext/${botId}
207
+ *
208
+ * @param {Object} message. The message to send
209
+ * @param {string} botId. Tiledesk botId
210
+ * @param {string} token. User token
211
+ */
212
+ function sendMessageToBot(message, botId, token, callback) {
213
+ // const jwt_token = this.fixToken(token);
214
+ const url = `${process.env.CHATBOT_ENDPOINT}/ext/${botId}`;
215
+ // console.log("sendMessageToBot URL", url);
216
+ const HTTPREQUEST = {
217
+ url: url,
218
+ headers: {
219
+ 'Content-Type' : 'application/json'
220
+ },
221
+ json: message,
222
+ method: 'POST'
223
+ };
224
+ myrequest(
225
+ HTTPREQUEST,
226
+ function(err, resbody) {
227
+ if (err) {
228
+ if (callback) {
229
+ callback(err);
230
+ }
231
+ }
232
+ else {
233
+ if (callback) {
234
+ callback(null, resbody);
235
+ }
236
+ }
237
+ }, true
238
+ );
239
+ }
240
+
241
+ function myrequest(options, callback, log) {
242
+ if (this.log) {
243
+ console.log("API URL:", options.url);
244
+ console.log("** Options:", options);
245
+ }
246
+ axios(
247
+ {
248
+ url: options.url,
249
+ method: options.method,
250
+ data: options.json,
251
+ params: options.params,
252
+ headers: options.headers
253
+ })
254
+ .then((res) => {
255
+ if (this.log) {
256
+ console.log("Response for url:", options.url);
257
+ console.log("Response headers:\n", res.headers);
258
+ //console.log("******** Response for url:", res);
259
+ }
260
+ if (res && res.status == 200 && res.data) {
261
+ if (callback) {
262
+ callback(null, res.data);
263
+ }
264
+ }
265
+ else {
266
+ if (callback) {
267
+ callback(TiledeskClient.getErr({message: "Response status not 200"}, options, res), null, null);
268
+ }
269
+ }
270
+ })
271
+ .catch( (error) => {
272
+ console.error("An error occurred:", error);
273
+ if (callback) {
274
+ callback(error, null, null);
275
+ }
276
+ });
277
+ }
@@ -1,4 +1,5 @@
1
1
  #npx mocha ./test/*.js --grep "_test 17_" --timeout 10000 --exit
2
2
  #npx mocha ./test/mock_query_test.js
3
3
  #npx mocha ./test/disable_input_text_directive_test.js
4
- npx mocha ./test/close_directive_test.js
4
+ #npx mocha ./test/close_directive_test.js
5
+ npx mocha ./test/conversation1-test.js --exit
@@ -83,8 +83,10 @@ class DirectivesChatbotPlug {
83
83
  const TILEBOT_ENDPOINT = this.TILEBOT_ENDPOINT;
84
84
 
85
85
  const requestId = supportRequest.request_id
86
- const depId = supportRequest.department._id;
87
- //const depId = supportRequest.attributes.departmentId;
86
+ let depId;
87
+ if (supportRequest.department && supportRequest.department._id) {
88
+ depId = supportRequest.department._id;
89
+ }
88
90
  const projectId = supportRequest.id_project;
89
91
  const tdcache = this.tdcache;
90
92
  //console.log("TDCACHE:", this.tdcache, tdcache)
@@ -204,11 +206,17 @@ class DirectivesChatbotPlug {
204
206
  });
205
207
  }
206
208
  else if (directive_name === Directives.AGENT) {
207
- const agentDir = new DirMoveToAgent(tdclient);
208
- directive.whenOnlineOnly = false;
209
- agentDir.execute(directive, requestId, depId, () => {
209
+ if (depId) {
210
+ const agentDir = new DirMoveToAgent(tdclient);
211
+ directive.whenOnlineOnly = false;
212
+ agentDir.execute(directive, requestId, depId, () => {
213
+ process(nextDirective());
214
+ });
215
+ }
216
+ else {
217
+ console.log("Warning. DepId null while calling 'AGENT' directive")
210
218
  process(nextDirective());
211
- });
219
+ }
212
220
  }
213
221
  else if (directive_name === Directives.CLOSE) {
214
222
  const closeDir = new DirClose({tdclient: tdclient});
@@ -217,11 +225,17 @@ class DirectivesChatbotPlug {
217
225
  });
218
226
  }
219
227
  else if (directive_name === Directives.WHEN_ONLINE_MOVE_TO_AGENT) {
220
- const agentDir = new DirMoveToAgent(tdclient);
221
- directive.whenOnlineOnly = true;
222
- agentDir.execute(directive, requestId, depId, () => {
228
+ if (depId) {
229
+ const agentDir = new DirMoveToAgent(tdclient);
230
+ directive.whenOnlineOnly = true;
231
+ agentDir.execute(directive, requestId, depId, () => {
232
+ process(nextDirective());
233
+ });
234
+ }
235
+ else {
236
+ console.log("Warning. DepId null while calling 'WHEN_ONLINE_MOVE_TO_AGENT' directive")
223
237
  process(nextDirective());
224
- });
238
+ }
225
239
  }
226
240
  else if (directive_name === Directives.REMOVE_CURRENT_BOT) {
227
241
  tdclient.removeCurrentBot(requestId, (err) => {
@@ -276,11 +290,11 @@ class DirectivesChatbotPlug {
276
290
  const supportRequest = this.supportRequest;
277
291
  const token = this.token;
278
292
  const API_URL = this.API_URL;
279
-
280
- //console.log("supportRequest", supportRequest)
281
- const requestId = supportRequest.request_id
282
- const depId = supportRequest.department._id;
283
- //const depId = supportRequest.attributes.departmentId;
293
+ // const requestId = supportRequest.request_id
294
+ // let depId;
295
+ // if (supportRequest.department && supportRequest.department._id) {
296
+ // depId = supportRequest.department._id;
297
+ // }
284
298
  const projectId = supportRequest.id_project;
285
299
  const tdclient = new TiledeskClient({
286
300
  projectId: projectId,
@@ -289,7 +303,6 @@ class DirectivesChatbotPlug {
289
303
  APIKEY: "___",
290
304
  log: false
291
305
  });
292
-
293
306
  let i = -1;
294
307
  if (this.log) { console.log("processing Inline directives:", directives); }
295
308
  const process = (directive) => {