@tiledesk/tiledesk-server 2.2.13 → 2.2.17

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.
@@ -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;
@@ -368,7 +368,7 @@ class FaqBotSupport {
368
368
  // found = true;
369
369
  // return resolve(bot_answer);
370
370
 
371
- if (message.channel.name == "chat21") { //why this contition on chat21 channel? bacause only chat21 support parsed replies?
371
+ // if (message.channel.name == "chat21") { //why this contition on chat21 channel? bacause only chat21 support parsed replies?
372
372
  winston.debug("faqBotSupport message.channel.name is chat21",message);
373
373
  that.getParsedMessage(bot_answer.text,message, bot, faqs[0]).then(function(bot_answerres) {
374
374
 
@@ -377,10 +377,10 @@ class FaqBotSupport {
377
377
  return resolve(bot_answerres);
378
378
  });
379
379
 
380
- } else {
381
- winston.debug("faqBotSupport message.channel.name is not chat21 returning default",message);
382
- return resolve(bot_answer);
383
- }
380
+ // } else {
381
+ // winston.debug("faqBotSupport message.channel.name is not chat21 returning default",message);
382
+ // return resolve(bot_answer);
383
+ // }
384
384
 
385
385
  } else {
386
386
  var message_key = "DEFAULT_NOTFOUND_NOBOT_SENTENCE_REPLY_MESSAGE";
@@ -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?