[CCSDK-28] populated the seed code for dgbuilder
[ccsdk/distribution.git] / dgbuilder / core_nodes / social / 61-email.js
1 /**
2  * Copyright 2013,2014 IBM Corp.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  **/
16
17 module.exports = function(RED) {
18     "use strict";
19     var nodemailer = require("nodemailer");
20     var Imap = require('imap');
21
22     //console.log(nodemailer.Transport.transports.SMTP.wellKnownHosts);
23
24     try {
25         var globalkeys = RED.settings.email || require(process.env.NODE_RED_HOME+"/../emailkeys.js");
26     } catch(err) {
27     }
28
29     function EmailNode(n) {
30         RED.nodes.createNode(this,n);
31         this.topic = n.topic;
32         this.name = n.name;
33         this.outserver = n.server;
34         this.outport = n.port;
35         var flag = false;
36         if (this.credentials && this.credentials.hasOwnProperty("userid")) {
37             this.userid = this.credentials.userid;
38         } else {
39             if (globalkeys) {
40                 this.userid = globalkeys.user;
41                 flag = true;
42             } else {
43                 this.error("No e-mail userid set");
44             }
45         }
46         if (this.credentials && this.credentials.hasOwnProperty("password")) {
47             this.password = this.credentials.password;
48         } else {
49             if (globalkeys) {
50                 this.password = globalkeys.pass;
51                 flag = true;
52             } else {
53                 this.error("No e-mail password set");
54             }
55         }
56         if (flag) {
57             RED.nodes.addCredentials(n.id,{userid:this.userid, password:this.password, global:true});
58         }
59         var node = this;
60
61         var smtpTransport = nodemailer.createTransport({
62             host: node.outserver,
63             port: node.outport,
64             secure: true,
65             auth: {
66                 user: node.userid,
67                 pass: node.password
68             }
69         });
70
71         this.on("input", function(msg) {
72             if (smtpTransport) {
73                 node.status({fill:"blue",shape:"dot",text:"sending"});
74                 var payload = RED.util.ensureString(msg.payload);
75                 smtpTransport.sendMail({
76                     from: node.userid, // sender address
77                     to: msg.to || node.name, // comma separated list of addressees
78                     subject: msg.topic, // subject line
79                     text: payload // plaintext body
80                 }, function(error, info) {
81                     if (error) {
82                         node.error(error);
83                         node.status({fill:"red",shape:"ring",text:"send failed"});
84                     } else {
85                         node.log("Message sent: " + info.response);
86                         node.status({});
87                     }
88                 });
89             }
90             else { node.warn("No Email credentials found. See info panel."); }
91         });
92     }
93     RED.nodes.registerType("e-mail",EmailNode,{
94         credentials: {
95             userid: {type:"text"},
96             password: {type: "password"},
97             global: { type:"boolean"}
98         }
99     });
100
101     function EmailInNode(n) {
102         RED.nodes.createNode(this,n);
103         this.name = n.name;
104         this.repeat = n.repeat * 1000 || 300000;
105         this.inserver = n.server || globalkeys.server || "imap.gmail.com";
106         this.inport = n.port || globalkeys.port || "993";
107         var flag = false;
108
109         if (this.credentials && this.credentials.hasOwnProperty("userid")) {
110             this.userid = this.credentials.userid;
111         } else {
112             if (globalkeys) {
113                 this.userid = globalkeys.user;
114                 flag = true;
115             } else {
116                 this.error("No e-mail userid set");
117             }
118         }
119         if (this.credentials && this.credentials.hasOwnProperty("password")) {
120             this.password = this.credentials.password;
121         } else {
122             if (globalkeys) {
123                 this.password = globalkeys.pass;
124                 flag = true;
125             } else {
126                 this.error("No e-mail password set");
127             }
128         }
129         if (flag) {
130             RED.nodes.addCredentials(n.id,{userid:this.userid, password:this.password, global:true});
131         }
132
133         var node = this;
134         this.interval_id = null;
135         var oldmail = {};
136
137         var imap = new Imap({
138             user: node.userid,
139             password: node.password,
140             host: node.inserver,
141             port: node.inport,
142             tls: true,
143             tlsOptions: { rejectUnauthorized: false },
144             connTimeout: node.repeat,
145             authTimeout: node.repeat
146         });
147
148         if (!isNaN(this.repeat) && this.repeat > 0) {
149             node.log("repeat = "+this.repeat);
150             this.interval_id = setInterval( function() {
151                 node.emit("input",{});
152             }, this.repeat );
153         }
154
155         this.on("input", function(msg) {
156             imap.once('ready', function() {
157                 node.status({fill:"blue",shape:"dot",text:"fetching"});
158                 var pay = {};
159                 imap.openBox('INBOX', true, function(err, box) {
160                     if (box.messages.total > 0) {
161                         var f = imap.seq.fetch(box.messages.total + ':*', { bodies: ['HEADER.FIELDS (FROM SUBJECT DATE)','TEXT'] });
162                         f.on('message', function(msg, seqno) {
163                             node.log('message: #'+ seqno);
164                             var prefix = '(#' + seqno + ') ';
165                             msg.on('body', function(stream, info) {
166                                 var buffer = '';
167                                 stream.on('data', function(chunk) {
168                                     buffer += chunk.toString('utf8');
169                                 });
170                                 stream.on('end', function() {
171                                     if (info.which !== 'TEXT') {
172                                         pay.from = Imap.parseHeader(buffer).from[0];
173                                         pay.topic = Imap.parseHeader(buffer).subject[0];
174                                         pay.date = Imap.parseHeader(buffer).date[0];
175                                     } else {
176                                         var parts = buffer.split("Content-Type");
177                                         for (var p = 0; p < parts.length; p++) {
178                                             if (parts[p].indexOf("text/plain") >= 0) {
179                                                 pay.payload = parts[p].split("\n").slice(1,-2).join("\n").trim();
180                                             }
181                                             if (parts[p].indexOf("text/html") >= 0) {
182                                                 pay.html = parts[p].split("\n").slice(1,-2).join("\n").trim();
183                                             }
184                                         }
185                                         //pay.body = buffer;
186                                     }
187                                 });
188                             });
189                             msg.on('end', function() {
190                                 //node.log('Finished: '+prefix);
191                             });
192                         });
193                         f.on('error', function(err) {
194                             node.warn('fetch error: ' + err);
195                             node.status({fill:"red",shape:"ring",text:"fetch error"});
196                         });
197                         f.on('end', function() {
198                             if (JSON.stringify(pay) !== oldmail) {
199                                 node.send(pay);
200                                 oldmail = JSON.stringify(pay);
201                                 node.log('received new email: '+pay.topic);
202                             }
203                             else { node.log('duplicate not sent: '+pay.topic); }
204                             //node.status({fill:"green",shape:"dot",text:"ok"});
205                             node.status({});
206                             imap.end();
207                         });
208                     }
209                     else {
210                         node.log("you have achieved inbox zero");
211                         //node.status({fill:"green",shape:"dot",text:"ok"});
212                         node.status({});
213                         imap.end();
214                     }
215                 });
216             });
217             node.status({fill:"grey",shape:"dot",text:"connecting"});
218             imap.connect();
219         });
220
221         imap.on('error', function(err) {
222             node.log(err);
223             node.status({fill:"red",shape:"ring",text:"connect error"});
224         });
225
226         this.on("error", function(err) {
227             node.log("error: ",err);
228         });
229
230         this.on("close", function() {
231             if (this.interval_id != null) {
232                 clearInterval(this.interval_id);
233             }
234             if (imap) { imap.destroy(); }
235         });
236
237         node.emit("input",{});
238     }
239     RED.nodes.registerType("e-mail in",EmailInNode,{
240         credentials: {
241             userid: {type:"text"},
242             password: {type: "password"},
243             global: { type:"boolean"}
244         }
245     });
246 }