diff --git a/lib/emailservice.js b/lib/emailservice.js index 3153374..6742071 100644 --- a/lib/emailservice.js +++ b/lib/emailservice.js @@ -38,6 +38,7 @@ function EmailService(opts) { this.storage = opts.storage; this.lock = opts.lock; this.mailer = opts.mailer || nodemailer.createTransport(opts.email); + this.subjectPrefix = opts.email.subjectPrefix || '[Wallet service]'; this.from = opts.email.from; $.checkState(this.mailer); @@ -95,6 +96,7 @@ EmailService.prototype._getDataForTemplate = function(notification, cb) { var self = this; var data = _.cloneDeep(notification.data); + data.subjectPrefix = _.trim(self.subjectPrefix) + ' '; self.storage.fetchWallet(notification.walletId, function(err, wallet) { if (err) return cb(err); data.walletId = wallet.id; @@ -175,7 +177,14 @@ EmailService.prototype.sendEmail = function(notification, cb) { }, function(emails, next) { async.each(emails, function(email, next) { - self._send(email, next); + self._send(email, function(err) { + if (err) { + email.setFail(); + } else { + email.setSent(); + } + self.storage.storeEmail(email, next); + }); }, function(err) { return next(); }); diff --git a/lib/model/email.js b/lib/model/email.js index 8671038..2d30f07 100644 --- a/lib/model/email.js +++ b/lib/model/email.js @@ -23,7 +23,7 @@ Email.create = function(opts) { x.body = opts.body; x.status = 'pending'; x.attempts = 0; - x.sentOn = null; + x.lastAttemptOn = null; return x; }; @@ -40,9 +40,23 @@ Email.fromObj = function(obj) { x.body = obj.body; x.status = obj.status; x.attempts = obj.attempts; - x.sentOn = obj.sentOn; + x.lastAttemptOn = obj.lastAttemptOn; return x; }; +Email.prototype._logAttempt = function(result) { + this.attempts++; + this.lastAttemptOn = Math.floor(Date.now() / 1000); + this.status = result; +}; + +Email.prototype.setSent = function() { + this._logAttempt('sent'); +}; + +Email.prototype.setFail = function() { + this._logAttempt('fail'); +}; + module.exports = Email; diff --git a/lib/server.js b/lib/server.js index 42584ad..96d5a44 100644 --- a/lib/server.js +++ b/lib/server.js @@ -82,6 +82,7 @@ WalletService.initialize = function(opts, cb) { }; function initEmailService(cb) { + if (!opts.mailer && !opts.email) return cb(); emailService = new EmailService({ lock: lock, storage: storage, diff --git a/lib/storage.js b/lib/storage.js index b340f3e..15a512a 100644 --- a/lib/storage.js +++ b/lib/storage.js @@ -402,7 +402,7 @@ Storage.prototype.fetchUnsentEmails = function(cb) { status: 'pending', }).toArray(function(err, result) { if (err) return cb(err); - if (!result) return cb(); + if (!result || _.isEmpty(result)) return cb(null, []); return cb(null, Model.Email.fromObj(result)); }); }; diff --git a/test/integration/server.js b/test/integration/server.js index 21cc116..5982cba 100644 --- a/test/integration/server.js +++ b/test/integration/server.js @@ -3114,11 +3114,20 @@ describe('Wallet service', function() { should.not.exist(err); var calls = sendMailStub.getCalls(); calls.length.should.equal(2); - var recipients = _.pluck(_.map(calls, function(c) { + var emails = _.map(calls, function(c) { return c.args[0]; - }), 'to'); - _.difference(['copayer1@domain.com', 'copayer2@domain.com'], recipients).should.be.empty; - done(); + }); + _.difference(['copayer1@domain.com', 'copayer2@domain.com'], _.pluck(emails, 'to')).should.be.empty; + var one = emails[0]; + one.from.should.equal('bws@dummy.net'); + one.subject.should.contain('New spend proposal'); + one.text.should.contain(wallet.name); + one.text.should.contain(wallet.copayers[0].name); + server.storage.fetchUnsentEmails(function(err, unsent) { + should.not.exist(err); + unsent.should.be.empty; + done(); + }); }); }); });