@tiledesk/tiledesk-server 2.2.38 → 2.3.1-8.1
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +121 -0
- package/LICENSE +14 -657
- package/README.md +36 -21
- package/app.js +35 -62
- package/channels/chat21/chat21Handler.js +18 -3
- package/channels/chat21/chat21WebHook.js +31 -15
- package/channels/chat21/package-lock.json +663 -706
- package/channels/chat21/package.json +2 -2
- package/config/labels/widget.json +320 -0
- package/deploy.sh +2 -0
- package/event/botEvent.js +1 -1
- package/event/subscriptionEvent.js +11 -0
- package/fonts/Roboto-Italic.ttf +0 -0
- package/fonts/Roboto-Medium.ttf +0 -0
- package/fonts/Roboto-MediumItalic.ttf +0 -0
- package/fonts/Roboto-Regular.ttf +0 -0
- package/middleware/ipFilter.js +220 -0
- package/middleware/passport.js +11 -2
- package/models/lead.js +2 -0
- package/models/project.js +10 -0
- package/models/project_user.js +4 -0
- package/models/request.js +50 -12
- package/models/subscriptionLog.js +34 -0
- package/models/tagLibrary.js +42 -0
- package/package.json +6 -11
- package/pubmodules/activities/activityArchiver.js +314 -0
- package/pubmodules/activities/index.js +3 -0
- package/pubmodules/activities/models/activity.js +88 -0
- package/pubmodules/activities/routes/activity.js +710 -0
- package/pubmodules/activities/test/activityRoute.js +85 -0
- package/pubmodules/analytics/analytics.js +1719 -0
- package/pubmodules/analytics/index.js +3 -0
- package/pubmodules/canned/cannedResponse.js +55 -0
- package/pubmodules/canned/cannedResponseRoute.js +163 -0
- package/pubmodules/canned/index.js +3 -0
- package/pubmodules/emailNotification/requestNotification.js +215 -28
- package/pubmodules/events/eventRoute.js +37 -7
- package/pubmodules/messageActions/messageActionsInterceptor.js +4 -2
- package/pubmodules/pubModulesManager.js +140 -7
- package/pubmodules/rasa/index.js +8 -1
- package/pubmodules/rasa/listener.js +30 -9
- package/pubmodules/rules/conciergeBot.js +4 -4
- package/pubmodules/scheduler/tasks/closeAgentUnresponsiveRequestTask.js +3 -1
- package/pubmodules/scheduler/tasks/closeBotUnresponsiveRequestTask.js +5 -3
- package/pubmodules/tilebot/index.js +11 -0
- package/pubmodules/tilebot/listener.js +69 -0
- package/pubmodules/trigger/default.js +271 -0
- package/pubmodules/trigger/event/actionEventEmitter.js +10 -0
- package/pubmodules/trigger/event/flowEventEmitter.js +10 -0
- package/pubmodules/trigger/event/triggerEventEmitter.js +10 -0
- package/pubmodules/trigger/index.js +3 -0
- package/pubmodules/trigger/models/trigger.js +149 -0
- package/pubmodules/trigger/rulesTrigger.js +1181 -0
- package/pubmodules/trigger/start.js +118 -0
- package/pubmodules/trigger/triggerRoute.js +150 -0
- package/routes/auth.js +7 -2
- package/routes/department.js +51 -0
- package/routes/faq.js +7 -0
- package/routes/faq_kb.js +1 -1
- package/routes/group.js +140 -0
- package/routes/lead.js +24 -1
- package/routes/message.js +6 -3
- package/routes/project.js +118 -0
- package/routes/project_user.js +9 -0
- package/routes/public-request.js +280 -2
- package/routes/request.js +124 -17
- package/routes/subscription.js +140 -0
- package/routes/tag.js +138 -0
- package/routes/user-request.js +3 -2
- package/routes/users.js +1 -1
- package/routes/widget.js +80 -3
- package/routes/widgetLoader.js +31 -0
- package/services/banUserNotifier.js +86 -0
- package/services/emailService.js +189 -11
- package/services/faqBotHandler.js +2 -2
- package/services/faqBotSupport.js +0 -1
- package/services/faqService.js +2 -2
- package/services/geoService.js +30 -4
- package/services/leadService.js +2 -0
- package/services/modulesManager.js +16 -182
- package/services/requestService.js +364 -6
- package/services/subscriptionNotifier.js +485 -0
- package/template/email/assignedEmailMessage.html +1 -1
- package/template/email/assignedRequest.html +1 -1
- package/template/email/newMessage.html +1 -1
- package/template/email/newMessageFollower.html +236 -0
- package/template/email/passwordChanged.html +1 -1
- package/template/email/pooledEmailMessage.html +1 -1
- package/template/email/pooledRequest.html +1 -1
- package/template/email/resetPassword.html +2 -2
- package/template/email/ticket.html +1 -1
- package/test/cannedRoute.js +166 -0
- package/test/messageRoute.js +69 -0
- package/test/requestService.js +3 -1
- package/utils/orgUtil.js +3 -3
- package/views/messages.jade +2 -2
- package/websocket/webSocketServer.js +23 -5
package/README.md
CHANGED
@@ -9,11 +9,23 @@
|
|
9
9
|
|
10
10
|
# Introduction
|
11
11
|
|
12
|
-
Tiledesk-server is the server engine of Tiledesk. Tiledesk is an Open Source Live Chat platform with integrated
|
12
|
+
Tiledesk-server is the server engine of Tiledesk. Tiledesk is an Open Source Live Chat platform with integrated Chatbots written in NodeJs and Express. Build your own customer support with a multi-channel platform for Web, Android and iOS.
|
13
13
|
|
14
|
-
|
14
|
+
Designed to be open source since the beginning, we actively worked on it to create a totally new, first class customer service platform based on instant messaging.
|
15
15
|
|
16
|
-
|
16
|
+
What is Tiledesk today? It became the open source “conversational app development” platform that everyone needs 😌
|
17
|
+
|
18
|
+
You can use Tiledesk to increase sales for your website or for post-sales customer service. Every conversation can be automated using our first class native chatbot technology.
|
19
|
+
You can also connect your own applications using our APIs or Webhooks.
|
20
|
+
Moreover you can deploy entire visual applications inside a conversation. And your applications can converse with your chatbots or your end-users! We know this is cool 😎
|
21
|
+
|
22
|
+
Tiledesk is multichannel in a totally new way. You can write your chatbot scripts with images, buttons and other cool elements that your channels support. But you will configureyour chatbot replies only once. They will run on every channel, auto-adapting the responses to the target channel whatever it is, Whatsapp, Facebook Messenger, Telegram etc.
|
23
|
+
|
24
|
+
More info on Tiledesk website: https://www.tiledesk.com.
|
25
|
+
|
26
|
+
You can find technical documentation here: https://developer.tiledesk.com
|
27
|
+
|
28
|
+
# Prerequisites for Installation
|
17
29
|
|
18
30
|
* [Nodejs](https://www.npmjs.com/) and npm installed. Suggested versions are NodeJS 12.20.2 and NPM 6.14.11
|
19
31
|
* [MongoDb](https://www.mongodb.com) installed
|
@@ -25,23 +37,6 @@ Use [Docker Compose Tiledesk installation guide](https://github.com/Tiledesk/til
|
|
25
37
|
|
26
38
|
# Running Tiledesk Server
|
27
39
|
|
28
|
-
## Run locally with npm
|
29
|
-
|
30
|
-
Steps to run with npm:
|
31
|
-
|
32
|
-
```
|
33
|
-
npm install -g @tiledesk/tiledesk-server mongodb-runner
|
34
|
-
mongodb-runner start
|
35
|
-
curl https://raw.githubusercontent.com/Tiledesk/tiledesk-server/master/.env.sample --output .env
|
36
|
-
nano .env #configure .env file properly
|
37
|
-
tiledesk-server
|
38
|
-
```
|
39
|
-
|
40
|
-
If you want to load .env file from another path: `DOTENV_PATH=/MY/ABSOLUTE/PATH/.env tiledesk-server`
|
41
|
-
|
42
|
-
Note: If installation with -g fails due to permission problems (npm ERR! code 'EACCES'), please refer to this [link](https://docs.npmjs.com/getting-started/fixing-npm-permissions).
|
43
|
-
|
44
|
-
|
45
40
|
## Using Docker
|
46
41
|
|
47
42
|
|
@@ -65,12 +60,30 @@ Otherwise if you want to run tiledesk only with docker run :
|
|
65
60
|
docker run -p 3000:3000 --env DATABASE_URI="mongodb://YOUR_MONGO_INSTALLATION_ENDPOINT/tiledesk-server" --env-file .env tiledesk/tiledesk-server
|
66
61
|
```
|
67
62
|
|
63
|
+
|
64
|
+
|
65
|
+
## Run locally with npm
|
66
|
+
|
67
|
+
Steps to run with npm:
|
68
|
+
|
69
|
+
```
|
70
|
+
npm install -g @tiledesk/tiledesk-server mongodb-runner
|
71
|
+
mongodb-runner start
|
72
|
+
curl https://raw.githubusercontent.com/Tiledesk/tiledesk-server/master/.env.sample --output .env
|
73
|
+
nano .env #configure .env file properly
|
74
|
+
tiledesk-server
|
75
|
+
```
|
76
|
+
|
77
|
+
If you want to load .env file from another path: `DOTENV_PATH=/MY/ABSOLUTE/PATH/.env tiledesk-server`
|
78
|
+
|
79
|
+
Note: If installation with -g fails due to permission problems (npm ERR! code 'EACCES'), please refer to this [link](https://docs.npmjs.com/getting-started/fixing-npm-permissions).
|
80
|
+
|
68
81
|
## Install from source code
|
69
82
|
|
70
83
|
* Clone this repo
|
71
84
|
* Install dependencies with `npm install`
|
72
85
|
* Configure the tiledesk .env file. You can see an example in the file .env.sample under the root folder. Rename it from .env.sample to .env and configure it properly.
|
73
|
-
* Run the app with the command `npm start
|
86
|
+
* Run the app with the command `npm start`.
|
74
87
|
|
75
88
|
|
76
89
|
## Deploy on Heroku
|
@@ -79,6 +92,8 @@ Deploy with button:
|
|
79
92
|
|
80
93
|
[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/Tiledesk/tiledesk-server)
|
81
94
|
|
95
|
+
# Community? Questions? Support ?
|
96
|
+
If you need help or just want to hang out, come, say hi on our [<img width="15" alt="Tiledesk discord" src="https://seeklogo.com/images/D/discord-color-logo-E5E6DFEF80-seeklogo.com.png"> Discord](https://discord.gg/nERZEZ7SmG) server.
|
82
97
|
|
83
98
|
# REST API
|
84
99
|
|
package/app.js
CHANGED
@@ -30,6 +30,7 @@ var Project = require("./models/project");
|
|
30
30
|
var validtoken = require('./middleware/valid-token');
|
31
31
|
var roleChecker = require('./middleware/has-role');
|
32
32
|
|
33
|
+
const MaskData = require("maskdata");
|
33
34
|
var winston = require('./config/winston');
|
34
35
|
|
35
36
|
// https://bretkikehara.wordpress.com/2013/05/02/nodejs-creating-your-first-global-module/
|
@@ -43,7 +44,18 @@ if (process.env.NODE_ENV == 'test') {
|
|
43
44
|
databaseUri = config.databasetest;
|
44
45
|
}
|
45
46
|
|
46
|
-
|
47
|
+
const masked_databaseUri = MaskData.maskPhone(databaseUri, {
|
48
|
+
maskWith : "*",
|
49
|
+
unmaskedStartDigits: 15,
|
50
|
+
unmaskedEndDigits: 5
|
51
|
+
});
|
52
|
+
|
53
|
+
if (process.env.DISABLE_MONGO_PASSWORD_MASK ==true || process.env.DISABLE_MONGO_PASSWORD_MASK == "true") {
|
54
|
+
winston.info("DatabaseUri: " + databaseUri);
|
55
|
+
}else {
|
56
|
+
winston.info("DatabaseUri: " + masked_databaseUri);
|
57
|
+
}
|
58
|
+
|
47
59
|
|
48
60
|
var autoIndex = true;
|
49
61
|
if (process.env.MONGOOSE_AUTOINDEX) {
|
@@ -75,6 +87,9 @@ var lead = require('./routes/lead');
|
|
75
87
|
var message = require('./routes/message');
|
76
88
|
var messagesRootRoute = require('./routes/messagesRoot');
|
77
89
|
var department = require('./routes/department');
|
90
|
+
var group = require('./routes/group');
|
91
|
+
var resthook = require('./routes/subscription');
|
92
|
+
var tag = require('./routes/tag');
|
78
93
|
var faq = require('./routes/faq');
|
79
94
|
var faq_kb = require('./routes/faq_kb');
|
80
95
|
var project = require('./routes/project');
|
@@ -112,6 +127,9 @@ var RouterLogger = require('./models/routerLogger');
|
|
112
127
|
|
113
128
|
require('./services/mongoose-cache-fn')(mongoose);
|
114
129
|
|
130
|
+
var subscriptionNotifier = require('./services/subscriptionNotifier');
|
131
|
+
subscriptionNotifier.start();
|
132
|
+
|
115
133
|
var botSubscriptionNotifier = require('./services/BotSubscriptionNotifier');
|
116
134
|
botSubscriptionNotifier.start();
|
117
135
|
|
@@ -123,15 +141,15 @@ var faqBotHandler = require('./services/faqBotHandler');
|
|
123
141
|
faqBotHandler.listen();
|
124
142
|
|
125
143
|
var pubModulesManager = require('./pubmodules/pubModulesManager');
|
126
|
-
|
127
|
-
|
144
|
+
pubModulesManager.init({express:express, mongoose:mongoose, passport:passport, databaseUri:databaseUri, routes:{}});
|
128
145
|
|
129
146
|
var channelManager = require('./channels/channelManager');
|
130
147
|
channelManager.listen();
|
131
148
|
|
132
|
-
|
133
|
-
// const IpDeniedError = require('express-ipfilter').IpDeniedError;
|
149
|
+
var IPFilter = require('./middleware/ipFilter');
|
134
150
|
|
151
|
+
var BanUserNotifier = require('./services/banUserNotifier');
|
152
|
+
BanUserNotifier.listen();
|
135
153
|
|
136
154
|
var modulesManager = undefined;
|
137
155
|
try {
|
@@ -158,7 +176,6 @@ if (process.env.CREATE_INITIAL_DATA !== "false") {
|
|
158
176
|
|
159
177
|
|
160
178
|
|
161
|
-
|
162
179
|
var app = express();
|
163
180
|
|
164
181
|
|
@@ -319,57 +336,6 @@ var projectSetter = function (req, res, next) {
|
|
319
336
|
}
|
320
337
|
|
321
338
|
|
322
|
-
function customDetection (req) {
|
323
|
-
// const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
|
324
|
-
const ip = (req.headers['x-forwarded-for'] || '').split(',').pop().trim() || //https://stackoverflow.com/questions/8107856/how-to-determine-a-users-ip-address-in-node
|
325
|
-
req.socket.remoteAddress
|
326
|
-
|
327
|
-
winston.info("standard ip: "+ip); // ip address of the user
|
328
|
-
return ip;
|
329
|
-
}
|
330
|
-
|
331
|
-
|
332
|
-
var projectIpFilter = function (req, res, next) {
|
333
|
-
// var projectIpFilter = function (err, req, res, next) {
|
334
|
-
|
335
|
-
// var ip = require('ip');
|
336
|
-
// winston.info("projectIpFilter ip2: " + ip.address() );
|
337
|
-
|
338
|
-
|
339
|
-
const nextIp = function(err) {
|
340
|
-
winston.info("projectIpFilter next",err);
|
341
|
-
|
342
|
-
if (err && err.name === "IpDeniedError") {
|
343
|
-
winston.info("IpDeniedError");
|
344
|
-
return res.status(401).json({ err: "error project ip filter" });
|
345
|
-
// next(err)
|
346
|
-
}
|
347
|
-
|
348
|
-
next();
|
349
|
-
|
350
|
-
}
|
351
|
-
|
352
|
-
|
353
|
-
if (!req.project) {
|
354
|
-
return next();
|
355
|
-
}
|
356
|
-
|
357
|
-
var projectIpFilterEnabled = req.project.ipFilterEnabled;
|
358
|
-
winston.debug("project projectIpFilterEnabled: " +projectIpFilterEnabled)
|
359
|
-
|
360
|
-
var projectIpFilter = req.project.ipFilter
|
361
|
-
winston.debug("project ipFilter: " + projectIpFilter)
|
362
|
-
|
363
|
-
if (projectIpFilterEnabled === true && projectIpFilter && projectIpFilter.length > 0) {
|
364
|
-
var ip = ipfilter(projectIpFilter, { detectIp: customDetection, mode: 'allow' })
|
365
|
-
// var ip = ipfilter(projectIpFilter, { mode: 'allow' })
|
366
|
-
ip(req, res, nextIp);
|
367
|
-
} else {
|
368
|
-
next();
|
369
|
-
}
|
370
|
-
|
371
|
-
}
|
372
|
-
|
373
339
|
|
374
340
|
|
375
341
|
// app.use('/admin', admin);
|
@@ -386,6 +352,8 @@ app.use('/auth', auth);
|
|
386
352
|
app.use('/testauth', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken], authtest);
|
387
353
|
|
388
354
|
app.use('/widgets', widgetsLoader);
|
355
|
+
app.use('/w', widgetsLoader);
|
356
|
+
|
389
357
|
app.use('/images', images);
|
390
358
|
app.use('/files', files);
|
391
359
|
app.use('/urls', urls);
|
@@ -413,8 +381,7 @@ if (modulesManager) {
|
|
413
381
|
modulesManager.use(app);
|
414
382
|
}
|
415
383
|
|
416
|
-
|
417
|
-
app.use('/:projectid/', [projectIdSetter, projectSetter, projectIpFilter]);
|
384
|
+
app.use('/:projectid/', [projectIdSetter, projectSetter, IPFilter.projectIpFilter, IPFilter.projectIpFilterDeny, IPFilter.decodeJwt, IPFilter.projectBanUserFilter]);
|
418
385
|
|
419
386
|
|
420
387
|
app.use('/:projectid/authtestWithRoleCheck', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken], authtestWithRoleCheck);
|
@@ -429,11 +396,17 @@ app.use('/:projectid/departments', department);
|
|
429
396
|
|
430
397
|
|
431
398
|
|
399
|
+
|
400
|
+
|
432
401
|
channelManager.useUnderProjects(app);
|
433
402
|
|
403
|
+
app.use('/:projectid/groups', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('agent')], group);
|
404
|
+
app.use('/:projectid/tags', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('agent')], tag);
|
405
|
+
app.use('/:projectid/subscriptions', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('admin')], resthook);
|
406
|
+
|
434
407
|
//deprecated
|
435
|
-
app.use('/:projectid/faq', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.
|
436
|
-
app.use('/:projectid/intents', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.
|
408
|
+
app.use('/:projectid/faq', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['bot','subscription'])], faq);
|
409
|
+
app.use('/:projectid/intents', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['bot','subscription'])], faq);
|
437
410
|
|
438
411
|
//Deprecated??
|
439
412
|
app.use('/:projectid/faqpub', faqpub);
|
@@ -516,7 +489,7 @@ app.use(function (err, req, res, next) {
|
|
516
489
|
// error handler
|
517
490
|
app.use((err, req, res, next) => {
|
518
491
|
|
519
|
-
winston.
|
492
|
+
winston.debug("err.name", err.name)
|
520
493
|
if (err.name === "IpDeniedError") {
|
521
494
|
winston.info("IpDeniedError");
|
522
495
|
return res.status(401).json({ err: "error ip filter" });
|
@@ -246,7 +246,18 @@ class Chat21Handler {
|
|
246
246
|
});
|
247
247
|
|
248
248
|
|
249
|
+
messageEvent.on('message.test', function(message) {
|
250
|
+
|
251
|
+
winston.info("Chat21Sender message.test");
|
252
|
+
|
253
|
+
chat21.auth.setAdminToken(adminToken);
|
249
254
|
|
255
|
+
return chat21.messages.sendToGroup(message.senderFullname, message.recipient,
|
256
|
+
message.recipient_fullname, message.text, message.sender, message.attributes, message.type, message.metadata, message.timestamp, message.group)
|
257
|
+
.then(function(data){
|
258
|
+
winston.info("Chat21Sender sendToGroup test: "+ JSON.stringify(data));
|
259
|
+
});
|
260
|
+
});
|
250
261
|
|
251
262
|
|
252
263
|
messageEvent.on('message.sending', function(message) {
|
@@ -299,7 +310,8 @@ class Chat21Handler {
|
|
299
310
|
}
|
300
311
|
|
301
312
|
var recipient_fullname = "Guest";
|
302
|
-
//
|
313
|
+
// guest_here
|
314
|
+
|
303
315
|
if (message.request && message.request.lead && message.request.lead.fullname) {
|
304
316
|
recipient_fullname = message.request.lead.fullname;
|
305
317
|
}
|
@@ -332,6 +344,7 @@ class Chat21Handler {
|
|
332
344
|
}
|
333
345
|
*/
|
334
346
|
|
347
|
+
|
335
348
|
return chat21.messages.sendToGroup(message.senderFullname, message.recipient,
|
336
349
|
recipient_fullname, message.text, message.sender, attributes, message.type, message.metadata, timestamp)
|
337
350
|
.then(function(data){
|
@@ -339,7 +352,7 @@ class Chat21Handler {
|
|
339
352
|
|
340
353
|
|
341
354
|
// chat21.conversations.stopTyping(message.recipient,message.sender);
|
342
|
-
|
355
|
+
|
343
356
|
chat21Event.emit('message.sent', data);
|
344
357
|
|
345
358
|
messageService.changeStatus(message._id, MessageConstants.CHAT_MESSAGE_STATUS.DELIVERED) .then(function(upMessage){
|
@@ -563,13 +576,15 @@ class Chat21Handler {
|
|
563
576
|
var groupId = request.request_id;
|
564
577
|
|
565
578
|
var group_name = "Guest";
|
566
|
-
|
579
|
+
// guest_here
|
580
|
+
|
567
581
|
if (request.lead && request.lead.fullname) {
|
568
582
|
group_name = request.lead.fullname;
|
569
583
|
}
|
570
584
|
if (request.subject) {
|
571
585
|
group_name = request.subject;
|
572
586
|
}
|
587
|
+
|
573
588
|
//TODO racecondition?
|
574
589
|
return chat21.groups.create(group_name, members, gAttributes, groupId).then(function(data) {
|
575
590
|
winston.verbose("Chat21 group created: " + JSON.stringify(data));
|
@@ -201,12 +201,16 @@ router.post('/', function (req, res) {
|
|
201
201
|
return winston.error("project_user not found with query: ", queryProjectUser);
|
202
202
|
}
|
203
203
|
|
204
|
+
|
205
|
+
|
206
|
+
|
204
207
|
|
205
208
|
var new_request = {
|
206
209
|
request_id: message.recipient, project_user_id:project_user_id, lead_id:createdLead._id, id_project:projectid, first_text:message.text,
|
207
210
|
departmentid:departmentid, sourcePage:sourcePage, language:language, userAgent:client, status:requestStatus, createdBy: undefined,
|
208
211
|
attributes:rAttributes, subject:undefined, preflight:false, channel:undefined, location:undefined,
|
209
212
|
lead:createdLead, requester:project_user
|
213
|
+
|
210
214
|
};
|
211
215
|
|
212
216
|
winston.debug("new_request", new_request);
|
@@ -226,10 +230,10 @@ router.post('/', function (req, res) {
|
|
226
230
|
// upsert(id, sender, senderFullname, recipient, text, id_project, createdBy, status, attributes, type, metadata, language)
|
227
231
|
return messageService.upsert(messageId, message.sender, message.sender_fullname, message.recipient, message.text,
|
228
232
|
projectid, null, MessageConstants.CHAT_MESSAGE_STATUS.RECEIVED, message.attributes, message.type, message.metadata, language).then(function(savedMessage){
|
229
|
-
|
230
|
-
return requestService.incrementMessagesCountByRequestId(savedRequest.request_id, savedRequest.id_project).then(function(savedRequestWithIncrement) {
|
231
|
-
return res.json(savedRequestWithIncrement);
|
232
|
-
});
|
233
|
+
return res.json(savedRequest);
|
234
|
+
// return requestService.incrementMessagesCountByRequestId(savedRequest.request_id, savedRequest.id_project).then(function(savedRequestWithIncrement) {
|
235
|
+
// return res.json(savedRequestWithIncrement);
|
236
|
+
// });
|
233
237
|
|
234
238
|
|
235
239
|
}).catch(function (err) {
|
@@ -286,23 +290,25 @@ router.post('/', function (req, res) {
|
|
286
290
|
|
287
291
|
// TOOD update also request attributes and sourcePage
|
288
292
|
|
289
|
-
return requestService.incrementMessagesCountByRequestId(request.request_id, request.id_project).then(function(savedRequest) {
|
293
|
+
// return requestService.incrementMessagesCountByRequestId(request.request_id, request.id_project).then(function(savedRequest) {
|
290
294
|
// winston.debug("savedRequest.participants.indexOf(message.sender)", savedRequest.participants.indexOf(message.sender));
|
291
295
|
|
292
296
|
// TODO it doesn't work for internal requests bacause participanets == message.sender⁄
|
293
|
-
if (
|
297
|
+
if (request.participants && request.participants.indexOf(message.sender) > -1) { //update waiitng time if write an agent (member of participants)
|
294
298
|
winston.debug("updateWaitingTimeByRequestId");
|
299
|
+
|
295
300
|
return requestService.updateWaitingTimeByRequestId(request.request_id, request.id_project).then(function(upRequest) {
|
296
301
|
return res.json(upRequest);
|
297
302
|
});
|
298
303
|
}else {
|
299
|
-
|
304
|
+
|
305
|
+
return res.json(savedMessage);
|
300
306
|
}
|
301
|
-
});
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
307
|
+
// });
|
308
|
+
}).catch(function(err){
|
309
|
+
winston.error("Error creating chat21 webhook message: "+ JSON.stringify({err: err, message: message}));
|
310
|
+
return res.status(500).send({success: false, msg: 'Error creating message', err:err });
|
311
|
+
});
|
306
312
|
|
307
313
|
|
308
314
|
|
@@ -398,7 +404,9 @@ router.post('/', function (req, res) {
|
|
398
404
|
// winston.debug('updatedParticipantsRequest', updatedParticipantsRequest);
|
399
405
|
// manca id
|
400
406
|
|
401
|
-
|
407
|
+
// closeRequestByRequestId(request_id, id_project, skipStatsUpdate, notify, closed_by)
|
408
|
+
const closed_by = user_id;
|
409
|
+
return requestService.closeRequestByRequestId(recipient_id, projectId, false, true,closed_by ).then(function(updatedStatusRequest) {
|
402
410
|
|
403
411
|
winston.debug('updatedStatusRequest', updatedStatusRequest.toObject());
|
404
412
|
return res.json(updatedStatusRequest);
|
@@ -532,7 +540,7 @@ router.post('/', function (req, res) {
|
|
532
540
|
});
|
533
541
|
}
|
534
542
|
|
535
|
-
else if (req.body.event_type == "deleted-archivedconversation") {
|
543
|
+
else if (req.body.event_type == "deleted-archivedconversation" || req.body.event_type == "conversation-unarchived") {
|
536
544
|
|
537
545
|
winston.debug("event_type","deleted-archivedconversation");
|
538
546
|
|
@@ -544,7 +552,7 @@ router.post('/', function (req, res) {
|
|
544
552
|
}
|
545
553
|
|
546
554
|
|
547
|
-
var conversation = req.body.data;
|
555
|
+
var conversation = req.body.data;
|
548
556
|
// winston.debug("conversation",conversation);
|
549
557
|
|
550
558
|
var user_id = req.body.user_id;
|
@@ -561,16 +569,24 @@ router.post('/', function (req, res) {
|
|
561
569
|
return res.status(400).send({success: false, msg: "not a support conversation" });
|
562
570
|
}
|
563
571
|
|
572
|
+
|
573
|
+
|
564
574
|
if (user_id!="system"){
|
565
575
|
winston.debug("not a system conversation");
|
566
576
|
return res.status(400).send({success: false, msg: "not a system conversation" });
|
567
577
|
}
|
568
578
|
|
569
579
|
|
580
|
+
|
581
|
+
// scrivo... nuova viene popolato projectid in attributes poi chiudo ed in archived c'è projectid
|
582
|
+
// quando scrivo viene cancellato archived e nuovo messaggio crea conv ma senza project id... lineare che è cosi
|
583
|
+
// si verifica solo se admin (da ionic ) archivia di nuovo senza che widget abbia scritto nulla (widget risetta projectid in properties)
|
584
|
+
|
570
585
|
var id_project;
|
571
586
|
if (conversation && conversation.attributes) {
|
572
587
|
id_project = conversation.attributes.projectId;
|
573
588
|
}else {
|
589
|
+
winston.debug( "not a support deleting archived conversation" );
|
574
590
|
return res.status(400).send({success: false, msg: "not a support deleting archived conversation" });
|
575
591
|
}
|
576
592
|
winston.debug("id_project", id_project);
|