Notification rest, mail log and error catch

This commit is contained in:
Joan Sanchez 2017-08-31 16:11:37 +02:00
parent 60c46b5fb7
commit 4c9383038f
11 changed files with 244 additions and 40 deletions

View File

@ -2,7 +2,7 @@
"name": "MailServer", "name": "MailServer",
"version": "1.0.0", "version": "1.0.0",
"port": 3003, "port": 3003,
"debug": true, "debug": false,
"defaultLanguage": "es", "defaultLanguage": "es",
"senderMail": "noreply@localhost", "senderMail": "noreply@localhost",
"senderName": "" "senderName": ""

View File

@ -4,9 +4,9 @@ var path = require('path');
module.exports = { module.exports = {
/** /**
* Devuelve las claves de idioma de una plantilla * Returns template locale
* @param {String} template - Nombre de la plantilla * @param {String} template - Template name
* @param {String} countryCode - Código de idioma * @param {String} countryCode - Language code
* @param {Object} cb - Callback * @param {Object} cb - Callback
*/ */
load: function(template, countryCode, cb) { load: function(template, countryCode, cb) {
@ -14,13 +14,16 @@ module.exports = {
var defaultLocaleFile = path.join(__dirname, 'template', `${template}`, 'locale', `${settings.app().defaultLanguage}.json`); var defaultLocaleFile = path.join(__dirname, 'template', `${template}`, 'locale', `${settings.app().defaultLanguage}.json`);
fs.stat(localeFile, (error, stats) => { fs.stat(localeFile, (error, stats) => {
if (error) if (error) {
fs.stat(defaultLocaleFile, (error, stats) => { fs.stat(defaultLocaleFile, (error, stats) => {
if (error) if (error)
cb(null, 'Translation not found for template ' + template + '.'); return cb({status: 'REJECT', data: {message: 'Translation not found for template ' + template + '.'}});
return cb(require(defaultLocaleFile));
cb({status: 'ACCEPT', data: {locale: require(defaultLocaleFile)}});
}); });
return cb(require(localeFile)); } else {
cb({status: 'ACCEPT', data: {locale: require(localeFile)}});
}
}); });
} }
}; };

View File

@ -1,6 +1,7 @@
var nodemailer = require('nodemailer'); var nodemailer = require('nodemailer');
var settings = require('./settings.js'); var settings = require('./settings.js');
var template = require('./template.js'); var template = require('./template.js');
var database = require('./database.js');
/** /**
* Mail module * Mail module
@ -28,9 +29,10 @@ module.exports = {
* @param {String} subject - Subject * @param {String} subject - Subject
* @param {String} body - Mail body * @param {String} body - Mail body
* @param {Object} attachments - Mail attachments * @param {Object} attachments - Mail attachments
* @param {Object} params - Params
* @param {Object} cb - Callback * @param {Object} cb - Callback
*/ */
send: function(recipient, subject, body, attachments, cb) { send: function(recipient, subject, body, attachments, params, cb) {
let mailOptions = { let mailOptions = {
from: '"' + settings.app().senderName + '" <' + settings.app().senderMail + '>', from: '"' + settings.app().senderName + '" <' + settings.app().senderMail + '>',
to: recipient, to: recipient,
@ -39,16 +41,20 @@ module.exports = {
attachments attachments
}; };
if (process.env.NODE_ENV !== 'production') { if (settings.app().debug) {
mailOptions.to = settings.testEmail; mailOptions.to = settings.testEmail;
} }
this.transporter.sendMail(mailOptions, (error, info) => { this.transporter.sendMail(mailOptions, (error, info) => {
if (error) { let status = (error ? error.message : 'OK');
this.log(params.sender, params.recipient, recipient, subject, body, params.message, status);
if (error)
return cb({status: 'REJECT', data: {message: 'Email not sent: ' + error}}); return cb({status: 'REJECT', data: {message: 'Email not sent: ' + error}});
} else if (settings.app().debug) {
if (settings.app().debug)
console.log('Mail sent ' + info.messageId + ' [' + info.response + ']'); console.log('Mail sent ' + info.messageId + ' [' + info.response + ']');
}
cb({status: 'ACCEPT', data: {message: 'Email sent'}}); cb({status: 'ACCEPT', data: {message: 'Email sent'}});
}); });
}, },
@ -60,10 +66,34 @@ module.exports = {
* @param {Object} cb - Callback * @param {Object} cb - Callback
*/ */
sendWithTemplate: function(tplName, params, cb) { sendWithTemplate: function(tplName, params, cb) {
template.get(tplName, params, data => { template.get(tplName, params, result => {
this.send(data.recipient, data.subject, data.body, data.attachments, result => { if (result.status == 'REJECT')
return cb(result);
this.send(result.data.recipient, result.data.subject, result.data.body, result.data.attachments, params, result => {
cb(result); cb(result);
}); });
}); });
},
/**
* Add mail log
* @param {Integer} senderId - Sender id
* @param {Integer} recipientId - Recipient id
* @param {String} sender - Sender email
* @param {String} subject - Mail subject
* @param {String} body - Mail body
* @param {String} plainTextBody - Mail plain text body
* @param {String} status - Mail status
*/
log: function(senderId, recipientId, sender, subject, body, plainTextBody, status) {
let qry = `INSERT INTO mail(senderFk, recipientFk, sender, replyTo, subject, body, plainTextBody, sent, status)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`;
let qryParams = [senderId, recipientId, sender, settings.app().senderMail, subject, body, plainTextBody, 1, status];
database.pool.query(qry, qryParams, function(error, result) {
if (settings.app().debug && error)
console.log('Mail log: ' + error);
});
} }
}; };

View File

@ -2,9 +2,9 @@ var express = require('express');
var router = new express.Router(); var router = new express.Router();
var mail = require('../mail.js'); var mail = require('../mail.js');
// Escrito de cambios en méto de pago del cliente // Payment method changes
router.post('/:userFk/payment-update', function(request, response, next) { router.post('/:recipient/payment-update', function(request, response, next) {
mail.sendWithTemplate('payment-update', {userId: request.params.userFk}, result => { mail.sendWithTemplate('payment-update', {recipient: request.params.recipient}, result => {
return response.json(result); return response.json(result);
}); });
}); });

View File

@ -1,12 +1,66 @@
var express = require('express'); var express = require('express');
var router = new express.Router(); var router = new express.Router();
var mail = require('../mail.js'); var mail = require('../mail.js');
var database = require('../database.js');
router.get('/:userFk/noticeUserSend', function(request, response) { // Single user notification
router.post('/:recipient/noticeUserSend', function(request, response) {
var params = {
recipient: request.params.recipient,
sender: request.body.sender,
category: request.body.category,
message: request.body.message
};
if (params.sender == params.recipient)
return;
let query = `SELECT COUNT(*) isEnabled
FROM noticeSubscription s
JOIN noticeCategory c ON c.id = s.noticeCategoryFk AND c.isEnabled
WHERE c.keyName = ? AND s.userFk = ?`;
database.pool.query(query, [params.category, params.recipient, params.sender], (error, result) => {
mail.sendWithTemplate('notice', params, result => {
return response.json(result);
});
});
}); });
router.get('/:categoryFk/noticeCategorySend', function(request, response) { // Send notification to all user subscribed to category
router.post('/:category/noticeCategorySend', function(request, response) {
var params = {
sender: request.body.sender,
category: request.params.category,
message: request.body.message
};
let query = `SELECT s.userFk id FROM noticeSubscription s JOIN noticeCategory
c ON c.id = s.noticeCategoryFk AND c.isEnabled WHERE c.keyName = ? AND s.userFk != ?`;
database.pool.query(query, [params.category, params.sender], (error, result) => {
result.forEach(function(user) {
params.recipient = user.id;
mail.sendWithTemplate('notice', params, result => {
return response.json(result);
});
}, this);
});
});
// Send system notification
router.post('/:recipient/noticeSystemSend', function(request, response) {
var params = {
recipient: request.params.recipient,
sender: 50069, // verdnatura
category: request.body.category,
message: request.body.message
};
mail.sendWithTemplate('notice', params, result => {
return response.json(result);
});
}); });
module.exports = router; module.exports = router;

View File

@ -28,7 +28,7 @@ module.exports = {
this.renderStyles(stylePath, body, body => { this.renderStyles(stylePath, body, body => {
var titleSubject = body.match(new RegExp('<title>(.*?)</title>', 'i'))[1]; var titleSubject = body.match(new RegExp('<title>(.*?)</title>', 'i'))[1];
this.getAttachments(template, body, attachments => { this.getAttachments(template, body, attachments => {
cb({recipient: instance.email, subject: titleSubject, body: body, attachments: attachments}); cb({status: 'ACCEPT', data: {recipient: instance.recipient, subject: titleSubject, body: body, attachments: attachments}});
}); });
}); });
}; };
@ -37,10 +37,16 @@ module.exports = {
this.render(templatePath, instance, body => getRenderedStyles(body)); this.render(templatePath, instance, body => getRenderedStyles(body));
}; };
instance.getData(params, () => { instance.getData(params, result => {
locale.load(template, instance.countryCode, (translations, error) => { if (result.status == 'REJECT')
instance._ = translations; return cb(result);
getDataCb();
locale.load(template, instance.countryCode, result => {
if (result.status == 'REJECT')
return cb(result);
instance._ = result.data.locale;
getDataCb(result);
}); });
}); });
}); });

View File

@ -2,7 +2,9 @@
"subject": "Has recibido una nueva notificación", "subject": "Has recibido una nueva notificación",
"title": "Nueva notificación", "title": "Nueva notificación",
"hello": "Hola", "hello": "Hola",
"bodyDescription": "test", "bodyDescription": "Has recibido la siguiente notificación de",
"noticeDescription": "Recibes esta notificación porque estás suscrito a",
"unsubscribe": "Puedes dejar de recibir estas notificaciones desde 'Notificaciones > Configuración' en cualquier aplicación de VerdNatura.",
"actionButton": "Visita nuestra Web", "actionButton": "Visita nuestra Web",
"infoButton": "Ayúdanos a mejorar", "infoButton": "Ayúdanos a mejorar",
"fiscalAddress": "VERDNATURA LEVANTE SL, B97367486 Avda. Espioca, 100, 46460 Silla _ www.verdnatura.es _ clientes@verdnatura.es", "fiscalAddress": "VERDNATURA LEVANTE SL, B97367486 Avda. Espioca, 100, 46460 Silla _ www.verdnatura.es _ clientes@verdnatura.es",

View File

@ -0,0 +1,92 @@
img {
margin: 0
}
.wrapper {
background-color: #EEE
}
.container {
font-family: arial, sans-serif;
max-width: 600px;
min-width: 320px;
font-size: 16px;
margin: 0 auto;
color: #555
}
.banner img {
width: 100%
}
.title {
background-color: #95d831;
text-align: center;
padding: 35px 0
}
.title h1 {
font-size: 32px;
color: #333;
margin: 0
}
.body {
background-color:#FFF;
padding: 20px
}
.buttons {
background-color: #FFF;
text-align: center;
width: 100%
}
.buttons a {
text-decoration: none;
font-size: 18px;
color: #fff
}
.buttons .btn {
background-color: #333;
min-width: 300px;
height: 72px;
display: inline-block;
text-align: center
}
.buttons .btn .text {
display: inline-block;
padding-top: 22px
}
.buttons .btn .icon {
background-color: #95d831;
text-align: center;
padding-top: 22px;
float: right;
height: 50px;
width: 70px
}
.footer {
background-color: #555;
text-align: center;
padding: 20px 0
}
.footer a {
text-decoration: none;
margin-right: 5px
}
.footer a img {
margin: 0
}
.privacy {
padding: 20px 0;
font-size: 10px;
font-weight: 100
}

View File

@ -20,8 +20,10 @@
<!-- Mail body block --> <!-- Mail body block -->
<div style="padding: 20px 0"> <div style="padding: 20px 0">
<p style="text-align: justify">Hola, {{username}}</p> <p style="text-align: justify">Hola, {{recipientName}}</p>
<p style="text-align: justify">{{_.bodyDescription}}</p> <p style="text-align: justify">{{_.bodyDescription}} <strong>{{senderName}}</strong>:</p>
<p style="text-align: justify;font-size: 22px">"{{message}}"<p>
<p style="text-align: justify">{{_.noticeDescription}} <strong>'{{categoryName}}'</strong>. {{_.unsubscribe}}</p>
</div> </div>
<!-- Mail body block end --> <!-- Mail body block end -->

View File

@ -3,12 +3,26 @@ var database = require(path.join(__dirname, '../../database.js'));
module.exports = class Notice { module.exports = class Notice {
getData(params, cb) { getData(params, cb) {
let query = `SELECT c. Cliente FROM Clientes AS c WHERE Id_Cliente = ?`; let query = `SELECT
database.pool.query(query, [params.userId], (error, result) => { LOWER(ct.code) countryCode,
c.email recipient,
nc.name categoryName,
recipient.name recipientName,
sender.name senderName
FROM client c
JOIN account.user recipient ON recipient.id = c.id
JOIN country ct ON ct.id = c.countryFk
JOIN noticeCategory nc ON nc.keyName = ?
JOIN account.user sender ON sender.id = ?
WHERE c.id = ?`;
database.pool.query(query, [params.category, params.sender, params.recipient], (error, result) => {
if (error || result.length == 0)
return cb({status: 'REJECT', data: {message: 'No data found', error: error}});
Object.assign(this, result[0]); Object.assign(this, result[0]);
cb(); this.message = params.message;
cb({status: 'ACCEPT', data: {}});
}); });
} }
}; };

View File

@ -10,16 +10,17 @@ module.exports = class PaymentUpdate {
c.dueDay, c.dueDay,
c.iban, c.iban,
LOWER(ct.code) countryCode, LOWER(ct.code) countryCode,
email c.email recipient
FROM FROM client c
client c
JOIN payMethod pm ON pm.id = c.paymentMethodFk JOIN payMethod pm ON pm.id = c.paymentMethodFk
JOIN country ct ON ct.id = c.countryFk JOIN country ct ON ct.id = c.countryFk
WHERE WHERE c.id = ?`;
c.id = ?`; database.pool.query(query, [params.recipient], (error, result) => {
database.pool.query(query, [params.userId], (error, result) => { if (error || result.length == 0)
return cb({status: 'REJECT', data: {message: 'No data found', error: error}});
Object.assign(this, result[0]); Object.assign(this, result[0]);
cb(); cb({status: 'ACCEPT', data: {}});
}); });
} }