Email node - better handling of criteria errors

This commit is contained in:
Dave Conway-Jones 2021-07-16 14:41:12 +01:00
parent 245109940c
commit 761bb30ada
No known key found for this signature in database
GPG Key ID: 88BA2B8A411BE9FF
4 changed files with 96 additions and 70 deletions

View File

@ -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();
}
});
}
});
})();

View File

@ -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

View File

@ -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."
}
}
}

View File

@ -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": [