0.0.11 | Built motion from commit e8dda05.
[motion.git] / server / config / smtp / smtp.js
1 'use strict';
2
3 var _ = require('lodash');
4 var nodemailer = require('nodemailer');
5 var smtpTransport = require('nodemailer-smtp-transport');
6
7 var MailRoom = require('../../models').MailRoom;
8 var MailMessage = require('../../models').MailMessage;
9 var ContactEmail = require('../../models').ContactEmail;
10 var Contact = require('../../models').Contact;
11
12 function Smtp(doc) {
13   console.log('New Smtp Instance...');
14   this.doc = doc;
15   this.smtp = nodemailer.createTransport(smtpTransport({
16     host: doc.host,
17     port: doc.port,
18     secure: doc.ssl,
19     debug: true,
20     auth: {
21       user: doc.username,
22       pass: doc.password
23     }
24   }));
25 }
26
27 Smtp.prototype.send = function(mailMessage) {
28   var that = this;
29   var mMessage = mailMessage;
30   var mRoom;
31
32   if (mMessage.inReplyTo) {
33     return MailMessage
34       .findOne({
35         where: {
36           messageId: mMessage.inReplyTo
37         }
38       })
39       .then(function(mailMessageParent) {
40         return mailMessageParent
41           .getMailRoom();
42       })
43       .then(function(mailRoom) {
44         mRoom = mailRoom;
45
46         return mailRoom
47           .addMailMessage(mMessage);
48       })
49       .then(function() {
50
51         return Contact
52           .findOrCreate({
53             where: {},
54             include: [{
55               model: ContactEmail,
56               as: 'Emails',
57               where: {
58                 email: mMessage.from
59               }
60             }],
61             defaults: {
62               Emails: [{
63                 email: mMessage.from
64               }]
65             }
66           });
67       })
68       .spread(function(contact, created) {
69         // CONTACT -> FROM
70         var promises = [];
71         var tos = mMessage.to ? mMessage.to.split(';') : [];
72
73         mMessage
74           .setFrom(contact);
75
76         tos.forEach(function(email) {
77           promises.push(Contact
78             .findOrCreate({
79               where: {},
80               include: [{
81                 model: ContactEmail,
82                 as: 'Emails',
83                 where: {
84                   email: email
85                 }
86               }],
87               defaults: {
88                 Emails: [{
89                   email: email
90                 }]
91               }
92             }));
93         });
94
95         return promises;
96       })
97       .all()
98       .then(function(contacts) {
99         // CONTACTS -> TO
100         var tos = _.map(contacts, function(elm) {
101           return elm[0];
102         });
103
104         mMessage
105           .setTo(tos);
106
107         var promises = [];
108         var ccs = mMessage.cc ? mMessage.cc.split(';') : [];
109
110         ccs.forEach(function(email) {
111           promises.push(Contact
112             .findOrCreate({
113               where: {},
114               include: [{
115                 model: ContactEmail,
116                 as: 'Emails',
117                 where: {
118                   email: email
119                 }
120               }],
121               defaults: {
122                 Emails: [{
123                   email: email
124                 }]
125               }
126             }));
127         });
128
129         return promises;
130       })
131       .all()
132       .then(function(contacts) {
133         // CONTACTS -> CC
134         var ccs = _.map(contacts, function(elm) {
135           return elm[0];
136         });
137
138         mMessage
139           .setCc(ccs);
140
141         var promises = [];
142         var bccs = mMessage.bcc ? mMessage.to.split(';') : [];
143
144         bccs.forEach(function(email) {
145           promises.push(Contact
146             .findOrCreate({
147               where: {},
148               include: [{
149                 model: ContactEmail,
150                 as: 'Emails',
151                 where: {
152                   email: email
153                 }
154               }],
155               defaults: {
156                 Emails: [{
157                   email: email
158                 }]
159               }
160             }));
161         });
162
163         return promises;
164       })
165       .all()
166       .then(function(contacts) {
167         // CONTACTS -> BCC
168         var bcs = _.map(contacts, function(elm) {
169           return elm[0];
170         });
171
172         mMessage
173           .setBcc(bcs);
174       })
175       .then(function() {
176         var options = {
177           status: mMessage.status,
178           from: mMessage.from,
179           to: mMessage.to,
180           cc: mMessage.cc,
181           subject: mMessage.subject,
182           html: mMessage.html,
183           text: mMessage.text,
184           headers: {
185             'X-Laziness-level': 1000
186           }
187         };
188
189         if (mMessage.MailAttachments) {
190           options.attachments = _.map(mMessage.MailAttachments, function(elm) {
191             return {
192               path: elm.path
193             }
194           });
195         }
196
197         that.smtp.sendMail(options, function(error, response) {
198           if (error) {
199             console.error('error', error);
200             return mMessage
201               .update({
202                 status: 'FAILED'
203               })
204               .catch(function(err) {
205                 console.error(err);
206               });
207           } else {
208             return mMessage
209               .update({
210                 messageId: response.messageId,
211                 status: 'SENT'
212               })
213               .catch(function(err) {
214                 console.error(err);
215               });
216           }
217         });
218       })
219       .catch(function(err) {
220         console.error('err', err);
221       });
222   } else {
223     return MailRoom
224       .findOrCreate({
225         where: {
226           id: mMessage.MailRoomId
227         },
228         defaults: {
229           subject: mMessage.subject,
230           from: mMessage.from,
231           status: 'OPEN',
232           MailAccountId: that.doc.MailAccountId
233         }
234       })
235       .spread(function(mailRoom) {
236         mRoom = mailRoom;
237
238         return mailRoom
239           .addMailMessage(mMessage);
240       })
241       .then(function() {
242
243         return Contact
244           .findOrCreate({
245             where: {},
246             include: [{
247               model: ContactEmail,
248               as: 'Emails',
249               where: {
250                 email: mMessage.from
251               }
252             }],
253             defaults: {
254               Emails: [{
255                 email: mMessage.from
256               }]
257             }
258           });
259       })
260       .spread(function(contact, created) {
261         // CONTACT -> FROM
262         var promises = [];
263         var tos = mMessage.to ? mMessage.to.split(';') : [];
264
265         mMessage
266           .setFrom(contact);
267
268         tos.forEach(function(email) {
269           promises.push(Contact
270             .findOrCreate({
271               where: {},
272               include: [{
273                 model: ContactEmail,
274                 as: 'Emails',
275                 where: {
276                   email: email
277                 }
278               }],
279               defaults: {
280                 Emails: [{
281                   email: email
282                 }]
283               }
284             }));
285         });
286
287         return promises;
288       })
289       .all()
290       .then(function(contacts) {
291         // CONTACTS -> TO
292         var tos = _.map(contacts, function(elm) {
293           return elm[0];
294         });
295
296         mMessage
297           .setTo(tos);
298
299         var promises = [];
300         var ccs = mMessage.cc ? mMessage.cc.split(';') : [];
301
302         ccs.forEach(function(email) {
303           promises.push(Contact
304             .findOrCreate({
305               where: {},
306               include: [{
307                 model: ContactEmail,
308                 as: 'Emails',
309                 where: {
310                   email: email
311                 }
312               }],
313               defaults: {
314                 Emails: [{
315                   email: email
316                 }]
317               }
318             }));
319         });
320
321         return promises;
322       })
323       .all()
324       .then(function(contacts) {
325         // CONTACTS -> CC
326         var ccs = _.map(contacts, function(elm) {
327           return elm[0];
328         });
329
330         mMessage
331           .setCc(ccs);
332
333         var promises = [];
334         var bccs = mMessage.bcc ? mMessage.to.split(';') : [];
335
336         bccs.forEach(function(email) {
337           promises.push(Contact
338             .findOrCreate({
339               where: {},
340               include: [{
341                 model: ContactEmail,
342                 as: 'Emails',
343                 where: {
344                   email: email
345                 }
346               }],
347               defaults: {
348                 Emails: [{
349                   email: email
350                 }]
351               }
352             }));
353         });
354
355         return promises;
356       })
357       .all()
358       .then(function(contacts) {
359         // CONTACTS -> BCC
360         var bcs = _.map(contacts, function(elm) {
361           return elm[0];
362         });
363
364         mMessage
365           .setBcc(bcs);
366       })
367       .then(function() {
368         var options = {
369           status: mMessage.status,
370           from: mMessage.from,
371           to: mMessage.to,
372           cc: mMessage.cc,
373           subject: mMessage.subject,
374           html: mMessage.html,
375           text: mMessage.text,
376           headers: {
377             'X-Laziness-level': 1000
378           }
379         };
380
381         if (mMessage.MailAttachments) {
382           options.attachments = _.map(mMessage.MailAttachments, function(elm) {
383             return {
384               path: elm.path
385             }
386           });
387         }
388
389         that.smtp.sendMail(options, function(error, response) {
390           if (error) {
391             console.error('error', error);
392             return mMessage
393               .update({
394                 status: 'FAILED'
395               })
396               .catch(function(err) {
397                 console.error(err);
398               });
399           } else {
400             return mMessage
401               .update({
402                 messageId: response.messageId,
403                 status: 'SENT'
404               })
405               .catch(function(err) {
406                 console.error(err);
407               });
408           }
409         });
410       })
411       .catch(function(err) {
412         console.error('err', err);
413       });
414   }
415 };
416
417 module.exports = Smtp;