@tiledesk/tiledesk-server 2.3.8 → 2.3.11
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +83 -3
- package/app.js +8 -4
- package/package.json +1 -1
- package/pubmodules/emailNotification/requestNotification.js +2 -3
- package/pubmodules/pubModulesManager.js +20 -0
- package/pubmodules/rasa/listener.js +1 -1
- package/pubmodules/tilebot/index.js +3 -0
- package/pubmodules/tilebot/listener.js +51 -0
- package/routes/faq_kb.js +1 -1
- package/routes/request.js +3 -3
- package/routes/widget.js +43 -0
- package/services/faqService.js +1 -1
package/CHANGELOG.md
CHANGED
@@ -1,15 +1,95 @@
|
|
1
1
|
|
2
|
+
# 2.3.11 -> PROD
|
3
|
+
- Getting ip fix
|
4
|
+
|
5
|
+
# 2.3.10
|
6
|
+
- Added tilebot submodule
|
7
|
+
- Askbot endpoint fix for tilebot and auto create faqs for tilebot
|
8
|
+
- Added /widgets/ip endpoint
|
9
|
+
- Added bot and subscription as permission check for /intents or /faq
|
10
|
+
|
11
|
+
# 2.3.9
|
12
|
+
- Rasa process env variable read fix
|
13
|
+
|
14
|
+
# 2.3.8
|
15
|
+
- @tiledesk/tiledesk-rasa-connector": "^1.0.10
|
16
|
+
|
17
|
+
# 2.3.7
|
18
|
+
- Find by intent_display_name parameter intents
|
19
|
+
|
20
|
+
# 2.3.5
|
21
|
+
- CHAT_REOPENED updated conversation true
|
22
|
+
|
23
|
+
# 2.3.4
|
24
|
+
- download pdf fix
|
25
|
+
- added no_count and no_textscore fields query parameters to request search endpoint
|
26
|
+
|
27
|
+
# 2.3.3
|
28
|
+
- Follower notification fix by email
|
2
29
|
|
3
30
|
# 2.3.2
|
4
31
|
- Dowload trascript as csv, pdf and txt endpoint
|
5
32
|
- Added closed_by field to the request model
|
6
|
-
- Added followers field to the request model
|
33
|
+
- Added followers field to the request model
|
7
34
|
- Added lead index
|
8
|
-
- Added widget v5 code loader /widgets/v5/:project_id -> heroku blocca cache-control
|
35
|
+
- Added widget v5 code loader /widgets/v5/:project_id -> heroku blocca cache-control PROVA IN PROD
|
9
36
|
- Bugfix Cannot read property 'profile' of null
|
10
37
|
- Added filter by channel offline and online
|
11
|
-
- Updated Rasa Connector to 1.0.7
|
38
|
+
- Updated Rasa Connector to 1.0.7 -- QUANDO PORTI IN PROD AGGIORNA SUL DB PER FARLI PUNTARE QUI..
|
12
39
|
- Send info message on lead.fullaname.update
|
40
|
+
- Follower email notification
|
41
|
+
|
42
|
+
https://support.zendesk.com/hc/en-us/articles/4408822451482-Using-CCs-followers-and-mentions#topic_wm2_zgq_qgb
|
43
|
+
|
44
|
+
Followers allow you to include additional internal users (agents or administrators) on ticket notifications. Internal users can add followers to tickets. There's no limit to the number of followers you can include on a ticket.
|
45
|
+
|
46
|
+
Agents and administrators can use the Followers field in the properties panel of the ticket interface to add internal users to a ticket.
|
47
|
+
|
48
|
+
Internal users who can view the ticket can add followers to the ticket.
|
49
|
+
|
50
|
+
Followers can:
|
51
|
+
|
52
|
+
* Receive public comments and private comments added to the ticket conversation.
|
53
|
+
* Ability to make a private comments and public comment.
|
54
|
+
* Replying to a private comment creates a private comment and likewise for public comments.
|
55
|
+
* Remove themselves from the ticket conversation.
|
56
|
+
* Remain hidden from end users copied on the ticket.
|
57
|
+
* Access any ticket that they are following, even if they would not normally be allowed to access the ticket.
|
58
|
+
|
59
|
+
# Adding agents as followers from the ticket interface
|
60
|
+
If followers have been enabled by the administrator, internal users (your company's agents and administrators) can add followers from the Followers field from the properties panel in the ticket interface. Followers are internal users such as agents, light agents, and administrators that receive email notifications when a ticket is updated.
|
61
|
+
|
62
|
+
Note these things about using followers:
|
63
|
+
|
64
|
+
* Followers can add and receive public comments and private comments.
|
65
|
+
* Followers can reply to a public comment with a public comment, and reply to a private comment with a private comment.
|
66
|
+
* Followers can remove themselves from the ticket.
|
67
|
+
* Followers are hidden from copied (CC'd) end users and other followers on email notifications. Their name and email address don't appear in email notifications sent to other users. For more information about the email notifications that followers receive, see Best practices for using email clients with CCs and followers.
|
68
|
+
* If your administrator has enabled Automatically make an agent a follower, you can added internal users, such as agents and admins, to tickets as followers from ticket notifications by adding them to the reply as a CC. In this case, the agent becomes both a CC and a follower.
|
69
|
+
## To add agents as followers from the ticket interface
|
70
|
+
* Select a ticket from one of your views.
|
71
|
+
The Followers field appears in the ticket properties panel on the left side.
|
72
|
+
|
73
|
+
* In the Followers field, enter a user's name, email domain, or organization name and the relevant results appear.
|
74
|
+
Internal users such as agents, light agents, and administrators can be followers.
|
75
|
+
|
76
|
+
* To quickly add yourself as a follower, click follow.
|
77
|
+
|
78
|
+
|
79
|
+
|
80
|
+
## To remove a follower from the ticket interface
|
81
|
+
* Click the delete button (X) in the person's name box in the Followers list
|
82
|
+
|
83
|
+
|
84
|
+
* To quickly remove yourself as a follower, click unfollow.
|
85
|
+
|
86
|
+
* To add agents as followers from ticket notifications
|
87
|
+
|
88
|
+
* From your email client, open the ticket notification.
|
89
|
+
* Open the CC line, per your email provider’s instructions.
|
90
|
+
* Add the name of the user you want to add as a follower. Repeat as necessary.
|
91
|
+
* Add your comment and send the email.
|
92
|
+
|
13
93
|
|
14
94
|
|
15
95
|
# 2.3.1
|
package/app.js
CHANGED
@@ -337,8 +337,12 @@ var projectSetter = function (req, res, next) {
|
|
337
337
|
|
338
338
|
function customDetection (req) {
|
339
339
|
// const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
|
340
|
-
const ip = (req.headers['x-forwarded-for'] || '').split(',').pop().trim() || //https://stackoverflow.com/questions/8107856/how-to-determine-a-users-ip-address-in-node
|
341
|
-
|
340
|
+
// const ip = (req.headers['x-forwarded-for'] || '').split(',').pop().trim() || //https://stackoverflow.com/questions/8107856/how-to-determine-a-users-ip-address-in-node
|
341
|
+
// req.socket.remoteAddress
|
342
|
+
|
343
|
+
const ip = (req) =>
|
344
|
+
req.headers['x-forwarded-for']?.split(',').shift()
|
345
|
+
|| req.socket?.remoteAddress
|
342
346
|
|
343
347
|
winston.info("standard ip: "+ip); // ip address of the user
|
344
348
|
return ip;
|
@@ -456,8 +460,8 @@ app.use('/:projectid/tags', [passport.authenticate(['basic', 'jwt'], { session:
|
|
456
460
|
app.use('/:projectid/subscriptions', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('admin')], resthook);
|
457
461
|
|
458
462
|
//deprecated
|
459
|
-
app.use('/:projectid/faq', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.
|
460
|
-
app.use('/:projectid/intents', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.
|
463
|
+
app.use('/:projectid/faq', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['bot','subscription'])], faq);
|
464
|
+
app.use('/:projectid/intents', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['bot','subscription'])], faq);
|
461
465
|
|
462
466
|
//Deprecated??
|
463
467
|
app.use('/:projectid/faqpub', faqpub);
|
package/package.json
CHANGED
@@ -78,7 +78,6 @@ listen() {
|
|
78
78
|
} else {
|
79
79
|
winston.debug("sendUserEmail chat channel");
|
80
80
|
|
81
|
-
//TODO mandare email se ultimo messaggio > X MINUTI configurato in Notification . potresti usare request.updated_at ?
|
82
81
|
|
83
82
|
|
84
83
|
|
@@ -684,7 +683,7 @@ sendUserEmail(projectid, message) {
|
|
684
683
|
|
685
684
|
|
686
685
|
if (process.env.DISABLE_SEND_OFFLINE_EMAIL === "true" || process.env.DISABLE_SEND_OFFLINE_EMAIL === true ) {
|
687
|
-
return winston.
|
686
|
+
return winston.debug("DISABLE_SEND_OFFLINE_EMAIL disabled");
|
688
687
|
}
|
689
688
|
if (message.attributes && message.attributes.subtype==='info/support') {
|
690
689
|
return winston.debug("not sending sendUserEmail for attributes.subtype info/support messages");
|
@@ -697,7 +696,7 @@ sendUserEmail(projectid, message) {
|
|
697
696
|
|
698
697
|
|
699
698
|
if (!message.request.lead || !message.request.lead.email) {
|
700
|
-
return winston.
|
699
|
+
return winston.debug("The lead object is undefined or has empty email");
|
701
700
|
}
|
702
701
|
|
703
702
|
if (project.settings && project.settings.email && project.settings.email.notification && project.settings.email.notification.conversation && project.settings.email.notification.conversation.offline && project.settings.email.notification.conversation.offline.blocked == true ) {
|
@@ -31,6 +31,8 @@ class PubModulesManager {
|
|
31
31
|
this.trigger = undefined;
|
32
32
|
this.triggerRoute = undefined;
|
33
33
|
|
34
|
+
this.tilebot = undefined;
|
35
|
+
|
34
36
|
}
|
35
37
|
|
36
38
|
|
@@ -257,6 +259,24 @@ class PubModulesManager {
|
|
257
259
|
}
|
258
260
|
}
|
259
261
|
|
262
|
+
|
263
|
+
|
264
|
+
|
265
|
+
try {
|
266
|
+
this.tilebot = require('./tilebot');
|
267
|
+
winston.debug("this.tilebot:"+ this.tilebot);
|
268
|
+
this.tilebot.listener.listen(config);
|
269
|
+
|
270
|
+
winston.info("PubModulesManager initialized tilebot.");
|
271
|
+
} catch(err) {
|
272
|
+
if (err.code == 'MODULE_NOT_FOUND') {
|
273
|
+
winston.info("PubModulesManager init tilebot module not found");
|
274
|
+
}else {
|
275
|
+
winston.info("PubModulesManager error initializing init tilebot module", err);
|
276
|
+
}
|
277
|
+
}
|
278
|
+
|
279
|
+
|
260
280
|
}
|
261
281
|
|
262
282
|
start() {
|
@@ -6,7 +6,7 @@ var configGlobal = require('../../config/global');
|
|
6
6
|
|
7
7
|
var port = process.env.PORT || '3000';
|
8
8
|
|
9
|
-
const BOT_RASA_ENDPOINT = "http://localhost:" + port+ "/modules/rasa/rasabot"
|
9
|
+
const BOT_RASA_ENDPOINT = process.env.BOT_RASA_ENDPOINT || "http://localhost:" + port+ "/modules/rasa/rasabot";
|
10
10
|
winston.debug("BOT_RASA_ENDPOINT: " + BOT_RASA_ENDPOINT);
|
11
11
|
|
12
12
|
// if (BOT_RASA_ENDPOINT) {
|
@@ -0,0 +1,51 @@
|
|
1
|
+
const botEvent = require('../../event/botEvent');
|
2
|
+
var Faq_kb = require("../../models/faq_kb");
|
3
|
+
var winston = require('../../config/winston');
|
4
|
+
|
5
|
+
var port = process.env.PORT || '3000';
|
6
|
+
|
7
|
+
const TILEBOT_ENDPOINT = process.env.TILEBOT_ENDPOINT || "http://localhost:" + port+ "/modules/tilebot/";
|
8
|
+
winston.debug("TILEBOT_ENDPOINT: " + TILEBOT_ENDPOINT);
|
9
|
+
|
10
|
+
winston.info("Tilebot endpoint: " + TILEBOT_ENDPOINT);
|
11
|
+
|
12
|
+
class Listener {
|
13
|
+
|
14
|
+
listen(config) {
|
15
|
+
|
16
|
+
winston.info('Tilebot Listener listen');
|
17
|
+
// winston.debug("config databaseUri: " + config.databaseUri);
|
18
|
+
|
19
|
+
|
20
|
+
var that = this;
|
21
|
+
|
22
|
+
|
23
|
+
botEvent.on('faqbot.create', function(bot) {
|
24
|
+
if (TILEBOT_ENDPOINT) {
|
25
|
+
|
26
|
+
winston.debug('bot.type:'+bot.type);
|
27
|
+
if (bot.type==="tilebot") {
|
28
|
+
|
29
|
+
winston.debug('qui.type:'+bot.type);
|
30
|
+
|
31
|
+
|
32
|
+
Faq_kb.findByIdAndUpdate(bot.id, {"url":TILEBOT_ENDPOINT+bot.id}, { new: true, upsert: true }, function (err, savedFaq_kb) {
|
33
|
+
|
34
|
+
// bot.save(function (err, savedFaq_kb) {
|
35
|
+
if (err) {
|
36
|
+
return winston.error('error saving faqkb tilebot ', err)
|
37
|
+
}
|
38
|
+
winston.verbose('Saved faqkb tilebot', savedFaq_kb.toObject())
|
39
|
+
});
|
40
|
+
}
|
41
|
+
}
|
42
|
+
});
|
43
|
+
|
44
|
+
}
|
45
|
+
|
46
|
+
}
|
47
|
+
|
48
|
+
var listener = new Listener();
|
49
|
+
|
50
|
+
|
51
|
+
module.exports = listener;
|
package/routes/faq_kb.js
CHANGED
@@ -133,7 +133,7 @@ router.post('/askbot', function (req, res) {
|
|
133
133
|
}
|
134
134
|
winston.debug('faq_kb ', faq_kb.toJSON());
|
135
135
|
winston.debug('faq_kb.type :'+ faq_kb.type);
|
136
|
-
if (faq_kb.type =="internal") {
|
136
|
+
if (faq_kb.type =="internal" || faq_kb.type =="tilebot") {
|
137
137
|
|
138
138
|
|
139
139
|
|
package/routes/request.js
CHANGED
@@ -778,8 +778,8 @@ router.get('/', function (req, res, next) {
|
|
778
778
|
* THE SEARCH FOR DATE INTERVAL OF THE HISTORY OF REQUESTS ARE DISABLED AND
|
779
779
|
* ARE DISPLAYED ONLY THE REQUESTS OF THE LAST 14 DAYS
|
780
780
|
*/
|
781
|
-
//secondo me qui manca un parentesi tonda per gli or
|
782
|
-
if ( history_search === true && req.project && req.project.profile && (req.project.profile.type === 'free' && req.project.trialExpired === true) || (req.project.profile.type === 'payment' && req.project.isActiveSubscription === false)) {
|
781
|
+
//fixato. secondo me qui manca un parentesi tonda per gli or
|
782
|
+
if ( history_search === true && req.project && req.project.profile && ((req.project.profile.type === 'free' && req.project.trialExpired === true) || (req.project.profile.type === 'payment' && req.project.isActiveSubscription === false))) {
|
783
783
|
|
784
784
|
|
785
785
|
var startdate = moment().subtract(14, "days").format("YYYY-MM-DD");
|
@@ -992,7 +992,7 @@ router.get('/', function (req, res, next) {
|
|
992
992
|
winston.debug('REQUEST ROUTE - objectToReturn ', objectToReturn);
|
993
993
|
|
994
994
|
const endExecTime = new Date();
|
995
|
-
winston.
|
995
|
+
winston.verbose('REQUEST ROUTE - exec time: ' + (endExecTime-startExecTime));
|
996
996
|
|
997
997
|
return res.json(objectToReturn);
|
998
998
|
|
package/routes/widget.js
CHANGED
@@ -190,7 +190,50 @@ router.get('/', function(req, res, next) {
|
|
190
190
|
|
191
191
|
|
192
192
|
|
193
|
+
router.get('/ip', function(req, res, next) {
|
193
194
|
|
195
|
+
var xforwarded = req.headers['x-forwarded-for'];
|
196
|
+
winston.info('xforwarded'+ xforwarded);
|
197
|
+
|
198
|
+
var connectionRemoteAddress = req.connection.remoteAddress;
|
199
|
+
winston.info('connectionRemoteAddress'+ connectionRemoteAddress);
|
200
|
+
|
201
|
+
var socketRemoteAddress = req.socket.remoteAddress;
|
202
|
+
winston.info('socketRemoteAddress'+ socketRemoteAddress);
|
203
|
+
|
204
|
+
if (req.connection.socket ) {
|
205
|
+
var connectionSocketRemoteAddress = req.connection.socket.remoteAddress;
|
206
|
+
winston.info('connectionSocketRemoteAddress'+ connectionSocketRemoteAddress);
|
207
|
+
|
208
|
+
}
|
209
|
+
|
210
|
+
|
211
|
+
var ip = req.headers['x-forwarded-for'] ||
|
212
|
+
req.connection.remoteAddress ||
|
213
|
+
req.socket.remoteAddress ||
|
214
|
+
(req.connection.socket ? req.connection.socket.remoteAddress : null);
|
215
|
+
winston.info("ip:"+ ip);
|
216
|
+
|
217
|
+
|
218
|
+
|
219
|
+
|
220
|
+
const ipStandard = (req.headers['x-forwarded-for'] || '').split(',').shift().trim() || //https://stackoverflow.com/questions/8107856/how-to-determine-a-users-ip-address-in-node
|
221
|
+
req.socket.remoteAddress
|
222
|
+
|
223
|
+
winston.info("standard ip: "+ipStandard); // ip address of the user
|
224
|
+
|
225
|
+
|
226
|
+
|
227
|
+
const parseIp = (req) =>
|
228
|
+
req.headers['x-forwarded-for']?.split(',').shift()
|
229
|
+
|| req.socket?.remoteAddress
|
230
|
+
|
231
|
+
winston.info("parseIp: "+parseIp); // ip address of the user
|
232
|
+
|
233
|
+
res.json( {ip:ip, ipStandard:ipStandard, parseIp: parseIp} );
|
234
|
+
|
235
|
+
|
236
|
+
});
|
194
237
|
|
195
238
|
|
196
239
|
|