Browse Source

select template based on language

activeAddress
Ivan Socolsky 9 years ago
parent
commit
044f511726
  1. 2
      config.js
  2. 91
      lib/emailservice.js
  3. 0
      lib/templates/en/new_copayer.plain
  4. 0
      lib/templates/en/new_incoming_tx.plain
  5. 0
      lib/templates/en/new_outgoing_tx.plain
  6. 0
      lib/templates/en/new_tx_proposal.plain
  7. 0
      lib/templates/en/txp_finally_rejected.plain
  8. 0
      lib/templates/en/wallet_complete.plain
  9. 2
      lib/templates/es/new_copayer.plain
  10. 2
      lib/templates/es/new_incoming_tx.plain
  11. 2
      lib/templates/es/new_outgoing_tx.plain
  12. 2
      lib/templates/es/new_tx_proposal.plain
  13. 2
      lib/templates/es/txp_finally_rejected.plain
  14. 2
      lib/templates/es/wallet_complete.plain
  15. 5
      test/integration/server.js

2
config.js

@ -52,6 +52,8 @@ var config = {
ignoreTLS: true, ignoreTLS: true,
subjectPrefix: '[Wallet Service]', subjectPrefix: '[Wallet Service]',
from: 'wallet-service@bitcore.io', from: 'wallet-service@bitcore.io',
templatePath: './lib/templates',
defaultLanguage: 'en',
}, },
}; };
module.exports = config; module.exports = config;

91
lib/emailservice.js

@ -7,6 +7,7 @@ var Mustache = require('mustache');
var log = require('npmlog'); var log = require('npmlog');
log.debug = log.verbose; log.debug = log.verbose;
var fs = require('fs'); var fs = require('fs');
var path = require('path');
var nodemailer = require('nodemailer'); var nodemailer = require('nodemailer');
var WalletUtils = require('bitcore-wallet-utils'); var WalletUtils = require('bitcore-wallet-utils');
@ -49,10 +50,32 @@ function EmailService() {};
EmailService.prototype.start = function(opts, cb) { EmailService.prototype.start = function(opts, cb) {
opts = opts || {}; opts = opts || {};
function _readDirectories(basePath, cb) {
fs.readdir(basePath, function(err, files) {
if (err) return cb(err);
async.filter(files, function(file, next) {
fs.stat(path.join(basePath, file), function(err, stats) {
return next(!err && stats.isDirectory());
});
}, function(dirs) {
return cb(null, dirs);
});
});
};
var self = this; var self = this;
self.defaultLanguage = opts.defaultLanguage || 'en';
self.templatePath = path.normalize((opts.templatePath || (__dirname + '/templates')) + '/');
async.parallel([ async.parallel([
function(done) {
_readDirectories(self.templatePath, function(err, res) {
self.availableLanguages = res;
done(err);
});
},
function(done) { function(done) {
if (opts.storage) { if (opts.storage) {
self.storage = opts.storage; self.storage = opts.storage;
@ -87,10 +110,13 @@ EmailService.prototype.start = function(opts, cb) {
// TODO: cache for X minutes // TODO: cache for X minutes
EmailService.prototype._readTemplate = function(filename, cb) { EmailService.prototype._readTemplate = function(filename, language, cb) {
fs.readFile(__dirname + '/templates/' + filename + '.plain', 'utf8', function(err, template) { var self = this;
var fullFilename = path.join(self.templatePath, language, filename + '.plain');
fs.readFile(fullFilename, 'utf8', function(err, template) {
if (err) { if (err) {
log.error('Could not read template file ' + filename, err); log.error('Could not read template file ' + fullFilename, err);
return cb(err); return cb(err);
} }
var lines = template.split('\n'); var lines = template.split('\n');
@ -126,9 +152,18 @@ EmailService.prototype._getRecipientsList = function(notification, emailType, cb
usedEmails[p.email] = true; usedEmails[p.email] = true;
if (notification.creatorId == p.copayerId && !emailType.notifyDoer) return; if (notification.creatorId == p.copayerId && !emailType.notifyDoer) return;
if (!_.contains(self.availableLanguages, p.language)) {
if (p.language) {
log.warn('Language for email "' + p.language + '" not available.');
}
p.language = self.defaultLanguage;
}
return { return {
copayerId: p.copayerId, copayerId: p.copayerId,
emailAddress: p.email emailAddress: p.email,
language: p.language,
unit: p.unit || 'btc',
}; };
})); }));
@ -189,6 +224,36 @@ EmailService.prototype._send = function(email, cb) {
}); });
}; };
EmailService.prototype._readAndApplyTemplates = function(notification, emailType, recipientsList, cb) {
var self = this;
async.waterfall([
function(next) {
self._getDataForTemplate(notification, next);
},
function(data, next) {
var languages = _.uniq(_.pluck(recipientsList, 'language'));
async.map(languages, function(lang, next) {
async.waterfall([
function(next) {
self._readTemplate(emailType.filename, lang, next);
},
function(template, next) {
self._applyTemplate(template, data, next);
},
], function(err, res) {
next(err, [lang, res]);
});
}, function(err, res) {
return next(err, _.zipObject(res));
});
},
], cb);
};
EmailService.prototype.sendEmail = function(notification, cb) { EmailService.prototype.sendEmail = function(notification, cb) {
var self = this; var self = this;
@ -211,23 +276,11 @@ EmailService.prototype.sendEmail = function(notification, cb) {
async.waterfall([ async.waterfall([
function(next) { function(next) {
async.parallel([ self._readAndApplyTemplates(notification, emailType, recipientsList, next);
function(next) {
self._readTemplate(emailType.filename, next);
},
function(next) {
self._getDataForTemplate(notification, next);
},
], function(err, res) {
next(err, res[0], res[1]);
});
},
function(template, data, next) {
self._applyTemplate(template, data, next);
}, },
function(content, next) { function(contents, next) {
async.map(recipientsList, function(recipient, next) { async.map(recipientsList, function(recipient, next) {
var content = contents[recipient.language];
var email = Model.Email.create({ var email = Model.Email.create({
walletId: notification.walletId, walletId: notification.walletId,
copayerId: recipient.copayerId, copayerId: recipient.copayerId,

0
lib/templates/new_copayer.plain → lib/templates/en/new_copayer.plain

0
lib/templates/new_incoming_tx.plain → lib/templates/en/new_incoming_tx.plain

0
lib/templates/new_outgoing_tx.plain → lib/templates/en/new_outgoing_tx.plain

0
lib/templates/new_tx_proposal.plain → lib/templates/en/new_tx_proposal.plain

0
lib/templates/txp_finally_rejected.plain → lib/templates/en/txp_finally_rejected.plain

0
lib/templates/wallet_complete.plain → lib/templates/en/wallet_complete.plain

2
lib/templates/es/new_copayer.plain

@ -0,0 +1,2 @@
{{subjectPrefix}}Nuevo copayer
Un nuevo copayer ha ingresado a su monedero {{walletName}}.

2
lib/templates/es/new_incoming_tx.plain

@ -0,0 +1,2 @@
{{subjectPrefix}}Nuevo pago recibido
Un pago de {{amount}} fue recibido en su monedero {{walletName}}.

2
lib/templates/es/new_outgoing_tx.plain

@ -0,0 +1,2 @@
{{subjectPrefix}}Pago enviado
Un pago de {{amount}} ha sido enviado de su monedero {{walletName}}.

2
lib/templates/es/new_tx_proposal.plain

@ -0,0 +1,2 @@
{{subjectPrefix}}Nueva propuesta de pago
Una nueva propuesta de pago ha sido creada en su monedero {{walletName}} por {{copayerName}}.

2
lib/templates/es/txp_finally_rejected.plain

@ -0,0 +1,2 @@
{{subjectPrefix}}Propuesta de pago rechazada
Una propuesta de pago en su monedero {{walletName}} ha sido rechazada por {{rejectorsNames}}.

2
lib/templates/es/wallet_complete.plain

@ -0,0 +1,2 @@
{{subjectPrefix}}Monedero completo
Su monedero {{walletName}} está completo.

5
test/integration/server.js

@ -308,7 +308,7 @@ describe('Wallet service', function() {
WalletService.shutDown(done); WalletService.shutDown(done);
}); });
describe.only('Email notifications', function() { describe('Email notifications', function() {
var server, wallet, mailerStub, emailService; var server, wallet, mailerStub, emailService;
beforeEach(function(done) { beforeEach(function(done) {
@ -543,9 +543,10 @@ describe('Wallet service', function() {
}); });
}); });
it('should build each email using preferences of the copayers', function(done) { it.only('should build each email using preferences of the copayers', function(done) {
// Set same email address for copayer1 and copayer2 // Set same email address for copayer1 and copayer2
server.savePreferences({ server.savePreferences({
email: 'copayer1@domain.com',
language: 'es', language: 'es',
unit: 'btc', unit: 'btc',
}, function(err) { }, function(err) {

Loading…
Cancel
Save