forked from lennym/snailmail
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
120 lines (106 loc) · 3.37 KB
/
Copy pathindex.js
File metadata and controls
120 lines (106 loc) · 3.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
const fs = require('fs');
const path = require('path');
const debug = require('debug')('snailmail');
const nodemailer = require('nodemailer');
const AWS = require('aws-sdk');
const mustache = require('mustache');
module.exports = (settings = {}) => {
if (!settings.templateDir || typeof settings.templateDir !== 'string') {
throw new Error('snailmail: Template directory must be defined');
}
if (!settings.from || typeof settings.from !== 'string') {
throw new Error('snailmail: From address must be defined');
}
const SES = new AWS.SES({
region: settings.region,
accessKeyId: settings.key,
secretAccessKey: settings.secret
});
const mailer = nodemailer.createTransport({ SES });
settings.ext = settings.ext || '.html';
const render = mustache.render;
const _templates = new Promise((resolve, reject) => {
fs.readdir(settings.templateDir, (err, files) => {
if (err) {
return resolve({});
}
files = files
.filter(f => path.extname(f) === settings.ext)
.reduce((map, f) => {
return {
...map,
[path.basename(f, settings.ext)]: { path: path.resolve(settings.templateDir, f) }
};
}, {});
resolve(files);
});
});
const _layout = new Promise((resolve, reject) => {
const def = '{{>message}}';
if (!settings.layout) {
debug('No layout defined. Using default.');
return resolve(def);
}
debug(`Loading layout from ${settings.layout}`);
fs.readFile(settings.layout, (err, content) => {
return err ? reject(err) : resolve(content.toString());
});
});
const getTemplates = () => _templates;
const getLayout = () => _layout;
const loadTemplate = config => {
return new Promise((resolve, reject) => {
if (config.content) {
debug(`Template "${config.path}" found in cache`);
return resolve(config.content);
}
debug(`Template "${config.path}" not found in cache. Loading from fs.`);
fs.readFile(config.path, (err, content) => {
if (err) {
return reject(err);
}
config.content = content.toString();
return resolve(config.content);
});
});
};
return {
send: ({ template, data = {}, to, subject = 'No subject', attachments }) => {
attachments = Object.assign({}, settings.attachments, attachments);
attachments = Object.keys(attachments).map(cid => {
return {
cid,
filename: path.basename(attachments[cid]),
path: attachments[cid]
}
});
return getTemplates()
.then(templates => {
if (!template || !templates[template]) {
throw new Error(`Unrecognised template: ${template}`);
}
return templates[template];
})
.then(config => {
return loadTemplate(config);
})
.then(message => {
return getLayout()
.then(layout => render(layout, data, { message }));
})
.then(message => {
return new Promise((resolve, reject) => {
mailer.sendMail({
to,
from: settings.from,
subject: render(subject, data),
html: message,
attachments
}, (err, response, r) => {
err ? reject(err) : resolve(response);
});
});
});
}
};
};