-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathindex.js
202 lines (167 loc) · 5.75 KB
/
index.js
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
/**
* Created by alykoshin on 8/12/14.
*/
'use strict';
const _ = require('lodash');
const path = require('path');
const nodemailer = require('nodemailer');
/**
* sendOptions - options for nodemailer
*
* @typedef {Object} sendOptions
* @property {string} options.user
* @property {string} options.pass
* @property {(string || string[])} options.files
* @property {string} options.from
* @property {string} options.to
* @property {string} options.replyTo
* @property {string} options.text
* @property {string} options.html
* @property {string} options.attachments - array of `nodemailer`s compatible attachments definitions
*/
/**
* @callback sendCallback
* @param {Object} error
* @param {string} result
* @param {Object} fullResult
*/
/**
* @constructor
* @param {sendOptions} options - options for underlying nodemailer
* @type {Function}
*/
const GMailSend = function (options) {
const self = this;
/** @member {string} */
self.options = options;
/** helper to build 'Some Name <[email protected]>' **/
function prepareAddress(name, address) {
return name + ' ' + '<' + address + '>';
}
function _send(options, callback) {
const handleSuccess = (info) => {
if (callback) {
callback(null, info.response, info);
//} else { //
// const result = {
// result: info && info.response,
// full: info,
// };
// resolve(result);
}
};
const handleError = (error) => {
if (typeof error === 'string') error = new Error(error);
if (callback) {
callback(error, error.message, undefined);
//} else {
// reject(error);
}
};
options.from = options.from || options.user;
//options.replyTo = options.replyTo || options.user;
// Configure email transport
const TRANSPORT = {
service: 'Gmail', auth: { user: options.user, pass: options.pass }
};
const smtpTransport = nodemailer.createTransport(TRANSPORT);
// Preparing nodemailer options (and attachments)
// File attachments
options.files = options.files || [];
if (!Array.isArray(options.files)) options.files = [ options.files ];
//if (typeof options.files === 'string') { options.files = [options.files]; }
options.attachments = options.attachments || [];
for (let i = 0; i < options.files.length; i++) {
let file = options.files[ i ];
// if string is passed, convert it to `nodemailer` attachment object
if (typeof file === 'string') {
file = {
path: file,
//filename: path.basename( file ),
//cid: path.basename( file ),
};
}
if (!file.path) {
//const msg = 'file/filepath to attach must be set';
//if (callback) callback(new Error(msg), msg, undefined);
//return reject()
return handleError('file/filepath to attach must be set');
}
if (typeof file.filename === 'undefined') file.filename = path.basename(file.path);
if (typeof file.cid === 'undefined') file.cid = file.filename;
// we do not validate if options.files[i] is really object and has valid properties
// add to options.attachments used by `nodemailer`
options.attachments.push(file);
}
delete options.files; // remove files property as incompatible with options of underlying `nodemailer`
// from
options.from = prepareAddress(options.from, options.user); // adjust to nodemailer format
// to
if (typeof options.to === 'string') {
options.to = prepareAddress(options.to, options.to); // adjust to nodemailer format
} else if (Array.isArray(options.to)) {
let to = options.to.map((addr) => prepareAddress(addr, addr));
options.to = to.join(',');
}
// Sending email
//console.log('gmail-send: send(): mailOptions: ', options);
return smtpTransport.sendMail(options, function (error, info) {
if (error) {
//console.log('gmail-send: send(): Error sending message:', error);
//if (callback) callback(error);
//return reject(error);
return handleError(error);
} else {
//console.log("gmail-send: send(): Message sent: " + info.response);
//if (callback) callback(null, info.response, info);
//return resolve(info.response, info);
return handleSuccess(info);
}
}); // smtpTransport.sendMail()
} // function _send()
/**
* Send email
*
* You may use almost any option available in Nodemailer,
* but if you need fine tuning I'd recommend to consider using Nodemailer directly.
*
* @param {sendOptions} [options] - options for underlying nodemailer
* @param {sendCallback} [callback]
* @return Promise({{ result: string, full: object }})
*/
self.send = function (options, callback) {
if (arguments.length === 1)
if (typeof options === 'function') { // only callback function is provided
callback = options;
options = {};
}
options = options || {};
options = _.extend({}, self.options, options);
if (!options.user || !options.pass) {
throw new Error('options.user and options.pass are mandatory.');
}
if (callback) return _send(
options,
callback,
);
else return new Promise((resolve, reject) =>
_send(
options,
(error, result, full) => error
? reject(error)
: resolve({ result, full })
) // _send()
); // return new Promise()
}; // self.send = function()
return self;
};
//
/**
* Exporting function to send email
*
* @param {sendOptions} options - options for new GMailSend()
* @returns {function}
*/
module.exports = function (options) {
return new GMailSend(options).send;
};