@tiledesk/tiledesk-server 2.10.66 → 2.10.68

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.
@@ -4,12 +4,13 @@ var winston = require('../config/winston');
4
4
  const botEvent = require('../event/botEvent');
5
5
  const ActionsConstants = require('../models/actionsConstants');
6
6
  const uuidv4 = require('uuid/v4');
7
+ const chatbotTypes = require("../models/chatbotTypes");
7
8
 
8
9
 
9
10
  class FaqService {
10
11
 
11
12
 
12
- create(name, url, projectid, user_id, type, description, webhook_url, webhook_enabled, language, template, mainCategory, intentsEngine, attributes) {
13
+ create(name, url, projectid, user_id, type, subtype, description, webhook_url, webhook_enabled, language, template, mainCategory, intentsEngine, attributes) {
13
14
  var that = this;
14
15
  return new Promise(function (resolve, reject) {
15
16
 
@@ -22,6 +23,7 @@ class FaqService {
22
23
  webhook_url: webhook_url,
23
24
  webhook_enabled: webhook_enabled,
24
25
  type: type,
26
+ subtype: subtype,
25
27
  language: language,
26
28
  public: false,
27
29
  certified: false,
@@ -47,6 +49,25 @@ class FaqService {
47
49
 
48
50
  if (type === "internal" || type === "tilebot") {
49
51
 
52
+ if (!subtype) {
53
+ if (!template) {
54
+ template = "empty";
55
+ }
56
+ } else {
57
+
58
+ if (subtype === chatbotTypes.CHATBOT) {
59
+ if (!template) {
60
+ template = "empty";
61
+ }
62
+ } else if (subtype === chatbotTypes.WEBHOOK) {
63
+ template = "blank_webhook"
64
+ } else if (subtype === chatbotTypes.COPILOT) {
65
+ template = "blank_copilot"
66
+ } else {
67
+ template = "empty";
68
+ }
69
+ }
70
+
50
71
  if (!template) {
51
72
  template = "empty";
52
73
  }
@@ -89,7 +110,6 @@ class FaqService {
89
110
  { 'question': 'Sample Frame', 'answer': 'tdFrame:https://www.emanueleferonato.com/wp-content/uploads/2019/02/runner/\n* What can you do?\n* Back to start tdAction:start', 'topic': 'sample' },
90
111
  { 'question': 'Sample Video', 'answer': 'tdVideo:https://www.youtube.com/embed/EngW7tLk6R8\n* What can you do?\n* Back to start tdAction:start', 'topic': 'sample' },
91
112
  { 'question': 'Where are you?', 'answer': 'We are here ❤️\ntdFrame:https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d6087916.923447935!2d8.234804542117423!3d41.836572992140624!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x12d4fe82448dd203%3A0xe22cf55c24635e6f!2sItaly!5e0!3m2!1sen!2sit!4v1613657475377!5m2!1sen!2sit\n* Back to start tdAction:start', 'topic': 'sample' },
92
-
93
113
  // { 'question': 'Sample Webhook', 'answer': 'tdWebhook:https://tiledesk-bot-webhook.tiledesk.repl.co', 'topic': 'sample' },
94
114
  { 'question': 'Sample Action', 'answer': 'Hello 👋 Would you like to take a closer look at our offer?\n* Yes, please tdAction:yes_action\n* No tdAction:no_action', 'intent_display_name': 'action1', 'topic': 'sample' },
95
115
  { 'question': 'Yes Action', 'answer': 'Great! Take a look here:\n* Tiledesk Pricing https://tiledesk.com/pricing-cloud/', 'intent_display_name': 'yes_action', 'topic': 'sample' },
@@ -108,76 +128,78 @@ class FaqService {
108
128
  // { 'question': '\\start', 'answer': 'Hello', 'intent_display_name': 'start', 'topic': 'internal' },
109
129
  // { 'question': 'defaultFallback', 'answer': 'I can not provide an adequate answer. Write a new question or talk to a human agent.\n* Back to start tdAction:start\n* See the docs https://docs.tiledesk.com/\n* 👨🏻‍🦰 I want an agent', 'intent_display_name': 'defaultFallback', 'topic': 'internal' }, //TODO se metto spazio n * nn va
110
130
  // ]
111
- faqsArray = [{
112
- "webhook_enabled": false,
113
- "enabled": true,
114
- "actions": [{
115
- "_tdActionType": "reply",
116
- "text": "I didn't understand. Can you rephrase your question?",
131
+ faqsArray = [
132
+ {
133
+ "webhook_enabled": false,
134
+ "enabled": true,
135
+ "actions": [{
136
+ "_tdActionType": "reply",
137
+ "text": "I didn't understand. Can you rephrase your question?",
138
+ "attributes": {
139
+ "commands": [{
140
+ "type": "wait",
141
+ "time": 500
142
+ }, {
143
+ "type": "message",
144
+ "message": {
145
+ "type": "text",
146
+ "text": "I didn't understand. Can you rephrase your question?"
147
+ }
148
+ }]
149
+ }
150
+ }],
151
+ "intent_display_name": "defaultFallback",
117
152
  "attributes": {
118
- "commands": [{
119
- "type": "wait",
120
- "time": 500
121
- },{
122
- "type": "message",
123
- "message": {
124
- "type": "text",
125
- "text": "I didn't understand. Can you rephrase your question?"
126
- }
127
- }]
153
+ "position": {
154
+ "x": 714,
155
+ "y": 528
156
+ }
128
157
  }
129
- }],
130
- "intent_display_name": "defaultFallback",
131
- "attributes": {
132
- "position": {
133
- "x": 714,
134
- "y": 528
135
- }
136
- }
137
- }, {
138
- "webhook_enabled": false,
139
- "enabled": true,
140
- "actions": [{
141
- "_tdActionType": "intent",
142
- "intentName": "#" + custom_intent_id
143
- }],
144
- "question": "\\start",
145
- "intent_display_name": "start",
146
- "attributes": {
147
- "position": {
148
- "x": 172,
149
- "y": 384
158
+ }, {
159
+ "webhook_enabled": false,
160
+ "enabled": true,
161
+ "actions": [{
162
+ "_tdActionType": "intent",
163
+ "intentName": "#" + custom_intent_id
164
+ }],
165
+ "question": "\\start",
166
+ "intent_display_name": "start",
167
+ "attributes": {
168
+ "position": {
169
+ "x": 172,
170
+ "y": 384
171
+ }
150
172
  }
151
- }
152
- }, {
153
- "webhook_enabled": false,
154
- "enabled": true,
155
- "actions": [{
156
- "_tdActionType": "reply",
173
+ }, {
174
+ "webhook_enabled": false,
175
+ "enabled": true,
176
+ "actions": [{
177
+ "_tdActionType": "reply",
178
+ "attributes": {
179
+ "disableInputMessage": false,
180
+ "commands": [{
181
+ "type": "wait",
182
+ "time": 500
183
+ }, {
184
+ "type": "message",
185
+ "message": {
186
+ "type": "text",
187
+ "text": "Hi, how can I help you?"
188
+ }
189
+ }]
190
+ },
191
+ "text": "Hi, how can I help you?\r\n"
192
+ }],
193
+ "intent_display_name": "welcome",
194
+ "intent_id": custom_intent_id,
157
195
  "attributes": {
158
- "disableInputMessage": false,
159
- "commands": [{
160
- "type": "wait",
161
- "time": 500
162
- }, {
163
- "type": "message",
164
- "message": {
165
- "type": "text",
166
- "text": "Hi, how can I help you?"
167
- }
168
- }]
169
- },
170
- "text": "Hi, how can I help you?\r\n"
171
- }],
172
- "intent_display_name": "welcome",
173
- "intent_id": custom_intent_id,
174
- "attributes": {
175
- "position": {
176
- "x": 714,
177
- "y": 113
196
+ "position": {
197
+ "x": 714,
198
+ "y": 113
199
+ }
178
200
  }
179
201
  }
180
- }]
202
+ ]
181
203
 
182
204
  }
183
205
 
@@ -196,7 +218,89 @@ class FaqService {
196
218
  faqsArray = [];
197
219
  }
198
220
 
221
+ if (template === "blank_webhook") {
222
+ let custom_intent_id = uuidv4();
223
+
224
+ faqsArray = [
225
+ {
226
+ "webhook_enabled": false,
227
+ "enabled": true,
228
+ "actions": [{
229
+ "_tdActionType": "intent",
230
+ "intentName": "#" + custom_intent_id
231
+ }],
232
+ "question": "",
233
+ "intent_display_name": "webhook",
234
+ "attributes": {
235
+ "position": {
236
+ "x": 172,
237
+ "y": 384
238
+ }
239
+ }
240
+ },
241
+ {
242
+ "webhook_enabled": false,
243
+ "enabled": true,
244
+ "actions": [{
245
+ "_tdActionType": "web_response",
246
+ "status": 200,
247
+ "bodyType": "json",
248
+ "payload": '{"success": true , "message": "Your webhook is online!"}'
249
+ }],
250
+ "intent_display_name": "response",
251
+ "intent_id": custom_intent_id,
252
+ "attributes": {
253
+ "position": {
254
+ "x": 714,
255
+ "y": 113
256
+ }
257
+ }
258
+ }
259
+ ]
260
+ }
261
+
262
+ if (template === "blank_copilot") {
263
+ let custom_intent_id = uuidv4();
264
+
265
+ faqsArray = [
266
+ {
267
+ "webhook_enabled": false,
268
+ "enabled": true,
269
+ "actions": [{
270
+ "_tdActionType": "intent",
271
+ "intentName": "#" + custom_intent_id
272
+ }],
273
+ "question": "",
274
+ "intent_display_name": "webhook",
275
+ "attributes": {
276
+ "position": {
277
+ "x": 172,
278
+ "y": 384
279
+ }
280
+ }
281
+ },
282
+ {
283
+ "webhook_enabled": false,
284
+ "enabled": true,
285
+ "actions": [{
286
+ "_tdActionType": "web_response",
287
+ "status": 200,
288
+ "bodyType": "json",
289
+ "payload": '{"title": "Official Copilot", "text": "This is a suggestion!"}'
290
+ }],
291
+ "intent_display_name": "response",
292
+ "intent_id": custom_intent_id,
293
+ "attributes": {
294
+ "position": {
295
+ "x": 714,
296
+ "y": 113
297
+ }
298
+ }
299
+ }
300
+ ]
301
+ }
199
302
 
303
+
200
304
  faqsArray.forEach(faq => {
201
305
 
202
306
  var newFaq = new Faq({
@@ -0,0 +1,71 @@
1
+ const faq_kb = require("../models/faq_kb");
2
+ const httpUtil = require("../utils/httpUtil");
3
+ const uuidv4 = require('uuid/v4');
4
+ var jwt = require('jsonwebtoken');
5
+ var winston = require('../config/winston');
6
+
7
+ const port = process.env.PORT || '3000';
8
+ let TILEBOT_ENDPOINT = "http://localhost:" + port + "/modules/tilebot/";;
9
+ if (process.env.TILEBOT_ENDPOINT) {
10
+ TILEBOT_ENDPOINT = process.env.TILEBOT_ENDPOINT + "/"
11
+ }
12
+ winston.debug("TILEBOT_ENDPOINT: " + TILEBOT_ENDPOINT);
13
+
14
+ class WebhookService {
15
+
16
+ async run(webhook, payload) {
17
+
18
+ return new Promise(async (resolve, reject) => {
19
+
20
+ winston.verbose("(WebhookService) Run webhook " + webhook.webhook_id);
21
+ let chatbot = await faq_kb.findById(webhook.chatbot_id).select("+secret").catch((err) => {
22
+ winston.error("Error finding chatbot ", err);
23
+ reject(err);
24
+ })
25
+
26
+ if (!chatbot) {
27
+ winston.verbose("Chatbot not found with id " + webhook.chatbot_id);
28
+ reject("Chatbot not found with id " + webhook.chatbot_id);
29
+ }
30
+
31
+ let token = await this.generateChatbotToken(chatbot);
32
+
33
+ let url = TILEBOT_ENDPOINT + 'block/' + webhook.id_project + "/" + webhook.chatbot_id + "/" + webhook.block_id;
34
+ winston.info("Webhook chatbot URL: ", url);
35
+
36
+ payload.async = webhook.async;
37
+ payload.token = token;
38
+
39
+ if (process.env.NODE_ENV === 'test') {
40
+ resolve(true);
41
+ }
42
+
43
+ await httpUtil.post(url, payload).then((response) => {
44
+ resolve(response.data);
45
+ }).catch((err) => {
46
+ winston.error("Error calling webhook on post: ", err);
47
+ reject(err);
48
+ })
49
+
50
+ })
51
+ }
52
+
53
+ async generateChatbotToken(chatbot) {
54
+ let signOptions = {
55
+ issuer: 'https://tiledesk.com',
56
+ subject: 'bot',
57
+ audience: 'https://tiledesk.com/bots/' + chatbot._id,
58
+ jwtid: uuidv4()
59
+ };
60
+
61
+ let botPayload = chatbot.toObject();
62
+ let botSecret = botPayload.secret;
63
+
64
+ var bot_token = jwt.sign(botPayload, botSecret, signOptions);
65
+ return bot_token;
66
+ }
67
+ }
68
+
69
+ let webhookService = new WebhookService();
70
+
71
+ module.exports = webhookService;
@@ -22,7 +22,7 @@ let log = false;
22
22
 
23
23
  describe('FaqService()', function () {
24
24
 
25
- it('create-and-search', (done) => {
25
+ it('createee-and-search', (done) => {
26
26
 
27
27
  var email = "test-subscription-" + Date.now() + "@email.com";
28
28
  var pwd = "pwd";
@@ -40,10 +40,12 @@ describe('FaqService()', function () {
40
40
  createdBy: savedUser._id,
41
41
  updatedBy: savedUser._id
42
42
  });
43
+
43
44
 
44
45
  newFaq.save(function (err, savedFaq) {
45
46
  winston.debug("err", err);
46
47
  winston.debug("resolve", savedFaq);
48
+
47
49
  expect(savedBot.name).to.equal("testbot");
48
50
  expect(savedBot.secret).to.not.equal(null);
49
51
  expect(savedFaq.question).to.equal("question");
@@ -51,15 +53,15 @@ describe('FaqService()', function () {
51
53
  expect(savedFaq.intent_display_name).to.not.equal(undefined);
52
54
  expect(savedFaq.webhook_enabled).to.equal(false);
53
55
 
54
- var query = { "id_project": savedProject._id };
56
+ var query = { "id_faq_kb": savedBot._id };
55
57
 
56
58
  // aggiunta qui
57
59
  query.$text = { "$search": "question" };
58
60
 
59
61
  return Faq.find(query, { score: { $meta: "textScore" } })
60
62
  .sort({ score: { $meta: "textScore" } }) //https://docs.mongodb.com/manual/reference/operator/query/text/#sort-by-text-search-score
61
- .lean().
62
- exec(function (err, faqs) {
63
+ .lean()
64
+ .exec(function (err, faqs) {
63
65
  if (log) { console.log("faqs", faqs); }
64
66
  // expect(faqs.length).to.equal(1);
65
67
  expect(faqs[0]._id.toString()).to.equal(savedFaq._id.toString());
@@ -106,7 +108,7 @@ describe('FaqService()', function () {
106
108
  expect(savedFaq.intent_display_name).to.equal("question1");
107
109
  expect(savedFaq.webhook_enabled).to.equal(false);
108
110
 
109
- var query = { "id_project": savedProject._id };
111
+ var query = { "id_faq_kb": savedBot._id };
110
112
 
111
113
  // aggiunta qui
112
114
  query.$text = { "$search": "question" };
@@ -115,6 +117,7 @@ describe('FaqService()', function () {
115
117
  .sort({ score: { $meta: "textScore" } }) //https://docs.mongodb.com/manual/reference/operator/query/text/#sort-by-text-search-score
116
118
  .lean().
117
119
  exec(function (err, faqs) {
120
+ if (err) { console.error("err: ", err )}
118
121
  if (log) { console.log("faqs", faqs); }
119
122
  // expect(faqs.length).to.equal(1);
120
123
  expect(faqs[0]._id.toString()).to.equal(savedFaq._id.toString());