17a33303bfd14601422f68e8f5b6986b223206bf
[motion.git] / server / api / xchatty / xchatty.controller.js
1 'use strict';
2
3 var _ = require('lodash');
4 var jsmin = require('jsmin').jsmin;
5 var Mustache = require('mustache');
6 var querystring = require('querystring');
7 var path = require('path');
8 var md5 = require('md5');
9 var fs = require('fs');
10 var UAParser = require('ua-parser-js');
11 var uaParser = new UAParser();
12 var languageParser = require('accept-language-parser');
13 var ipaddr = require('ipaddr.js');
14 var geoip = require('geoip-lite');
15 var csv = require('to-csv')
16
17 var config = require('../../config/environment');
18 var Xchatty = require('../../models').Xchatty;
19 var xchatty_components = require('../../components/xchatty');
20
21 var sequelize = require('../../models').sequelize;
22 var User = require('../../models').User;
23 var Agent = require('../../models').User;
24 var ChatRoom = require('../../models').ChatRoom;
25 var ChatEnquiry = require('../../models').ChatEnquiry;
26 var ChatVisitor = require('../../models').ChatVisitor;
27 var ChatMessage = require('../../models').ChatMessage;
28 var ChatWebsite = require('../../models').ChatWebsite;
29
30 var id = 1;
31
32 // var ip = addr.toIPv4Address().octets.join('.');
33
34 // Get list of xchattys
35 exports.index = function (req, res, next) {
36   Xchatty
37     .findAll()
38     .then(function (xchattys) {
39       return res.status(200).send(xchattys);
40     })
41     .catch(function (err) {
42       return next(err);
43     });
44 };
45
46 exports.getJsByWebsite = function (req, res, next) {
47
48   // TO DO: Find the configuration of the website and replace configuration in the file
49   ChatWebsite
50     .findById(req.params.id)
51     .then(function (chatWebsite) {
52       res.set({
53         'Content-Type': 'application/javascript',
54         'x-timestamp': Date.now(),
55         'x-sent': true
56       });
57
58       var js = xchatty_components.js;
59       /*jshint multistr: true */
60       var configJS = {
61         websiteId: req.params.id,
62         // rootPath: path.join(chatWebsite.remote, 'api', 'xchatty/'),
63         rootPath: chatWebsite.remote + '/api/xchatty/',
64         signedUp: 'false',
65         windowFocused: 'false',
66         isNewPage: 'true',
67         processingSignUp: 'false',
68         processingEnquiry: 'false',
69         processingSend: 'false',
70         visitorFullname: '""',
71         visitorAvatar: '""',
72         timerReadMessages: 'null',
73         timerCheckStatus: 'null',
74         isOnline: 'false',
75         decayHistory: 0,
76         defaultTimeout: 2000,
77         isInitialStatusCheck: 'true',
78         muteNotificationSoundOnce: 'false',
79         assetBase: chatWebsite.remote + '/api/xchatty/assets',
80         hasSessionSaf: 'false',
81         restoreOpenState: 'false',
82         animateHover: chatWebsite.animation,
83         hideEmail: 'false',
84         hideOffline: 'false',
85         headerShape: chatWebsite.header_shape,
86         HeaderOnline: chatWebsite.header_online,
87         OnlineMessage: chatWebsite.online_message,
88         UsernamePlaceholder: chatWebsite.username_placeholder,
89         EmailPlaceholder: chatWebsite.email_placeholder,
90         StartChatButtonText: chatWebsite.start_chat_button,
91         OfflineMessage: chatWebsite.offline_message,
92         HeaderOffline: chatWebsite.header_offline,
93         EnquiryMessagePlaceholder: chatWebsite.enquiry_message_placeholder,
94         EnquiryButtonText: chatWebsite.enquiry_button,
95         downloadTranscript: chatWebsite.download_transcript
96       };
97
98       js = Mustache.render(js, configJS);
99       res.send(js);
100
101     })
102     .catch(function (err) {
103       next(err);
104     });
105
106 };
107
108 exports.getStyleByWebsite = function (req, res, next) {
109
110   // TO DO: Find the configuration of the website and replace configuration in the file
111   ChatWebsite
112     .findById(req.params.id)
113     .then(function (chatWebsite) {
114
115       res.set({
116         'Content-Type': 'text/css',
117         'x-timestamp': Date.now(),
118         'x-sent': true
119       });
120
121       var css = xchatty_components.css;
122
123       var configCSS = {
124         // assetBase: path.join(chatWebsite.remote, 'api', 'xchatty',
125         //   'assets'),
126         assetBase: chatWebsite.remote + '/api/xchatty/assets',
127         color: chatWebsite.color,
128         colorFocus: chatWebsite.color_focus,
129         colorButton: chatWebsite.color_button
130       };
131
132       css = Mustache.render(css, configCSS);
133       res.send(css);
134     })
135     .catch(function (err) {
136       next(err);
137     });
138 };
139
140 exports.getAssets = function (req, res, next) {
141   res.download(path.join(config.root, 'server', 'components', 'xchatty', 'assets', req.query.resource));
142 };
143
144 exports.getJqueryLibrary = function (req, res, next) {
145
146   // TODO: Find the configuration of the website and replace configuration in the file
147   res.set({
148     'Content-Type': 'application/javascript',
149     'x-timestamp': Date.now(),
150     'x-sent': true
151   });
152
153   var jquery = xchatty_components.jquery;
154   res.send(jquery);
155
156 };
157
158 exports.getStatus = function (req, res, next) {
159
160   if (!req.session.xchatty) {
161     req.session.xchatty = {};
162   }
163   // Get all users (later agents) online in the interface
164   Agent
165     .findAll({
166       where: {
167         online: true,
168         role: 'agent'
169       }
170     })
171     .then(function (users) {
172
173       if (req.query.data.open_state)
174         req.session.xchatty.open_state = req.query.data.open_state === 'true' ? true : false;
175
176       var jsonResponse = {
177         success: true,
178         has_session_saf: null,
179         signed_up: req.session.xchatty.room_id ? true : false,
180         fullname: req.session.xchatty.fullname ? req.session.xchatty.fullname : '',
181         email: req.session.xchatty.email ? req.session.xchatty.email : '',
182         avatar: req.session.xchatty.avatar ? req.session.xchatty.avatar : '',
183         open_state: req.session.xchatty.open_state || req.session.xchatty.room_id ? true : false,
184         online: users.length ? true : false
185       };
186
187       if (req.session.xchatty.visitor_id) {
188         ChatRoom
189           .findOne({
190             where: {
191               ChatVisitorId: req.session.xchatty.visitor_id,
192               status: 'open'
193             }
194           })
195           .then(function (chatRoom) {
196             if (chatRoom) {
197               req.session.xchatty.room_id = chatRoom.id;
198               jsonResponse.signed_up = true;
199             } else {
200               jsonResponse.signed_up = false;
201             }
202
203             res.send(req.query.callback + '(' + JSON.stringify(jsonResponse) + ')');
204           })
205           .catch(function (err) {
206             next(err);
207           });
208       } else {
209         res.send(req.query.callback + '(' + JSON.stringify(jsonResponse) + ')');
210       }
211
212     })
213     .catch(function (err) {
214       return next(err);
215     });
216 };
217
218 exports.getMessages = function (req, res, next) {
219
220   /*jshint multistr: true */
221   var condition = {
222     where: {
223       ChatRoomId: req.session.xchatty.room_id
224     },
225     include: [{
226       model: User,
227       attributes: ['id', 'name', 'fullname', 'email']
228     }, {
229       model: ChatVisitor,
230       attributes: ['id', 'fullname', 'email']
231     }]
232   };
233
234   if (req.query.data.is_new_page === 'false') {
235     condition.where.id = {
236       $gt: req.query.data.last_id
237     };
238   }
239
240   ChatMessage
241     .findAll(condition)
242     .then(function (chatMessages) {
243       var json = {
244         success: true,
245         messages: chatMessages,
246         composing: false,
247         composing_fullname: null
248       };
249
250       res.send(req.query.callback + '(' + JSON.stringify(json) + ')');
251     })
252     .catch(function (err) {
253       next(err);
254     });
255 };
256
257 exports.sendMessage = function (req, res, next) {
258
259   /*jshint multistr: true */
260   var condition = {
261     where: {
262       ChatRoomId: req.session.xchatty.room_id
263     },
264     include: [{
265       model: User,
266       attributes: ['id', 'name', 'fullname', 'email']
267     }, {
268       model: ChatVisitor,
269       attributes: ['id', 'fullname', 'email']
270     }]
271   };
272
273   if (req.query.data.is_new_page === 'false') {
274     condition.where.id = {
275       $gt: req.query.data.last_id
276     };
277   }
278
279   ChatMessage
280     .create({
281       body: req.query.data.Message.message,
282       ChatRoomId: req.session.xchatty.room_id,
283       ChatVisitorId: req.session.xchatty.visitor_id
284     })
285     .then(function (chatMessage) {
286       console.log('chatMessage', chatMessage);
287       ChatMessage
288         .findAll(condition)
289         .then(function (chatMessages) {
290           var json = {
291             errors: [],
292             success: true,
293             data: chatMessage,
294             messages: chatMessages
295           };
296
297           res.send(req.query.callback + '(' + JSON.stringify(json) + ')');
298         })
299         .catch(function (err) {
300           next(err);
301         });
302     })
303     .catch(function (err) {
304       next(err);
305     });
306
307 };
308
309 exports.signoutCustomer = function (req, res, next) {
310
311   ChatRoom
312     .findById(req.session.xchatty.room_id)
313     .then(function (chatRoom) {
314       chatRoom.updateAttributes({
315           status: 'close'
316         })
317         .then(function (chatRoom) {
318           var json = {
319             success: true,
320             errors: []
321           };
322           req.session.xchatty = {};
323           res.send(req.query.callback + '(' + JSON.stringify(json) + ')');
324         })
325         .catch(function (err) {
326           next(err);
327         })
328     })
329     .catch(function (err) {
330       next(err);
331     });
332 };
333
334 exports.signupCustomer = function (req, res, next) {
335   var ua = uaParser.setUA(req.headers['user-agent']).getResult();
336   var languages = languageParser.parse(req.headers['accept-language']);
337   // var addr = ipaddr.parse(req.connection.remoteAddress);
338
339   // var ipv4Addr = "151.0.175.186";
340   // var geo = geoip.lookup(ipv4Addr);
341
342   var body = {
343     fullname: req.query.data.Discussion.fullname,
344     email: req.query.data.Discussion.email,
345     // remote_address: addr,
346     remote_address: req.connection.remoteAddress,
347     user_agent: req.headers['user-agent'],
348     visitor_language: req.headers['accept-language'],
349     referer: req.headers.referer,
350     origin: 'webchat',
351     browser: ua.browser.name + ' ' + ua.browser.version,
352     engine: ua.engine.name + ' ' + ua.engine.version,
353     os: ua.os.name + ' ' + ua.os.version,
354     device: ua.device.model ? ua.device.model + ' ' + ua.device.vendor + ' ' + ua.device.type : null,
355     // country: geo.country,
356     // city: geo.city,
357     // region: geo.region,
358     // latitude: geo.ll.length ? geo.ll[0].toString() : null,
359     // longitude: geo.ll.length ? geo.ll[1].toString() : null,
360     ChatWebsiteId: req.query.chatWebsiteId
361   };
362
363   return ChatVisitor
364     .create(body)
365     .then(function (chatVisitor) {
366
367       req.session.xchatty.fullname = chatVisitor.fullname;
368       req.session.xchatty.email = chatVisitor.email;
369       req.session.xchatty.avatar = md5(chatVisitor.email).toString('base64');
370       req.session.xchatty.visitor_id = chatVisitor.id;
371
372       var json = {
373         success: true,
374         errors: [],
375         chatVisitor: {
376           id: chatVisitor.id
377         }
378       };
379
380       /*jshint multistr: true */
381       res.send(req.query.callback + '(' + JSON.stringify(json) + ')');
382     })
383     .catch(function (err) {
384       next(err);
385     });
386 };
387
388 exports.unservedCustomer = function (req, res, next) {
389
390   ChatVisitor
391     .findById(req.session.xchatty.visitor_id)
392     .then(function (chatVisitor) {
393
394       chatVisitor.updateAttributes({
395           status: 'unserved'
396         }).then(function () {
397           var json = {
398             success: true,
399             errors: []
400           };
401           req.session.xchatty = {};
402           res.send(req.query.callback + '(' + JSON.stringify(json) + ')');
403         })
404         .catch(function (err) {
405           next(err);
406         });
407     })
408     .catch(function (err) {
409       next(err);
410     });
411 };
412
413 exports.submitEnquiry = function (req, res, next) {
414
415   var _chatVisitor;
416   var _chatEnquiry;
417
418   return sequelize.transaction().then(function (t) {
419
420     return ChatVisitor
421       .create({
422         fullname: req.query.data.Enquiry.fullname,
423         email: req.query.data.Enquiry.email,
424         remote_address: req.connection.remoteAddress,
425         user_agent: req.headers['user-agent'],
426         visitor_language: req.headers['accept-language'],
427         referer: req.headers.referer,
428         origin: 'enquiry',
429         status: 'unserved'
430       }, {
431         transaction: t
432       })
433       .then(function (chatVisitor) {
434         _chatVisitor = chatVisitor;
435         return ChatEnquiry
436           .create({
437             username: req.query.data.Enquiry.fullname,
438             email: chatVisitor.email,
439             text: req.query.data.Enquiry.message,
440             ChatWebsiteId: parseInt(req.query.data.Enquiry.websiteId, 10),
441             ChatVisitorId: _chatVisitor.id
442           }, {
443             include: [{
444               all: true,
445               include: [{
446                 all: true
447               }]
448             }],
449             transaction: t
450           });
451       })
452       .then(function () {
453         t.commit();
454         res.send(req.query.callback + '(' + JSON.stringify({
455           success: true,
456           errors: []
457         }) + ')');
458       })
459       .catch(function (err) {
460         t.rollback();
461         next(err);
462       });
463   });
464 };
465
466 exports.getTranscript = function (req, res, next) {
467   if (req.session.xchatty && req.session.xchatty.visitor_id && req.session.xchatty
468     .room_id) {
469     ChatMessage
470       .findAll({
471         where: {
472           ChatRoomId: req.session.xchatty.room_id
473         }
474       })
475       .then(function (chatMessages) {
476
477         var chatMessageForCSV = [];
478         chatMessages.forEach(function (chatMessage) {
479           var chatMsg = {
480             name: chatMessage.fullname,
481             text: chatMessage.body.replace(/(\r\n|\n|\r)/gm, " "),
482             date: chatMessage.createdAt
483           };
484           chatMessageForCSV.push(chatMsg);
485         });
486         var csv_transcript = csv(chatMessageForCSV);
487         res.type('text/csv').status(200).send(csv_transcript);
488       })
489       .catch(function (err) {
490         next(err);
491       });
492   }
493 };
494
495 // Get a single xchatty
496 exports.show = function (req, res, next) {
497   Xchatty
498     .findById(req.params.id)
499     .then(function (xchatty) {
500       if (!xchatty) {
501         return res.sendStatus(404);
502       }
503       return res.send(xchatty);
504     })
505     .catch(function (err) {
506       return next(err);
507     });
508 };
509
510 // Creates a new xchatty in the DB.
511 exports.create = function (req, res, next) {
512   Xchatty
513     .create(req.body)
514     .then(function (xchatty) {
515       return res.status(201).send(xchatty);
516     })
517     .catch(function (err) {
518       return next(err);
519     });
520 };
521
522 // Updates an existing xchatty in the DB.
523 exports.update = function (req, res, next) {
524   if (req.body.id) {
525     delete req.body.id;
526   }
527   Xchatty
528     .findById(req.params.id)
529     .then(function (xchatty) {
530       if (!xchatty) {
531         return res.sendStatus(404);
532       }
533       var updated = _.merge(xchatty, req.body);
534       updated.save()
535         .then(function () {
536           return res.status(200).send(xchatty);
537         })
538         .catch(function (err) {
539           return next(err);
540         });
541     })
542     .catch(function (err) {
543       return next(err);
544     });
545 };
546
547 // Deletes a xchatty from the DB.
548 exports.destroy = function (req, res, next) {
549   Xchatty
550     .findById(req.params.id)
551     .then(function (xchatty) {
552       if (!xchatty) {
553         return res.sendStatus(404);
554       }
555       xchatty.destroy()
556         .then(function () {
557           return res.sendStatus(204);
558         })
559         .catch(function (err) {
560           return next(err);
561         });
562     })
563     .catch(function (err) {
564       return next(err);
565     });
566 };