@tiledesk/tiledesk-tybot-connector 0.1.47 → 0.1.48

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 CHANGED
@@ -6,10 +6,4 @@ TYBOT_ENDPOINT=http://localhost:10001
6
6
  _TYBOT_ENDPOINT=http://localhost:3000
7
7
  CHATBOT_TOKEN=JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3ZWJob29rX2VuYWJsZWQiOmZhbHNlLCJ0eXBlIjoiZXh0ZXJuYWwiLCJsYW5ndWFnZSI6ImVuIiwicHVibGljIjpmYWxzZSwiX2lkIjoiNjM4Yzc5MDQxZGI0NDkwMDM1MTEwMjYwIiwibmFtZSI6IlRoZSBGb3JtIHYyIC0gZXh0IiwidXJsIjoiaHR0cHM6Ly90aWxlYm90LWRldi5oZXJva3VhcHAuY29tL2V4dC82MzhjNzhkNzFkYjQ0OTAwMzUxMTAxYzIiLCJpZF9wcm9qZWN0IjoiNjM4Yzc4YTYxZGI0NDkwMDM1MTBmZjkxIiwidHJhc2hlZCI6ZmFsc2UsImNyZWF0ZWRCeSI6IjVlMDlkMTZkNGQzNjExMDAxNzUwNmQ3ZiIsImNyZWF0ZWRBdCI6IjIwMjItMTItMDRUMTA6NDA6MDQuMjA3WiIsInVwZGF0ZWRBdCI6IjIwMjItMTItMDVUMDc6MjE6MDIuOTIxWiIsIl9fdiI6MCwiZGVzY3JpcHRpb24iOiJPbiBIZXJva3UiLCJpYXQiOjE2NzA2NzE4ODksImF1ZCI6Imh0dHBzOi8vdGlsZWRlc2suY29tL2JvdHMvNjM4Yzc5MDQxZGI0NDkwMDM1MTEwMjYwIiwiaXNzIjoiaHR0cHM6Ly90aWxlZGVzay5jb20iLCJzdWIiOiJib3QiLCJqdGkiOiJmNDVlZGIwYS0zNzVhLTQ0NjMtYjFhZi1jM2ZiZDg4YmE3ZGQifQ.FbW3csHl1sQgSyRz5Jg0qaTvvpXWXgWHlJ1JWoVbv3s
8
8
  _CHATBOT_ENDPOINT=http://localhost:10001
9
- _API_LOG=1
10
- TEST_PROJECT_ID=638c78a61db449003510ff91
11
- TEST_BOT_ID=638c78d71db44900351101c2
12
-
13
- TEST_ACTIONS_PROJECT_ID=63b2ab8fd0029e0035252df5
14
- TEST_ACTIONS_BOT_ID=63b2aba4d0029e0035252ebb
15
- ACTIONS_CHATBOT_TOKEN=JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3ZWJob29rX2VuYWJsZWQiOmZhbHNlLCJ0eXBlIjoiZXh0ZXJuYWwiLCJsYW5ndWFnZSI6ImVuIiwicHVibGljIjpmYWxzZSwiY2VydGlmaWVkIjpmYWxzZSwiaW50ZW50c0VuZ2luZSI6Im5vbmUiLCJfaWQiOiI2M2IyYWJkY2QwMDI5ZTAwMzUyNTMyNGIiLCJuYW1lIjoiQWN0aW9ucyBCb3QgLSBleHQiLCJ1cmwiOiJodHRwczovL3RpbGVib3QtZGV2Lmhlcm9rdWFwcC5jb20vZXh0LzYzYjJhYmE0ZDAwMjllMDAzNTI1MmViYiIsImlkX3Byb2plY3QiOiI2M2IyYWI4ZmQwMDI5ZTAwMzUyNTJkZjUiLCJ0cmFzaGVkIjpmYWxzZSwiY3JlYXRlZEJ5IjoiNWUwOWQxNmQ0ZDM2MTEwMDE3NTA2ZDdmIiwiY3JlYXRlZEF0IjoiMjAyMy0wMS0wMlQxMDowMzowOC43NTVaIiwidXBkYXRlZEF0IjoiMjAyMy0wMS0wMlQxMDowMzo1MS4yOTZaIiwiX192IjowLCJpYXQiOjE2NzMzNzA5NzksImF1ZCI6Imh0dHBzOi8vdGlsZWRlc2suY29tL2JvdHMvNjNiMmFiZGNkMDAyOWUwMDM1MjUzMjRiIiwiaXNzIjoiaHR0cHM6Ly90aWxlZGVzay5jb20iLCJzdWIiOiJib3QiLCJqdGkiOiJjMTI2ZTk1Yi1lMGY2LTRmNDQtOTQ3NS0xN2IxNDMzYmY0MjEifQ.TWfVy7frEA98o596xCa-8hNnBAzBVhpYTz9p_zmNA4M
9
+ API_LOG=1
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
+ ### 0.1.48
9
+ - fixed ReplaceBot "log" bug
10
+ - ReplaceBot fill-variables botName
11
+
8
12
  ### 0.1.47
9
13
  - Introduced _tdIfOnlineAgents --trueIntent -- falseIntent
10
14
  - Refactored _tdIfOpenHours --trueIntent -- falseIntent
@@ -1,3 +1,5 @@
1
+ const {VM} = require('vm2');
2
+
1
3
  class TiledeskExpression {
2
4
  // rules:
3
5
  // check valid operators (only those in operators are allowed)
@@ -45,17 +47,33 @@ class TiledeskExpression {
45
47
  }
46
48
 
47
49
  // private
50
+ // evaluate(expression, context) {
51
+ // let fn;
52
+ // let res
53
+ // try {
54
+ // fn = Function(`let $data = this;return (${expression})`);
55
+ // res = fn.bind(context)()
56
+ // }
57
+ // catch (err) {
58
+ // console.error("TiledeskExpression.evaluate() error:", err.message, "evaluating expression: '" + expression + "'");
59
+ // }
60
+ // // let fn = Function(`let $data = this;console.log('data', $data);return (${conditionExpression})`);
61
+ // return res;
62
+ // }
63
+
48
64
  evaluate(expression, context) {
49
- let fn;
50
- let res
65
+ let res;
51
66
  try {
52
- fn = Function(`let $data = this;return (${expression})`);
53
- res = fn.bind(context)()
67
+ const vm = new VM({
68
+ timeout: 200,
69
+ allowAsync: false,
70
+ sandbox: context
71
+ });
72
+ res = vm.run(`let $data = this;${expression}`);
54
73
  }
55
74
  catch (err) {
56
75
  console.error("TiledeskExpression.evaluate() error:", err.message, "evaluating expression: '" + expression + "'");
57
76
  }
58
- // let fn = Function(`let $data = this;console.log('data', $data);return (${conditionExpression})`);
59
77
  return res;
60
78
  }
61
79
 
package/index.js CHANGED
@@ -27,30 +27,31 @@ let log = false;
27
27
  let tdcache = null;
28
28
 
29
29
  // DEV
30
- const { MessagePipeline } = require('./tiledeskChatbotPlugs/MessagePipeline');
30
+ // const { MessagePipeline } = require('./tiledeskChatbotPlugs/MessagePipeline');
31
31
  const { DirectivesChatbotPlug } = require('./tiledeskChatbotPlugs/DirectivesChatbotPlug');
32
- /*const { SplitsChatbotPlug } = require('./tiledeskChatbotPlugs/SplitsChatbotPlug');
33
- const { MarkbotChatbotPlug } = require('./tiledeskChatbotPlugs/MarkbotChatbotPlug');*/
34
- const { WebhookChatbotPlug } = require('./tiledeskChatbotPlugs/WebhookChatbotPlug');
32
+ // const { SplitsChatbotPlug } = require('./tiledeskChatbotPlugs/SplitsChatbotPlug');
33
+ // const { MarkbotChatbotPlug } = require('./tiledeskChatbotPlugs/MarkbotChatbotPlug');
34
+ // const { WebhookChatbotPlug } = require('./tiledeskChatbotPlugs/WebhookChatbotPlug');
35
35
 
36
36
  // PROD
37
- /*const { MessagePipeline } = require('@tiledesk/tiledesk-chatbot-plugs/MessagePipeline');
38
- const { DirectivesChatbotPlug } = require('@tiledesk/tiledesk-chatbot-plugs/DirectivesChatbotPlug');
39
- const { SplitsChatbotPlug } = require('@tiledesk/tiledesk-chatbot-plugs/SplitsChatbotPlug');
40
- const { MarkbotChatbotPlug } = require('@tiledesk/tiledesk-chatbot-plugs/MarkbotChatbotPlug');
41
- const { WebhookChatbotPlug } = require('@tiledesk/tiledesk-chatbot-plugs/WebhookChatbotPlug');*/
37
+ // const { MessagePipeline } = require('@tiledesk/tiledesk-chatbot-plugs/MessagePipeline');
38
+ // const { DirectivesChatbotPlug } = require('@tiledesk/tiledesk-chatbot-plugs/DirectivesChatbotPlug');
39
+ // const { SplitsChatbotPlug } = require('@tiledesk/tiledesk-chatbot-plugs/SplitsChatbotPlug');
40
+ // const { MarkbotChatbotPlug } = require('@tiledesk/tiledesk-chatbot-plugs/MarkbotChatbotPlug');
41
+ // const { WebhookChatbotPlug } = require('@tiledesk/tiledesk-chatbot-plugs/WebhookChatbotPlug');
42
42
 
43
43
  // THE IMPORT
44
44
  let mongoose = require('mongoose');
45
- const { DirSendEmail } = require('./tiledeskChatbotPlugs/directives/DirSendEmail.js');
45
+ // const { DirSendEmail } = require('./tiledeskChatbotPlugs/directives/DirSendEmail.js');
46
46
  const { Directives } = require('./tiledeskChatbotPlugs/directives/Directives.js');
47
- //let Faq = require('./models/faq');
48
- //let Faq_kb = require('./models/faq_kb');
49
- // let connection;
50
47
  let APIURL = null;
51
48
  let staticBots;
52
49
 
53
50
  router.post('/ext/:botid', async (req, res) => {
51
+ if (req && req.body && req.body.payload && req.body.payload.request && req.body.payload.request.snapshot) {
52
+ delete req.body.payload.request.snapshot;
53
+ console.log("Removed req.body.payload.request.snapshot field");
54
+ }
54
55
  if (log) {console.log("REQUEST BODY:", JSON.stringify(req.body));}
55
56
  res.status(200).send({"success":true});
56
57
 
@@ -68,16 +69,6 @@ router.post('/ext/:botid', async (req, res) => {
68
69
  if (message.request.id_project === null || message.request.id_project === undefined) {
69
70
  message.request.id_project = projectId;
70
71
  }
71
-
72
- let requestSourcePage = null;
73
- let requestLanguage = null;
74
- let requestUserAgent = null;
75
-
76
- if (message.payload) {
77
- requestSourcePage = message.payload.sourcePage;
78
- requestLanguage = message.payload.language;
79
- requestUserAgent = message.payload.userAgent;
80
- }
81
72
 
82
73
  // NEXTTTTTTT
83
74
  // const message_context = {
@@ -117,8 +108,10 @@ router.post('/ext/:botid', async (req, res) => {
117
108
 
118
109
  let intentsMachine;
119
110
  if (!staticBots) {
120
- intentsMachine = new MongodbIntentsMachine({projectId: projectId, language: bot.language});
111
+ if (log) {console.log("intentsMachine to MongoDB");}
112
+ intentsMachine = new MongodbIntentsMachine({projectId: projectId, language: bot.language, log});
121
113
  if (bot.intentsEngine === "tiledesk-ai") {
114
+ if (log) {console.log("intentsMachine to tiledesk-ai");}
122
115
  intentsMachine = new TiledeskIntentsMachine(
123
116
  {
124
117
  //projectId: projectId,
@@ -146,60 +139,14 @@ router.post('/ext/:botid', async (req, res) => {
146
139
  log: log
147
140
  });
148
141
 
149
- // initial request context
150
- await chatbot.addParameter("_tdLastMessageId", messageId);
151
- await chatbot.addParameter("_tdProjectId", projectId);
152
- await chatbot.addParameter("_tdRequestId", requestId);
153
- if (message.request && message.request.location && message.request.location.country) {
154
- await chatbot.addParameter("_tdCountry", message.request.location.country);
155
- }
156
- if (message.request && message.request.location && message.request.location.city) {
157
- await chatbot.addParameter("_tdCity", message.request.location.city);
158
- }
159
- if (message.text) {
160
- await chatbot.addParameter("_tdUserText", message.text);
161
- }
162
- if (requestSourcePage) {
163
- await chatbot.addParameter("_tdRequestSourcePage", sourcePage);
164
- }
165
- if (requestLanguage) {
166
- await chatbot.addParameter("_tdRequestLanguage", language);
167
- }
168
- if (requestUserAgent) {
169
- await chatbot.addParameter("_tdRequestUserAgent", userAgent);
170
- }
142
+ await updateRequestVariables(chatbot, message, projectId, requestId);
143
+
171
144
  let reply = await chatbot.replyToMessage(message);
172
145
  if (!reply) {
173
146
  reply = {
174
147
  "text": "No messages found. Is 'defaultFallback' intent missing?"
175
148
  }
176
149
  }
177
- // console.log("reply back:", JSON.stringify(reply));
178
-
179
- // TEMP
180
- // if (reply.attributes && reply.attributes.intent_info) {
181
- // switch (reply.attributes.intent_info.intent_name) {
182
- // case "MessageActions":
183
- // reply.actions = MockActions.MessageActions()
184
- // break;
185
- // case "Message_plus_Agent":
186
- // reply.actions = MockActions.Message_plus_Agent();
187
- // break;
188
- // case "Message_plus_AgentWhenOnline":
189
- // reply.actions = MockActions.Message_plus_AgentWhenOnline();
190
- // break;
191
- // case "Message_plus_Close":
192
- // reply.actions = MockActions.Message_plus_Close();
193
- // break;
194
- // case "ChangeDepartment":
195
- // reply.actions = MockActions.ChangeDepartment();
196
- // break;
197
- // case "Intent":
198
- // reply.actions = MockActions.Intent();
199
- // break;
200
- // }
201
- // }
202
-
203
150
 
204
151
  // console.log("reply.actions:", reply.actions);
205
152
  if (reply.actions && reply.actions.length > 0) { // structured actions (coming from chatbot designer)
@@ -250,6 +197,81 @@ router.post('/ext/:botid', async (req, res) => {
250
197
 
251
198
  });
252
199
 
200
+ async function updateRequestVariables(chatbot, message, projectId, requestId) {
201
+ // update request context
202
+ const messageId = message._id;
203
+ await chatbot.addParameter("_tdProjectId", projectId);
204
+ await chatbot.addParameter("_tdRequestId", requestId);
205
+ if (message.text) {
206
+ await chatbot.addParameter("_tdLastUserText", message.text);
207
+ }
208
+ await chatbot.addParameter("_tdLastMessageId", messageId);
209
+ if (message.request && message.request.location && message.request.location.country) {
210
+ await chatbot.addParameter("_tdCountry", message.request.location.country);
211
+ }
212
+ if (message.request && message.request.location && message.request.location.city) {
213
+ await chatbot.addParameter("_tdCity", message.request.location.city);
214
+ }
215
+ await chatbot.addParameter("_tdRequestSourcePage", message.sourcePage);
216
+ await chatbot.addParameter("_tdRequestLanguage", message.language);
217
+ await chatbot.addParameter("_tdRequestUserAgent", message.userAgent);
218
+
219
+ if (message.attributes) {
220
+ await chatbot.addParameter("_tdRequestDepartmentId", message.attributes.departmentId);
221
+ await chatbot.addParameter("_tdRequestDepartmentName", message.attributes.departmentName);
222
+ await chatbot.addParameter("_tdRequestRequesterId", message.attributes.requester_id);
223
+ await chatbot.addParameter("_tdRequestIpAddress", message.attributes.ipAddress);
224
+ if (message.attributes.payload) {
225
+ try {
226
+ for (const [key, value] of Object.entries(message.attributes.payload)) {
227
+ // const value = all_parameters[key];
228
+ const value_type = typeof value;
229
+ if (chatbot.log) {console.log("importing payload parameter:", key, "value:", value, "type:", value_type)}
230
+ await chatbot.addParameter(key, String(value));
231
+ }
232
+ }
233
+ catch(err) {
234
+ console.error("Error importing message payload in request variables:", err);
235
+ }
236
+ }
237
+ }
238
+ if (chatbot.log) {
239
+ const all_parameters = await TiledeskChatbot.allParametersStatic(chatbot.tdcache, requestId);
240
+ for (const [key, value] of Object.entries(all_parameters)) {
241
+ // const value = all_parameters[key];
242
+ const value_type = typeof value;
243
+ if (chatbot.log) {console.log("request parameter:", key, "value:", value, "type:", value_type)}
244
+ }
245
+ }
246
+ // message["attributes"]: {
247
+ // "departmentId": "63c980054f857c00350535bc",
248
+ // "departmentName": "Default Department",
249
+ // "client": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36",
250
+ // "sourcePage": "https://tiledesk-html-site.tiledesk.repl.co/custom-attributes.html",
251
+ // "projectId": "63c980054f857c00350535b8",
252
+ // "payload": {
253
+ // "user_country": "Italy",
254
+ // "user_code": "E001"
255
+ // },
256
+ // "userFullname": "guest#7216 ",
257
+ // "requester_id": "7216926a-84c3-4bd5-aa79-8bd763094dc0",
258
+ // "ipAddress": "79.8.190.172",
259
+ // "sourceTitle": "Custom attributes",
260
+ // "widgetVer": "v.5.0.53-rc.4",
261
+ // "subtype": "info",
262
+ // "decoded_jwt": {
263
+ // "_id": "7216926a-84c3-4bd5-aa79-8bd763094dc0",
264
+ // "firstname": "guest#7216",
265
+ // "id": "7216926a-84c3-4bd5-aa79-8bd763094dc0",
266
+ // "fullName": "guest#7216 ",
267
+ // "iat": 1674201892,
268
+ // "aud": "https://tiledesk.com",
269
+ // "iss": "https://tiledesk.com",
270
+ // "sub": "guest",
271
+ // "jti": "f053af3d-14ca-411b-9903-78bd74e24218"
272
+ // }
273
+ }
274
+
253
275
  function actionsToDirectives(actions) {
254
276
  let directives = [];
255
277
  if (actions && actions.length > 0) {
@@ -9,7 +9,7 @@ class MockTdCache {
9
9
 
10
10
  set(k, v) {
11
11
  return new Promise( (resolve, reject) => {
12
- this.db.set(k, "" + v) // saves as string, to simulate Redis
12
+ this.db.set(k, "" + v) // saves as string
13
13
  resolve();
14
14
  });
15
15
  }
@@ -19,7 +19,7 @@ class MongodbIntentsMachine {
19
19
  */
20
20
  async decode(botId, text) {
21
21
  return new Promise( (resolve, reject) => {
22
- if (this.log) {console.log("NLP decode intent...");}
22
+ if (this.log) {console.log("Mongodb NLP decode intent...");}
23
23
  let query = { "id_project": this.projectId, "id_faq_kb": botId };
24
24
  var mongoproject = undefined;
25
25
  var sort = undefined;
@@ -37,7 +37,7 @@ class MongodbIntentsMachine {
37
37
  if (err) {
38
38
  console.error("Error:", err);
39
39
  }
40
- if (faqs && faqs.length > 0 && faqs[0].answer) {
40
+ if (faqs && faqs.length > 0) {
41
41
  resolve(faqs);
42
42
  }
43
43
  else {
@@ -12,6 +12,8 @@ const { DirUnlockIntent } = require('../tiledeskChatbotPlugs/directives/DirUnloc
12
12
 
13
13
  class TiledeskChatbot {
14
14
 
15
+ static MAX_STEPS = 20;
16
+
15
17
  constructor(config) {
16
18
  if (!config.botsDataSource) {
17
19
  throw new Error("config.botsDataSource is mandatory");
@@ -61,6 +63,11 @@ class TiledeskChatbot {
61
63
  console.log("replyToMessage() > lead found:", JSON.stringify(lead));
62
64
  }
63
65
 
66
+ // any external invocation restarts the steps counter
67
+ // if (message.sender != "_tdinternal") {
68
+ // await TiledeskChatbot.resetStep(this.tdcache, this.requestId);
69
+ // }
70
+
64
71
  // Checking locked intent (for non-internal intents)
65
72
  // internal intents always "skip" the locked intent
66
73
  // if (message.text.startsWith("/") && message.sender != "_tdinternal") {
@@ -184,7 +191,7 @@ class TiledeskChatbot {
184
191
  return;
185
192
  }
186
193
  else { // NLP
187
- if (this.log) {console.log("NLP decode intent...");}
194
+ if (this.log) {console.log("Chatbot NLP decode intent...");}
188
195
  let intents;
189
196
  try {
190
197
  intents = await this.intentsFinder.decode(this.botId, message.text);
@@ -210,7 +217,9 @@ class TiledeskChatbot {
210
217
  else {
211
218
  // fallback
212
219
  let fallbackIntent = await this.botsDataSource.getByIntentDisplayName(this.botId, "defaultFallback");
220
+ console.log("fallbackIntent found", fallbackIntent);
213
221
  if (!fallbackIntent) {
222
+ console.log("No defaultFallback found!");
214
223
  resolve(null);
215
224
  return;
216
225
  }
@@ -449,6 +458,36 @@ class TiledeskChatbot {
449
458
  await _tdcache.hset(parameter_key, parameter_name, parameter_value);
450
459
  }
451
460
 
461
+ static async checkStep(_tdcache, requestId, max_steps) {
462
+ let go_on = true;
463
+ const parameter_key = TiledeskChatbot.requestCacheKey(requestId) + ":step";
464
+ console.log("parameter_key:", parameter_key);
465
+ let _current_step = await _tdcache.get(parameter_key);
466
+ if (!_current_step) { // this shouldn't be happening
467
+ _current_step = 0;
468
+ }
469
+ console.log("_current_step:", _current_step);
470
+ let current_step = Number(_current_step);
471
+ console.log("current_step:", current_step);
472
+ if (current_step > max_steps) {
473
+ console.log("current_step > max_steps!", current_step);
474
+ await TiledeskChatbot.resetStep(_tdcache, requestId);
475
+ go_on = false;
476
+ }
477
+ else {
478
+ console.log("current_step < max_steps :)", current_step);
479
+ current_step += 1;
480
+ await _tdcache.set(parameter_key, current_step); // increment step
481
+ console.log("current_step from cache:", await _tdcache.get(parameter_key));
482
+ }
483
+ return go_on;
484
+ }
485
+
486
+ static async resetStep(_tdcache, requestId) {
487
+ const parameter_key = TiledeskChatbot.requestCacheKey(requestId) + ":step";
488
+ await _tdcache.set(parameter_key, 0);
489
+ }
490
+
452
491
  async allParameters() {
453
492
  return await TiledeskChatbot.allParametersStatic(this.tdcache, this.requestId);
454
493
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiledesk/tiledesk-tybot-connector",
3
- "version": "0.1.47",
3
+ "version": "0.1.48",
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.39",
17
- "@tiledesk/tiledesk-client": "^0.9.5",
17
+ "@tiledesk/tiledesk-client": "^0.9.6",
18
18
  "axios": "^0.27.2",
19
19
  "body-parser": "^1.19.0",
20
20
  "cors": "^2.8.5",
@@ -26,6 +26,7 @@
26
26
  "mongoose": "^6.3.5",
27
27
  "nanoid": "^3.1.25",
28
28
  "redis": "^3.1.2",
29
- "uuid": "^3.3.3"
29
+ "uuid": "^3.3.3",
30
+ "vm2": "^3.9.13"
30
31
  }
31
32
  }
@@ -0,0 +1,173 @@
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
+ app.use((err, req, res, next) => {
9
+ console.error("General error", err);
10
+ });
11
+ require('dotenv').config();
12
+ const bodyParser = require('body-parser');
13
+ const { v4: uuidv4 } = require('uuid');
14
+ const bots_data = require('./conversation-actions_bot.js').bots_data;
15
+
16
+ const PROJECT_ID = "projectID"; //process.env.TEST_ACTIONS_PROJECT_ID;
17
+ const REQUEST_ID = "support-group-" + PROJECT_ID + "-" + uuidv4().replace(/-/g, "");
18
+ const BOT_ID = "botID"; //process.env.TEST_ACTIONS_BOT_ID;
19
+ const CHATBOT_TOKEN = "XXX"; //process.env.ACTIONS_CHATBOT_TOKEN;
20
+
21
+ describe('Conversation for anomaly detection test', async () => {
22
+
23
+ let app_listener;
24
+
25
+ before(() => {
26
+ return new Promise(async (resolve, reject) => {
27
+ console.log("Starting tilebot server...");
28
+ tybot.startApp(
29
+ {
30
+ // MONGODB_URI: process.env.mongoUrl,
31
+ bots: bots_data,
32
+ API_ENDPOINT: process.env.API_ENDPOINT,
33
+ REDIS_HOST: process.env.REDIS_HOST,
34
+ REDIS_PORT: process.env.REDIS_PORT,
35
+ REDIS_PASSWORD: process.env.REDIS_PASSWORD,
36
+ log: process.env.API_LOG
37
+ }, () => {
38
+ console.log("ACTIONS Tilebot route successfully started.");
39
+ var port = process.env.PORT || 10001;
40
+ app_listener = app.listen(port, () => {
41
+ console.log('Tilebot connector listening on port ', port);
42
+ resolve();
43
+ });
44
+ });
45
+ })
46
+ });
47
+
48
+ after(function (done) {
49
+ app_listener.close(() => {
50
+ // console.log('ACTIONS app_listener closed.');
51
+ done();
52
+ });
53
+ });
54
+
55
+ it('/anomaly', (done) => {
56
+ console.log("/anomaly story...");
57
+ let message_id = uuidv4();
58
+ let listener;
59
+ let endpointServer = express();
60
+ endpointServer.use(bodyParser.json());
61
+ endpointServer.post('/:projectId/requests/:requestId/messages', function (req, res) {
62
+ console.log("...req.body:", JSON.stringify(req.body));
63
+ res.send({ success: true });
64
+ const message = req.body;
65
+ assert(message.attributes.error !== null);
66
+ assert(message.attributes.error.message !== null);
67
+ assert(message.attributes.error.message === "Request anomaly detection");
68
+ listener.close(() => {
69
+ done();
70
+ });
71
+ });
72
+
73
+ listener = endpointServer.listen(10002, '0.0.0.0', () => {
74
+ // console.log('endpointServer started', listener.address());
75
+ let request = {
76
+ "payload": {
77
+ "_id": message_id,
78
+ "senderFullname": "guest#367e",
79
+ "type": "text",
80
+ "sender": "A-SENDER",
81
+ "recipient": REQUEST_ID,
82
+ "text": "/anomaly",
83
+ "id_project": PROJECT_ID,
84
+ "metadata": "",
85
+ "request": {
86
+ "request_id": REQUEST_ID
87
+ }
88
+ },
89
+ "token": CHATBOT_TOKEN
90
+ }
91
+ sendMessageToBot(request, BOT_ID, () => {
92
+ console.log("Message sent:\n", request);
93
+ });
94
+ });
95
+
96
+ });
97
+
98
+ });
99
+
100
+ /**
101
+ * A stub to send message to the "ext/botId" endpoint, hosted by tilebot on:
102
+ * /${TILEBOT_ROUTE}/ext/${botId}
103
+ *
104
+ * @param {Object} message. The message to send
105
+ * @param {string} botId. Tiledesk botId
106
+ * @param {string} token. User token
107
+ */
108
+ function sendMessageToBot(message, botId, callback) {
109
+ // const jwt_token = this.fixToken(token);
110
+ const url = `${process.env.TYBOT_ENDPOINT}/ext/${botId}`;
111
+ // console.log("sendMessageToBot URL", url);
112
+ const HTTPREQUEST = {
113
+ url: url,
114
+ headers: {
115
+ 'Content-Type': 'application/json'
116
+ },
117
+ json: message,
118
+ method: 'POST'
119
+ };
120
+ myrequest(
121
+ HTTPREQUEST,
122
+ function (err, resbody) {
123
+ if (err) {
124
+ if (callback) {
125
+ callback(err);
126
+ }
127
+ }
128
+ else {
129
+ if (callback) {
130
+ callback(null, resbody);
131
+ }
132
+ }
133
+ }, false
134
+ );
135
+ }
136
+
137
+ function myrequest(options, callback, log) {
138
+ if (log) {
139
+ console.log("API URL:", options.url);
140
+ console.log("** Options:", JSON.stringify(options));
141
+ }
142
+ axios(
143
+ {
144
+ url: options.url,
145
+ method: options.method,
146
+ data: options.json,
147
+ params: options.params,
148
+ headers: options.headers
149
+ })
150
+ .then((res) => {
151
+ if (log) {
152
+ console.log("Response for url:", options.url);
153
+ console.log("Response headers:\n", JSON.stringify(res.headers));
154
+ //console.log("******** Response for url:", res);
155
+ }
156
+ if (res && res.status == 200 && res.data) {
157
+ if (callback) {
158
+ callback(null, res.data);
159
+ }
160
+ }
161
+ else {
162
+ if (callback) {
163
+ callback(TiledeskClient.getErr({ message: "Response status not 200" }, options, res), null, null);
164
+ }
165
+ }
166
+ })
167
+ .catch((error) => {
168
+ console.error("An error occurred:", error);
169
+ if (callback) {
170
+ callback(error, null, null);
171
+ }
172
+ });
173
+ }
@@ -0,0 +1,26 @@
1
+ var assert = require('assert');
2
+ const { TiledeskChatbot } = require('../models/TiledeskChatbot.js');
3
+ const { MockTdCache } = require('../models/MockTdCache');
4
+ const { v4: uuidv4 } = require('uuid');
5
+
6
+ describe('checkStep()', function() {
7
+
8
+ it('checkStep() function', async () => {
9
+ const MAX_STEPS = 20;
10
+ const requestId = uuidv4();
11
+ const tdcache = new MockTdCache();
12
+ let i;
13
+ // trying to brute-pass MAX_STEPS limit by doubling it
14
+ for (i = 0; i < MAX_STEPS * 2; i++) {
15
+ console.log("i: " + i);
16
+ let go_on = await TiledeskChatbot.checkStep(tdcache, requestId, MAX_STEPS);
17
+ console.log("go on?", go_on);
18
+ if (!go_on) {
19
+ break;
20
+ }
21
+ }
22
+ console.log("last i: " + i);
23
+ assert(i === MAX_STEPS + 1);
24
+ });
25
+
26
+ });
@@ -21,7 +21,7 @@ const bot = {
21
21
  "enabled": true,
22
22
  "question": "***",
23
23
  "actions": [{
24
- "type": "message",
24
+ "_tdActionType": "message",
25
25
  "attributes": {
26
26
  "commands": [{
27
27
  "type": "message",
@@ -58,7 +58,7 @@ const bot = {
58
58
  "question": "***",
59
59
  "answer": "***",
60
60
  "actions": [{
61
- "type": "message",
61
+ "_tdActionType": "message",
62
62
  "attributes": {
63
63
  "commands": [{
64
64
  "type": "message",
@@ -79,7 +79,7 @@ const bot = {
79
79
  "question": "***",
80
80
  "answer": "***",
81
81
  "actions": [{
82
- "type": "message",
82
+ "_tdActionType": "message",
83
83
  "attributes": {
84
84
  "commands": [{
85
85
  "type": "message",
@@ -100,7 +100,7 @@ const bot = {
100
100
  "question": "***",
101
101
  "answer": "***",
102
102
  "actions": [{
103
- "type": "message",
103
+ "_tdActionType": "message",
104
104
  "attributes": {
105
105
  "commands": [{
106
106
  "type": "message",
@@ -122,10 +122,10 @@ const bot = {
122
122
  "answer": "***",
123
123
  "actions": [
124
124
  {
125
- "type": "department",
125
+ "_tdActionType": "department",
126
126
  "depName": "Support"
127
127
  }, {
128
- "type": "message",
128
+ "_tdActionType": "message",
129
129
  "text": "/start",
130
130
  "attributes": {
131
131
  "subtype": "info"
@@ -139,7 +139,7 @@ const bot = {
139
139
  "question": "***",
140
140
  "answer": "***",
141
141
  "actions": [{
142
- "type": "intent",
142
+ "_tdActionType": "intent",
143
143
  "intentName": "intentAction"
144
144
  }],
145
145
  "language": "en",
@@ -202,6 +202,17 @@ const bot = {
202
202
  "answer": "Eureka!\nThis is the reply for **intentAction4**\n* /start",
203
203
  "language": "en",
204
204
  "intent_display_name": "intentAction4"
205
+ }, {
206
+ "webhook_enabled": false,
207
+ "enabled": true,
208
+ "question": "***",
209
+ "answer": "***",
210
+ "actions": [{
211
+ "_tdActionType": "intent",
212
+ "intentName": "anomaly"
213
+ }],
214
+ "language": "en",
215
+ "intent_display_name": "anomaly"
205
216
  }]
206
217
  }
207
218
 
@@ -0,0 +1,242 @@
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
+ app.use((err, req, res, next) => {
9
+ console.error("General error", err);
10
+ });
11
+ require('dotenv').config();
12
+ const bodyParser = require('body-parser');
13
+ const { v4: uuidv4 } = require('uuid');
14
+ const bots_data = require('./conversation-form_bot.js').bots_data;
15
+
16
+ const PROJECT_ID = "projectID"; //const PROJECT_ID = process.env.TEST_PROJECT_ID;
17
+ const REQUEST_ID = "support-group-" + PROJECT_ID + "-" + uuidv4().replace(/-/g, "");
18
+ const BOT_ID = "botID";
19
+ const CHATBOT_TOKEN = process.env.CHATBOT_TOKEN;
20
+
21
+ let app_listener;
22
+
23
+ describe('Conversation1 - Form filling', async () => {
24
+
25
+ before(() => {
26
+ return new Promise(async (resolve, reject) => {
27
+ console.log("Starting tilebot server...");
28
+ tybot.startApp(
29
+ {
30
+ // MONGODB_URI: process.env.mongoUrl,
31
+ bots: bots_data,
32
+ API_ENDPOINT: process.env.API_ENDPOINT,
33
+ REDIS_HOST: process.env.REDIS_HOST,
34
+ REDIS_PORT: process.env.REDIS_PORT,
35
+ REDIS_PASSWORD: process.env.REDIS_PASSWORD,
36
+ log: process.env.API_LOG
37
+ }, () => {
38
+ console.log("Tilebot route successfully started.");
39
+ var port = process.env.PORT || 10001;
40
+ app_listener = app.listen(port, () => {
41
+ console.log('Tilebot connector listening on port ', port);
42
+ resolve();
43
+ });
44
+ });
45
+ })
46
+ });
47
+
48
+ after(function (done) {
49
+ app_listener.close(() => {
50
+ // console.log('CONVERSATION FORM app_listener closed.');
51
+ done();
52
+ });
53
+ });
54
+
55
+ it('/locked', (done) => {
56
+ // console.log("/locked...");
57
+ let request0_uuid = uuidv4();
58
+ let request1_uuid = uuidv4();
59
+ let request2_uuid = uuidv4();
60
+ let request3_uuid = uuidv4();
61
+ let listener;
62
+ let endpointServer = express();
63
+ endpointServer.use(bodyParser.json());
64
+ endpointServer.post('/:projectId/requests/:requestId/messages', function (req, res) {
65
+ res.send({ success: true });
66
+ const message = req.body;
67
+ if (message.text.startsWith("Hi welcome to this dialog.")) {
68
+ console.log("got #0 sending #1", message.text);
69
+ let request = {
70
+ "payload": {
71
+ "_id": request1_uuid,
72
+ "senderFullname": "guest#367e",
73
+ "type": "text",
74
+ "sender": "A-SENDER",
75
+ "recipient": REQUEST_ID,
76
+ "text": "/dialog_question2",
77
+ "id_project": PROJECT_ID,
78
+ "request": {
79
+ "request_id": REQUEST_ID,
80
+ "id_project": PROJECT_ID
81
+ }
82
+ },
83
+ "token": CHATBOT_TOKEN
84
+ }
85
+ sendMessageToBot(request, BOT_ID, CHATBOT_TOKEN, () => {
86
+ // console.log("Message sent.", request);
87
+ });
88
+ }
89
+ else if (message.text.startsWith("As I told you,")) {
90
+ console.log("got #1 sending #2", message.text);
91
+ let request = {
92
+ "payload": {
93
+ "_id": request2_uuid,
94
+ "senderFullname": "guest#367e",
95
+ "type": "text",
96
+ "sender": "A-SENDER",
97
+ "recipient": REQUEST_ID,
98
+ "text": "/dialog_question3",
99
+ "id_project": PROJECT_ID,
100
+ "request": {
101
+ "request_id": REQUEST_ID,
102
+ "id_project": PROJECT_ID
103
+ }
104
+ },
105
+ "token": CHATBOT_TOKEN
106
+ }
107
+ sendMessageToBot(request, BOT_ID, CHATBOT_TOKEN, () => {
108
+ // console.log("Message sent4.", request);
109
+ });
110
+ }
111
+ else if (message.text.startsWith("And now tell me,")) {
112
+ console.log("got #2 sending #3", message.text);
113
+ let request = {
114
+ "payload": {
115
+ "_id": request3_uuid,
116
+ "senderFullname": "guest#367e",
117
+ "type": "text",
118
+ "sender": "A-SENDER",
119
+ "recipient": REQUEST_ID,
120
+ "text": "/dialog_question4",
121
+ "id_project": PROJECT_ID,
122
+ "request": {
123
+ "request_id": REQUEST_ID,
124
+ "id_project": PROJECT_ID
125
+ }
126
+ },
127
+ "token": CHATBOT_TOKEN
128
+ }
129
+ sendMessageToBot(request, BOT_ID, CHATBOT_TOKEN, () => {
130
+ // console.log("Message sent5.", request);
131
+ });
132
+ }
133
+ else if (message.text.startsWith("Well, survey completed!")) {
134
+ // console.log("got #4. End.", message.text);
135
+ listener.close(() => {
136
+ done();
137
+ });
138
+ }
139
+
140
+ });
141
+
142
+ listener = endpointServer.listen(10002, '0.0.0.0', function () {
143
+ // console.log('endpointServer started', listener.address());
144
+ // console.log("REQUEST_ID:", REQUEST_ID);
145
+ let request = {
146
+ "payload": {
147
+ "_id": request0_uuid,
148
+ "senderFullname": "guest#367e",
149
+ "type": "text",
150
+ "sender": "A-SENDER",
151
+ "recipient": REQUEST_ID,
152
+ "text": "/dialog_start",
153
+ "id_project": PROJECT_ID,
154
+ "request": {
155
+ "request_id": REQUEST_ID,
156
+ "id_project": PROJECT_ID
157
+ }
158
+ },
159
+ "token": CHATBOT_TOKEN
160
+ }
161
+ // console.log("sending message:", request);
162
+ sendMessageToBot(request, BOT_ID, CHATBOT_TOKEN, () => {
163
+ // console.log("Message sent.");
164
+ });
165
+ });
166
+ });
167
+ });
168
+
169
+ /**
170
+ * A stub to send message to the "ext/botId" endpoint, hosted by tilebot on:
171
+ * /${TILEBOT_ROUTE}/ext/${botId}
172
+ *
173
+ * @param {Object} message. The message to send
174
+ * @param {string} botId. Tiledesk botId
175
+ * @param {string} token. User token
176
+ */
177
+ function sendMessageToBot(message, botId, token, callback) {
178
+ // const jwt_token = this.fixToken(token);
179
+ const url = `${process.env.TYBOT_ENDPOINT}/ext/${botId}`;
180
+ // console.log("sendMessageToBot URL", url);
181
+ const HTTPREQUEST = {
182
+ url: url,
183
+ headers: {
184
+ 'Content-Type': 'application/json'
185
+ },
186
+ json: message,
187
+ method: 'POST'
188
+ };
189
+ myrequest(
190
+ HTTPREQUEST,
191
+ function (err, resbody) {
192
+ if (err) {
193
+ if (callback) {
194
+ callback(err);
195
+ }
196
+ }
197
+ else {
198
+ if (callback) {
199
+ callback(null, resbody);
200
+ }
201
+ }
202
+ }, false
203
+ );
204
+ }
205
+
206
+ function myrequest(options, callback, log) {
207
+ if (log) {
208
+ console.log("API URL:", options.url);
209
+ console.log("** Options:", JSON.stringify(options));
210
+ }
211
+ axios(
212
+ {
213
+ url: options.url,
214
+ method: options.method,
215
+ data: options.json,
216
+ params: options.params,
217
+ headers: options.headers
218
+ })
219
+ .then((res) => {
220
+ if (log) {
221
+ console.log("Response for url:", options.url);
222
+ console.log("Response headers:\n", JSON.stringify(res.headers));
223
+ //console.log("******** Response for url:", res);
224
+ }
225
+ if (res && res.status == 200 && res.data) {
226
+ if (callback) {
227
+ callback(null, res.data);
228
+ }
229
+ }
230
+ else {
231
+ if (callback) {
232
+ callback(TiledeskClient.getErr({ message: "Response status not 200" }, options, res), null, null);
233
+ }
234
+ }
235
+ })
236
+ .catch((error) => {
237
+ console.error("An error occurred:", error);
238
+ if (callback) {
239
+ callback(error, null, null);
240
+ }
241
+ });
242
+ }
@@ -27,6 +27,7 @@ const { DirAssign } = require('./directives/DirAssign');
27
27
 
28
28
  const { TiledeskChatbot } = require('../models/TiledeskChatbot');
29
29
  const { DirIfOnlineAgents } = require('./directives/DirIfOnlineAgents');
30
+ const { DirReply } = require('./directives/DirReply');
30
31
 
31
32
  class DirectivesChatbotPlug {
32
33
 
@@ -194,52 +195,23 @@ class DirectivesChatbotPlug {
194
195
  });
195
196
  }
196
197
  else if (directive_name === Directives.MESSAGE) {
197
- const messageDir = new DirMessage(
198
- {
199
- API_ENDPOINT: API_URL,
200
- TILEBOT_ENDPOINT:TILEBOT_ENDPOINT,
201
- log: false,
202
- projectId: projectId,
203
- requestId: requestId,
204
- token: token
205
- }
206
- );
198
+ const messageDir = new DirMessage(context);
207
199
  messageDir.execute(directive, async () => {
208
- // const requestVariables =
209
- // await TiledeskChatbot.allParametersStatic(
210
- // tdcache, requestId
211
- // );
212
- // console.log("message executed.", requestVariables);
200
+ process(nextDirective());
201
+ });
202
+ }
203
+ else if (directive_name === Directives.REPLY) {
204
+ console.log("...DirReply");
205
+ new DirReply(context).execute(directive, async () => {
213
206
  process(nextDirective());
214
207
  });
215
208
  }
216
209
  else if (directive_name === Directives.IF_OPEN_HOURS) {
217
- // const intentDir = new DirIntent(
218
- // {
219
- // API_ENDPOINT: API_URL,
220
- // TILEBOT_ENDPOINT:TILEBOT_ENDPOINT,
221
- // log: false,
222
- // supportRequest: supportRequest,
223
- // token: token
224
- // }
225
- // );
226
-
227
210
  const ifOpenHours = new DirIfOpenHours(context);
228
- // {
229
- // tdclient: tdclient,
230
- // intentDir: intentDir,
231
- // log: false
232
- // });
233
211
  ifOpenHours.execute(directive, () => {
234
212
  process(nextDirective());
235
213
  });
236
214
  }
237
- // else if (directive_name === Directives.IF_NOT_OPEN_HOURS) {
238
- // const ifNotOpenHours = new DirIfNotOpenHours(context);
239
- // ifNotOpenHours.execute(directive, () => {
240
- // process(nextDirective());
241
- // });
242
- // }
243
215
  else if (directive_name === Directives.IF_ONLINE_AGENTS) {
244
216
  const ifOnlineAgents = new DirIfOnlineAgents(context);
245
217
  // {
@@ -325,30 +297,8 @@ class DirectivesChatbotPlug {
325
297
  agentDir.execute(directive, () => {
326
298
  process(nextDirective());
327
299
  });
328
- // if (depId) {
329
- // const agentDir = new DirMoveToAgent(
330
- // {
331
- // tdclient: tdclient,
332
- // requestId: requestId,
333
- // depId: depId
334
- // }
335
- // );
336
- // if (!directive.body) {
337
- // directive.action = {}
338
- // directive.action.body = {
339
- // whenOnlineOnly: false
340
- // }
341
- // }
342
- // agentDir.execute(directive, () => {
343
- // process(nextDirective());
344
- // });
345
- // }
346
- // else {
347
- // console.log("Warning. DepId null while calling 'AGENT' directive")
348
- // process(nextDirective());
349
- // }
350
300
  }
351
- else if (directive_name === Directives.WHEN_ONLINE_MOVE_TO_AGENT) {
301
+ else if (directive_name === Directives.WHEN_ONLINE_MOVE_TO_AGENT) { // DEPRECATED?
352
302
  if (depId) {
353
303
  const agentDir = new DirMoveToAgent(
354
304
  {
@@ -374,24 +324,17 @@ class DirectivesChatbotPlug {
374
324
  }
375
325
  else if (directive_name === Directives.CLOSE) {
376
326
  // console.log("Exec close()")
377
- const closeDir = new DirClose(context);
378
- closeDir.execute(directive, () => {
327
+ new DirClose(context).execute(directive, () => {
379
328
  process(nextDirective());
380
329
  });
381
330
  }
382
331
  else if (directive_name === Directives.REMOVE_CURRENT_BOT) {
383
- new DirRemoveCurrentBot({
384
- tdclient: tdclient,
385
- requestId: requestId
386
- }).execute(directive, () => {
332
+ new DirRemoveCurrentBot(context).execute(directive, () => {
387
333
  process(nextDirective());
388
334
  });
389
335
  }
390
336
  else if (directive_name === Directives.REPLACE_BOT) {
391
- new DirReplaceBot({
392
- tdclient: tdclient,
393
- requestId: requestId
394
- }).execute(directive, () => {
337
+ new DirReplaceBot(context).execute(directive, () => {
395
338
  process(nextDirective());
396
339
  });
397
340
  }
@@ -411,41 +354,23 @@ class DirectivesChatbotPlug {
411
354
  });
412
355
  }
413
356
  else if (directive_name === Directives.FIRE_TILEDESK_EVENT) {
414
- new DirFireTiledeskEvent(
415
- {
416
- tdclient: tdclient
417
- }).execute(directive, () => {
357
+ new DirFireTiledeskEvent(context).execute(directive, () => {
418
358
  process(nextDirective());
419
359
  });
420
360
  }
421
361
  else if (directive_name === Directives.SEND_EMAIL) {
422
362
  // console.log("...DirSendEmail");
423
- const email_dir = new DirSendEmail(context);
424
- email_dir.execute(directive, () => {
363
+ new DirSendEmail(context).execute(directive, () => {
425
364
  process(nextDirective());
426
365
  });
427
-
428
- // new DirSendEmail(
429
- // {
430
- // tdclient: tdclient,
431
- // tdcache: tdcache,
432
- // requestId: requestId
433
- // }).execute(directive, () => {
434
- // process(nextDirective());
435
- // });
436
366
  }
437
367
  else if (directive_name === Directives.DELETE) {
438
368
  // console.log("got delete dir...")
439
- new DirDeleteVariable(
440
- {
441
- tdclient: tdclient,
442
- tdcache: tdcache,
443
- requestId: requestId
444
- }).execute(directive, async () => {
445
- const requestVariables =
446
- await TiledeskChatbot.allParametersStatic(
447
- tdcache, requestId
448
- );
369
+ new DirDeleteVariable(context).execute(directive, async () => {
370
+ // const requestVariables =
371
+ // await TiledeskChatbot.allParametersStatic(
372
+ // tdcache, requestId
373
+ // );
449
374
  // console.log("delete executed.",directive, requestVariables);
450
375
  process(nextDirective());
451
376
  });
@@ -77,7 +77,7 @@ class FillParamsChatbotPlug {
77
77
  }
78
78
  if (all_parameters) {
79
79
  for (const [key, value] of Object.entries(all_parameters)) {
80
- const value = all_parameters[key];
80
+ // const value = all_parameters[key];
81
81
  const value_type = typeof value;
82
82
  if (this.log) {console.log("checking parameter:", key, "value:", value, "type:", value_type)}
83
83
  message_text = message_text.replace(new RegExp("(\\$\\{" + key + "\\})", 'i'), value);
@@ -3,7 +3,7 @@ class Filler {
3
3
  fill(text, parameters) {
4
4
  if (parameters) {
5
5
  for (const [key, value] of Object.entries(parameters)) {
6
- text = text.replace(new RegExp("(\\$\\{" + key + "\\})", 'i'), parameters[key]);
6
+ text = text.replace(new RegExp("(\\$\\{" + key + "\\})", 'i'), value); //parameters[key]);
7
7
  }
8
8
  }
9
9
  return text;
@@ -58,17 +58,13 @@ class DirMessage {
58
58
  else if (directive.parameter) {
59
59
  let text = directive.parameter.trim();
60
60
  action = {
61
- // body: {
62
- // message: {
63
- text: text,
64
- attributes: {
65
- directives: false,
66
- splits: true,
67
- markbot: true,
68
- fillParams: true
69
- }
70
- // }
71
- // }
61
+ text: text,
62
+ attributes: {
63
+ directives: false,
64
+ splits: true,
65
+ markbot: true,
66
+ fillParams: true
67
+ }
72
68
  }
73
69
  if (directive.name === Directives.HMESSAGE) {
74
70
  action.attributes.subtype = "info";
@@ -1,3 +1,5 @@
1
+ const { TiledeskChatbot } = require('../../models/TiledeskChatbot');
2
+ const { Filler } = require('../Filler');
1
3
 
2
4
  class DirReplaceBot {
3
5
 
@@ -8,7 +10,7 @@ class DirReplaceBot {
8
10
  this.context = context;
9
11
  this.tdclient = context.tdclient;
10
12
  this.requestId = context.requestId;
11
- this.log = log;
13
+ this.log = context.log;
12
14
  }
13
15
 
14
16
  execute(directive, callback) {
@@ -33,8 +35,16 @@ class DirReplaceBot {
33
35
  })
34
36
  }
35
37
 
36
- go(action, callback) {
37
- this.tdclient.replaceBotByName(this.requestId, action.botName, () => {
38
+ async go(action, callback) {
39
+ let botName = action.botName;
40
+ let variables = null;
41
+ variables =
42
+ await TiledeskChatbot.allParametersStatic(
43
+ this.context.tdcache, this.context.requestId
44
+ );
45
+ const filler = new Filler();
46
+ botName = filler.fill(botName, variables);
47
+ this.tdclient.replaceBotByName(this.requestId, botName, () => {
38
48
  callback();
39
49
  });
40
50
  }
@@ -0,0 +1,89 @@
1
+ const { Filler } = require('../Filler');
2
+ const { TiledeskChatbot } = require('../../models/TiledeskChatbot');
3
+
4
+ class DirReply {
5
+
6
+ constructor(context) {
7
+ if (!context) {
8
+ throw new Error('context object is mandatory.');
9
+ }
10
+ this.context = context;
11
+ this.projectId = context.projectId;
12
+ this.requestId = context.requestId;
13
+ this.token = context.token;
14
+ this.tdcache = context.tdcache;
15
+ }
16
+
17
+ execute(directive, callback) {
18
+ console.log("Reply directive:", directive);
19
+ let action;
20
+ if (directive.action) {
21
+ action = directive.action;
22
+ console.log("got action:", JSON.stringify(action));
23
+ if (!action.attributes) {
24
+ action.attributes = {}
25
+ }
26
+ action.attributes.fillParams = true;
27
+ }
28
+ else {
29
+ console.error("Incorrect directive (no action provided):", directive);
30
+ callback();
31
+ return;
32
+ }
33
+ this.go(action, () => {
34
+ callback();
35
+ });
36
+ }
37
+
38
+ async go(action, callback) {
39
+ const message = action;
40
+ // fill
41
+ let requestVariables = null;
42
+ if (this.tdcache) {
43
+ requestVariables =
44
+ await TiledeskChatbot.allParametersStatic(
45
+ this.tdcache, this.requestId
46
+ );
47
+ const filler = new Filler();
48
+ // fill text attribute
49
+ message.text = filler.fill(message.text, requestVariables);
50
+ // fill commands' text attribute
51
+ if (message.attributes && message.attributes.commands) {
52
+ let commands = message.attributes.commands;
53
+ if (commands.length > 1) {
54
+ for (let i = 0; i < commands.length; i++) {
55
+ if (commands[i].type === 'message' && commands[i].message && commands[i].message.text) {
56
+ commands[i].message.text = this.fillWithRequestParams(commands[i].message.text, requestVariables);
57
+ }
58
+ }
59
+ }
60
+ }
61
+ // temporary send back of reserved attributes
62
+ if (!message.attributes) {
63
+ message.attributes = {}
64
+ }
65
+ // Reserved names: userEmail, userFullname
66
+ if (requestVariables['userEmail']) {
67
+ message.attributes.updateUserEmail = requestVariables['userEmail'];
68
+ }
69
+ if (requestVariables['userFullname']) {
70
+ message.attributes.updateUserFullname = requestVariables['userFullname'];
71
+ }
72
+ }
73
+ // send!
74
+ if (this.log) {console.log("Message to extEndpoint:", message)};
75
+ this.context.tdclient.sendSupportMessage(
76
+ this.requestId,
77
+ message,
78
+ (err) => {
79
+ if (err) {
80
+ console.error("Error sending reply:", err.message);
81
+ }
82
+ if (this.log) {console.log("Message sent.");}
83
+ callback();
84
+ });
85
+ }
86
+
87
+ }
88
+
89
+ module.exports = { DirReply };
@@ -23,16 +23,12 @@ class DirWait {
23
23
  millis = 1000
24
24
  }
25
25
  action = {
26
- // body: {
27
- millis: millis
28
- // }
26
+ millis: millis
29
27
  }
30
28
  }
31
29
  else {
32
30
  action = {
33
- // body: {
34
- millis: 500
35
- // }
31
+ millis: 500
36
32
  }
37
33
  }
38
34
  this.go(action, () => {
@@ -33,12 +33,16 @@ class Directives {
33
33
  static ASSIGN = "assign";
34
34
  static IF_AVAILABLE_AGENTS = "ifavailableagents"; // TODO
35
35
  static IF_NO_AVAILABLE_AGENTS = "ifnotavailableagents"; // TODO
36
+ static REPLY = 'reply';
36
37
 
37
38
  static actionToDirective(action) {
39
+ console.log("actionToDirective:", action);
38
40
  let directive = {
39
- name: action.type,
41
+ name: action["_tdActionType"],//.type, //_tdActionType
40
42
  action: action
41
43
  }
44
+ // delete directive.action["_tdActionType"];
45
+ console.log("Directive out:", directive);
42
46
  return directive;
43
47
  }
44
48
  }