Notification rest, mail log and error catch
This commit is contained in:
parent
60c46b5fb7
commit
4c9383038f
|
@ -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": ""
|
||||||
|
|
|
@ -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)}});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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 -->
|
||||||
|
|
||||||
|
|
|
@ -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: {}});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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: {}});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue