@5minds/node-red-contrib-processcube-tools 1.0.1-feature-df88cf-mfdx610k → 1.0.1-feature-3af406-mfdy163c

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,138 @@
1
+ <script type="text/javascript">
2
+ RED.nodes.registerType('email-sender',{
3
+ category: 'ProcessCube Tools',
4
+ color: '#02AFD6',
5
+ defaults: {
6
+ name: { value: "" },
7
+ // Definition der Felder mit dem Typ 'typedInput'
8
+ fromName: { value: "Stoelting Ticket-System", type: "typedInput", types: ["str", "msg", "flow", "global", "env"] },
9
+ fromAddress: { value: "", type: "typedInput", types: ["str", "msg", "flow", "global", "env"] },
10
+ to: { value: "", type: "typedInput", types: ["str", "msg", "flow", "global", "env"] },
11
+ cc: { value: "", type: "typedInput", types: ["str", "msg", "flow", "global", "env"] },
12
+ bcc: { value: "", type: "typedInput", types: ["str", "msg", "flow", "global", "env"] },
13
+ subject: { value: "", type: "typedInput", types: ["str", "msg", "flow", "global", "env"] },
14
+ attachments: { value: "", type: "typedInput", types: ["msg", "flow", "global"] },
15
+ htmlContent: { value: "", type: "typedInput", types: ["str", "msg", "flow", "global", "json"] },
16
+
17
+ // SMTP-Felder
18
+ smtpHost: { value: "", type: "typedInput", types: ["str", "msg", "flow", "global", "env"] },
19
+ smtpPort: { value: "", type: "typedInput", types: ["num", "str", "msg", "flow", "global", "env"] },
20
+ smtpUser: { value: "", type: "typedInput", types: ["str", "msg", "flow", "global", "env"] },
21
+ smtpPassword: { value: "", type: "typedInput", types: ["str", "msg", "flow", "global", "env"] },
22
+ smtpSecure: { value: true, type: "typedInput", types: ["bool", "msg", "flow", "global"] },
23
+ smtpRejectUnauthorized: { value: true, type: "typedInput", types: ["bool", "msg", "flow", "global"] }
24
+ },
25
+ inputs:1,
26
+ outputs:1,
27
+ icon: "font-awesome/fa-paper-plane",
28
+ label: function() {
29
+ return this.name || "Email Sender";
30
+ },
31
+ labelStyle: function() {
32
+ return this.name?"node_label_italic":"";
33
+ }
34
+ });
35
+ </script>
36
+ <script type="text/html" data-template-name="custom-email-sender">
37
+ <div class="form-row">
38
+ <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
39
+ <input type="text" id="node-input-name" placeholder="Name">
40
+ </div>
41
+
42
+ <h3>E-Mail Konfiguration</h3>
43
+ <div class="form-row">
44
+ <label for="node-input-fromName"><i class="fa fa-user"></i> Absendername</label>
45
+ <input type="text" id="node-input-fromName">
46
+ </div>
47
+ <div class="form-row">
48
+ <label for="node-input-fromAddress"><i class="fa fa-envelope"></i> Absenderadresse</label>
49
+ <input type="text" id="node-input-fromAddress">
50
+ </div>
51
+ <div class="form-row">
52
+ <label for="node-input-to"><i class="fa fa-user-plus"></i> Empfänger (To)</label>
53
+ <input type="text" id="node-input-to">
54
+ </div>
55
+ <div class="form-row">
56
+ <label for="node-input-cc"><i class="fa fa-user"></i> CC</label>
57
+ <input type="text" id="node-input-cc">
58
+ </div>
59
+ <div class="form-row">
60
+ <label for="node-input-bcc"><i class="fa fa-user-secret"></i> BCC</label>
61
+ <input type="text" id="node-input-bcc">
62
+ </div>
63
+ <div class="form-row">
64
+ <label for="node-input-subject"><i class="fa fa-info-circle"></i> Betreff</label>
65
+ <input type="text" id="node-input-subject">
66
+ </div>
67
+ <div class="form-row">
68
+ <label for="node-input-attachments"><i class="fa fa-paperclip"></i> Anhänge</label>
69
+ <input type="text" id="node-input-attachments">
70
+ </div>
71
+ <div class="form-row">
72
+ <label for="node-input-htmlContent"><i class="fa fa-file-code-o"></i> HTML Inhalt</label>
73
+ <input type="text" id="node-input-htmlContent">
74
+ </div>
75
+
76
+ <h3>SMTP Konfiguration</h3>
77
+ <div class="form-row">
78
+ <label for="node-input-smtpHost"><i class="fa fa-server"></i> Host</label>
79
+ <input type="text" id="node-input-smtpHost">
80
+ </div>
81
+ <div class="form-row">
82
+ <label for="node-input-smtpPort"><i class="fa fa-plug"></i> Port</label>
83
+ <input type="text" id="node-input-smtpPort">
84
+ </div>
85
+ <div class="form-row">
86
+ <label for="node-input-smtpUser"><i class="fa fa-user"></i> Benutzer</label>
87
+ <input type="text" id="node-input-smtpUser">
88
+ </div>
89
+ <div class="form-row">
90
+ <label for="node-input-smtpPassword"><i class="fa fa-lock"></i> Passwort</label>
91
+ <input type="password" id="node-input-smtpPassword">
92
+ </div>
93
+ <div class="form-row">
94
+ <label for="node-input-smtpSecure"><i class="fa fa-shield"></i> SSL/TLS (Secure)</label>
95
+ <input type="checkbox" id="node-input-smtpSecure">
96
+ </div>
97
+ <div class="form-row">
98
+ <label for="node-input-smtpRejectUnauthorized"><i class="fa fa-ban"></i> Zertifikate ablehnen</label>
99
+ <input type="checkbox" id="node-input-smtpRejectUnauthorized">
100
+ </div>
101
+ </script>
102
+
103
+ <script type="text/html" data-help-name="custom-email-sender">
104
+ <p>Eine benutzerdefinierte Node, um E-Mails über einen SMTP-Server zu versenden. Die Konfiguration kann über die Node-Eigenschaften, die eingehende Nachricht, Flow- oder Global-Kontexte oder Umgebungsvariablen erfolgen.</p>
105
+ <h3>Konfiguration der Felder</h3>
106
+ <p>Jedes Feld kann so konfiguriert werden, dass es einen festen Wert (string, number, boolean) oder einen Wert aus <code>msg</code>, <code>flow</code>, <code>global</code> oder <code>env</code> bezieht. Verwenden Sie das Dropdown-Menü neben dem Eingabefeld, um den Typ auszuwählen.</p>
107
+ </script>
108
+
109
+ <script type="text/javascript">
110
+ (function() {
111
+ // Initialisierung des typedInput-Widgets für die einzelnen Felder
112
+ function initializeTypedInput(id, types) {
113
+ $("#node-input-" + id).typedInput({
114
+ default: types[0],
115
+ types: types
116
+ });
117
+ }
118
+
119
+ // Initialisierung aller Felder
120
+ RED.events.on('nodes:load', function() {
121
+ initializeTypedInput('fromName', ["str", "msg", "flow", "global", "env"]);
122
+ initializeTypedInput('fromAddress', ["str", "msg", "flow", "global", "env"]);
123
+ initializeTypedInput('to', ["str", "msg", "flow", "global", "env"]);
124
+ initializeTypedInput('cc', ["str", "msg", "flow", "global", "env"]);
125
+ initializeTypedInput('bcc', ["str", "msg", "global", "env"]);
126
+ initializeTypedInput('subject', ["str", "msg", "flow", "global", "env"]);
127
+ initializeTypedInput('attachments', ["msg", "flow", "global"]);
128
+ initializeTypedInput('htmlContent', ["str", "msg", "flow", "global"]);
129
+
130
+ initializeTypedInput('smtpHost', ["str", "msg", "flow", "global", "env"]);
131
+ initializeTypedInput('smtpPort', ["num", "str", "msg", "flow", "global", "env"]);
132
+ initializeTypedInput('smtpUser', ["str", "msg", "flow", "global", "env"]);
133
+ initializeTypedInput('smtpPassword', ["str", "msg", "flow", "global", "env"]);
134
+ initializeTypedInput('smtpSecure', ["bool", "msg", "flow", "global"]);
135
+ initializeTypedInput('smtpRejectUnauthorized', ["bool", "msg", "flow", "global"]);
136
+ });
137
+ })();
138
+ </script>
@@ -0,0 +1,84 @@
1
+ module.exports = function(RED) {
2
+ "use strict";
3
+ const nodemailer = require("nodemailer");
4
+
5
+ function EmailSenderNode(config) {
6
+ RED.nodes.createNode(this, config);
7
+ var node = this;
8
+
9
+ node.on('input', function(msg, send, done) {
10
+
11
+ // Konfiguration und Daten aus der Nachricht extrahieren
12
+ const emailConfig = RED.util.evaluateNodeProperty(config.email, config.emailType, node, msg) || {};
13
+ const smtpConfig = RED.util.evaluateNodeProperty(config.smtp, config.smtpType, node, msg) || {};
14
+
15
+ // Fallback für send und done, falls ältere Node-RED Version
16
+ send = send || function() { node.send.apply(node, arguments); }
17
+ done = done || function(err) { if (err) node.error(err, msg); }
18
+
19
+ // Logik vom Code-Snippet
20
+ const transporter = nodemailer.createTransport({
21
+ host: smtpConfig.host,
22
+ port: smtpConfig.port,
23
+ auth: {
24
+ user: smtpConfig.auth?.user,
25
+ pass: smtpConfig.auth?.pass
26
+ },
27
+ secure: smtpConfig.secure !== undefined ? smtpConfig.secure : true,
28
+ proxy: smtpConfig.proxy || undefined,
29
+ tls: {
30
+ rejectUnauthorized: smtpConfig.tls?.rejectUnauthorized !== undefined
31
+ ? smtpConfig.tls.rejectUnauthorized
32
+ : true
33
+ }
34
+ });
35
+
36
+ const mail = {
37
+ from: emailConfig.from,
38
+ to: emailConfig.to,
39
+ cc: emailConfig.cc || "",
40
+ bcc: emailConfig.bcc || "",
41
+ subject: emailConfig.subject || msg.topic || "Message from Node-RED",
42
+ attachments: emailConfig.attachments,
43
+ text: emailConfig.text,
44
+ html: emailConfig.html,
45
+ amp: emailConfig.amp,
46
+ priority: emailConfig.priority || "normal"
47
+ };
48
+
49
+ // E-Mail senden und den Status überprüfen
50
+ transporter.sendMail(mail, (error, info) => {
51
+ if (error) {
52
+ node.error(error, msg);
53
+ done(error); // Fehler an Node-RED weiterleiten
54
+ return;
55
+ }
56
+
57
+ node.log('E-Mail gesendet: ' + info.response);
58
+ msg.payload = info;
59
+
60
+ // Statusprüfung basierend auf dem Code-Auszug
61
+ if (msg.payload.accepted && msg.payload.accepted.length > 0) {
62
+ msg.payload = { result: msg.input };
63
+ send(msg); // Nachricht an den nächsten Knoten senden
64
+ } else if (msg.payload.rejected && msg.payload.rejected.length > 0) {
65
+ msg.error = { result: msg.payload.rejected };
66
+ done('E-Mail abgelehnt: ' + msg.payload.rejected.join(', '));
67
+ node.status({fill:"red", shape:"dot", text:"rejected"});
68
+ return;
69
+ } else if (msg.payload.pending && msg.payload.pending.length > 0) {
70
+ msg.error = { result: msg.payload.pending };
71
+ done('E-Mail ausstehend: ' + msg.payload.pending.join(', '));
72
+ node.status({fill:"yellow", shape:"dot", text:"pending"});
73
+ return;
74
+ } else {
75
+ done('Unbekannter Fehler beim Senden der E-Mail.');
76
+ node.status({fill:"red", shape:"dot", text:"error"});
77
+ return;
78
+ }
79
+ });
80
+ });
81
+ }
82
+
83
+ RED.nodes.registerType("email-sender", EmailSenderNode);
84
+ };
package/package.json CHANGED
@@ -1,14 +1,10 @@
1
1
  {
2
2
  "name": "@5minds/node-red-contrib-processcube-tools",
3
- "version": "1.0.1-feature-df88cf-mfdx610k",
3
+ "version": "1.0.1-feature-3af406-mfdy163c",
4
4
  "license": "MIT",
5
5
  "description": "Node-RED tools nodes for ProcessCube",
6
6
  "scripts": {
7
- "lint": "prettier --write --config ./.prettierrc.json \"**/*.{html,js}\"",
8
- "test:unit": "mocha test/unit/**/*.test.js --timeout 10000",
9
- "test:integration": "mocha test/integration/**/*.test.js --timeout 10000",
10
- "test": "npm run test:unit && npm run test:integration",
11
- "test:debug": "mocha test/unit/**/*.test.js test/integration/**/*.test.js --timeout 0 --reporter spec"
7
+ "lint": "prettier --write --config ./.prettierrc.json \"**/*.{html,js}\""
12
8
  },
13
9
  "authors": [
14
10
  {
@@ -18,10 +14,6 @@
18
14
  {
19
15
  "name": "Robin Lenz",
20
16
  "email": "Robin.Lenz@5Minds.de"
21
- },
22
- {
23
- "name": "Diana Stefan",
24
- "email": "Diana.Stefan@5Minds.de"
25
17
  }
26
18
  ],
27
19
  "repository": {
@@ -39,27 +31,14 @@
39
31
  "node-red": {
40
32
  "version": ">=3.1.9",
41
33
  "nodes": {
42
- "EmailReceiver": "email-receiver/email-receiver.js",
43
- "HtmlToText": "processcube-html-to-text.js"
34
+ "EmailSender": "email-sender/email-sender.js",
35
+ "HtmlToText": "processcube-html-to-text/processcube-html-to-text.js"
44
36
  },
45
37
  "examples": "examples"
46
38
  },
47
39
  "dependencies": {
48
40
  "html-to-text": "^9.0.5",
49
- "mailparser": "^3.6.8",
50
- "node-imap": "^0.9.6",
51
- "utf7": "^1.0.2"
52
- },
53
- "devDependencies": {
54
- "chai": "^4.3.4",
55
- "mocha": "^11.7.2",
56
- "node-red": "^4.1.0",
57
- "node-red-node-test-helper": "^0.3.5",
58
- "should": "^13.2.3",
59
- "sinon": "^11.1.2"
60
- },
61
- "overrides": {
62
- "semver": ">=7.5.2"
41
+ "nodemailer": "^7.0.6"
63
42
  },
64
43
  "keywords": [
65
44
  "node-red",
@@ -1,187 +0,0 @@
1
- <script type="text/javascript">
2
- RED.nodes.registerType('email-receiver', {
3
- category: 'ProcessCube Tools',
4
- color: '#02AFD6',
5
- defaults: {
6
- name: { value: "" },
7
- host: { value: "", required: true, validate: RED.validators.typedInput("hostType") },
8
- hostType: { value: "str" },
9
- port: { value: "", required: true, validate: RED.validators.typedInput("portType") },
10
- portType: { value: "num" },
11
- tls: { value: true, required: true, validate: RED.validators.typedInput("tlsType") },
12
- tlsType: { value: "bool" },
13
- user: { value: "", required: true, validate: RED.validators.typedInput("userType") },
14
- userType: { value: "str" },
15
- password: { value: "", required: true, type: "password" },
16
- passwordType: { value: "env", required: true },
17
- folder: { value: "", required: true, validate: RED.validators.typedInput("folderType") },
18
- folderType: { value: "json" },
19
- markseen: { value: true, validate: RED.validators.typedInput("markseenType") },
20
- markseenType: { value: "bool" }
21
- },
22
- inputs: 1,
23
- outputs: 1,
24
- icon: "font-awesome/fa-inbox",
25
- label: function() {
26
- return this.name || "E-Mail Receiver";
27
- },
28
- oneditprepare: function() {
29
- $('#node-input-host').typedInput({
30
- default: 'str',
31
- types: ['str', 'msg', 'flow', 'global', 'env'],
32
- typeField: '#node-input-hostType'
33
- });
34
-
35
- $('#node-input-port').typedInput({
36
- default: 'num',
37
- types: ['num', 'msg', 'flow', 'global', 'env'],
38
- typeField: '#node-input-portType'
39
- });
40
-
41
- $('#node-input-tls').typedInput({
42
- default: 'bool',
43
- types: ['bool', 'msg', 'flow', 'global', 'env'],
44
- typeField: '#node-input-tlsType'
45
- });
46
-
47
- $('#node-input-user').typedInput({
48
- default: 'str',
49
- types: ['str', 'msg', 'flow', 'global', 'env'],
50
- typeField: '#node-input-userType'
51
- });
52
-
53
- $('#node-input-password').typedInput({
54
- default: 'env',
55
- types: ['msg', 'flow', 'global', 'env'],
56
- typeField: '#node-input-passwordType'
57
- });
58
-
59
- $('#node-input-folder').typedInput({
60
- default: 'json',
61
- types: ['msg', 'flow', 'global', 'json', 'jsonata', 'env'],
62
- typeField: '#node-input-folderType'
63
- });
64
-
65
- $('#node-input-markseen').typedInput({
66
- default: 'bool',
67
- types: ['bool', 'msg', 'flow', 'global', 'env'],
68
- typeField: '#node-input-markseenType'
69
- });
70
- }
71
- });
72
- </script>
73
-
74
- <script type="text/html" data-template-name="email-receiver">
75
- <div class="form-row">
76
- <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
77
- <input type="text" id="node-input-name" placeholder="Name">
78
- </div>
79
-
80
- <div class="form-row">
81
- <label for="node-input-host"><i class="fa fa-server"></i> IMAP Host</label>
82
- <input type="text" id="node-input-host" placeholder="imap.gmail.com">
83
- <input type="hidden" id="node-input-hostType">
84
- </div>
85
-
86
- <div class="form-row">
87
- <label for="node-input-port"><i class="fa fa-terminal"></i> Port</label>
88
- <input type="text" id="node-input-port" placeholder="993">
89
- <input type="hidden" id="node-input-portType">
90
- </div>
91
-
92
- <div class="form-row">
93
- <label for="node-input-tls"><i class="fa fa-lock"></i> Use TLS</label>
94
- <input type="text" id="node-input-tls">
95
- <input type="hidden" id="node-input-tlsType">
96
- </div>
97
-
98
- <div class="form-row">
99
- <label for="node-input-user"><i class="fa fa-user"></i> User</label>
100
- <input type="text" id="node-input-user">
101
- <input type="hidden" id="node-input-userType">
102
- </div>
103
-
104
- <div class="form-row">
105
- <label for="node-input-password"><i class="fa fa-key"></i> Password</label>
106
- <input type="text" id="node-input-password">
107
- <input type="hidden" id="node-input-passwordType">
108
- </div>
109
-
110
- <div class="form-row">
111
- <label for="node-input-folder"><i class="fa fa-folder-open"></i> Folder(s)</label>
112
- <input type="text" id="node-input-folder" placeholder="[INBOX]">
113
- <input type="hidden" id="node-input-folderType">
114
- </div>
115
-
116
- <div class="form-row">
117
- <label for="node-input-markseen"><i class="fa fa-eye"></i> Mark as seen</label>
118
- <input type="text" id="node-input-markseen">
119
- <input type="hidden" id="node-input-markseenType">
120
- </div>
121
- </script>
122
-
123
- <script type="text/html" data-help-name="email-receiver">
124
- <p>A Node-RED node that fetches unseen emails from a specified IMAP server. Each fetched email is sent as a separate message on the output.</p>
125
-
126
- <p>All fields can be configured as a <strong>string</strong>, from a <strong>message property (msg)</strong>, <strong>flow</strong> or <strong>global</strong> context, or an <strong>environment variable</strong>.</p>
127
-
128
- <p><strong>Security Tip:</strong> It's a best practice to avoid storing sensitive information like passwords directly in your Node-RED flow. This prevents them from being exposed in your flow file. Instead, use an <strong>environment variable</strong>. You can define these variables in a <code>.env</code> file, which is especially useful when deploying your application with Docker.</p>
129
-
130
- <p>A <code>.env</code> file should look like this:</p>
131
- <pre>
132
- EMAIL_SEND_PORT=123
133
- EMAIL_SEND_HOST=smtp.gmail.com
134
- EMAIL_SEND_USER=myTestMail@company.com
135
- EMAIL_SEND_PASSWORD=mySecretPassword
136
- </pre>
137
-
138
- <p>To ensure Docker loads these variables from the <code>.env</code> file, you need to add the following line to your <code>docker-compose.yaml</code> file:</p>
139
- <pre>
140
- services:
141
- your_service_name:
142
- ...
143
- env_file:
144
- - .env
145
- </pre>
146
-
147
- <p>In your flow, you can then access the password using the environment variable <code>EMAIL_SEND_PASSWORD</code>.</p>
148
-
149
- Inputs
150
- <dl class="message-properties">
151
- <dt>payload</dt>
152
- <dd>The node is triggered by any incoming message. The node's configuration can be overridden by properties of the incoming <code>msg</code> object.</dd>
153
- </dl>
154
-
155
- Outputs
156
- <dl class="message-properties">
157
- <dt>payload
158
- <span class="property-type">string</span>
159
- </dt>
160
- <dd>The text body of the email.</dd>
161
- </dl>
162
-
163
- Optional Message Properties
164
- <p>You can override default settings by passing the following properties in the incoming <code>msg</code> object:</p>
165
- <dl class="message-properties">
166
- <dt>msg.imap_connTimeout
167
- <span class="property-type">number</span>
168
- </dt>
169
- <dd>The connection timeout in milliseconds (default: 10000).</dd>
170
- <dt>msg.imap_authTimeout
171
- <span class="property-type">number</span>
172
- </dt>
173
- <dd>The authentication timeout in milliseconds (default: 5000).</dd>
174
- <dt>msg.imap_keepalive
175
- <span class="property-type">boolean</span>
176
- </dt>
177
- <dd>If set to <code>true</code>, a periodic NOOP command is sent to keep the connection alive (default: <code>true</code>).</dd>
178
- <dt>msg.imap_autotls
179
- <span class="property-type">string</span>
180
- </dt>
181
- <dd>Controls STARTTLS behavior. Set to <code>never</code> to disable it (default: <code>never</code>).</dd>
182
- <dt>msg.imap_tlsOptions
183
- <span class="property-type">object</span>
184
- </dt>
185
- <dd>An object containing TLS options for the connection.</dd>
186
- </dl>
187
- </script>