mail-time 1.3.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -107
- package/index.js +23 -21
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
[](https://github.com/sponsors/
|
|
1
|
+
[](https://github.com/sponsors/dr-dimitru)
|
|
2
2
|
[](https://paypal.me/veliovgroup)
|
|
3
3
|
<a href="https://ostr.io/info/built-by-developers-for-developers">
|
|
4
4
|
<img src="https://ostr.io/apple-touch-icon-60x60.png" height="20">
|
|
@@ -22,21 +22,20 @@ The main difference between *Server* and *Client* modes is that the *Server* han
|
|
|
22
22
|
|
|
23
23
|
## ToC
|
|
24
24
|
|
|
25
|
-
- [How it works?](https://github.com/veliovgroup/
|
|
26
|
-
- [With single SMTP](https://github.com/veliovgroup/
|
|
27
|
-
- [With multiple SMTP](https://github.com/veliovgroup/
|
|
28
|
-
- [As Micro-Service](https://github.com/veliovgroup/
|
|
29
|
-
- [Features](https://github.com/veliovgroup/
|
|
30
|
-
- [Installation](https://github.com/veliovgroup/
|
|
31
|
-
- [Meteor.js
|
|
32
|
-
- [
|
|
33
|
-
- [
|
|
34
|
-
- [
|
|
35
|
-
- [
|
|
36
|
-
- [
|
|
37
|
-
|
|
38
|
-
- [
|
|
39
|
-
- [~92% tests coverage](https://github.com/veliovgroup/Mail-Time#testing)
|
|
25
|
+
- [How it works?](https://github.com/veliovgroup/mail-time#how-it-works)
|
|
26
|
+
- [With single SMTP](https://github.com/veliovgroup/mail-time#single-point-of-failure)
|
|
27
|
+
- [With multiple SMTP](https://github.com/veliovgroup/mail-time#multiple-smtp-providers)
|
|
28
|
+
- [As Micro-Service](https://github.com/veliovgroup/mail-time#cluster-issue)
|
|
29
|
+
- [Features](https://github.com/veliovgroup/mail-time#features)
|
|
30
|
+
- [Installation](https://github.com/veliovgroup/mail-time#installation)
|
|
31
|
+
- [Meteor.js usage](https://github.com/veliovgroup/mail-time/blob/master/docs/meteor.md)
|
|
32
|
+
- [Usage example](https://github.com/veliovgroup/mail-time#basic-usage)
|
|
33
|
+
- [API](https://github.com/veliovgroup/mail-time#api)
|
|
34
|
+
- [*Constructor*](https://github.com/veliovgroup/mail-time#new-mailtimeopts-constructor)
|
|
35
|
+
- [`.send()`](https://github.com/veliovgroup/mail-time#sendmailopts--callback)
|
|
36
|
+
- [Default Template](https://github.com/veliovgroup/mail-time#static-mailtimetemplate)
|
|
37
|
+
- [Custom Templates](https://github.com/veliovgroup/mail-time#template-example)
|
|
38
|
+
- [~92% tests coverage](https://github.com/veliovgroup/mail-time#testing)
|
|
40
39
|
|
|
41
40
|
## Main features:
|
|
42
41
|
|
|
@@ -174,8 +173,8 @@ const directTransportOpts = {
|
|
|
174
173
|
from: 'no-reply@example.com',
|
|
175
174
|
};
|
|
176
175
|
transports.push(nodemailer.createTransport(directTransport(directTransportOpts)));
|
|
177
|
-
// IMPORTANT:
|
|
178
|
-
//
|
|
176
|
+
// IMPORTANT: Add `.options` to a newly created transport,
|
|
177
|
+
// this is necessary to make sure options are available to MailTime package:
|
|
179
178
|
transports[0].options = directTransportOpts;
|
|
180
179
|
|
|
181
180
|
// Private SMTP
|
|
@@ -213,12 +212,12 @@ transports.push(nodemailer.createTransport({
|
|
|
213
212
|
As the next step initiate `mail-time` in the *Server* mode, it will be able to __send__ and __add__ emails to the queue. Connecting to a MongoDB before initiating `new MailTime` instance:
|
|
214
213
|
|
|
215
214
|
```js
|
|
215
|
+
const MailTime = require('mail-time');
|
|
216
216
|
const MongoClient = require('mongodb').MongoClient;
|
|
217
|
-
const MailTime = require('mail-time');
|
|
218
|
-
const dbName = 'DatabaseName';
|
|
219
217
|
|
|
220
|
-
|
|
221
|
-
|
|
218
|
+
const dbName = 'databaseName';
|
|
219
|
+
|
|
220
|
+
// Use MONGO_URL environment variable to store connection string to MongoDB
|
|
222
221
|
// example: "MONGO_URL=mongodb://127.0.0.1:27017/myapp node mail-micro-service.js"
|
|
223
222
|
MongoClient.connect(process.env.MONGO_URL, (error, client) => {
|
|
224
223
|
const db = client.db(dbName);
|
|
@@ -243,9 +242,10 @@ MongoClient.connect(process.env.MONGO_URL, (error, client) => {
|
|
|
243
242
|
Only __one__ `MailTime` *Server* instance required to send email. In the other parts of an app (like UI units or in sub-apps) use `mail-time` in the *Client* mode to __add__ emails to queue:
|
|
244
243
|
|
|
245
244
|
```js
|
|
245
|
+
const MailTime = require('mail-time');
|
|
246
246
|
const MongoClient = require('mongodb').MongoClient;
|
|
247
|
-
|
|
248
|
-
const dbName
|
|
247
|
+
|
|
248
|
+
const dbName = 'databaseName';
|
|
249
249
|
|
|
250
250
|
MongoClient.connect(process.env.MONGO_URL, (error, client) => {
|
|
251
251
|
const db = client.db(dbName);
|
|
@@ -275,7 +275,7 @@ mailQueue.sendMail({
|
|
|
275
275
|
Create two `MailTime` instances with different settings.
|
|
276
276
|
|
|
277
277
|
```js
|
|
278
|
-
//
|
|
278
|
+
// CREATE mailQueue FOR NON-URGENT EMAILS WHICH IS OKAY TO CONCATENATE
|
|
279
279
|
const mailQueue = new MailTime({
|
|
280
280
|
db: db,
|
|
281
281
|
interval: 35,
|
|
@@ -286,7 +286,7 @@ const mailQueue = new MailTime({
|
|
|
286
286
|
zombieTime: 120000
|
|
287
287
|
});
|
|
288
288
|
|
|
289
|
-
//
|
|
289
|
+
// CREATE mailInstantQueue FOR TRANSACTIONAL EMAILS AND ALERTS
|
|
290
290
|
const mailInstantQueue = new MailTime({
|
|
291
291
|
db: db,
|
|
292
292
|
prefix: 'instant',
|
|
@@ -318,12 +318,12 @@ All options passed to the `.sendMail()` method is available inside `text`, `html
|
|
|
318
318
|
|
|
319
319
|
```js
|
|
320
320
|
const templates = {
|
|
321
|
-
global: '<html xmlns="http://www.w3.org/1999/xhtml"><head><title>{{subject}}</title></head><body>{{html}}<footer>Message sent to @{{username}} user ({{to}})</footer></body></html>',
|
|
321
|
+
global: '<html xmlns="http://www.w3.org/1999/xhtml"><head><title>{{subject}}</title></head><body>{{{html}}}<footer>Message sent to @{{username}} user ({{to}})</footer></body></html>',
|
|
322
322
|
signInCode: {
|
|
323
|
-
text: 'Hello @{{username}}! Here\'s your login code: {{code}}'
|
|
324
|
-
html: `<h1>Sign-in request</h1><p>Hello @{{username}}! Copy your login code below <pre><code>{{code}}</code></pre>`
|
|
323
|
+
text: 'Hello @{{username}}! Here\'s your login code: {{code}}',
|
|
324
|
+
html: `<h1>Sign-in request</h1><p>Hello @{{username}}! <p>Copy your login code below:</p> <pre><code>{{code}}</code></pre>`
|
|
325
325
|
}
|
|
326
|
-
}
|
|
326
|
+
};
|
|
327
327
|
|
|
328
328
|
const mailQueue = new MailTime({
|
|
329
329
|
db: db,
|
|
@@ -334,85 +334,12 @@ mailQueue.sendMail({
|
|
|
334
334
|
to: 'user@gmail.com',
|
|
335
335
|
subject: 'Sign-in request',
|
|
336
336
|
username: 'johndoe',
|
|
337
|
-
code: 'XXXXX-YY'
|
|
337
|
+
code: 'XXXXX-YY',
|
|
338
338
|
text: templates.signInCode.text,
|
|
339
339
|
html: templates.signInCode.html
|
|
340
340
|
});
|
|
341
341
|
```
|
|
342
342
|
|
|
343
|
-
## Meteor.js usage:
|
|
344
|
-
|
|
345
|
-
Mail-Time package can be installed and used within [Meteor.js](https://docs.meteor.com/) via [NPM](https://www.npmjs.com/package/mail-time) or [Atmosphere](https://atmospherejs.com/ostrio/mailer)
|
|
346
|
-
|
|
347
|
-
### Installation & Import (*via NPM*):
|
|
348
|
-
|
|
349
|
-
Install [NPM `mail-time` package](https://www.npmjs.com/package/mail-time):
|
|
350
|
-
|
|
351
|
-
```shell
|
|
352
|
-
meteor npm install --save mail-time
|
|
353
|
-
```
|
|
354
|
-
|
|
355
|
-
Meteor.js: ES6 Import NPM package:
|
|
356
|
-
|
|
357
|
-
```js
|
|
358
|
-
import MailTime from 'mail-time';
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
### Installation & Import (*via Atmosphere*):
|
|
362
|
-
|
|
363
|
-
Install [Atmosphere `ostrio:mailer` package](https://atmospherejs.com/ostrio/mailer):
|
|
364
|
-
|
|
365
|
-
```shell
|
|
366
|
-
meteor add ostrio:mailer
|
|
367
|
-
```
|
|
368
|
-
|
|
369
|
-
Meteor.js: ES6 Import atmosphere package:
|
|
370
|
-
|
|
371
|
-
```js
|
|
372
|
-
import MailTime from 'meteor/ostrio:mailer';
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
### Usage:
|
|
376
|
-
|
|
377
|
-
`mail-time` package usage examples in Meteor.js
|
|
378
|
-
|
|
379
|
-
```js
|
|
380
|
-
import { MongoInternals } from 'meteor/mongo';
|
|
381
|
-
|
|
382
|
-
import MailTime from 'mail-time';
|
|
383
|
-
import nodemailer from 'nodemailer';
|
|
384
|
-
// Use DIRECT transport
|
|
385
|
-
// To enable sending email from localhost
|
|
386
|
-
// install "nodemailer-direct-transport" NPM package:
|
|
387
|
-
import directTransport from 'nodemailer-direct-transport';
|
|
388
|
-
|
|
389
|
-
const transports = [];
|
|
390
|
-
const directTransportOpts = {
|
|
391
|
-
pool: false,
|
|
392
|
-
direct: true,
|
|
393
|
-
name: 'mail.example.com',
|
|
394
|
-
from: 'no-reply@example.com',
|
|
395
|
-
};
|
|
396
|
-
transports.push(nodemailer.createTransport(directTransport(directTransportOpts)));
|
|
397
|
-
// IMPORTANT: Copy-paste passed options from directTransport() to
|
|
398
|
-
// transport's "options" property, to make sure it's available to MailTime package:
|
|
399
|
-
transports[0].options = directTransportOpts;
|
|
400
|
-
|
|
401
|
-
////////////////////////
|
|
402
|
-
// For more transports example see sections above and read nodemailer's docs
|
|
403
|
-
////////////////////////
|
|
404
|
-
|
|
405
|
-
const mailQueue = new MailTime({
|
|
406
|
-
db: MongoInternals.defaultRemoteCollectionDriver().mongo.db, // MongoDB
|
|
407
|
-
transports,
|
|
408
|
-
from(transport) {
|
|
409
|
-
// To pass spam-filters `from` field should be correctly set
|
|
410
|
-
// for each transport, check `transport` object for more options
|
|
411
|
-
return '"Awesome App" <' + transport.options.from + '>';
|
|
412
|
-
}
|
|
413
|
-
});
|
|
414
|
-
```
|
|
415
|
-
|
|
416
343
|
## API
|
|
417
344
|
|
|
418
345
|
All available constructor options and `.sendMail()` method API overview
|
|
@@ -447,15 +374,15 @@ All available constructor options and `.sendMail()` method API overview
|
|
|
447
374
|
- `opts.sendAt` {*Date*} - When email should be sent, default - `new Date()` use with caution on multi-server setup at different location with the different time-zones
|
|
448
375
|
- `opts.template` - Email specific template, this will override default template passed to `MailTime` constructor
|
|
449
376
|
- `opts.concatSubject` - Email specific concatenation subject, this will override default concatenation subject passed to `MailTime` constructor
|
|
450
|
-
- `opts[key]` {*Mix*} - Other custom and NodeMailer specific options, like `text`, `html` and `to`,
|
|
377
|
+
- `opts[key]` {*Mix*} - Other custom and NodeMailer specific options, like `text`, `html` and `to`, [learn more here](https://github.com/nodemailer/nodemailer/tree/v2#e-mail-message-fields). Note `attachments` should work only via `path`, and file must exists on all micro-services servers
|
|
451
378
|
- `callback` {*Function*} - Callback called after the email was sent or failed to be sent. __Do not use on multi-server setup__
|
|
452
379
|
|
|
453
380
|
### `static MailTime.Template`
|
|
454
381
|
|
|
455
|
-
Simple and bulletproof HTML template, see [its source](https://github.com/veliovgroup/
|
|
382
|
+
Simple and bulletproof HTML template, see [its source](https://github.com/veliovgroup/mail-time/blob/master/template.html). Usage example:
|
|
456
383
|
|
|
457
384
|
```js
|
|
458
|
-
const MailTime
|
|
385
|
+
const MailTime = require('mail-time');
|
|
459
386
|
// Make it default
|
|
460
387
|
const mailQueue = new MailTime({
|
|
461
388
|
db: db, // MongoDB
|
package/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const JoSk = require('josk');
|
|
2
2
|
const noop = () => {};
|
|
3
|
-
const merge
|
|
3
|
+
const merge = require('deepmerge');
|
|
4
4
|
const _debug = (isDebug, ...args) => {
|
|
5
5
|
if (isDebug) {
|
|
6
6
|
console.info.call(console, '[DEBUG] [mail-time]', `${new Date}`, ...args);
|
|
@@ -102,13 +102,13 @@ module.exports = class MailTime {
|
|
|
102
102
|
throw new Error('[mail-time] MongoDB database {db} option is required, like returned from `MongoClient.connect`');
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
this.callbacks
|
|
106
|
-
this.type
|
|
107
|
-
this.debug
|
|
108
|
-
this.prefix
|
|
109
|
-
this.maxTries
|
|
110
|
-
this.interval
|
|
111
|
-
this.template
|
|
105
|
+
this.callbacks = {};
|
|
106
|
+
this.type = (!opts.type || (opts.type !== 'client' && opts.type !== 'server')) ? 'server' : opts.type;
|
|
107
|
+
this.debug = (opts.debug !== true) ? false : true;
|
|
108
|
+
this.prefix = opts.prefix || '';
|
|
109
|
+
this.maxTries = ((opts.maxTries && !isNaN(opts.maxTries)) ? parseInt(opts.maxTries) : 59) + 1;
|
|
110
|
+
this.interval = ((opts.interval && !isNaN(opts.interval)) ? parseInt(opts.interval) : 60) * 1000;
|
|
111
|
+
this.template = (typeof opts.template === 'string') ? opts.template : '{{{html}}}';
|
|
112
112
|
this.zombieTime = opts.zombieTime || 32786;
|
|
113
113
|
this.keepHistory = opts.keepHistory || false;
|
|
114
114
|
|
|
@@ -124,11 +124,11 @@ module.exports = class MailTime {
|
|
|
124
124
|
this.zombieTime = 8192;
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
this.strategy = (opts.strategy === 'backup' || opts.strategy === 'balancer') ? opts.strategy : 'backup';
|
|
128
127
|
this.failsToNext = (opts.failsToNext && !isNaN(opts.failsToNext)) ? parseInt(opts.failsToNext) : 4;
|
|
129
|
-
this.
|
|
130
|
-
this.
|
|
131
|
-
this.
|
|
128
|
+
this.strategy = (opts.strategy === 'backup' || opts.strategy === 'balancer') ? opts.strategy : 'backup';
|
|
129
|
+
this.transports = opts.transports || [];
|
|
130
|
+
this.transport = 0;
|
|
131
|
+
this.from = (() => {
|
|
132
132
|
if (typeof opts.from === 'string') {
|
|
133
133
|
return () => {
|
|
134
134
|
return opts.from;
|
|
@@ -320,10 +320,10 @@ module.exports = class MailTime {
|
|
|
320
320
|
this.transport = 0;
|
|
321
321
|
}
|
|
322
322
|
transportIndex = this.transport;
|
|
323
|
-
transport = this.transports[
|
|
323
|
+
transport = this.transports[transportIndex];
|
|
324
324
|
} else {
|
|
325
325
|
transportIndex = task.transport;
|
|
326
|
-
transport = this.transports[
|
|
326
|
+
transport = this.transports[transportIndex];
|
|
327
327
|
}
|
|
328
328
|
|
|
329
329
|
try {
|
|
@@ -499,12 +499,14 @@ module.exports = class MailTime {
|
|
|
499
499
|
}
|
|
500
500
|
|
|
501
501
|
if (task.tries >= this.maxTries) {
|
|
502
|
-
this.
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
502
|
+
if (!this.keepHistory) {
|
|
503
|
+
this.collection.deleteOne({
|
|
504
|
+
_id: task._id
|
|
505
|
+
}, (deleteError) => {
|
|
506
|
+
_debug(this.debug, `Giving up trying send email after ${task.tries} attempts to: `, task.mailOptions[0].to, error, deleteError);
|
|
507
|
+
this.___triggerCallbacks(error, task, info);
|
|
508
|
+
});
|
|
509
|
+
}
|
|
508
510
|
} else {
|
|
509
511
|
let transportIndex = task.transport;
|
|
510
512
|
|
|
@@ -591,7 +593,7 @@ module.exports = class MailTime {
|
|
|
591
593
|
}
|
|
592
594
|
}
|
|
593
595
|
|
|
594
|
-
const matchStr
|
|
596
|
+
const matchStr = string.match(/\{{2}\s?([a-zA-Z0-9\-\_]+)\s?\}{2}/g);
|
|
595
597
|
if (matchStr) {
|
|
596
598
|
for (i = 0; i < matchStr.length; i++) {
|
|
597
599
|
if (replacements[matchStr[i].replace('{{', '').replace('}}', '').trim()]) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mail-time",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "Bulletproof email queue on top of NodeMailer for a single and multi-server setups",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -36,12 +36,12 @@
|
|
|
36
36
|
],
|
|
37
37
|
"repository": {
|
|
38
38
|
"type": "git",
|
|
39
|
-
"url": "git://github.com/veliovgroup/
|
|
39
|
+
"url": "git://github.com/veliovgroup/mail-time.git"
|
|
40
40
|
},
|
|
41
41
|
"bugs": {
|
|
42
|
-
"url": "https://github.com/veliovgroup/
|
|
42
|
+
"url": "https://github.com/veliovgroup/mail-time/issues"
|
|
43
43
|
},
|
|
44
|
-
"homepage": "https://github.com/veliovgroup/
|
|
44
|
+
"homepage": "https://github.com/veliovgroup/mail-time",
|
|
45
45
|
"author": "dr.dimitru (https://veliovgroup.com)",
|
|
46
46
|
"license": "BSD-3-Clause",
|
|
47
47
|
"engines": {
|