mirror of
https://github.com/node-red/node-red-nodes.git
synced 2023-10-10 13:36:58 +02:00
tidy up email listing - no code changes
This commit is contained in:
parent
3107080b19
commit
1cfb5f403d
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright 2013, 2015 IBM Corp.
|
* Copyright 2013, 2016 IBM Corp.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* POP3 protocol - RFC1939 - https://www.ietf.org/rfc/rfc1939.txt
|
* POP3 protocol - RFC1939 - https://www.ietf.org/rfc/rfc1939.txt
|
||||||
*
|
*
|
||||||
* Dependencies:
|
* Dependencies:
|
||||||
* * poplib - https://www.npmjs.com/package/poplib
|
* * poplib - https://www.npmjs.com/package/poplib
|
||||||
* * nodemailer - https://www.npmjs.com/package/nodemailer
|
* * nodemailer - https://www.npmjs.com/package/nodemailer
|
||||||
@ -27,7 +27,7 @@
|
|||||||
module.exports = function(RED) {
|
module.exports = function(RED) {
|
||||||
"use strict";
|
"use strict";
|
||||||
var nodemailer = require("nodemailer");
|
var nodemailer = require("nodemailer");
|
||||||
var Imap = require('imap');
|
var Imap = require('imap');
|
||||||
var POP3Client = require("poplib");
|
var POP3Client = require("poplib");
|
||||||
var MailParser = require("mailparser").MailParser;
|
var MailParser = require("mailparser").MailParser;
|
||||||
var util = require("util");
|
var util = require("util");
|
||||||
@ -133,26 +133,26 @@ module.exports = function(RED) {
|
|||||||
global: { type:"boolean"}
|
global: { type:"boolean"}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// EmailInNode
|
//
|
||||||
//
|
// EmailInNode
|
||||||
// Setup the EmailInNode
|
//
|
||||||
|
// Setup the EmailInNode
|
||||||
function EmailInNode(n) {
|
function EmailInNode(n) {
|
||||||
var imap;
|
var imap;
|
||||||
|
|
||||||
RED.nodes.createNode(this,n);
|
RED.nodes.createNode(this,n);
|
||||||
this.name = n.name;
|
this.name = n.name;
|
||||||
this.repeat = n.repeat * 1000 || 300000;
|
this.repeat = n.repeat * 1000 || 300000;
|
||||||
this.inserver = n.server || (globalkeys && globalkeys.server) || "imap.gmail.com";
|
this.inserver = n.server || (globalkeys && globalkeys.server) || "imap.gmail.com";
|
||||||
this.inport = n.port || (globalkeys && globalkeys.port) || "993";
|
this.inport = n.port || (globalkeys && globalkeys.port) || "993";
|
||||||
this.box = n.box || "INBOX";
|
this.box = n.box || "INBOX";
|
||||||
this.useSSL = n.useSSL;
|
this.useSSL= n.useSSL;
|
||||||
this.protocol = n.protocol || "IMAP";
|
this.protocol = n.protocol || "IMAP";
|
||||||
this.disposition = n.disposition || "None"; // "None", "Delete", "Read"
|
this.disposition = n.disposition || "None"; // "None", "Delete", "Read"
|
||||||
|
|
||||||
var flag = false;
|
var flag = false;
|
||||||
|
|
||||||
if (this.credentials && this.credentials.hasOwnProperty("userid")) {
|
if (this.credentials && this.credentials.hasOwnProperty("userid")) {
|
||||||
@ -181,14 +181,14 @@ module.exports = function(RED) {
|
|||||||
|
|
||||||
var node = this;
|
var node = this;
|
||||||
this.interval_id = null;
|
this.interval_id = null;
|
||||||
|
|
||||||
// Process a new email message by building a Node-RED message to be passed onwards
|
// Process a new email message by building a Node-RED message to be passed onwards
|
||||||
// in the message flow. The parameter called `msg` is the template message we
|
// in the message flow. The parameter called `msg` is the template message we
|
||||||
// start with while `mailMessage` is an object returned from `mailparser` that
|
// start with while `mailMessage` is an object returned from `mailparser` that
|
||||||
// will be used to populate the email.
|
// will be used to populate the email.
|
||||||
function processNewMessage(msg, mailMessage) {
|
function processNewMessage(msg, mailMessage) {
|
||||||
msg = JSON.parse(JSON.stringify(msg)); // Clone the message
|
msg = JSON.parse(JSON.stringify(msg)); // Clone the message
|
||||||
|
|
||||||
// Populate the msg fields from the content of the email message
|
// Populate the msg fields from the content of the email message
|
||||||
// that we have just parsed.
|
// that we have just parsed.
|
||||||
msg.html = mailMessage.html;
|
msg.html = mailMessage.html;
|
||||||
@ -204,25 +204,25 @@ module.exports = function(RED) {
|
|||||||
if (mailMessage.from && mailMessage.from.length > 0) {
|
if (mailMessage.from && mailMessage.from.length > 0) {
|
||||||
msg.from = mailMessage.from[0].address;
|
msg.from = mailMessage.from[0].address;
|
||||||
}
|
}
|
||||||
|
|
||||||
node.send(msg); // Propagate the message down the flow
|
node.send(msg); // Propagate the message down the flow
|
||||||
}; // End of processNewMessage
|
} // End of processNewMessage
|
||||||
|
|
||||||
// Check the POP3 email mailbox for any new messages. For any that are found,
|
// Check the POP3 email mailbox for any new messages. For any that are found,
|
||||||
// retrieve each message, call processNewMessage to process it and then delete
|
// retrieve each message, call processNewMessage to process it and then delete
|
||||||
// the messages from the server.
|
// the messages from the server.
|
||||||
function checkPOP3(msg) {
|
function checkPOP3(msg) {
|
||||||
var currentMessage;
|
var currentMessage;
|
||||||
var maxMessage;
|
var maxMessage;
|
||||||
|
|
||||||
// Form a new connection to our email server using POP3.
|
// Form a new connection to our email server using POP3.
|
||||||
var pop3Client = new POP3Client(
|
var pop3Client = new POP3Client(
|
||||||
node.inport, node.inserver,
|
node.inport, node.inserver,
|
||||||
{enabletls: node.useSSL} // Should we use SSL to connect to our email server?
|
{enabletls: node.useSSL} // Should we use SSL to connect to our email server?
|
||||||
);
|
);
|
||||||
|
|
||||||
// If we have a next message to retrieve, ask to retrieve it otherwise issue a
|
// If we have a next message to retrieve, ask to retrieve it otherwise issue a
|
||||||
// quit request.
|
// quit request.
|
||||||
function nextMessage() {
|
function nextMessage() {
|
||||||
if (currentMessage > maxMessage) {
|
if (currentMessage > maxMessage) {
|
||||||
pop3Client.quit();
|
pop3Client.quit();
|
||||||
@ -231,22 +231,22 @@ module.exports = function(RED) {
|
|||||||
pop3Client.retr(currentMessage);
|
pop3Client.retr(currentMessage);
|
||||||
currentMessage++;
|
currentMessage++;
|
||||||
} // End of nextMessage
|
} // End of nextMessage
|
||||||
|
|
||||||
pop3Client.on("stat", function(status, data) {
|
pop3Client.on("stat", function(status, data) {
|
||||||
// Data contains:
|
// Data contains:
|
||||||
// {
|
// {
|
||||||
// count: <Number of messages to be read>
|
// count: <Number of messages to be read>
|
||||||
// octect: <size of messages to be read>
|
// octect: <size of messages to be read>
|
||||||
// }
|
// }
|
||||||
if (status) {
|
if (status) {
|
||||||
currentMessage = 1;
|
currentMessage = 1;
|
||||||
maxMessage = data.count;
|
maxMessage = data.count;
|
||||||
nextMessage();
|
nextMessage();
|
||||||
} else {
|
} else {
|
||||||
node.log(util.format("stat error: %s %j", status, data));
|
node.log(util.format("stat error: %s %j", status, data));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
pop3Client.on("error", function(err) {
|
pop3Client.on("error", function(err) {
|
||||||
node.log("We caught an error: " + JSON.stringify(err));
|
node.log("We caught an error: " + JSON.stringify(err));
|
||||||
});
|
});
|
||||||
@ -270,8 +270,8 @@ module.exports = function(RED) {
|
|||||||
node.log(util.format("retr: status=%s, msgNumber=%d, data=%j", status, msgNumber, data));
|
node.log(util.format("retr: status=%s, msgNumber=%d, data=%j", status, msgNumber, data));
|
||||||
if (status) {
|
if (status) {
|
||||||
|
|
||||||
// We have now received a new email message. Create an instance of a mail parser
|
// We have now received a new email message. Create an instance of a mail parser
|
||||||
// and pass in the email message. The parser will signal when it has parsed the message.
|
// and pass in the email message. The parser will signal when it has parsed the message.
|
||||||
var mailparser = new MailParser();
|
var mailparser = new MailParser();
|
||||||
mailparser.on("end", function(mailObject) {
|
mailparser.on("end", function(mailObject) {
|
||||||
//node.log(util.format("mailparser: on(end): %j", mailObject));
|
//node.log(util.format("mailparser: on(end): %j", mailObject));
|
||||||
@ -280,7 +280,7 @@ module.exports = function(RED) {
|
|||||||
mailparser.write(data);
|
mailparser.write(data);
|
||||||
mailparser.end();
|
mailparser.end();
|
||||||
pop3Client.dele(msgNumber);
|
pop3Client.dele(msgNumber);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
node.log(util.format("retr error: %s %j", status, rawData));
|
node.log(util.format("retr error: %s %j", status, rawData));
|
||||||
pop3Client.quit();
|
pop3Client.quit();
|
||||||
@ -294,129 +294,129 @@ module.exports = function(RED) {
|
|||||||
pop3Client.on("locked", function(cmd) {
|
pop3Client.on("locked", function(cmd) {
|
||||||
node.log("We were locked: " + cmd);
|
node.log("We were locked: " + cmd);
|
||||||
});
|
});
|
||||||
|
|
||||||
// When we have deleted the last processed message, we can move on to
|
// When we have deleted the last processed message, we can move on to
|
||||||
// processing the next message.
|
// processing the next message.
|
||||||
pop3Client.on("dele", function(status, msgNumber) {
|
pop3Client.on("dele", function(status, msgNumber) {
|
||||||
nextMessage();
|
nextMessage();
|
||||||
});
|
});
|
||||||
}; // End of checkPOP3
|
} // End of checkPOP3
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// checkIMAP
|
// checkIMAP
|
||||||
//
|
//
|
||||||
// Check the email sever using the IMAP protocol for new messages.
|
// Check the email sever using the IMAP protocol for new messages.
|
||||||
function checkIMAP(msg) {
|
function checkIMAP(msg) {
|
||||||
node.log("Checkimg IMAP for new messages");
|
node.log("Checkimg IMAP for new messages");
|
||||||
// We get back a 'ready' event once we have connected to imap
|
// We get back a 'ready' event once we have connected to imap
|
||||||
imap.once("ready", function() {
|
imap.once("ready", function() {
|
||||||
node.status({fill:"blue", shape:"dot", text:"email.status.fetching"});
|
node.status({fill:"blue", shape:"dot", text:"email.status.fetching"});
|
||||||
console.log("> ready");
|
console.log("> ready");
|
||||||
// Open the inbox folder
|
// Open the inbox folder
|
||||||
imap.openBox('INBOX', // Mailbox name
|
imap.openBox('INBOX', // Mailbox name
|
||||||
false, // Open readonly?
|
false, // Open readonly?
|
||||||
function(err, box) {
|
function(err, box) {
|
||||||
console.log("> Inbox open: %j", box);
|
console.log("> Inbox open: %j", box);
|
||||||
imap.search([ 'UNSEEN' ], function(err, results) {
|
imap.search([ 'UNSEEN' ], function(err, results) {
|
||||||
if (err) {
|
if (err) {
|
||||||
node.status({fill:"red", shape:"ring", text:"email.status.foldererror"});
|
node.status({fill:"red", shape:"ring", text:"email.status.foldererror"});
|
||||||
node.error(RED._("email.errors.fetchfail", {folder:node.box}),err);
|
node.error(RED._("email.errors.fetchfail", {folder:node.box}),err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log("> search - err=%j, results=%j", err, results);
|
console.log("> search - err=%j, results=%j", err, results);
|
||||||
if (results.length === 0) {
|
if (results.length === 0) {
|
||||||
console.log(" [X] - Nothing to fetch");
|
console.log(" [X] - Nothing to fetch");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have the search results that contain the list of unseen messages and can now fetch those messages.
|
// We have the search results that contain the list of unseen messages and can now fetch those messages.
|
||||||
var fetch = imap.fetch(results, {
|
var fetch = imap.fetch(results, {
|
||||||
bodies : ["HEADER", "TEXT"],
|
bodies : ["HEADER", "TEXT"],
|
||||||
markSeen : true
|
markSeen : true
|
||||||
});
|
});
|
||||||
|
|
||||||
// For each fetched message returned ...
|
// For each fetched message returned ...
|
||||||
fetch.on('message', function(imapMessage, seqno) {
|
fetch.on('message', function(imapMessage, seqno) {
|
||||||
node.log(RED._("email.status.message",{number:seqno}));
|
node.log(RED._("email.status.message",{number:seqno}));
|
||||||
var messageText = "";
|
var messageText = "";
|
||||||
console.log("> Fetch message - msg=%j, seqno=%d", imapMessage, seqno);
|
console.log("> Fetch message - msg=%j, seqno=%d", imapMessage, seqno);
|
||||||
imapMessage.on('body', function(stream, info) {
|
imapMessage.on('body', function(stream, info) {
|
||||||
console.log("> message - body - stream=?, info=%j", info);
|
console.log("> message - body - stream=?, info=%j", info);
|
||||||
// Info defined which part of the message this is ... for example
|
// Info defined which part of the message this is ... for example
|
||||||
// 'TEXT' or 'HEADER'
|
// 'TEXT' or 'HEADER'
|
||||||
stream.on('data', function(chunk) {
|
stream.on('data', function(chunk) {
|
||||||
console.log("> stream - data - chunk=??");
|
console.log("> stream - data - chunk=??");
|
||||||
messageText += chunk.toString('utf8');
|
messageText += chunk.toString('utf8');
|
||||||
});
|
});
|
||||||
}); // End of msg->body
|
}); // End of msg->body
|
||||||
// When the `end` event is raised on the message
|
// When the `end` event is raised on the message
|
||||||
imapMessage.once('end', function() {
|
imapMessage.once('end', function() {
|
||||||
console.log("> msg - end : %j", messageText);
|
console.log("> msg - end : %j", messageText);
|
||||||
var mailparser = new MailParser();
|
var mailparser = new MailParser();
|
||||||
mailparser.on("end", function(mailMessage) {
|
mailparser.on("end", function(mailMessage) {
|
||||||
//console.log("mailparser: on(end): %j", mailMessage);
|
//console.log("mailparser: on(end): %j", mailMessage);
|
||||||
processNewMessage(msg, mailMessage);
|
processNewMessage(msg, mailMessage);
|
||||||
});
|
});
|
||||||
mailparser.write(messageText);
|
mailparser.write(messageText);
|
||||||
mailparser.end();
|
mailparser.end();
|
||||||
}); // End of msg->end
|
}); // End of msg->end
|
||||||
}); // End of fetch->message
|
}); // End of fetch->message
|
||||||
|
|
||||||
// When we have fetched all the messages, we don't need the imap connection any more.
|
// When we have fetched all the messages, we don't need the imap connection any more.
|
||||||
fetch.on('end', function() {
|
fetch.on('end', function() {
|
||||||
var cleanup = function() {
|
var cleanup = function() {
|
||||||
node.status({});
|
node.status({});
|
||||||
imap.end();
|
imap.end();
|
||||||
};
|
};
|
||||||
if (this.disposition == "Delete") {
|
if (this.disposition == "Delete") {
|
||||||
imap.addFlags(results, "\Deleted", cleanup);
|
imap.addFlags(results, "\Deleted", cleanup);
|
||||||
} else if (this.disposition == "Read") {
|
} else if (this.disposition == "Read") {
|
||||||
imap.addFlags(results, "\Answered", cleanup);
|
imap.addFlags(results, "\Answered", cleanup);
|
||||||
} else {
|
} else {
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
fetch.once('error', function(err) {
|
fetch.once('error', function(err) {
|
||||||
console.log('Fetch error: ' + err);
|
console.log('Fetch error: ' + err);
|
||||||
});
|
});
|
||||||
}); // End of imap->search
|
}); // End of imap->search
|
||||||
}); // End of imap->openInbox
|
}); // End of imap->openInbox
|
||||||
}); // End of imap->ready
|
}); // End of imap->ready
|
||||||
imap.connect();
|
imap.connect();
|
||||||
node.status({fill:"grey",shape:"dot",text:"node-red:common.status.connecting"});
|
node.status({fill:"grey",shape:"dot",text:"node-red:common.status.connecting"});
|
||||||
}; // End of checkIMAP
|
} // End of checkIMAP
|
||||||
|
|
||||||
|
|
||||||
// Perform a check of the email inboxes using either POP3 or IMAP
|
// Perform a check of the email inboxes using either POP3 or IMAP
|
||||||
function checkEmail(msg) {
|
function checkEmail(msg) {
|
||||||
if (node.protocol === "POP3") {
|
if (node.protocol === "POP3") {
|
||||||
checkPOP3(msg);
|
checkPOP3(msg);
|
||||||
} else if (node.protocol === "IMAP") {
|
} else if (node.protocol === "IMAP") {
|
||||||
checkIMAP(msg);
|
checkIMAP(msg);
|
||||||
}
|
}
|
||||||
}; // End of checkEmail
|
} // End of checkEmail
|
||||||
|
|
||||||
if (node.protocol === "IMAP") {
|
if (node.protocol === "IMAP") {
|
||||||
imap = new Imap({
|
imap = new Imap({
|
||||||
user: node.userid,
|
user: node.userid,
|
||||||
password: node.password,
|
password: node.password,
|
||||||
host: node.inserver,
|
host: node.inserver,
|
||||||
port: node.inport,
|
port: node.inport,
|
||||||
tls: node.useSSL,
|
tls: node.useSSL,
|
||||||
tlsOptions: { rejectUnauthorized: false },
|
tlsOptions: { rejectUnauthorized: false },
|
||||||
connTimeout: node.repeat,
|
connTimeout: node.repeat,
|
||||||
authTimeout: node.repeat
|
authTimeout: node.repeat
|
||||||
});
|
});
|
||||||
imap.on('error', function(err) {
|
imap.on('error', function(err) {
|
||||||
node.log(err);
|
node.log(err);
|
||||||
node.status({fill:"red",shape:"ring",text:"email.status.connecterror"});
|
node.status({fill:"red",shape:"ring",text:"email.status.connecterror"});
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
this.on("input", function(msg) {
|
this.on("input", function(msg) {
|
||||||
checkEmail(msg);
|
checkEmail(msg);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.on("close", function() {
|
this.on("close", function() {
|
||||||
@ -426,21 +426,21 @@ module.exports = function(RED) {
|
|||||||
if (imap) { imap.destroy(); }
|
if (imap) { imap.destroy(); }
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set the repetition timer as needed
|
// Set the repetition timer as needed
|
||||||
if (!isNaN(this.repeat) && this.repeat > 0) {
|
if (!isNaN(this.repeat) && this.repeat > 0) {
|
||||||
this.interval_id = setInterval( function() {
|
this.interval_id = setInterval( function() {
|
||||||
|
node.emit("input",{});
|
||||||
|
}, this.repeat );
|
||||||
|
}
|
||||||
|
|
||||||
node.emit("input",{});
|
node.emit("input",{});
|
||||||
}, this.repeat );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
node.emit("input",{});
|
|
||||||
}
|
|
||||||
|
|
||||||
RED.nodes.registerType("e-mail in",EmailInNode,{
|
RED.nodes.registerType("e-mail in",EmailInNode,{
|
||||||
credentials: {
|
credentials: {
|
||||||
userid: { type:"text" },
|
userid: { type:"text" },
|
||||||
password: { type: "password" },
|
password: { type: "password" },
|
||||||
global: { type:"boolean" }
|
global: { type:"boolean" }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user