mirror of
https://github.com/node-red/node-red-nodes.git
synced 2023-10-10 13:36:58 +02:00
Add MTA node to email
This commit is contained in:
parent
8f2c631410
commit
14087a9f77
@ -86,7 +86,7 @@
|
|||||||
return this._("email.email");
|
return this._("email.email");
|
||||||
},
|
},
|
||||||
label: function() {
|
label: function() {
|
||||||
return this.dname||this.name||"email";
|
return this.dname||this.name||this._("email.email");
|
||||||
},
|
},
|
||||||
labelStyle: function() {
|
labelStyle: function() {
|
||||||
return (this.dname)?"node_label_italic":"";
|
return (this.dname)?"node_label_italic":"";
|
||||||
@ -280,3 +280,37 @@
|
|||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
</script>
|
</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
|
* POP3 protocol - RFC1939 - https://www.ietf.org/rfc/rfc1939.txt
|
||||||
@ -11,11 +12,13 @@
|
|||||||
|
|
||||||
module.exports = function(RED) {
|
module.exports = function(RED) {
|
||||||
"use strict";
|
"use strict";
|
||||||
var nodemailer = require("nodemailer");
|
var util = require("util");
|
||||||
var Imap = require('imap');
|
var Imap = require('imap');
|
||||||
var POP3Client = require("poplib");
|
var POP3Client = require("poplib");
|
||||||
var SimpleParser = require("mailparser").simpleParser;
|
var nodemailer = require("nodemailer");
|
||||||
var util = require("util");
|
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) {
|
if (parseInt(process.version.split("v")[1].split(".")[0]) < 8) {
|
||||||
throw "Error : Requires nodejs version >= 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
|
// 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.
|
||||||
SimpleParser(data, {}, function(err, parsed) {
|
simpleParser(data, {}, function(err, parsed) {
|
||||||
//node.log(util.format("SimpleParser: on(end): %j", mailObject));
|
//node.log(util.format("simpleParser: on(end): %j", mailObject));
|
||||||
if (err) {
|
if (err) {
|
||||||
node.status({fill:"red", shape:"ring", text:"email.status.parseerror"});
|
node.status({fill:"red", shape:"ring", text:"email.status.parseerror"});
|
||||||
node.error(RED._("email.errors.parsefail", {folder:node.box}), err);
|
node.error(RED._("email.errors.parsefail", {folder:node.box}), err);
|
||||||
@ -406,7 +409,7 @@ module.exports = function(RED) {
|
|||||||
//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);
|
||||||
SimpleParser(stream, {}, function(err, parsed) {
|
simpleParser(stream, {}, function(err, parsed) {
|
||||||
if (err) {
|
if (err) {
|
||||||
node.status({fill:"red", shape:"ring", text:"email.status.parseerror"});
|
node.status({fill:"red", shape:"ring", text:"email.status.parseerror"});
|
||||||
node.error(RED._("email.errors.parsefail", {folder:node.box}),err);
|
node.error(RED._("email.errors.parsefail", {folder:node.box}),err);
|
||||||
@ -513,4 +516,63 @@ module.exports = function(RED) {
|
|||||||
global: { type:"boolean" }
|
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
|
||||||
|
})
|
||||||
|
.then(parsed => {
|
||||||
|
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);
|
||||||
|
})
|
||||||
|
.catch(err => { node.error(RED._("email.errors.parsefail"),err); })
|
||||||
|
.finally(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);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -51,3 +51,13 @@
|
|||||||
|
|
||||||
</script>
|
</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__",
|
"default-message": "__description__\n\nFile from Node-RED is attached: __filename__",
|
||||||
"tip": {
|
"tip": {
|
||||||
"cred": "<b>Note:</b> Copied credentials from global emailkeys.js file.",
|
"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": {
|
"status": {
|
||||||
"messagesent": "Message sent: __response__",
|
"messagesent": "Message sent: __response__",
|
||||||
@ -47,6 +48,7 @@
|
|||||||
"inboxzero": "you have achieved Inbox Zero",
|
"inboxzero": "you have achieved Inbox Zero",
|
||||||
"sending": "sending",
|
"sending": "sending",
|
||||||
"sendfail": "send failed",
|
"sendfail": "send failed",
|
||||||
|
"parseerror": "Failed to parse message",
|
||||||
"connecterror": "connect error"
|
"connecterror": "connect error"
|
||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
@ -56,6 +58,7 @@
|
|||||||
"nosmtptransport": "No SMTP transport. See info panel.",
|
"nosmtptransport": "No SMTP transport. See info panel.",
|
||||||
"nopayload": "No payload to send",
|
"nopayload": "No payload to send",
|
||||||
"fetchfail": "Failed to fetch folder: __folder__",
|
"fetchfail": "Failed to fetch folder: __folder__",
|
||||||
|
"parsefail": "Failed to parse message",
|
||||||
"messageerror": "Fetch message error: __error__",
|
"messageerror": "Fetch message error: __error__",
|
||||||
"refreshtoolarge": "Refresh interval too large. Limiting to 2147483 seconds"
|
"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>
|
<p>POP3プロトコルでのデフォルトポート番号は、素のTCPでは110番、SSLでは995番です。IMAPプロトコルでは、素のTCPでは143番、SSLでは993番です。</p>
|
||||||
|
|
||||||
</script>
|
</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__",
|
"default-message": "__description__\n\nNode-REDからファイルが添付されました: __filename__",
|
||||||
"tip": {
|
"tip": {
|
||||||
"cred": "<b>注釈:</b> emailkeys.jsファイルから認証情報をコピーしました。",
|
"cred": "<b>注釈:</b> emailkeys.jsファイルから認証情報をコピーしました。",
|
||||||
"recent": "注釈: 最新のメールを1件のみ取得します。"
|
"recent": "注釈: 最新のメールを1件のみ取得します。",
|
||||||
|
"mta": "<b>注釈:</b> 1024未満のポートを使用するには、昇格された(root)特権が必要です。ヘルプサイドバーを参照してください。"
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
"messagesent": "メッセージを送信しました: __response__",
|
"messagesent": "メッセージを送信しました: __response__",
|
||||||
@ -34,6 +35,7 @@
|
|||||||
"inboxzero": "受信トレイにメールがありません",
|
"inboxzero": "受信トレイにメールがありません",
|
||||||
"sending": "送信中",
|
"sending": "送信中",
|
||||||
"sendfail": "送信が失敗しました",
|
"sendfail": "送信が失敗しました",
|
||||||
|
"parseerror": "メッセージのパースに失敗",
|
||||||
"connecterror": "接続エラー"
|
"connecterror": "接続エラー"
|
||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
@ -43,6 +45,7 @@
|
|||||||
"nosmtptransport": "SMTP転送が設定されていません。「情報」タブを参照してください",
|
"nosmtptransport": "SMTP転送が設定されていません。「情報」タブを参照してください",
|
||||||
"nopayload": "送信するペイロードがありません",
|
"nopayload": "送信するペイロードがありません",
|
||||||
"fetchfail": "フォルダの受信に失敗しました: __folder__",
|
"fetchfail": "フォルダの受信に失敗しました: __folder__",
|
||||||
|
"parsefail": "メッセージのパースに失敗",
|
||||||
"messageerror": "メッセージ受信エラー: __error__"
|
"messageerror": "メッセージ受信エラー: __error__"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "node-red-node-email",
|
"name": "node-red-node-email",
|
||||||
"version": "1.7.11",
|
"version": "1.8.0",
|
||||||
"description": "Node-RED nodes to send and receive simple emails",
|
"description": "Node-RED nodes to send and receive simple emails.",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"imap": "^0.8.19",
|
"imap": "^0.8.19",
|
||||||
"mailparser": "^2.8.1",
|
"poplib": "^0.1.7",
|
||||||
"nodemailer": "^6.4.11",
|
"mailparser": "^3.0.0",
|
||||||
"poplib": "^0.1.7"
|
"nodemailer": "~6.4.10",
|
||||||
|
"smtp-server": "^3.7.0"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -18,7 +19,8 @@
|
|||||||
"email",
|
"email",
|
||||||
"gmail",
|
"gmail",
|
||||||
"imap",
|
"imap",
|
||||||
"pop"
|
"pop",
|
||||||
|
"mta"
|
||||||
],
|
],
|
||||||
"node-red": {
|
"node-red": {
|
||||||
"nodes": {
|
"nodes": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user