mirror of
				https://github.com/node-red/node-red-nodes.git
				synced 2025-03-01 10:37:43 +00:00 
			
		
		
		
	Add MTA node to email
This commit is contained in:
		@@ -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": {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user