@tiledesk/tiledesk-server 2.4.53 → 2.4.55

Sign up to get free protection for your applications and to get access to all the features.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,12 @@
5
5
  🚀 IN PRODUCTION 🚀
6
6
  (https://www.npmjs.com/package/@tiledesk/tiledesk-server/v/2.3.77)
7
7
 
8
+ # 2.3.44
9
+ - updated tybot-connector to 0.1.97
10
+
11
+ # 2.4.43
12
+ - updated tybot-connector to 0.1.96
13
+ - added segment module
8
14
 
9
15
  # 2.4.42
10
16
  - createIfNotExistsWithLeadId now update the lead email if jwt email changes
package/app.js CHANGED
@@ -129,6 +129,8 @@ var requestUtilRoot = require('./routes/requestUtilRoot');
129
129
  var urls = require('./routes/urls');
130
130
  var email = require('./routes/email');
131
131
  var property = require('./routes/property');
132
+ var segment = require('./routes/segment');
133
+
132
134
 
133
135
  var bootDataLoader = require('./services/bootDataLoader');
134
136
  var settingDataLoader = require('./services/settingDataLoader');
@@ -550,6 +552,7 @@ app.use('/:projectid/campaigns',[passport.authenticate(['basic', 'jwt'], { sessi
550
552
  app.use('/:projectid/emails',[passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['bot','subscription'])], email);
551
553
 
552
554
  app.use('/:projectid/properties',[passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['bot','subscription'])], property);
555
+ app.use('/:projectid/segments',[passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['bot','subscription'])], segment);
553
556
 
554
557
  app.use('/:projectid/openai', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent')], openai);
555
558
  app.use('/:projectid/kbsettings', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['bot','subscription'])], kbsettings);
package/docs/api-dev.md CHANGED
@@ -882,4 +882,45 @@ curl -v -X GET -H 'Content-Type:application/json' -H "Authorization: JWT eyJhbGc
882
882
 
883
883
 
884
884
 
885
- curl -v -X POST -H 'Content-Type:application/json' -u andrea.leo@frontiere21.it:258456 https://tiledesk-server-pre.herokuapp.com/chat21/native/auth/createCustomToken
885
+ curl -v -X POST -H 'Content-Type:application/json' -u andrea.leo@frontiere21.it:258456 https://tiledesk-server-pre.herokuapp.com/chat21/native/auth/createCustomToken
886
+
887
+
888
+
889
+
890
+
891
+ curl -v -X POST -H 'Content-Type:application/json' -u admin@tiledesk.com:adminadmin -d '{"name":"testprj"}' http://localhost:3000/projects
892
+
893
+ curl -v -X POST -H 'Content-Type:application/json' -u admin@tiledesk.com:adminadmin -d '{ "name":"segment1", "filters": [{"field":"field1","operator":"=","value":"ciao2"}]}' http://localhost:3000/651446eeaf0e4e333f86db6d/segments
894
+
895
+
896
+ curl -v -X POST -H 'Content-Type:application/json' -u admin@tiledesk.com:adminadmin -d '{"text":"firstText"}' http://localhost:3000/651446eeaf0e4e333f86db6d/requests/req123456999-651446eeaf0e4e333f86db6d/messages
897
+
898
+
899
+ curl -v -X GET -u admin@tiledesk.com:adminadmin http://localhost:3000/651446eeaf0e4e333f86db6d/leads?segment=651448cc39405451f2165a80
900
+
901
+
902
+ number
903
+
904
+ curl -v -X POST -H 'Content-Type:application/json' -u admin@tiledesk.com:adminadmin -d '{ "name":"segment1", "filters": [{"field":"field1","operator":"=","value":44}]}' http://localhost:3000/651446eeaf0e4e333f86db6d/segments
905
+
906
+ curl -v -X GET -u admin@tiledesk.com:adminadmin http://localhost:3000/651446eeaf0e4e333f86db6d/leads?segment=6515a7e0066727cb94bccd5c
907
+
908
+
909
+
910
+
911
+ sudo systemctl start mongod
912
+
913
+
914
+
915
+
916
+ curl -v -X PUT -H 'Content-Type:application/json' -u admin@tiledesk.com:adminadmin -d '{ "name":"segment2", "filters": [{"field":"field1","operator":"=","value":"ciao2"}]}' http://localhost:3000/651446eeaf0e4e333f86db6d/segments/6516eb0a11e143e3548b8dd6
917
+
918
+
919
+
920
+ curl -v -X GET -H 'Content-Type:application/json' -u admin@tiledesk.com:adminadmin http://localhost:3000/651446eeaf0e4e333f86db6d/segments/6516eb0a11e143e3548b8dd6
921
+
922
+
923
+ curl -v -X GET -H 'Content-Type:application/json' -u admin@tiledesk.com:adminadmin http://localhost:3000/651446eeaf0e4e333f86db6d/segments/
924
+
925
+
926
+ curl -v -X DELETE -H 'Content-Type:application/json' -u admin@tiledesk.com:adminadmin http://localhost:3000/651446eeaf0e4e333f86db6d/segments/6516eb0a11e143e3548b8dd6
@@ -0,0 +1,67 @@
1
+ var mongoose = require('mongoose');
2
+ var Schema = mongoose.Schema;
3
+ var winston = require('../config/winston');
4
+
5
+
6
+
7
+ var SegmentFilterSchema = new Schema({
8
+ field: { //ex: email
9
+ type: String,
10
+ required: true,
11
+ // index:true
12
+ },
13
+ operator: {
14
+ type: String,
15
+ required: true
16
+ },
17
+ value: { //tidio supports date, tag, dropdown
18
+ //type: String,
19
+ type: Object,
20
+ required: true
21
+ },
22
+ },{ _id : false });
23
+
24
+
25
+ var SegmentSchema = new Schema({
26
+
27
+ name: {
28
+ type: String,
29
+ required: true,
30
+ // index: true
31
+ },
32
+ match: {
33
+ type: String,
34
+ required: true,
35
+ // index:
36
+ default: "all" //or any
37
+ },
38
+ filters: [SegmentFilterSchema],
39
+ id_project: {
40
+ type: String,
41
+ required: true,
42
+ index: true
43
+ },
44
+ status: {
45
+ type: Number,
46
+ default: 100,
47
+ required: true,
48
+ index: true
49
+ },
50
+ createdBy: {
51
+ type: String,
52
+ required: true
53
+ }
54
+ },{
55
+ timestamps: true
56
+ }
57
+ );
58
+
59
+
60
+ var segment = mongoose.model('segment', SegmentSchema);
61
+
62
+ if (process.env.MONGOOSE_SYNCINDEX) {
63
+ segment.syncIndexes();
64
+ winston.info("segment syncIndexes")
65
+ }
66
+
67
+ module.exports = segment;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tiledesk/tiledesk-server",
3
3
  "description": "The Tiledesk server module",
4
- "version": "2.4.53",
4
+ "version": "2.4.55",
5
5
  "scripts": {
6
6
  "start": "node ./bin/www",
7
7
  "pretest": "mongodb-runner start",
@@ -44,7 +44,7 @@
44
44
  "@tiledesk/tiledesk-kaleyra-proxy": "^0.1.7",
45
45
  "@tiledesk/tiledesk-messenger-connector": "0.1.9",
46
46
  "@tiledesk/tiledesk-rasa-connector": "^1.0.10",
47
- "@tiledesk/tiledesk-tybot-connector": "^0.1.94",
47
+ "@tiledesk/tiledesk-tybot-connector": "^0.1.97",
48
48
  "@tiledesk/tiledesk-whatsapp-connector": "^0.1.51",
49
49
  "amqplib": "^0.5.5",
50
50
  "app-root-path": "^3.0.0",
@@ -3,6 +3,7 @@ var KBSettings = require('../models/kb_setting');
3
3
  // var KB = require('../models/kb_setting')
4
4
  var router = express.Router();
5
5
  var winston = require('../config/winston');
6
+ const openaiService = require('../services/openaiService');
6
7
 
7
8
  router.get('/', async (req, res) => {
8
9
  let project_id = req.projectid;
@@ -54,35 +55,6 @@ router.post('/', async (req, res) => {
54
55
  })
55
56
  })
56
57
 
57
- router.post('/:settings_id', async (req, res) => {
58
-
59
- let settings_id = req.params.settings_id;
60
- let body = req.body;
61
-
62
- KBSettings.findById(settings_id, (err, settings) => {
63
- if (err) {
64
- winston.error("find knoledge base error: ", err);
65
- return res.status(500).send({ success: false, error: err});
66
- } else {
67
-
68
- let new_kb = {
69
- name: body.name,
70
- url: body.url
71
- }
72
- settings.kbs.push(new_kb);
73
-
74
- KBSettings.findByIdAndUpdate( settings_id, settings, { new: true }, (err, savedSettings) => {
75
- if (err) {
76
- winston.err("findByIdAndUpdate error: ", err);
77
- res.status(500).send({ success: false, error: err });
78
- } else {
79
- res.status(200).send(savedSettings);
80
- }
81
- })
82
- }
83
- })
84
- })
85
-
86
58
  router.put('/:settings_id', async (req, res) => {
87
59
 
88
60
  let settings_id = req.params.settings_id;
@@ -123,6 +95,81 @@ router.delete('/:settings_id/:kb_id', async (req, res) => {
123
95
  res.status(200).send(settings);
124
96
  }
125
97
  })
98
+
99
+ })
100
+
101
+
102
+ // PROXY PUGLIA AI - START
103
+ router.post('/qa', async (req, res) => {
104
+ let data = req.body;
105
+ console.log("data: ", data);
106
+
107
+ openaiService.ask(data).then((resp) => {
108
+ // console.log("qa resp: ", resp.data);
109
+ res.status(200).send(resp.data);
110
+ }).catch((err) => {
111
+ winston.error("qa err: ", err);
112
+ res.status(500).send(err);
113
+ })
114
+ })
115
+
116
+ router.post('/startscrape', async (req, res) => {
117
+
118
+ let data = req.body;
119
+ console.log("data: ", data);
120
+
121
+ openaiService.startScrape(data).then((resp) => {
122
+ // console.log("startScrape resp: ", resp.data);
123
+ res.status(200).send(resp.data);
124
+ }).catch((err) => {
125
+ winston.error("startScrape err: ", err);
126
+ res.status(500).send(err);
127
+ })
128
+ })
129
+
130
+
131
+ router.post('/checkstatus', async (req, res) => {
132
+
133
+ let data = req.body;
134
+ console.log("data: ", data);
135
+
136
+ openaiService.checkStatus(data).then((resp) => {
137
+ // console.log("checkStatus resp: ", resp.data);
138
+ res.status(200).send(resp.data);
139
+ }).catch((err) => {
140
+ winston.error("checkStatus err: ", err);
141
+ res.status(500).send(err);
142
+ })
143
+ })
144
+ // PROXY PUGLIA AI - END
145
+
146
+ router.post('/:settings_id', async (req, res) => {
147
+
148
+ let settings_id = req.params.settings_id;
149
+ let body = req.body;
150
+
151
+ KBSettings.findById(settings_id, (err, settings) => {
152
+ if (err) {
153
+ winston.error("find knoledge base error: ", err);
154
+ return res.status(500).send({ success: false, error: err});
155
+ } else {
156
+
157
+ let new_kb = {
158
+ name: body.name,
159
+ url: body.url
160
+ }
161
+ settings.kbs.push(new_kb);
162
+
163
+ KBSettings.findByIdAndUpdate( settings_id, settings, { new: true }, (err, savedSettings) => {
164
+ if (err) {
165
+ winston.err("findByIdAndUpdate error: ", err);
166
+ res.status(500).send({ success: false, error: err });
167
+ } else {
168
+ res.status(200).send(savedSettings);
169
+ }
170
+ })
171
+ }
172
+ })
126
173
  })
127
174
 
128
175
  module.exports = router;
package/routes/lead.js CHANGED
@@ -7,6 +7,8 @@ var leadService = require("../services/leadService");
7
7
  csv = require('csv-express');
8
8
  csv.separator = ';';
9
9
  const leadEvent = require('../event/leadEvent');
10
+ var Segment = require("../models/segment");
11
+ var Segment2MongoConverter = require("../utils/segment2mongoConverter");
10
12
 
11
13
 
12
14
  router.post('/', function (req, res) {
@@ -388,7 +390,7 @@ router.get('/:leadid', function (req, res) {
388
390
  });
389
391
 
390
392
 
391
- router.get('/', function (req, res) {
393
+ router.get('/', async(req, res) => {
392
394
 
393
395
  var limit = 40; // Number of request per page
394
396
 
@@ -407,7 +409,7 @@ router.get('/', function (req, res) {
407
409
  winston.debug('LEAD ROUTE - SKIP PAGE ', skip);
408
410
 
409
411
 
410
- var query = { "id_project": req.projectid, "status": LeadConstants.NORMAL};
412
+ var query = {};
411
413
 
412
414
  if (req.query.full_text) {
413
415
  winston.debug('LEAD ROUTE req.query.fulltext', req.query.full_text);
@@ -440,6 +442,24 @@ router.get('/', function (req, res) {
440
442
  query["tags"] = req.query.tags;
441
443
  }
442
444
 
445
+
446
+ if (req.query.segment) {
447
+ let segment = await Segment.findOne({id_project: req.projectid, _id: req.query.segment }).exec();
448
+ if (!segment) {
449
+ return res.status(404).send({ success: false, msg: 'Error segment not found' });
450
+ }
451
+ Segment2MongoConverter.convert(query, segment);
452
+ }
453
+
454
+
455
+
456
+ // last query modifier
457
+ query["id_project"] = req.projectid;
458
+ query["status"] = LeadConstants.NORMAL;
459
+
460
+ winston.debug("query", query);
461
+
462
+
443
463
  var direction = -1; //-1 descending , 1 ascending
444
464
  if (req.query.direction) {
445
465
  direction = req.query.direction;
@@ -0,0 +1,157 @@
1
+ var express = require('express');
2
+ var router = express.Router();
3
+ var winston = require('../config/winston');
4
+ var Segment = require("../models/segment");
5
+
6
+
7
+ router.post('/', function (req, res) {
8
+
9
+ winston.debug(req.body);
10
+ winston.debug("req.user", req.user);
11
+
12
+ var newSegment = new Segment({
13
+ name: req.body.name,
14
+ match: req.body.match,
15
+ filters: req.body.filters,
16
+ id_project: req.projectid,
17
+ createdBy: req.user.id
18
+ });
19
+
20
+ newSegment.save(function(err, segment) {
21
+ if (err) {
22
+ winston.error('Error saving the segment '+ JSON.stringify(segment), err);
23
+ return res.status(500).send({ success: false, msg: 'Error updating object.' });
24
+
25
+ }
26
+ winston.verbose('segment created ', segment.toJSON());
27
+
28
+
29
+ res.json(segment);
30
+ })
31
+
32
+ });
33
+
34
+ router.put('/:segmentid', function (req, res) {
35
+ winston.debug(req.body);
36
+ var update = {};
37
+
38
+ if (req.body.name!=undefined) {
39
+ update.name = req.body.name;
40
+ }
41
+
42
+ if (req.body.match!=undefined) {
43
+ update.match = req.body.match;
44
+ }
45
+ if (req.body.filters!=undefined) {
46
+ update.filters = req.body.filters;
47
+ }
48
+
49
+
50
+
51
+ Segment.findByIdAndUpdate(req.params.segmentid, update, { new: true, upsert: true }, function (err, updatedSegment) {
52
+ if (err) {
53
+ winston.error('--- > ERROR ', err);
54
+ return res.status(500).send({ success: false, msg: 'Error updating object.' });
55
+ }
56
+
57
+ res.json(updatedSegment);
58
+ });
59
+ });
60
+
61
+
62
+
63
+ router.delete('/:segmentid', function (req, res) {
64
+ winston.debug(req.body);
65
+
66
+ Segment.findByIdAndUpdate(req.params.segmentid, {status:0}, { new: true, upsert: true }, function (err, updatedSegment) {
67
+ if (err) {
68
+ winston.error('--- > ERROR ', err);
69
+ return res.status(500).send({ success: false, msg: 'Error updating object.' });
70
+ }
71
+
72
+ res.json(updatedSegment);
73
+ });
74
+ });
75
+
76
+
77
+ router.get('/:segmentid', function (req, res) {
78
+ winston.debug(req.body);
79
+
80
+ Segment.findById(req.params.segmentid, function (err, segment) {
81
+ if (err) {
82
+ return res.status(500).send({ success: false, msg: 'Error getting object.' });
83
+ }
84
+ if (!segment) {
85
+ return res.status(404).send({ success: false, msg: 'Object not found.' });
86
+ }
87
+ res.json(segment);
88
+ });
89
+ });
90
+
91
+
92
+ router.get('/', function (req, res) {
93
+
94
+ var limit = 40; // Number of request per page
95
+
96
+ if (req.query.limit) {
97
+ limit = parseInt(req.query.limit);
98
+ winston.debug('LEAD ROUTE - limit: '+limit);
99
+ }
100
+
101
+ var page = 0;
102
+
103
+ if (req.query.page) {
104
+ page = req.query.page;
105
+ }
106
+
107
+ var skip = page * limit;
108
+ winston.debug('LEAD ROUTE - SKIP PAGE ', skip);
109
+
110
+
111
+ var query = { "id_project": req.projectid, "status": 100};
112
+
113
+ var direction = -1; //-1 descending , 1 ascending
114
+ if (req.query.direction) {
115
+ direction = req.query.direction;
116
+ }
117
+
118
+ var sortField = "createdAt";
119
+ if (req.query.sort) {
120
+ sortField = req.query.sort;
121
+ }
122
+
123
+ var sortQuery = {};
124
+ sortQuery[sortField] = direction;
125
+
126
+ winston.debug("sort query", sortQuery);
127
+
128
+
129
+
130
+ return Segment.find(query).
131
+ skip(skip).limit(limit).
132
+ sort(sortQuery).
133
+ exec(function (err, segments) {
134
+ if (err) {
135
+ winston.error('segments ROUTE - REQUEST FIND ERR ', err)
136
+ return (err);
137
+ }
138
+
139
+ // blocked to 1000 TODO increases it
140
+ // collection.count is deprecated, and will be removed in a future version. Use Collection.countDocuments or Collection.estimatedDocumentCount instead
141
+ return Segment.countDocuments(query, function (err, totalRowCount) {
142
+
143
+ var objectToReturn = {
144
+ perPage: limit,
145
+ count: totalRowCount,
146
+ segments: segments
147
+ };
148
+
149
+ return res.json(objectToReturn);
150
+ });
151
+ });
152
+ });
153
+
154
+
155
+
156
+
157
+ module.exports = router;
package/routes/users.js CHANGED
@@ -203,7 +203,7 @@ router.post('/loginemail', function (req, res) {
203
203
  winston.debug("user found: ", user);
204
204
 
205
205
  emailService.sendEmailRedirectOnDesktop(user.email, token, project_id, user.email)
206
- return res.status(200).send("Sending email...")
206
+ return res.status(200).send({ success: true, message: "Sending email..."})
207
207
  })
208
208
 
209
209
 
@@ -4,12 +4,14 @@ var configGlobal = require('../config/global');
4
4
  require('dotenv').config();
5
5
 
6
6
  let openai_endpoint = process.env.OPENAI_ENDPOINT;
7
+ let kb_endpoint = process.env.KB_ENDPOINT;
7
8
 
8
9
  class OpenaiService {
9
10
 
11
+ // OPEN AI
10
12
  completions(data, gptkey) {
11
13
 
12
- console.log("****** Serivcesssssssss openai_endpoint: ", openai_endpoint);
14
+ winston.debug("[OPENAI SERVICE] openai endpoint: ", openai_endpoint);
13
15
 
14
16
  return new Promise((resolve, reject) => {
15
17
 
@@ -33,7 +35,74 @@ class OpenaiService {
33
35
  })
34
36
 
35
37
  }
38
+
39
+
40
+ // PUGLIA AI
41
+ checkStatus(data) {
42
+ winston.debug("[OPENAI SERVICE] kb endpoint: ", kb_endpoint);
43
+
44
+ return new Promise((resolve, reject) => {
45
+
46
+ axios({
47
+ url: kb_endpoint + "/scrape/status",
48
+ headers: {
49
+ 'Content-Type': 'application/json'
50
+ },
51
+ data: data,
52
+ method: 'POST'
53
+ }).then((resbody) => {
54
+ resolve(resbody);
55
+ }).catch((err) => {
56
+ console.log("err: ", err);
57
+ reject(err);
58
+ })
59
+
60
+ })
61
+ }
62
+
63
+ startScrape(data) {
64
+ winston.debug("[OPENAI SERVICE] kb endpoint: ", kb_endpoint);
65
+
66
+ return new Promise((resolve, reject) => {
67
+
68
+ axios({
69
+ url: kb_endpoint + "/scrape/",
70
+ headers: {
71
+ 'Content-Type': 'application/json'
72
+ },
73
+ data: data,
74
+ method: 'POST'
75
+ }).then((resbody) => {
76
+ resolve(resbody);
77
+ }).catch((err) => {
78
+ console.log("err: ", err);
79
+ reject(err);
80
+ })
36
81
 
82
+ })
83
+ }
84
+
85
+ ask(data) {
86
+ winston.debug("[OPENAI SERVICE] kb endpoint: ", kb_endpoint);
87
+
88
+ return new Promise((resolve, reject) => {
89
+
90
+ axios({
91
+ url: kb_endpoint + "/qa/",
92
+ headers: {
93
+ 'Content-Type': 'application/json'
94
+ },
95
+ data: data,
96
+ method: 'POST'
97
+ }).then((resbody) => {
98
+ resolve(resbody);
99
+ }).catch((err) => {
100
+ console.log("err: ", err);
101
+ reject(err);
102
+ })
103
+
104
+ })
105
+ }
37
106
  }
38
107
 
39
108
  var openaiService = new OpenaiService();
@@ -162,7 +162,7 @@
162
162
  <div style="margin-top: 20px; font-weight: 600;">Access Tiledesk on your desktop now 👇</div>
163
163
 
164
164
  <div style="margin-top: 10px;">
165
- <a href="{{baseScope.baseUrl}}/#/handle-invitation/{{pendinginvitationid}}/{{projectName}}/{{currentUserFirstname}}/{{currentUserLastname}}"
165
+ <a href="{{baseScope.baseUrl}}/#/project/{{project_id}}/home?token={{token}}"
166
166
  style=" background-color: #ff8574 !important; border: none; color: white; padding: 6px 18px; text-align: center; text-decoration: none; display: inline-block; font-size: 14px; font-weight: 600; letter-spacing: 1px; margin: 4px 2px; cursor: pointer; border-radius: 8px;">
167
167
  Enjoy Tiledesk
168
168
  </a>
@@ -174,8 +174,8 @@
174
174
  Alternatively, simply copy and paste this URL into your browser:
175
175
  <div>
176
176
  <a
177
- href="{{baseScope.baseUrl}}/#/handle- invitation/{{pendinginvitationid}}/{{projectName}}/{{currentUserFirstname}}/{{currentUserLastname}}">
178
- https://panel.tiledesk.com/v3/dashboard/#/login?user=email@user.com
177
+ href="{{baseScope.baseUrl}}/#/project/{{project_id}}/home?token={{token}}">
178
+ {{baseScope.baseUrl}}/#/project/{{project_id}}/home
179
179
  </a>
180
180
  </div>
181
181
  </div>
@@ -4,312 +4,6 @@
4
4
  <html lang="en" xmlns="http://www.w3.org/1999/xhtml"
5
5
  style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
6
6
 
7
- <head>
8
- <meta name="viewport" content="width=device-width" />
9
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
10
- <title>Join Tiledesk from Desktop</title>
11
-
12
- <style type="text/css">
13
- img {
14
- max-width: 100%;
15
- text-align: center !important;
16
- }
17
-
18
- img.CToWUd {
19
- margin-bottom: 16px;
20
- max-width: 200px !important;
21
- width: 200px !important;
22
- min-width: 200px !important;
23
- outline: none;
24
- text-decoration: none;
25
- border: none;
26
- height: auto;
27
- margin-left: 0px;
28
- }
29
-
30
- body {
31
- -webkit-font-smoothing: antialiased;
32
- -webkit-text-size-adjust: none;
33
- width: 100% !important;
34
- height: 100%;
35
- line-height: 1.6em;
36
- }
37
-
38
- body {
39
- background-color: #f6f6f6;
40
- }
41
-
42
- .header-image-container {
43
- margin-top: 10px;
44
- height: 40px;
45
- background-image: url("https://tiledesk.com/wp-content/uploads/2022/08/tiledesk_v1-1.png");
46
- background-size: contain;
47
- background-position: center;
48
- background-repeat: no-repeat;
49
- }
50
-
51
- .social-icon-container {
52
- border: solid 1px;
53
- border-radius: 14px;
54
- padding: 4px;
55
- margin: 0px 6px;
56
- cursor: pointer;
57
- }
58
-
59
- @media only screen and (max-width: 640px) {
60
- body {
61
- padding: 0 !important;
62
- }
63
-
64
- h1 {
65
- font-weight: 800 !important;
66
- margin: 20px 0 5px !important;
67
- text-align: center !important;
68
- }
69
-
70
- h2 {
71
- font-weight: 800 !important;
72
- margin: 20px 0 5px !important;
73
- }
74
-
75
- h3 {
76
- font-weight: 800 !important;
77
- margin: 20px 0 5px !important;
78
- }
79
-
80
- h4 {
81
- font-weight: 800 !important;
82
- margin: 20px 0 5px !important;
83
- }
84
-
85
- h1 {
86
- font-size: 22px !important;
87
- }
88
-
89
- h2 {
90
- font-size: 18px !important;
91
- }
92
-
93
- h3 {
94
- font-size: 16px !important;
95
- }
96
-
97
- .container {
98
- padding: 0 !important;
99
- width: 100% !important;
100
- }
101
-
102
- .content {
103
- padding: 0 !important;
104
- }
105
-
106
- .content-wrap {
107
- padding: 10px !important;
108
- }
109
-
110
- .invoice {
111
- width: 100% !important;
112
- }
113
- }
114
- </style>
115
- </head>
116
-
117
- <body itemscope itemtype="http://schema.org/EmailMessage"
118
- style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6em; background-color: #f6f6f6; margin: 0;"
119
- bgcolor="#f6f6f6">
120
-
121
- <table class="body-wrap"
122
- style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; background-color: #f6f6f6; margin: 0;"
123
- bgcolor="#f6f6f6">
124
- <tr
125
- style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
126
- <td
127
- style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;"
128
- valign="top"></td>
129
- <td class="container" width="600"
130
- style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; display: block !important; max-width: 600px !important; clear: both !important; margin: 0 auto;"
131
- valign="top">
132
- <div class="content"
133
- style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; max-width: 600px; display: block; margin: 0 auto; padding: 20px;">
134
-
135
- <table class="main" width="100%" cellpadding="0" cellspacing="0"
136
- style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; border-radius: 3px; background-color: #fff; margin: 0; border: 1px solid #e9e9e9;"
137
- bgcolor="#fff">
138
-
139
-
140
- <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
141
-
142
- <td class="alert alert-warning" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 16px; vertical-align: top; font-weight: 500; text-align: center; border-radius: 3px 3px 0 0; margin: 0;"
143
- align="center" valign="top">
144
- <div>
145
- <div class="header-image-container"></div>
146
- <h2 style="margin-top: 40px;">Get Ready for a Full Tiledesk Experience!</h2>
147
- </div>
148
-
149
- </td>
150
- </tr>
151
-
152
- <tr
153
- style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
154
- <td class="content-wrap"
155
- style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 20px;"
156
- valign="top">
157
- <table width="100%" cellpadding="0" cellspacing="0"
158
- style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
159
-
160
-
161
- <tr
162
- style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
163
- <td class="content-block">
164
- <div style="text-align: center;">
165
- For the optimal Tiledesk experience, we recommend using it on a desktop device. We've made
166
- access easier for you with a personalized link.
167
-
168
- <div style="margin-top: 20px; font-weight: 600;">Access Tiledesk on your desktop now 👇</div>
169
-
170
- <div style="margin-top: 10px;">
171
- <a href="{{baseScope.baseUrl}}/#/handle-invitation/{{pendinginvitationid}}/{{projectName}}/{{currentUserFirstname}}/{{currentUserLastname}}"
172
- style=" background-color: #ff8574 !important; border: none; color: white; padding: 6px 18px; text-align: center; text-decoration: none; display: inline-block; font-size: 14px; font-weight: 600; letter-spacing: 1px; margin: 4px 2px; cursor: pointer; border-radius: 8px;">
173
- Enjoy Tiledesk
174
- </a>
175
- </div>
176
-
177
- </div>
178
-
179
- <div style="margin-top: 40px;">
180
- Alternatively, simply copy and paste this URL into your browser:
181
- <div>
182
- <a
183
- href="{{baseScope.baseUrl}}/#/handle- invitation/{{pendinginvitationid}}/{{projectName}}/{{currentUserFirstname}}/{{currentUserLastname}}">
184
- https://panel.tiledesk.com/v3/dashboard/#/login?user=email@user.com
185
- </a>
186
- </div>
187
- </div>
188
-
189
- </td>
190
- </tr>
191
-
192
- <tr
193
- style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
194
- <td class="content-block"
195
- style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;"
196
- valign="top">
197
- </td>
198
- </tr>
199
- </table>
200
- </td>
201
- </tr>
202
-
203
- <tr>
204
- <td>
205
- <hr style="width:94%;height:1px;border:none;background-color: #cacaca;">
206
-
207
- <div style="display: flex; padding: 20px 18px; color: #888888; align-items: center;">
208
- <span>Powered by </span>
209
- <span style="display: flex;"><img
210
- src="https://tiledesk.com/wp-content/uploads/2023/05/tiledesk-solo_logo_new_gray.png" width="15"
211
- height="15" style="margin-left: 6px; margin-top: 2px;" /></span>
212
- <span style="font-weight: bold; margin-left: 2px;">Tiledesk</span>
213
- </div>
214
-
215
- </td>
216
- </tr>
217
-
218
-
219
- </table>
220
- <div class="footer"
221
- style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; clear: both; color: #999; margin: 0; padding: 20px;">
222
- <table width="100%"
223
- style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
224
- <tr>
225
- <td class="aligncener content-block">
226
- <div style="display: flex; flex-direction: column; align-items: center; margin-bottom: 30px;">
227
- <div style="margin-bottom: 10px; font-style: italic;">Follow us on:</div>
228
- <div style="display: flex; flex-direction: row;">
229
-
230
- <!-- Facebook -->
231
- <a href="https://www.facebook.com/tiledesk" target="_blank">
232
- <div class="social-icon-container" style="border-color: #3d6ad6;">
233
- <img
234
- src="https://github.com/Tiledesk/tiledesk-dashboard/assets/45603238/f762a3d7-541a-4b78-ae33-c35cdbe3b083"
235
- width="20px" height="20px" />
236
- </div>
237
- </a>
238
-
239
- <!-- YouTube -->
240
- <a href="https://www.youtube.com/@tiledesk" target="_blank">
241
- <div class="social-icon-container" style="border-color: #e7332f;">
242
- <img
243
- src="https://github.com/Tiledesk/tiledesk-dashboard/assets/45603238/5dc5be2d-8bd3-43cf-b1ca-f12a36c01f1a"
244
- width="20px" height="20px" />
245
- </div>
246
- </a>
247
-
248
- <!-- Linkedin -->
249
- <a href="https://www.linkedin.com/company/tiledesk/" target="_blank">
250
- <div class="social-icon-container" style="border-color: #1f77b5;">
251
- <img
252
- src="https://github.com/Tiledesk/tiledesk-dashboard/assets/45603238/52d8909f-c847-4b44-8dfb-7cd041e481c3"
253
- width="20px" height="20px" />
254
- </div>
255
- </a>
256
-
257
- <!-- Instagram -->
258
- <a href="https://www.instagram.com/tiledesk/" target="_blank">
259
- <div class="social-icon-container" style="border-color: #f78881;">
260
- <img
261
- src="https://github.com/Tiledesk/tiledesk-dashboard/assets/45603238/4c35afe2-277a-4fdd-8e50-0844148216c8"
262
- width="20px" height="20px" />
263
- </div>
264
- </a>
265
-
266
- <!-- Twitter -->
267
- <a href="https://twitter.com/tiledesk" target="_blank">
268
- <div class="social-icon-container" style="border-color: #2ea1f2;">
269
- <img
270
- src="https://github.com/Tiledesk/tiledesk-dashboard/assets/45603238/3288635e-50b6-4b2d-bccc-0c9313dd11a5"
271
- width="20px" height="20px" />
272
- </div>
273
- </a>
274
-
275
- </div>
276
-
277
- </div>
278
- </td>
279
- </tr>
280
- <tr
281
- style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
282
- <td class="aligncenter content-block"
283
- style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; vertical-align: top; color: #999; text-align: center; margin: 0;"
284
- align="center" valign="top">
285
- <span><a href="http://www.tiledesk.com"
286
- style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; color: #999; text-decoration: underline; margin: 0;">
287
- Tiledesk.com </a></span>
288
- <br><span><a href="%unsubscribe_url%"
289
- style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; color: #999; text-decoration: underline; margin: 0;">Unsubscribe</a></span>
290
- </td>
291
- </tr>
292
- </table>
293
-
294
-
295
- </div>
296
- </div>
297
- </td>
298
- <td
299
- style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;"
300
- valign="top"></td>
301
- </tr>
302
- </table>
303
-
304
- </body>
305
-
306
- </html>
307
-
308
-
309
- <!--
310
- <html lang="en" xmlns="http://www.w3.org/1999/xhtml"
311
- style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
312
-
313
7
  <head>
314
8
  <meta name="viewport" content="width=device-width" />
315
9
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
@@ -391,18 +85,18 @@
391
85
  }
392
86
 
393
87
  .custom-button {
394
- background-color: #ff8574 !important;
395
- border: none;
396
- color: white !important;
397
- padding: 6px 18px;
398
- text-align: center;
399
- text-decoration: none;
400
- display: inline-block;
401
- font-size: 14px;
402
- font-weight: 600;
403
- letter-spacing: 1px;
404
- margin: 4px 2px;
405
- cursor: pointer;
88
+ background-color: #ff8574 !important;
89
+ border: none;
90
+ color: white !important;
91
+ padding: 6px 18px;
92
+ text-align: center;
93
+ text-decoration: none;
94
+ display: inline-block;
95
+ font-size: 14px;
96
+ font-weight: 600;
97
+ letter-spacing: 1px;
98
+ margin: 4px 2px;
99
+ cursor: pointer;
406
100
  border-radius: 8px;
407
101
  }
408
102
 
@@ -413,15 +107,15 @@
413
107
  }
414
108
 
415
109
  .powered-by-container {
416
- display: flex;
417
- padding: 20px 18px;
418
- color: #888888;
110
+ display: flex;
111
+ padding: 20px 18px;
112
+ color: #888888;
419
113
  }
420
114
 
421
115
  .social-button-container {
422
- display: flex;
116
+ display: flex;
423
117
  }
424
-
118
+
425
119
  .social-icon-container {
426
120
  border: solid 1px;
427
121
  border-radius: 14px;
@@ -506,7 +200,7 @@
506
200
 
507
201
  <div class="content" style="flex-direction: column;align-items: center;">
508
202
  <div class="inner-content">
509
-
203
+
510
204
  <div class="content-box">
511
205
  <div class="header-image-container"></div>
512
206
  <div class="title-container" style="justify-content: center;">
@@ -518,8 +212,7 @@
518
212
 
519
213
  <div style="margin-top: 20px; font-weight: 600;">Access Tiledesk on your desktop now 👇</div>
520
214
  <div style="margin-top: 10px;">
521
- <a href="{{baseScope.baseUrl}}/{{project_id}}/home?token={{token}}" class="custom-button"
522
- style="color: white;">
215
+ <a href="{{baseScope.baseUrl}}/{{project_id}}/home?token={{token}}" class="custom-button" style="color: white;">
523
216
  Enjoy Tiledesk
524
217
  </a>
525
218
  </div>
@@ -527,7 +220,8 @@
527
220
  <div style="margin-top: 40px; text-align: left;">
528
221
  Alternatively, simply copy and paste this URL into your browser:
529
222
  <div>
530
- <a href="{{baseScope.baseUrl}}/{{project_id}}/home?token={{token}}">
223
+ <a
224
+ href="{{baseScope.baseUrl}}/{{project_id}}/home?token={{token}}">
531
225
  {{baseScope.baseUrl}}/{{project_id}}/home
532
226
  </a>
533
227
  </div>
@@ -535,7 +229,7 @@
535
229
  </div>
536
230
 
537
231
  <hr class="custom-divider">
538
-
232
+
539
233
  <div class="powered-by-container" style="align-items: center;">
540
234
  <span>Powered by </span>
541
235
  <span style="display: flex;"><img
@@ -543,13 +237,14 @@
543
237
  height="15" style="margin-left: 6px; margin-top: 2px;" /></span>
544
238
  <span style="font-weight: bold; margin-left: 2px;">Tiledesk</span>
545
239
  </div>
546
-
240
+
547
241
  </div>
548
-
242
+
549
243
  <div class="footer">
550
244
  <div style="margin-bottom: 10px; font-style: italic;">Follow us on:</div>
551
245
  <div class="social-button-container" style="flex-direction: row; justify-content: center;">
552
-
246
+
247
+ <!-- Facebook -->
553
248
  <a href="https://www.facebook.com/tiledesk" target="_blank">
554
249
  <div class="social-icon-container" style="border-color: #3d6ad6;">
555
250
  <img
@@ -558,6 +253,7 @@
558
253
  </div>
559
254
  </a>
560
255
 
256
+ <!-- YouTube -->
561
257
  <a href="https://www.youtube.com/@tiledesk" target="_blank">
562
258
  <div class="social-icon-container" style="border-color: #e7332f;">
563
259
  <img
@@ -566,6 +262,7 @@
566
262
  </div>
567
263
  </a>
568
264
 
265
+ <!-- Linkedin -->
569
266
  <a href="https://www.linkedin.com/company/tiledesk/" target="_blank">
570
267
  <div class="social-icon-container" style="border-color: #1f77b5;">
571
268
  <img
@@ -574,6 +271,7 @@
574
271
  </div>
575
272
  </a>
576
273
 
274
+ <!-- Instagram -->
577
275
  <a href="https://www.instagram.com/tiledesk/" target="_blank">
578
276
  <div class="social-icon-container" style="border-color: #f78881;">
579
277
  <img
@@ -582,6 +280,7 @@
582
280
  </div>
583
281
  </a>
584
282
 
283
+ <!-- Twitter -->
585
284
  <a href="https://twitter.com/tiledesk" target="_blank">
586
285
  <div class="social-icon-container" style="border-color: #2ea1f2;">
587
286
  <img
@@ -589,7 +288,7 @@
589
288
  width="20px" height="20px" />
590
289
  </div>
591
290
  </a>
592
-
291
+
593
292
  </div>
594
293
 
595
294
  <div class="unsubscribe-container" style="display: flex;flex-direction: column;">
@@ -597,8 +296,8 @@
597
296
  <a href="%unsubscribe_url%" class="unsubscribe-link">Unsubscribe</a>
598
297
  </div>
599
298
 
600
- </div>
299
+ </div>
601
300
  </div>
602
301
  </div>
603
302
 
604
- </body> -->
303
+ </body>
@@ -0,0 +1,98 @@
1
+
2
+ class Segment2MongoConverter {
3
+
4
+ convert(query, segment) {
5
+ //console.log("qui", query);
6
+
7
+ let condition = query;
8
+ //let condition = {};
9
+
10
+ // if (segment.match == "any") {
11
+ // // db.inventory.find( { $or: [ { quantity: { $lt: 20 } }, { price: 10 } ] } )
12
+ // condition["$or"] = [];
13
+ // }
14
+
15
+ if (segment.filters && segment.filters.length > 0) {
16
+ for(var i = 0; i < segment.filters.length; i++) {
17
+ let filter = segment.filters[i];
18
+ switch (filter.operator) {
19
+ case '=':
20
+ //console.log('Operator =');
21
+ this.convertEqualsOperatorFilter(condition, filter);
22
+ break;
23
+ case '!=':
24
+ //console.log('Operator !=');
25
+ this.convertNotEqualsOperatorFilter(condition, filter);
26
+ break;
27
+ case '>':
28
+ //console.log('Operator !=');
29
+ this.convertGreaterThanOperatorFilter(condition, filter);
30
+ break;
31
+ case '>=':
32
+ //console.log('Operator >=');
33
+ this.convertGreaterThanOrEqualOperatorFilter(condition, filter);
34
+ break;
35
+ case 'stars with':
36
+ //console.log('Operator >=');
37
+ this.convertStarsWithOperatorFilter(condition, filter);
38
+ break;
39
+ case 'contains':
40
+ //console.log('Operator >=');
41
+ this.convertContainsOperatorFilter(condition, filter);
42
+ break;
43
+ case 'is null':
44
+ //console.log('Operator >=');
45
+ this.convertIsUndefinedOperatorFilter(condition, filter);
46
+ break;
47
+ case 'is not null':
48
+ //console.log('Operator >=');
49
+ this.convertExistsOperatorFilter(condition, filter);
50
+ break;
51
+
52
+ default:
53
+ console.log('Operator default');
54
+ }
55
+
56
+ }
57
+ }
58
+
59
+ //console.log("qui2", query);
60
+
61
+ }
62
+
63
+ convertEqualsOperatorFilter(query, filter) {
64
+ query[filter.field] = filter.value;
65
+ }
66
+
67
+ convertNotEqualsOperatorFilter(query, filter) {
68
+ query[filter.field] = {"$ne": filter.value};
69
+ }
70
+
71
+ convertGreaterThanOperatorFilter(query, filter) {
72
+ query[filter.field] = {"$gt": filter.value};
73
+ }
74
+ convertGreaterThanOrEqualOperatorFilter(query, filter) {
75
+ query[filter.field] = {"$gte": filter.value};
76
+ }
77
+
78
+ convertStartWithOperatorFilter(query, filter) {
79
+ query[filter.field] = {"$regex": "/^"+filter.value+"/i"};
80
+ }
81
+ convertStartWithOperatorFilter(query, filter) {
82
+ query[filter.field] = {"$regex": "/^"+filter.value+"/i"};
83
+ }
84
+ convertContainsOperatorFilter(query, filter) {
85
+ query[filter.field] = {"$regex": filter.value};
86
+ }
87
+ convertIsUndefinedOperatorFilter(query, filter) {
88
+ query[filter.field] = {"$exists": false};
89
+ }
90
+ convertExistsOperatorFilter(query, filter) {
91
+ query[filter.field] = {"$exists": true};
92
+ }
93
+ }
94
+
95
+ var segment2MongoConverter = new Segment2MongoConverter();
96
+
97
+ module.exports = segment2MongoConverter;
98
+