From 761bb30ada8bffb4c37d3ec3333289732a467515 Mon Sep 17 00:00:00 2001 From: Dave Conway-Jones Date: Fri, 16 Jul 2021 14:41:12 +0100 Subject: [PATCH] Email node - better handling of criteria errors --- social/email/61-email.html | 6 + social/email/61-email.js | 150 +++++++++++++---------- social/email/locales/en-US/61-email.json | 6 +- social/email/package.json | 4 +- 4 files changed, 96 insertions(+), 70 deletions(-) diff --git a/social/email/61-email.html b/social/email/61-email.html index a17581f8..b6885ccc 100644 --- a/social/email/61-email.html +++ b/social/email/61-email.html @@ -291,6 +291,12 @@ that.inputs = 0; } }); + $("#node-input-criteria").change(function() { + if ($("#node-input-criteria").val() === "_msg_") { + $("#node-input-fetch").val("trigger"); + $("#node-input-fetch").change(); + } + }); } }); })(); diff --git a/social/email/61-email.js b/social/email/61-email.js index bee1ec66..92845323 100644 --- a/social/email/61-email.js +++ b/social/email/61-email.js @@ -393,78 +393,96 @@ module.exports = function(RED) { var criteria = ((node.criteria === '_msg_')? (msg.criteria || ["UNSEEN"]): ([node.criteria])); - imap.search(criteria, function(err, results) { - if (err) { - node.status({fill:"red", shape:"ring", text:"email.status.foldererror"}); - node.error(RED._("email.errors.fetchfail", {folder:node.box}),err); - imap.end(); - s = false; - setInputRepeatTimeout(); - return; - } - else { - //console.log("> search - err=%j, results=%j", err, results); - if (results.length === 0) { - //console.log(" [X] - Nothing to fetch"); - node.status({results:0}); - imap.end(); - s = false; - setInputRepeatTimeout(); - return; - } - - var marks = false; - if (node.disposition === "Read") { marks = true; } - // We have the search results that contain the list of unseen messages and can now fetch those messages. - var fetch = imap.fetch(results, { - bodies: '', - struct: true, - markSeen: marks - }); - - // For each fetched message returned ... - fetch.on('message', function(imapMessage, seqno) { - //node.log(RED._("email.status.message",{number:seqno})); - //console.log("> Fetch message - msg=%j, seqno=%d", imapMessage, seqno); - imapMessage.on('body', function(stream, info) { - //console.log("> message - body - stream=?, info=%j", info); - simpleParser(stream, {}, function(err, parsed) { - if (err) { - node.status({fill:"red", shape:"ring", text:"email.status.parseerror"}); - node.error(RED._("email.errors.parsefail", {folder:node.box}),err); - } - else { - processNewMessage(msg, parsed); - } - }); - }); // End of msg->body - }); // End of fetch->message - - // When we have fetched all the messages, we don't need the imap connection any more. - fetch.on('end', function() { - node.status({results:results.length}); - var cleanup = function() { + if (Array.isArray(criteria)) { + try { + imap.search(criteria, function(err, results) { + if (err) { + node.status({fill:"red", shape:"ring", text:"email.status.foldererror"}); + node.error(RED._("email.errors.fetchfail", {folder:node.box}),err); imap.end(); s = false; setInputRepeatTimeout(); - }; - if (node.disposition === "Delete") { - imap.addFlags(results, "\Deleted", cleanup); - } else if (node.disposition === "Read") { - imap.addFlags(results, "\Seen", cleanup); - } else { - cleanup(); + return; } - }); + else { + //console.log("> search - err=%j, results=%j", err, results); + if (results.length === 0) { + //console.log(" [X] - Nothing to fetch"); + node.status({results:0}); + imap.end(); + s = false; + setInputRepeatTimeout(); + return; + } - fetch.once('error', function(err) { - console.log('Fetch error: ' + err); - imap.end(); - s = false; - setInputRepeatTimeout(); - }); + var marks = false; + if (node.disposition === "Read") { marks = true; } + // We have the search results that contain the list of unseen messages and can now fetch those messages. + var fetch = imap.fetch(results, { + bodies: '', + struct: true, + markSeen: marks + }); + + // For each fetched message returned ... + fetch.on('message', function(imapMessage, seqno) { + //node.log(RED._("email.status.message",{number:seqno})); + //console.log("> Fetch message - msg=%j, seqno=%d", imapMessage, seqno); + imapMessage.on('body', function(stream, info) { + //console.log("> message - body - stream=?, info=%j", info); + simpleParser(stream, {}, function(err, parsed) { + if (err) { + node.status({fill:"red", shape:"ring", text:"email.status.parseerror"}); + node.error(RED._("email.errors.parsefail", {folder:node.box}),err); + } + else { + processNewMessage(msg, parsed); + } + }); + }); // End of msg->body + }); // End of fetch->message + + // When we have fetched all the messages, we don't need the imap connection any more. + fetch.on('end', function() { + node.status({results:results.length}); + var cleanup = function() { + imap.end(); + s = false; + setInputRepeatTimeout(); + }; + if (node.disposition === "Delete") { + imap.addFlags(results, "\Deleted", cleanup); + } else if (node.disposition === "Read") { + imap.addFlags(results, "\Seen", cleanup); + } else { + cleanup(); + } + }); + + fetch.once('error', function(err) { + console.log('Fetch error: ' + err); + imap.end(); + s = false; + setInputRepeatTimeout(); + }); + } + }); // End of imap->search } - }); // End of imap->search + catch(e) { + node.status({fill:"red", shape:"ring", text:"email.status.bad_criteria"}); + node.error(e.toString(),e); + s = ss = false; + imap.end(); + return; + } + } + else { + node.status({fill:"red", shape:"ring", text:"email.status.bad_criteria"}); + node.error(RED._("email.errors.bad_criteria"),msg); + s = ss = false; + imap.end(); + return; + } } }); // End of imap->openInbox }); // End of imap->ready diff --git a/social/email/locales/en-US/61-email.json b/social/email/locales/en-US/61-email.json index f5aaa8dc..9d876117 100644 --- a/social/email/locales/en-US/61-email.json +++ b/social/email/locales/en-US/61-email.json @@ -54,7 +54,8 @@ "sending": "sending", "sendfail": "send failed", "parseerror": "Failed to parse message", - "connecterror": "connect error" + "connecterror": "connect error", + "bad_criteria": "Invalid criteria" }, "errors": { "nouserid": "No e-mail userid set", @@ -66,7 +67,8 @@ "parsefail": "Failed to parse message", "messageerror": "Fetch message error: __error__", "refreshtoolarge": "Refresh interval too large. Limiting to 2147483 seconds", - "invalidattachment": "Invalid attachment content. Must be String or buffer" + "invalidattachment": "Invalid attachment content. Must be String or buffer", + "bad_criteria": "Criteria must be a JSON array. See info." } } } diff --git a/social/email/package.json b/social/email/package.json index 461a62b2..58ef6089 100644 --- a/social/email/package.json +++ b/social/email/package.json @@ -1,12 +1,12 @@ { "name": "node-red-node-email", - "version": "1.12.2", + "version": "1.12.3", "description": "Node-RED nodes to send and receive simple emails.", "dependencies": { "imap": "^0.8.19", "poplib": "^0.1.7", "mailparser": "^3.2.0", - "nodemailer": "~6.6.2", + "nodemailer": "~6.6.3", "smtp-server": "^3.9.0" }, "bundledDependencies": [