Skip to content

Commit 5c6b5ae

Browse files
committed
send email from a separate service
1 parent d12c040 commit 5c6b5ae

File tree

5 files changed

+63
-95
lines changed

5 files changed

+63
-95
lines changed

emailservice/emailservice.js

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/usr/bin/env node
2+
3+
'use strict';
4+
5+
var _ = require('lodash');
6+
var log = require('npmlog');
7+
log.debug = log.verbose;
8+
9+
var config = require('../config');
10+
var EmailService = require('../lib/emailservice');
11+
12+
var emailService = new EmailService();
13+
emailService.start(config, function(err) {
14+
if (err) throw err;
15+
16+
console.log('Email service started');
17+
});

lib/blockchainmonitor.js

+3-16
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ var BlockchainExplorer = require('./blockchainexplorer');
1010
var Storage = require('./storage');
1111
var MessageBroker = require('./messagebroker');
1212
var Lock = require('./lock');
13-
var EmailService = require('./emailservice');
1413

1514
var Notification = require('./model/notification');
1615

@@ -20,8 +19,8 @@ BlockchainMonitor.prototype.start = function(opts, cb) {
2019
opts = opts || {};
2120
$.checkArgument(opts.blockchainExplorerOpts);
2221
$.checkArgument(opts.storageOpts);
22+
$.checkArgument(opts.messageBrokerOpts);
2323
$.checkArgument(opts.lockOpts);
24-
$.checkArgument(opts.emailOpts);
2524

2625
var self = this;
2726

@@ -49,16 +48,8 @@ BlockchainMonitor.prototype.start = function(opts, cb) {
4948
], function(err) {
5049
if (err) {
5150
log.error(err);
52-
return cb(err);
5351
}
54-
55-
self.emailService = new EmailService({
56-
lock: self.lock,
57-
storage: self.storage,
58-
mailer: opts.mailer,
59-
emailOpts: opts.emailOpts,
60-
});
61-
return cb();
52+
return cb(err);
6253
});
6354
};
6455

@@ -136,11 +127,7 @@ BlockchainMonitor.prototype._createNotification = function(walletId, txid, addre
136127
});
137128
self.storage.storeNotification(walletId, notification, function() {
138129
self.messageBroker.send(notification)
139-
if (self.emailService) {
140-
self.emailService.sendEmail(notification, cb);
141-
} else {
142-
return cb();
143-
}
130+
return cb();
144131
});
145132
};
146133

lib/emailservice.js

+42-10
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ log.debug = log.verbose;
88
var fs = require('fs');
99
var nodemailer = require('nodemailer');
1010

11+
var Storage = require('./storage');
12+
var MessageBroker = require('./messagebroker');
13+
var Lock = require('./lock');
14+
1115
var Model = require('./model');
1216

1317
var EMAIL_TYPES = {
@@ -38,21 +42,47 @@ var EMAIL_TYPES = {
3842
};
3943

4044

41-
function EmailService(opts) {
42-
$.checkArgument(opts);
45+
function EmailService() {};
4346

44-
opts.emailOpts = opts.emailOpts || {};
47+
EmailService.prototype.start = function(opts, cb) {
48+
opts = opts || {};
49+
$.checkArgument(opts.storageOpts);
50+
$.checkArgument(opts.messageBrokerOpts);
51+
$.checkArgument(opts.lockOpts);
52+
$.checkArgument(opts.emailOpts);
4553

46-
this.storage = opts.storage;
47-
this.lock = opts.lock;
48-
this.mailer = opts.mailer || nodemailer.createTransport(opts.emailOpts);
49-
this.subjectPrefix = opts.emailOpts.subjectPrefix || '[Wallet service]';
50-
this.from = opts.emailOpts.from;
54+
var self = this;
5155

52-
$.checkState(this.mailer);
53-
$.checkState(this.from);
56+
async.parallel([
57+
58+
function(done) {
59+
self.storage = new Storage();
60+
self.storage.connect(opts.storageOpts, done);
61+
},
62+
function(done) {
63+
self.messageBroker = new MessageBroker(opts.messageBrokerOpts);
64+
self.messageBroker.onMessage(_.bind(self.sendEmail, self));
65+
done();
66+
},
67+
function(done) {
68+
self.lock = new Lock(opts.lockOpts);
69+
done();
70+
},
71+
function(done) {
72+
self.mailer = opts.mailer || nodemailer.createTransport(opts.emailOpts);
73+
self.subjectPrefix = opts.emailOpts.subjectPrefix || '[Wallet service]';
74+
self.from = opts.emailOpts.from;
75+
done();
76+
},
77+
], function(err) {
78+
if (err) {
79+
log.error(err);
80+
}
81+
return cb(err);
82+
});
5483
};
5584

85+
5686
// TODO: cache for X minutes
5787
EmailService.prototype._readTemplate = function(filename, cb) {
5888
fs.readFile(__dirname + '/templates/' + filename + '.plain', 'utf8', function(err, template) {
@@ -144,6 +174,8 @@ EmailService.prototype._send = function(email, cb) {
144174
EmailService.prototype.sendEmail = function(notification, cb) {
145175
var self = this;
146176

177+
cb = cb || function() {};
178+
147179
var emailType = EMAIL_TYPES[notification.type];
148180
if (!emailType) return cb();
149181

lib/server.js

+1-22
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ var Lock = require('./lock');
1919
var Storage = require('./storage');
2020
var MessageBroker = require('./messagebroker');
2121
var BlockchainExplorer = require('./blockchainexplorer');
22-
var EmailService = require('./emailservice');
2322

2423
var Model = require('./model');
2524
var Wallet = Model.Wallet;
@@ -31,7 +30,6 @@ var storage;
3130
var blockchainExplorer;
3231
var blockchainExplorerOpts;
3332
var messageBroker;
34-
var emailService;
3533

3634

3735
/**
@@ -48,7 +46,6 @@ function WalletService() {
4846
this.blockchainExplorerOpts = blockchainExplorerOpts;
4947
this.messageBroker = messageBroker;
5048
this.notifyTicker = 0;
51-
this.emailService = emailService;
5249
};
5350

5451
/**
@@ -80,17 +77,6 @@ WalletService.initialize = function(opts, cb) {
8077
}
8178
};
8279

83-
function initEmailService(cb) {
84-
if (!opts.mailer && !opts.emailOpts) return cb();
85-
emailService = new EmailService({
86-
lock: lock,
87-
storage: storage,
88-
mailer: opts.mailer,
89-
emailOpts: opts.emailOpts,
90-
});
91-
return cb();
92-
};
93-
9480
function initMessageBroker(cb) {
9581
if (opts.messageBroker) {
9682
messageBroker = opts.messageBroker;
@@ -108,9 +94,6 @@ WalletService.initialize = function(opts, cb) {
10894
function(next) {
10995
initMessageBroker(next);
11096
},
111-
function(next) {
112-
initEmailService(next);
113-
},
11497
], function(err) {
11598
if (err) {
11699
log.error('Could not initialize', err);
@@ -356,11 +339,7 @@ WalletService.prototype._notify = function(type, data, opts, cb) {
356339

357340
this.storage.storeNotification(walletId, notification, function() {
358341
self.messageBroker.send(notification);
359-
if (self.emailService) {
360-
self.emailService.sendEmail(notification, cb);
361-
} else {
362-
return cb();
363-
}
342+
return cb();
364343
});
365344
};
366345

test/integration/server.js

-47
Original file line numberDiff line numberDiff line change
@@ -3229,51 +3229,4 @@ describe('Wallet service', function() {
32293229
});
32303230
});
32313231
});
3232-
3233-
describe('Email notifications', function() {
3234-
var server, wallet, sendMailStub;
3235-
beforeEach(function(done) {
3236-
helpers.createAndJoinWallet(2, 3, function(s, w) {
3237-
server = s;
3238-
wallet = w;
3239-
sendMailStub = sinon.stub();
3240-
sendMailStub.yields();
3241-
server.emailService.mailer.sendMail = sendMailStub;
3242-
3243-
var i = 0;
3244-
async.eachSeries(w.copayers, function(copayer, next) {
3245-
helpers.getAuthServer(copayer.id, function(server) {
3246-
server.savePreferences({
3247-
email: 'copayer' + (i++) + '@domain.com',
3248-
}, next);
3249-
});
3250-
}, done);
3251-
});
3252-
});
3253-
3254-
it('should notify copayers a new tx proposal has been created', function(done) {
3255-
helpers.stubUtxos(server, wallet, [1, 1], function() {
3256-
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 0.8, 'some message', TestData.copayers[0].privKey_1H_0);
3257-
server.createTx(txOpts, function(err, tx) {
3258-
should.not.exist(err);
3259-
var calls = sendMailStub.getCalls();
3260-
calls.length.should.equal(2);
3261-
var emails = _.map(calls, function(c) {
3262-
return c.args[0];
3263-
});
3264-
_.difference(['[email protected]', '[email protected]'], _.pluck(emails, 'to')).should.be.empty;
3265-
var one = emails[0];
3266-
one.from.should.equal('[email protected]');
3267-
one.subject.should.contain('New payment proposal');
3268-
one.text.should.contain(wallet.name);
3269-
one.text.should.contain(wallet.copayers[0].name);
3270-
server.storage.fetchUnsentEmails(function(err, unsent) {
3271-
should.not.exist(err);
3272-
unsent.should.be.empty;
3273-
done();
3274-
});
3275-
});
3276-
});
3277-
});
3278-
});
32793232
});

0 commit comments

Comments
 (0)