@tiledesk/tiledesk-server 2.2.11 → 2.2.16

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,453 @@
1
+
2
+
3
+ 'use strict';
4
+
5
+ const Faq = require('../models/faq');
6
+ const Faq_kb = require('../models/faq_kb');
7
+ const MessageConstants = require('../models/messageConstants');
8
+ var winston = require('../config/winston');
9
+
10
+ var jwt = require('jsonwebtoken');
11
+ const uuidv4 = require('uuid/v4');
12
+
13
+ const { TiledeskChatbotUtil } = require('@tiledesk/tiledesk-chatbot-util');
14
+
15
+ var request = require('retry-request', {
16
+ request: require('request')
17
+ });
18
+
19
+
20
+ var webhook_origin = process.env.WEBHOOK_ORIGIN || "http://localhost:3000";
21
+ winston.debug("webhook_origin: "+webhook_origin);
22
+
23
+ class FaqBotSupport {
24
+
25
+
26
+
27
+
28
+ getMessage(key, lang, labelsObject) {
29
+
30
+
31
+ if (!lang) {
32
+ lang = "EN";
33
+ }
34
+
35
+ lang = lang.toUpperCase();
36
+
37
+ winston.debug('getMessage: ' + key + ' ' + lang+ ' ' + JSON.stringify(labelsObject) );
38
+
39
+ var label = "";
40
+
41
+ try {
42
+ // winston.debug("1");
43
+ label = labelsObject[lang][key];
44
+ // winston.debug("2");
45
+ } catch(e) {
46
+ // winston.debug("Error", e);
47
+ label = labelsObject["EN"][key];
48
+ }
49
+ winston.debug('label: ' + label );
50
+ return label;
51
+
52
+ }
53
+ // usa api di sponziello parseReply: https://github.com/Tiledesk/tiledesk-nodejs-libs/blob/master/tiledesk-chatbot-util/index.js
54
+
55
+ parseMicrolanguage(text, message, bot, faq, disableWebHook, json) {
56
+ var that = this;
57
+ return new Promise(async (resolve, reject) => {
58
+ winston.info('parseMicrolanguage message: ' + JSON.stringify(message) );
59
+
60
+ winston.info('text: '+text);
61
+ var commands = TiledeskChatbotUtil.findSplits(text)
62
+ winston.info('commands: ' + JSON.stringify(commands) );
63
+
64
+ let messageReply;
65
+ // da mettere anche in microlanguage = true
66
+ if (commands.length > 1) {
67
+ commands.forEach(command => {
68
+ if (command.type === "message" && command.text != null) {
69
+ let replyCommand = TiledeskChatbotUtil.parseReply(command.text);
70
+ winston.info('replyCommand: ' + JSON.stringify(replyCommand) );
71
+ let messageCommandReply = replyCommand.message;
72
+
73
+ //TODO merge degli attributi dopo. fai lo stesso codice di giù
74
+ command.message = messageCommandReply;
75
+ }
76
+ });
77
+
78
+ messageReply = message.toObject();
79
+ messageReply.attributes = {commands: commands};
80
+
81
+ winston.info('messageReply: ' + JSON.stringify(messageReply) );
82
+
83
+ } else {
84
+
85
+ var reply = TiledeskChatbotUtil.parseReply(text);
86
+ winston.debug('parseReply: ' + JSON.stringify(reply) );
87
+
88
+ messageReply = reply.message;
89
+
90
+ }
91
+
92
+
93
+
94
+
95
+ var msg_attributes = {"_raw_message": text};
96
+
97
+ // prendi attributi e li mergi
98
+ // metadata prendi da messageReply SOLO SE CI SONO (DIVERSI NULL). Se riesci fai il merge
99
+ // prendi type e text
100
+
101
+ // if (message && message.attributes) {
102
+ // for(const [key, value] of Object.entries(message.attributes)) {
103
+ // msg_attributes[key] = value
104
+ // }
105
+ // }
106
+
107
+ if (json && json.attributes) {
108
+ for(const [key, value] of Object.entries(json.attributes)) {
109
+ msg_attributes[key] = value
110
+ }
111
+ }
112
+
113
+ if (messageReply && messageReply.attributes) {
114
+ for(const [key, value] of Object.entries(messageReply.attributes)) {
115
+ msg_attributes[key] = value
116
+ }
117
+ }
118
+
119
+ messageReply.attributes = msg_attributes;
120
+
121
+ // not used in faqBotHandler but used when the message is returned by webhook (subscription). So you must clone(add) all message fields here.
122
+ // winston.debug('message.language: '+ message.language );
123
+ // if (message.language) {
124
+ // messageReply.language = message.language;
125
+ // }
126
+
127
+ if (json && json.language) {
128
+ messageReply.language = json.language;
129
+ }
130
+
131
+ if (json && json.type) {
132
+ messageReply.type = json.type;
133
+ }
134
+
135
+ if (json && json.metadata) {
136
+ messageReply.metadata = json.metadata;
137
+ }
138
+
139
+
140
+ winston.debug('faq: ', faq );
141
+ if (disableWebHook === false && bot.webhook_enabled ===true && (faq.webhook_enabled === true ))
142
+ //|| reply.webhook))
143
+ {
144
+
145
+ winston.debug("bot.webhook_url "+ bot.webhook_url)
146
+ var webhookurl = bot.webhook_url;
147
+
148
+
149
+ // winston.debug("reply.webhook "+ reply.webhook )
150
+
151
+ // if (reply.webhook) {
152
+ // if (reply.webhook === true) {
153
+ webhookurl = bot.webhook_url;
154
+ // } else {
155
+ // webhookurl = reply.webhook;
156
+ // }
157
+ // }
158
+
159
+ if (!webhookurl) {
160
+ winston.debug("webhookurl is undefined return standard");
161
+ return resolve(messageReply);
162
+ }
163
+
164
+ var botWithSecret = await Faq_kb.findById(bot._id).select('+secret').exec();
165
+
166
+ var signOptions = {
167
+ issuer: 'https://tiledesk.com',
168
+ subject: 'bot',
169
+ audience: 'https://tiledesk.com/bots/'+bot._id,
170
+ jwtid: uuidv4()
171
+ };
172
+
173
+ // TODO metti bot_? a user._id
174
+ var token = jwt.sign(bot.toObject(), botWithSecret.secret, signOptions);
175
+
176
+
177
+ winston.debug("webhookurl "+ webhookurl)
178
+
179
+ return request({
180
+ uri : webhookurl,
181
+ headers: {
182
+ 'Content-Type' : 'application/json',
183
+ 'User-Agent': 'tiledesk-bot',
184
+ 'Origin': webhook_origin
185
+ //'x-hook-secret': s.secret
186
+ },
187
+ method: 'POST',
188
+ json: true,
189
+ body: {payload:{text: text, bot: bot, message: message, intent: faq}, token: token},
190
+ // }).then(response => {
191
+ }, function(err, response, json){
192
+ if (err) {
193
+ winston.error("Error from webhook reply of getParsedMessage. Return standard reply", err);
194
+
195
+ return resolve(messageReply);
196
+
197
+ // return error
198
+ /*
199
+ var bot_answer = {};
200
+ bot_answer.text = err.toString();
201
+ if(response && response.text) {
202
+ bot_answer.text = bot_answer.text + ' '+response.text;
203
+ }
204
+ bot_answer.type = "text";
205
+
206
+ return resolve(bot_answer);
207
+ */
208
+ }
209
+ if (response.statusCode >= 400) {
210
+ winston.verbose("The ChatBot webhook return error http status code. Return standard reply", response);
211
+ return resolve(messageReply);
212
+ }
213
+
214
+ if (!json) { //the webhook return empty body
215
+ winston.verbose("The ChatBot webhook return no json. Return standard reply", response);
216
+ return resolve(messageReply);
217
+ }
218
+
219
+ winston.debug("webhookurl repl_message ", response);
220
+
221
+ var text = undefined;
222
+ if(json && json.text===undefined) {
223
+ winston.verbose("webhookurl json is defined but text not. return standard reply",{json:json, response:response});
224
+ // text = 'Field text is not defined in the webhook respose of the faq with id: '+ faq._id+ ". Error: " + JSON.stringify(response);
225
+ return resolve(messageReply);
226
+ }else {
227
+ text = json.text;
228
+ }
229
+ winston.debug("webhookurl text: "+ text);
230
+
231
+ // // let cloned_message = Object.assign({}, messageReply);
232
+ // let cloned_message = message;
233
+ // winston.debug("cloned_message : ",cloned_message);
234
+
235
+ // if (json.attributes) {
236
+ // if (!cloned_message.attributes) {
237
+ // cloned_message.attributes = {}
238
+ // }
239
+ // winston.debug("ChatBot webhook json.attributes: ",json.attributes);
240
+ // for(const [key, value] of Object.entries(json.attributes)) {
241
+ // cloned_message.attributes[key] = value
242
+ // }
243
+ // }
244
+
245
+ // winston.debug("cloned_message after attributes: ",cloned_message);
246
+
247
+ that.parseMicrolanguage(text, message, bot, faq, true, json).then(function(bot_answer) {
248
+ return resolve(bot_answer);
249
+ });
250
+ });
251
+ }
252
+
253
+ return resolve(messageReply);
254
+ });
255
+ }
256
+
257
+ getParsedMessage(text, message, bot, faq) {
258
+ return this.parseMicrolanguage(text, message, bot, faq, false);
259
+ // return this.parseMicrolanguageOld(text, message, bot, faq);
260
+ }
261
+
262
+ // parseMicrolanguageOld(text, message, bot, faq) {
263
+ // var that = this;
264
+ // // text = "*"
265
+ // return new Promise(function(resolve, reject) {
266
+ // winston.debug("getParsedMessage ******",text);
267
+ // var repl_message = {};
268
+
269
+ // // cerca i bottoni eventualmente definiti
270
+ // var button_pattern = /^\*.*/mg; // buttons are defined as a line starting with an asterisk
271
+ // var text_buttons = text.match(button_pattern);
272
+ // if (text_buttons) {
273
+ // var text_with_removed_buttons = text.replace(button_pattern,"").trim();
274
+ // repl_message.text = text_with_removed_buttons
275
+ // var buttons = []
276
+ // text_buttons.forEach(element => {
277
+ // winston.debug("button ", element)
278
+ // var remove_extra_from_button = /^\*/mg;
279
+ // var button_text = element.replace(remove_extra_from_button, "").trim()
280
+ // var button = {}
281
+ // button["type"] = "text"
282
+ // button["value"] = button_text
283
+ // buttons.push(button)
284
+ // });
285
+ // repl_message.attributes =
286
+ // {
287
+ // attachment: {
288
+ // type:"template",
289
+ // buttons: buttons
290
+ // }
291
+ // }
292
+ // repl_message.type = MessageConstants.MESSAGE_TYPE.TEXT;
293
+ // } else {
294
+ // // no buttons
295
+ // repl_message.text = text
296
+ // repl_message.type = MessageConstants.MESSAGE_TYPE.TEXT;
297
+ // }
298
+
299
+ // var image_pattern = /^\\image:.*/mg;
300
+ // var imagetext = text.match(image_pattern);
301
+ // if (imagetext && imagetext.length>0) {
302
+ // var imageurl = imagetext[0].replace("\\image:","").trim();
303
+ // winston.debug("imageurl ", imageurl)
304
+ // var text_with_removed_image = text.replace(image_pattern,"").trim();
305
+ // repl_message.text = text_with_removed_image + " " + imageurl
306
+ // repl_message.metadata = {src: imageurl, width:200, height:200};
307
+ // repl_message.type = MessageConstants.MESSAGE_TYPE.IMAGE;
308
+ // }
309
+
310
+ // var frame_pattern = /^\\frame:.*/mg;
311
+ // var frametext = text.match(frame_pattern);
312
+ // if (frametext && frametext.length>0) {
313
+ // var frameurl = frametext[0].replace("\\frame:","").trim();
314
+ // winston.debug("frameurl ", frameurl)
315
+ // // var text_with_removed_image = text.replace(frame_pattern,"").trim();
316
+ // // repl_message.text = text_with_removed_image + " " + imageurl
317
+ // repl_message.metadata = {src: frameurl};
318
+ // repl_message.type = MessageConstants.MESSAGE_TYPE.FRAME;
319
+ // }
320
+
321
+
322
+ // var webhook_pattern = /^\\webhook:.*/mg;
323
+ // var webhooktext = text.match(webhook_pattern);
324
+ // if (webhooktext && webhooktext.length>0) {
325
+ // var webhookurl = webhooktext[0].replace("\\webhook:","").trim();
326
+ // winston.debug("webhookurl ", webhookurl)
327
+
328
+ // return request({
329
+ // uri : webhookurl,
330
+ // headers: {
331
+ // 'Content-Type': 'application/json'
332
+ // },
333
+ // method: 'POST',
334
+ // json: true,
335
+ // body: {payload:{text: text, bot: bot, message: message, faq: faq}},
336
+ // // }).then(response => {
337
+ // }, function(err, response, json){
338
+ // if (err) {
339
+ // bot_answer.text = err +' '+ response.text;
340
+ // bot_answer.type = MessageConstants.MESSAGE_TYPE.TEXT;
341
+ // winston.error("Error from webhook reply of getParsedMessage", err);
342
+ // return resolve(bot_answer);
343
+ // }
344
+ // // if (response.statusCode >= 400) {
345
+ // // return reject(`HTTP Error: ${response.statusCode}`);
346
+ // // }
347
+ // winston.debug("webhookurl repl_message ", response);
348
+
349
+ // var text = undefined;
350
+ // if(json && json.text===undefined) {
351
+ // text = 'Field text is not defined in the webhook respose of the faq with id: '+ faq._id+ ". Error: " + JSON.stringify(response);
352
+ // }else {
353
+ // text = json.text;
354
+ // }
355
+
356
+
357
+ // that.getParsedMessage(text,message, bot, faq).then(function(bot_answer) {
358
+ // return resolve(bot_answer);
359
+ // });
360
+ // });
361
+
362
+ // }else {
363
+ // winston.debug("repl_message ", repl_message)
364
+ // return resolve(repl_message);
365
+ // }
366
+
367
+
368
+
369
+ // });
370
+ // }
371
+
372
+
373
+ getBotMessage(botAnswer, projectid, bot, message, threshold) {
374
+ var that = this;
375
+ return new Promise(function(resolve, reject) {
376
+
377
+ winston.debug('botAnswer', botAnswer);
378
+ // var found = false;
379
+ var bot_answer={};
380
+
381
+ if (!botAnswer ) {
382
+
383
+ var query = { "id_project": projectid, "id_faq_kb": bot._id, "question": "defaultFallback"};
384
+ winston.debug('query', query);
385
+
386
+
387
+ Faq.find(query)
388
+ .lean(). //fai cache
389
+ exec(function (err, faqs) {
390
+ if (err) {
391
+ return res.status(500).send({ success: false, msg: 'Error getting object.' });
392
+ }
393
+
394
+ winston.debug("faqs", faqs);
395
+
396
+ if (faqs && faqs.length>0) {
397
+ winston.debug("faqs exact", faqs);
398
+
399
+ bot_answer.text=faqs[0].answer;
400
+
401
+ winston.debug("bot_answer exact", bot_answer);
402
+ // found = true;
403
+ // return resolve(bot_answer);
404
+
405
+ if (message.channel.name == "chat21") { //why this contition on chat21 channel? bacause only chat21 support parsed replies?
406
+ winston.debug("faqBotSupport message.channel.name is chat21",message);
407
+ that.getParsedMessage(bot_answer.text,message, bot, faqs[0]).then(function(bot_answerres) {
408
+
409
+ bot_answerres.defaultFallback=true;
410
+
411
+ return resolve(bot_answerres);
412
+ });
413
+
414
+ } else {
415
+ winston.debug("faqBotSupport message.channel.name is not chat21 returning default",message);
416
+ return resolve(bot_answer);
417
+ }
418
+
419
+ } else {
420
+ var message_key = "DEFAULT_NOTFOUND_NOBOT_SENTENCE_REPLY_MESSAGE";
421
+ bot_answer.text = that.getMessage(message_key, message.language, faqBotSupport.LABELS);
422
+ bot_answer.defaultFallback = true;
423
+ // console.log("bot_answer ", bot_answer)
424
+ return resolve(bot_answer);
425
+ }
426
+ });
427
+ }
428
+
429
+
430
+ });
431
+
432
+ }
433
+
434
+
435
+
436
+ }
437
+
438
+
439
+ var faqBotSupport = new FaqBotSupport();
440
+
441
+ faqBotSupport.LABELS = {
442
+ EN : {
443
+ DEFAULT_NOTFOUND_NOBOT_SENTENCE_REPLY_MESSAGE: "I did not find an answer in the knowledge base. \n Please reformulate your question?"
444
+ },
445
+ IT : {
446
+ DEFAULT_NOTFOUND_NOBOT_SENTENCE_REPLY_MESSAGE: "Non sono in grado di fornirti una risposta adeguata. \n Prego riformula la domanda."
447
+ },
448
+ "IT-IT" : {
449
+ DEFAULT_NOTFOUND_NOBOT_SENTENCE_REPLY_MESSAGE: "Non sono in grado di fornirti una risposta adeguata. \n Prego riformula la domanda."
450
+ }
451
+ }
452
+
453
+ module.exports = faqBotSupport;
@@ -85,6 +85,7 @@ class FaqService {
85
85
  question: faq.question,
86
86
  answer: faq.answer,
87
87
  intent_display_name: faq.intent_display_name,
88
+ language: "en",
88
89
  id_project: projectid,
89
90
  topic: faq.topic,
90
91
  createdBy: created_by,
@@ -121,7 +121,7 @@ class MessageService {
121
121
 
122
122
  return newMessage.save(function(err, savedMessage) {
123
123
  if (err) {
124
- winston.error("Error savig the message", {err:err, message: message, newMessage: newMessage});
124
+ winston.error("Error saving the message", {err:err, message: message, newMessage: newMessage});
125
125
  return reject(err);
126
126
  }
127
127
  winston.verbose("Message created", savedMessage.toObject());
@@ -284,7 +284,9 @@ class RequestService {
284
284
 
285
285
 
286
286
  requestEvent.emit('request.update',requestComplete);
287
- requestEvent.emit("request.update.comment", {comment:"REROUTE",request:requestComplete});
287
+ requestEvent.emit("request.update.comment", {comment:"REROUTE",request:requestComplete});//Deprecated
288
+ requestEvent.emit("request.updated", {comment:"REROUTE",request:requestComplete, patch:{removedParticipants: removedParticipants, addedParticipants:addedParticipants}});
289
+
288
290
  requestEvent.emit('request.participants.update', {beforeRequest:request,
289
291
  removedParticipants:removedParticipants,
290
292
  addedParticipants:addedParticipants,
@@ -726,8 +728,10 @@ class RequestService {
726
728
  winston.error(err);
727
729
  return reject(err);
728
730
  }
729
- requestEvent.emit('request.update',updatedRequest);
730
- requestEvent.emit("request.update.comment", {comment:"STATUS_CHANGE",request:updatedRequest});
731
+
732
+ requestEvent.emit('request.update',updatedRequest); //deprecated
733
+ requestEvent.emit("request.update.comment", {comment:"STATUS_CHANGE",request:updatedRequest});//Deprecated
734
+ requestEvent.emit("request.updated", {comment:"STATUS_CHANGE",request:updatedRequest, patch:{status: newstatus}});
731
735
  //TODO emit request.clone or reopen also
732
736
 
733
737
  return resolve(updatedRequest);
@@ -765,7 +769,9 @@ class RequestService {
765
769
 
766
770
  requestEvent.emit('request.update.preflight',updatedRequest); //archive to audit log
767
771
  requestEvent.emit('request.update',updatedRequest);
768
- requestEvent.emit("request.update.comment", {comment:"FIRSTTEXT_PREFLIGHT_CHANGE",request:updatedRequest});
772
+ requestEvent.emit("request.update.comment", {comment:"FIRSTTEXT_PREFLIGHT_CHANGE",request:updatedRequest});//Deprecated
773
+ requestEvent.emit("request.updated", {comment:"FIRSTTEXT_PREFLIGHT_CHANGE",request:updatedRequest, patch: {first_text: first_text, preflight: preflight}});
774
+
769
775
  //TODO emit request.clone or reopen also
770
776
 
771
777
  return resolve(updatedRequest);
@@ -794,7 +800,9 @@ class RequestService {
794
800
  return reject(err);
795
801
  }
796
802
  requestEvent.emit('request.update',updatedRequest);
797
- requestEvent.emit("request.update.comment", {comment:"FIRSTTEXT_CHANGE",request:updatedRequest});
803
+ requestEvent.emit("request.update.comment", {comment:"FIRSTTEXT_CHANGE",request:updatedRequest});//Deprecated
804
+ requestEvent.emit("request.updated", {comment:"FIRSTTEXT_CHANGE",request:updatedRequest, patch: {first_text: first_text}});
805
+
798
806
  //TODO emit request.clone or reopen also
799
807
 
800
808
  return resolve(updatedRequest);
@@ -825,7 +833,8 @@ class RequestService {
825
833
  return reject(err);
826
834
  }
827
835
  requestEvent.emit('request.update',updatedRequest);
828
- requestEvent.emit("request.update.comment", {comment:"PREFLIGHT_CHANGE",request:updatedRequest});
836
+ requestEvent.emit("request.update.comment", {comment:"PREFLIGHT_CHANGE",request:updatedRequest});//Deprecated
837
+ requestEvent.emit("request.updated", {comment:"PREFLIGHT_CHANGE",request:updatedRequest, patch: {preflight: preflight}});
829
838
 
830
839
  return resolve(updatedRequest);
831
840
  });
@@ -1058,7 +1067,9 @@ class RequestService {
1058
1067
  }
1059
1068
 
1060
1069
  requestEvent.emit('request.update', savedRequest);
1061
- requestEvent.emit("request.update.comment", {comment:"REOPEN",request:savedRequest});
1070
+ requestEvent.emit("request.update.comment", {comment:"REOPEN",request:savedRequest});//Deprecated
1071
+ requestEvent.emit("request.updated", {comment:"REOPEN",request:savedRequest, patch: {status: savedRequest.status}});
1072
+
1062
1073
  requestEvent.emit('request.reopen', savedRequest);
1063
1074
 
1064
1075
  winston.verbose("Request reopened", savedRequest);
@@ -1223,10 +1234,6 @@ class RequestService {
1223
1234
  return reject(err);
1224
1235
  }
1225
1236
 
1226
- requestEvent.emit('request.update', requestComplete);
1227
- requestEvent.emit("request.update.comment", {comment:"PARTICIPANTS_SET",request:requestComplete});
1228
-
1229
-
1230
1237
  winston.debug("oldParticipants ", oldParticipants);
1231
1238
 
1232
1239
  let newParticipants = requestComplete.participants;
@@ -1238,6 +1245,11 @@ class RequestService {
1238
1245
  var addedParticipants = newParticipants.filter(d => !oldParticipants.includes(d));
1239
1246
  winston.debug("addedParticipants ", addedParticipants);
1240
1247
 
1248
+
1249
+ requestEvent.emit('request.update', requestComplete);
1250
+ requestEvent.emit("request.update.comment", {comment:"PARTICIPANTS_SET",request:requestComplete});//Deprecated
1251
+ requestEvent.emit("request.updated", {comment:"PARTICIPANTS_SET",request:requestComplete, patch: {removedParticipants:removedParticipants, addedParticipants:addedParticipants}});
1252
+
1241
1253
  requestEvent.emit('request.participants.update', {beforeRequest:request,
1242
1254
  removedParticipants:removedParticipants,
1243
1255
  addedParticipants:addedParticipants,
@@ -1338,9 +1350,9 @@ class RequestService {
1338
1350
  winston.debug("populated", requestComplete);
1339
1351
 
1340
1352
  requestEvent.emit('request.update', requestComplete);
1341
- requestEvent.emit("request.update.comment", {comment:"PARTICIPANT_ADD",request:requestComplete});
1353
+ requestEvent.emit("request.update.comment", {comment:"PARTICIPANT_ADD",request:requestComplete});//Deprecated
1354
+ requestEvent.emit("request.updated", {comment:"PARTICIPANT_ADD",request:requestComplete, patch: {member:member}});
1342
1355
  requestEvent.emit('request.participants.join', {member:member, request: requestComplete});
1343
- // requestEvent.emit('request.participants.update', {beforeRequest:request, request:savedRequest});
1344
1356
 
1345
1357
  return resolve(requestComplete);
1346
1358
  });
@@ -1487,9 +1499,9 @@ class RequestService {
1487
1499
 
1488
1500
 
1489
1501
  requestEvent.emit('request.update', requestComplete);
1490
- requestEvent.emit("request.update.comment", {comment:"PARTICIPANT_REMOVE",request:requestComplete});
1502
+ requestEvent.emit("request.update.comment", {comment:"PARTICIPANT_REMOVE",request:requestComplete});//Deprecated
1503
+ requestEvent.emit("request.updated", {comment:"PARTICIPANT_REMOVE",request:requestComplete, patch: {member:member}});
1491
1504
  requestEvent.emit('request.participants.leave', {member:member, request: requestComplete});
1492
- // requestEvent.emit('request.participants.update', {beforeRequest: request, request:savedRequest});
1493
1505
 
1494
1506
 
1495
1507
  return resolve(requestComplete);
@@ -1562,7 +1574,9 @@ class RequestService {
1562
1574
  }
1563
1575
  winston.verbose(" saved request attributes",savedRequest.toObject())
1564
1576
  requestEvent.emit("request.update", savedRequest);
1565
- requestEvent.emit("request.update.comment", {comment:"ATTRIBUTES_UPDATE",request:savedRequest});
1577
+ requestEvent.emit("request.update.comment", {comment:"ATTRIBUTES_UPDATE",request:savedRequest});//Deprecated
1578
+ requestEvent.emit("request.updated", {comment:"ATTRIBUTES_UPDATE",request:savedRequest, patch: {attributes:data}});
1579
+
1566
1580
  requestEvent.emit("request.attributes.update", savedRequest);
1567
1581
  // allora neanche qui participatingAgent è ok?
1568
1582
  return resolve(savedRequest);
@@ -1621,8 +1635,9 @@ class RequestService {
1621
1635
  }
1622
1636
 
1623
1637
  requestEvent.emit('request.update', savedRequest);
1624
- requestEvent.emit("request.update.comment", {comment:"TAG_ADD",request:savedRequest});
1625
-
1638
+ requestEvent.emit("request.update.comment", {comment:"TAG_ADD",request:savedRequest}); //Deprecated
1639
+ requestEvent.emit("request.updated", {comment:"TAG_ADD",request:savedRequest, patch: {tags:tag}});
1640
+
1626
1641
 
1627
1642
  // allora neanche qui participatingAgent è ok?
1628
1643
  return resolve(savedRequest);
@@ -1688,7 +1703,9 @@ class RequestService {
1688
1703
 
1689
1704
  if (!err) {
1690
1705
  requestEvent.emit('request.update', savedRequest);
1691
- requestEvent.emit("request.update.comment", {comment:"TAG_REMOVE",request:savedRequest});
1706
+ requestEvent.emit("request.update.comment", {comment:"TAG_REMOVE",request:savedRequest});//Deprecated
1707
+ requestEvent.emit("request.updated", {comment:"TAG_REMOVE",request:savedRequest, patch: {tags:tag}});
1708
+
1692
1709
  }
1693
1710
 
1694
1711
  // allora neanche qui participatingAgent è ok?