mirror of
https://github.com/node-red/node-red-nodes.git
synced 2025-03-01 10:37:43 +00:00
Merge branch 'master' of github.com:node-red/node-red-nodes
This commit is contained in:
@@ -86,7 +86,7 @@
|
||||
return this._("email.email");
|
||||
},
|
||||
label: function() {
|
||||
return this.dname||this.name||"email";
|
||||
return this.dname||this.name||this._("email.email");
|
||||
},
|
||||
labelStyle: function() {
|
||||
return (this.dname)?"node_label_italic":"";
|
||||
@@ -280,3 +280,37 @@
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/html" data-template-name="e-mail mta">
|
||||
<div class="form-row">
|
||||
<label for="node-input-port"><i class="fa fa-random"></i> <span data-i18n="email.label.port"></span></label>
|
||||
<input type="text" id="node-input-port" style="width:70%;"/>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></span></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
|
||||
</div>
|
||||
<div class="form-tips" id="node-tip"><span data-i18n="[html]email.tip.mta"></span></div>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('e-mail mta',{
|
||||
category: 'social',
|
||||
color:"#c7e9c0",
|
||||
defaults: {
|
||||
name: {value:""},
|
||||
port: {value:"1025",required:true},
|
||||
},
|
||||
inputs:0,
|
||||
outputs:1,
|
||||
icon: "envelope.png",
|
||||
paletteLabel: function() { return this._("email.email") + " MTA" },
|
||||
label: function() {
|
||||
return this.name||this._("email.email") + " MTA";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable indent */
|
||||
|
||||
/**
|
||||
* POP3 protocol - RFC1939 - https://www.ietf.org/rfc/rfc1939.txt
|
||||
@@ -11,11 +12,13 @@
|
||||
|
||||
module.exports = function(RED) {
|
||||
"use strict";
|
||||
var nodemailer = require("nodemailer");
|
||||
var util = require("util");
|
||||
var Imap = require('imap');
|
||||
var POP3Client = require("poplib");
|
||||
var SimpleParser = require("mailparser").simpleParser;
|
||||
var util = require("util");
|
||||
var nodemailer = require("nodemailer");
|
||||
var simpleParser = require("mailparser").simpleParser;
|
||||
var SMTPServer = require("smtp-server").SMTPServer;
|
||||
//var microMTA = require("micromta").microMTA;
|
||||
|
||||
if (parseInt(process.version.split("v")[1].split(".")[0]) < 8) {
|
||||
throw "Error : Requires nodejs version >= 8.";
|
||||
@@ -291,8 +294,8 @@ module.exports = function(RED) {
|
||||
|
||||
// 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.
|
||||
SimpleParser(data, {}, function(err, parsed) {
|
||||
//node.log(util.format("SimpleParser: on(end): %j", mailObject));
|
||||
simpleParser(data, {}, function(err, parsed) {
|
||||
//node.log(util.format("simpleParser: on(end): %j", mailObject));
|
||||
if (err) {
|
||||
node.status({fill:"red", shape:"ring", text:"email.status.parseerror"});
|
||||
node.error(RED._("email.errors.parsefail", {folder:node.box}), err);
|
||||
@@ -341,17 +344,29 @@ module.exports = function(RED) {
|
||||
ss = true;
|
||||
node.status({fill:"blue", shape:"dot", text:"email.status.fetching"});
|
||||
//console.log("> ready");
|
||||
// Open the inbox folder
|
||||
// Open the folder
|
||||
imap.openBox(node.box, // Mailbox name
|
||||
false, // Open readonly?
|
||||
function(err, box) {
|
||||
//console.log("> Inbox err : %j", err);
|
||||
//console.log("> Inbox open: %j", box);
|
||||
if (err) {
|
||||
s = false;
|
||||
var boxs = [];
|
||||
imap.getBoxes(function(err,boxes) {
|
||||
if (err) { return; }
|
||||
for (var prop in boxes) {
|
||||
if (boxes.hasOwnProperty(prop)) {
|
||||
if (boxes[prop].children) {
|
||||
boxs.push(prop+"/{"+Object.keys(boxes[prop].children)+'}');
|
||||
}
|
||||
else { boxs.push(prop); }
|
||||
}
|
||||
}
|
||||
node.error(RED._("email.errors.fetchfail", {folder:node.box+". Folders - "+boxs.join(', ')}),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;
|
||||
}
|
||||
@@ -394,7 +409,7 @@ module.exports = function(RED) {
|
||||
//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) {
|
||||
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);
|
||||
@@ -412,19 +427,21 @@ module.exports = function(RED) {
|
||||
var cleanup = function() {
|
||||
imap.end();
|
||||
s = false;
|
||||
setInputRepeatTimeout();
|
||||
};
|
||||
if (this.disposition === "Delete") {
|
||||
if (node.disposition === "Delete") {
|
||||
imap.addFlags(results, "\Deleted", cleanup);
|
||||
} else if (this.disposition === "Read") {
|
||||
} else if (node.disposition === "Read") {
|
||||
imap.addFlags(results, "\Seen", cleanup);
|
||||
} else {
|
||||
cleanup();
|
||||
}
|
||||
setInputRepeatTimeout();
|
||||
});
|
||||
|
||||
fetch.once('error', function(err) {
|
||||
console.log('Fetch error: ' + err);
|
||||
imap.end();
|
||||
s = false;
|
||||
setInputRepeatTimeout();
|
||||
});
|
||||
}
|
||||
@@ -442,7 +459,7 @@ module.exports = function(RED) {
|
||||
if (node.protocol === "POP3") {
|
||||
checkPOP3(msg);
|
||||
} else if (node.protocol === "IMAP") {
|
||||
if (s === false) { checkIMAP(msg); }
|
||||
if (s === false && ss == false) { checkIMAP(msg); }
|
||||
}
|
||||
} // End of checkEmail
|
||||
|
||||
@@ -499,4 +516,61 @@ module.exports = function(RED) {
|
||||
global: { type:"boolean" }
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function EmailMtaNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.port = n.port;
|
||||
var node = this;
|
||||
|
||||
node.mta = new SMTPServer({
|
||||
secure: false,
|
||||
logger: false,
|
||||
disabledCommands: ['AUTH', 'STARTTLS'],
|
||||
|
||||
onData: function (stream, session, callback) {
|
||||
simpleParser(stream, { skipTextToHtml:true, skipTextLinks:true }, (err, parsed) => {
|
||||
if (err) { node.error(RED._("email.errors.parsefail"),err); }
|
||||
else {
|
||||
node.status({fill:"green", shape:"dot", text:""});
|
||||
var msg = {}
|
||||
msg.payload = parsed.text;
|
||||
msg.topic = parsed.subject;
|
||||
msg.date = parsed.date;
|
||||
msg.header = {};
|
||||
parsed.headers.forEach((v, k) => {msg.header[k] = v;});
|
||||
if (parsed.html) { msg.html = parsed.html; }
|
||||
if (parsed.to) {
|
||||
if (typeof(parsed.to) === "string" && parsed.to.length > 0) { msg.to = parsed.to; }
|
||||
else if (parsed.to.hasOwnProperty("text") && parsed.to.text.length > 0) { msg.to = parsed.to.text; }
|
||||
}
|
||||
if (parsed.cc) {
|
||||
if (typeof(parsed.cc) === "string" && parsed.cc.length > 0) { msg.cc = parsed.cc; }
|
||||
else if (parsed.cc.hasOwnProperty("text") && parsed.cc.text.length > 0) { msg.cc = parsed.cc.text; }
|
||||
}
|
||||
if (parsed.cc && parsed.cc.length > 0) { msg.cc = parsed.cc; }
|
||||
if (parsed.bcc && parsed.bcc.length > 0) { msg.bcc = parsed.bcc; }
|
||||
if (parsed.from && parsed.from.value && parsed.from.value.length > 0) { msg.from = parsed.from.value[0].address; }
|
||||
if (parsed.attachments) { msg.attachments = parsed.attachments; }
|
||||
else { msg.attachments = []; }
|
||||
node.send(msg); // Propagate the message down the flow
|
||||
setTimeout(function() { node.status({})}, 500);
|
||||
}
|
||||
callback();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
node.mta.listen(node.port);
|
||||
|
||||
node.mta.on("error", err => {
|
||||
node.error("Error: " + err.message, err);
|
||||
});
|
||||
|
||||
node.on("close", function() {
|
||||
node.mta.close();
|
||||
});
|
||||
}
|
||||
RED.nodes.registerType("e-mail mta",EmailMtaNode);
|
||||
|
||||
};
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<p>Additionally <code>msg.header</code> contains the complete header object including
|
||||
<i>to</i>, <i>cc</i> and other potentially useful properties.</p>
|
||||
<p>It can optionally mark the message as Read (default), Delete it, or leave unmarked (None).</p>
|
||||
<p>Uses the <a href="https://github.com/mscdex/node-imap/blob/master/README.md" target="_new">node-imap module</a> - see that page for
|
||||
<p>Uses the <a href="https://github.com/mscdex/node-imap/blob/master/README.md" target="_new">node-imap module</a> - see that page for
|
||||
information on the <code>msg.criteria</code> format if needed.</p>
|
||||
<p><b>Note</b>: uses IMAP with SSL to port 993.</p>
|
||||
<p>Any attachments supplied in the incoming email can be found in the <code>msg.attachments</code> property. This will be an array of objects where
|
||||
@@ -51,3 +51,13 @@
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-help-name="e-mail mta">
|
||||
<p>Mail Transfer Agent - listens on a port for incoming SMTP mail.</p>
|
||||
<p><b>Note</b>: "NOT for production use" as there is no security built in.
|
||||
This is primarily for local testing of outbound mail sending, but could be used
|
||||
as a mail forwarder to a real email service if required.</p>
|
||||
<p>To use ports below 1024, for example 25 or 465, you may need to get privileged access.
|
||||
On linux systems this can be done by running
|
||||
<pre>sudo setcap 'cap_net_bind_service=+eip' $(which node)</pre>
|
||||
and restarting Node-RED. Be aware - this gives all node applications access to all ports.</p>
|
||||
</script>
|
||||
@@ -34,7 +34,8 @@
|
||||
"default-message": "__description__\n\nFile from Node-RED is attached: __filename__",
|
||||
"tip": {
|
||||
"cred": "<b>Note:</b> Copied credentials from global emailkeys.js file.",
|
||||
"recent": "Tip: Only retrieves the single most recent email."
|
||||
"recent": "Tip: Only retrieves the single most recent email.",
|
||||
"mta": "<b>Note:</b> To use ports below 1024 you may need elevated (root) privileges. See help sidebar."
|
||||
},
|
||||
"status": {
|
||||
"messagesent": "Message sent: __response__",
|
||||
@@ -47,6 +48,7 @@
|
||||
"inboxzero": "you have achieved Inbox Zero",
|
||||
"sending": "sending",
|
||||
"sendfail": "send failed",
|
||||
"parseerror": "Failed to parse message",
|
||||
"connecterror": "connect error"
|
||||
},
|
||||
"errors": {
|
||||
@@ -56,6 +58,7 @@
|
||||
"nosmtptransport": "No SMTP transport. See info panel.",
|
||||
"nopayload": "No payload to send",
|
||||
"fetchfail": "Failed to fetch folder: __folder__",
|
||||
"parsefail": "Failed to parse message",
|
||||
"messageerror": "Fetch message error: __error__",
|
||||
"refreshtoolarge": "Refresh interval too large. Limiting to 2147483 seconds"
|
||||
}
|
||||
|
||||
@@ -38,3 +38,13 @@
|
||||
<p>POP3プロトコルでのデフォルトポート番号は、素のTCPでは110番、SSLでは995番です。IMAPプロトコルでは、素のTCPでは143番、SSLでは993番です。</p>
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-help-name="e-mail mta">
|
||||
<p>メール転送エージェント - 入ってくるSMTPメールのため、ポートでリッスンします。</p>
|
||||
<p><b>注釈</b>: セキュリティが組み込まれていないため、"プロダクション向けではありません"。
|
||||
これは主に、外部へのメール送信のローカルテスト向けですが、必要に応じて実際のメールサービスへのメール転送としても使用できます。</p>
|
||||
<p>1024未満のポート(例えば25や465など)を使用するには、特権的アクセスを得る必要がある場合があります。
|
||||
Linuxシステムでは以下のコマンドを実行し、Node-REDを再起動することで達成できます。
|
||||
<pre>sudo setcap ‘cap_net_bind_service=+eip’ $(which node)</pre>
|
||||
これによって、全てのnodeアプリケーションが全ポートにアクセスできる様になることに注意してください.</p>
|
||||
</script>
|
||||
@@ -21,7 +21,8 @@
|
||||
"default-message": "__description__\n\nNode-REDからファイルが添付されました: __filename__",
|
||||
"tip": {
|
||||
"cred": "<b>注釈:</b> emailkeys.jsファイルから認証情報をコピーしました。",
|
||||
"recent": "注釈: 最新のメールを1件のみ取得します。"
|
||||
"recent": "注釈: 最新のメールを1件のみ取得します。",
|
||||
"mta": "<b>注釈:</b> 1024未満のポートを使用するには、昇格された(root)特権が必要です。ヘルプサイドバーを参照してください。"
|
||||
},
|
||||
"status": {
|
||||
"messagesent": "メッセージを送信しました: __response__",
|
||||
@@ -34,6 +35,7 @@
|
||||
"inboxzero": "受信トレイにメールがありません",
|
||||
"sending": "送信中",
|
||||
"sendfail": "送信が失敗しました",
|
||||
"parseerror": "メッセージのパースに失敗",
|
||||
"connecterror": "接続エラー"
|
||||
},
|
||||
"errors": {
|
||||
@@ -43,6 +45,7 @@
|
||||
"nosmtptransport": "SMTP転送が設定されていません。「情報」タブを参照してください",
|
||||
"nopayload": "送信するペイロードがありません",
|
||||
"fetchfail": "フォルダの受信に失敗しました: __folder__",
|
||||
"parsefail": "メッセージのパースに失敗",
|
||||
"messageerror": "メッセージ受信エラー: __error__"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
{
|
||||
"name": "node-red-node-email",
|
||||
"version": "1.7.8",
|
||||
"description": "Node-RED nodes to send and receive simple emails",
|
||||
"version": "1.8.1",
|
||||
"description": "Node-RED nodes to send and receive simple emails.",
|
||||
"dependencies": {
|
||||
"imap": "^0.8.19",
|
||||
"mailparser": "^2.7.7",
|
||||
"nodemailer": "^6.4.6",
|
||||
"poplib": "^0.1.7"
|
||||
"poplib": "^0.1.7",
|
||||
"mailparser": "^3.0.0",
|
||||
"nodemailer": "~6.4.10",
|
||||
"smtp-server": "^3.7.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -18,7 +19,8 @@
|
||||
"email",
|
||||
"gmail",
|
||||
"imap",
|
||||
"pop"
|
||||
"pop",
|
||||
"mta"
|
||||
],
|
||||
"node-red": {
|
||||
"nodes": {
|
||||
|
||||
@@ -3,9 +3,7 @@ module.exports = function(RED) {
|
||||
"use strict";
|
||||
var PushBullet = require('pushbullet');
|
||||
var fs = require('fs');
|
||||
var util = require('util');
|
||||
var when = require('when');
|
||||
var nodefn = require('when/node');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
|
||||
function onError(err, node) {
|
||||
@@ -127,17 +125,19 @@ module.exports = function(RED) {
|
||||
stream.on('close', function() {
|
||||
self.emitter.emit('stream_disconnected');
|
||||
if (!closing) {
|
||||
if (tout) { clearTimeout(tout); }
|
||||
tout = setTimeout(function() {
|
||||
stream.connect();
|
||||
},15000);
|
||||
}, 15000);
|
||||
}
|
||||
});
|
||||
stream.on('error', function(err) {
|
||||
self.emitter.emit('stream_error', err);
|
||||
if (!closing) {
|
||||
if (tout) { clearTimeout(tout); }
|
||||
tout = setTimeout(function() {
|
||||
stream.connect();
|
||||
},15000);
|
||||
}, 15000);
|
||||
}
|
||||
});
|
||||
stream.connect();
|
||||
@@ -229,10 +229,14 @@ module.exports = function(RED) {
|
||||
msg.payload = incoming.body;
|
||||
}
|
||||
else if (incoming.type === 'dismissal') {
|
||||
msg.topic = "dismissal";
|
||||
msg.topic = "Push dismissed";
|
||||
msg.payload = incoming.iden;
|
||||
}
|
||||
else if (incoming.type === 'sms_changed') {
|
||||
msg.topic = "SMS: "+ incoming.notifications[0].title;
|
||||
msg.payload = incoming.notifications[0].body;
|
||||
msg.message = incoming;
|
||||
}
|
||||
else {
|
||||
this.error("unknown push type: " + incoming.type + " content: " + JSON.stringify(incoming));
|
||||
return;
|
||||
@@ -257,8 +261,7 @@ module.exports = function(RED) {
|
||||
try {
|
||||
pushkeys = RED.settings.pushbullet || require(process.env.NODE_RED_HOME+"/../pushkey.js");
|
||||
}
|
||||
catch(err) {
|
||||
}
|
||||
catch(err) { }
|
||||
|
||||
var cred = RED.nodes.getCredentials(n.id);
|
||||
// get old apikey
|
||||
@@ -327,7 +330,7 @@ module.exports = function(RED) {
|
||||
try {
|
||||
this.deviceid = this.credentials.deviceid;
|
||||
}
|
||||
catch(err) {}
|
||||
catch(err) { }
|
||||
}
|
||||
|
||||
if (configNode) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name" : "node-red-node-pushbullet",
|
||||
"version" : "0.0.14",
|
||||
"version" : "0.0.17",
|
||||
"description" : "A Node-RED node to send alerts via Pushbullet",
|
||||
"dependencies" : {
|
||||
"pushbullet": "^2.4.0",
|
||||
|
||||
@@ -103,8 +103,8 @@ module.exports = function(RED) {
|
||||
if (err) { node.error(err,msg); }
|
||||
else {
|
||||
try {
|
||||
response = JSON.parse(response);
|
||||
if (response.status !== 1) { node.error("[57-pushover.js] Error: "+response); }
|
||||
var responseObject = JSON.parse(response);
|
||||
if (responseObject.status !== 1) { node.error("[57-pushover.js] Error: "+response); }
|
||||
}
|
||||
catch(e) {
|
||||
node.error("[57-pushover.js] Error: "+response);
|
||||
|
||||
@@ -155,7 +155,7 @@ module.exports = function(RED) {
|
||||
}
|
||||
}
|
||||
else if(stanza.attrs.type === 'result'){
|
||||
// AM To-Do check for 'bind' result with our current jid
|
||||
// To-Do check for 'bind' result with our current jid
|
||||
var query = stanza.getChild('query');
|
||||
if (RED.settings.verbose || LOGITALL) {that.log("result!");}
|
||||
if (RED.settings.verbose || LOGITALL) {that.log(query);}
|
||||
@@ -164,7 +164,6 @@ module.exports = function(RED) {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// We shouldn't have any errors here that the input/output nodes can't handle
|
||||
// if you need to see everything though; uncomment this block
|
||||
// this.client.on('error', err => {
|
||||
@@ -497,6 +496,10 @@ module.exports = function(RED) {
|
||||
node.error("Server doesn't exist "+xmpp.options.service,err);
|
||||
node.status({fill:"red",shape:"ring",text:"bad address"});
|
||||
}
|
||||
if (err.errno === "ENOTFOUND") {
|
||||
node.error("Server doesn't exist "+xmpp.options.service,err);
|
||||
node.status({fill:"red",shape:"ring",text:"bad address"});
|
||||
}
|
||||
else if (err === "XMPP authentication failure") {
|
||||
node.error(err,err);
|
||||
node.status({fill:"red",shape:"ring",text:"XMPP authentication failure"});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "node-red-node-xmpp",
|
||||
"version": "0.2.4",
|
||||
"version": "0.3.0",
|
||||
"description": "A Node-RED node to talk to an XMPP server",
|
||||
"dependencies": {
|
||||
"@xmpp/client": "^0.11.1"
|
||||
|
||||
Reference in New Issue
Block a user