node-red-contrib-remote 1.4.0 → 1.5.1
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.
- package/README.md +12 -1
- package/nodes/locales/de/remote-access.json +2 -1
- package/nodes/locales/de/remote-config.json +1 -0
- package/nodes/locales/en-US/remote-access.json +2 -1
- package/nodes/locales/en-US/remote-config.json +1 -0
- package/nodes/remote-access.html +2 -4
- package/nodes/remote-access.js +29 -8
- package/nodes/remote-commons.js +28 -2
- package/nodes/remote-config.html +4 -0
- package/nodes/remote-config.js +7 -1
- package/nodes/remote-notification.js +10 -8
- package/nodes/remote-question.js +16 -13
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Remote-RED
|
|
2
2
|
|
|
3
|
-
Remote-RED is an ecosystem to bring remote access and
|
|
3
|
+
Remote-RED is an ecosystem to bring remote access, push notification and geofencing to Node-RED. There are also additional functions like directly answer on a notification and homescreen widgets. It consists of several parts:
|
|
4
4
|
- node-red-contrib-remote: The Node-RED nodes of Remote-RED. Published in this repro.
|
|
5
5
|
- Remote-RED servers: Several servers used for proxying the remote access traffic and sending push notifications.
|
|
6
6
|
- Remote-RED apps: Apps to access the services published by the Remote-RED remote-access node and receiving the push notifications of the remote-notification node. Available or Android, iOS and iPadOS.
|
|
@@ -36,6 +36,17 @@ You will find more information on [www.remote-red-com](https://www.remote-red.co
|
|
|
36
36
|
|
|
37
37
|
## Version History
|
|
38
38
|
|
|
39
|
+
Version 1.5.1
|
|
40
|
+
- Added support for running Node-RED with a self signed https certificate.
|
|
41
|
+
- Notifications and Questions will automatically convert values to string if a string is needed (e.g. title and body).
|
|
42
|
+
|
|
43
|
+
Version 1.5.0
|
|
44
|
+
- Geofencing! You can add geofences in the apps. Entering and leaving them will trigger a message on the new output of the remote access node.
|
|
45
|
+
- Adding server location in Asia.
|
|
46
|
+
- New instances will have the base url '/ui' again.
|
|
47
|
+
- Error with "Multiple requests" after a missing internet connection fixed.
|
|
48
|
+
- iOS App: Links with target '_blank' will be redirected to iOS.
|
|
49
|
+
|
|
39
50
|
Version 1.4.0
|
|
40
51
|
- In addition to the QR code, a link is now generated to add an instance in the app.
|
|
41
52
|
- Sending notifications and questions is prevented if msg.playload.send === false.
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
"commerror": "Fehler bei der Kommunikation mit dem Server.",
|
|
18
18
|
"noconfig": "Keine Konfiguration gefunden.",
|
|
19
19
|
"incompleteconfig": "Konfiguration unvollständig.",
|
|
20
|
-
"backupconfig": "Konfiguration aus Backup."
|
|
20
|
+
"backupconfig": "Konfiguration aus Backup.",
|
|
21
|
+
"banned": "Die Instanz wurde deaktiviert. Möglicherweise aufgrund einer DDOS-Attacke. Wenn Sie dieses System nicht missbrauchen, erstelle bitte eine neuen Konfig Node, um Remote-RED wieder zu verwenden. Andernfalls suchen Sie nach falschen Weiterleitungen oder Proxy Fehlern. Diese IP wird für 10 Minuten gesperrt."
|
|
21
22
|
},
|
|
22
23
|
"help": {
|
|
23
24
|
"title": "Hilfe",
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"region": "Standort Server",
|
|
13
13
|
"region_us": "Amerika (USA)",
|
|
14
14
|
"region_de": "Europa (Deutschland)",
|
|
15
|
+
"region_sg": "Asien (Singapur)",
|
|
15
16
|
"region_dev": "Entwicklung",
|
|
16
17
|
"region_desc": "Der Standort kann nicht mehr geändert werden, sobald eine App registriert wurde.",
|
|
17
18
|
"change_info": "Wenn Du Einstellungen änderst, musst Du die App neu verbinden.",
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
"commerror": "Error communicating with server.",
|
|
18
18
|
"noconfig": "No configuration found.",
|
|
19
19
|
"incompleteconfig": "Configuration incomplete.",
|
|
20
|
-
"backupconfig": "Configuration from backup."
|
|
20
|
+
"backupconfig": "Configuration from backup.",
|
|
21
|
+
"banned": "Instance is deactivated. Maybe due DDOS attacks. If you are not missusing this system, please create new config node to use Remote-RED again. Otherwise look for incorrect redirects or such errors. Banning IP for 10 minutes."
|
|
21
22
|
},
|
|
22
23
|
"help": {
|
|
23
24
|
"title": "Help",
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"region": "Server location",
|
|
13
13
|
"region_us": "America (USA)",
|
|
14
14
|
"region_de": "Europe (Germany)",
|
|
15
|
+
"region_sg": "Asia (Singapur)",
|
|
15
16
|
"region_dev": "Development host",
|
|
16
17
|
"region_desc": "The region can´t be changed after registering an app.",
|
|
17
18
|
"change_info": "If you change settings, you need to reconnect the app.",
|
package/nodes/remote-access.html
CHANGED
|
@@ -8,10 +8,8 @@
|
|
|
8
8
|
verbose: {value:0}
|
|
9
9
|
},
|
|
10
10
|
inputs: 0,
|
|
11
|
-
outputs:
|
|
12
|
-
outputLabels: ["action output"],
|
|
13
|
-
// outputs: 2,
|
|
14
|
-
// outputLabels: ["action output", "geofence output"],
|
|
11
|
+
outputs: 2,
|
|
12
|
+
outputLabels: ["action output", "geofence output"],
|
|
15
13
|
icon: "font-awesome/fa-mobile",
|
|
16
14
|
label: function() {
|
|
17
15
|
return this.name || "remote access";
|
package/nodes/remote-access.js
CHANGED
|
@@ -4,6 +4,7 @@ module.exports = function(RED) {
|
|
|
4
4
|
const os = require("os");
|
|
5
5
|
let sshprocess = undefined
|
|
6
6
|
let statustext = ''
|
|
7
|
+
let instanceIsBanned = false
|
|
7
8
|
|
|
8
9
|
function startSSH(node, server, port) {
|
|
9
10
|
try {
|
|
@@ -18,7 +19,7 @@ module.exports = function(RED) {
|
|
|
18
19
|
if ( host === 'localhost' && os.platform() === 'win32' ) {
|
|
19
20
|
host = '127.0.0.1'
|
|
20
21
|
}
|
|
21
|
-
//node.log('ssh -o StrictHostKeyChecking=no -R ' + port.toString() + ':' + host + ':' + node.confignode.port.toString() + ' forward@proxy-' + server + ' -N');
|
|
22
|
+
// node.log('ssh -o StrictHostKeyChecking=no -R ' + port.toString() + ':' + host + ':' + node.confignode.port.toString() + ' forward@proxy-' + server + ' -N');
|
|
22
23
|
var sshparameters = ['-o StrictHostKeyChecking=no', '-R', port.toString() + ':' + host + ':' + node.confignode.port.toString(), 'forward@proxy-' + server, '-N'];
|
|
23
24
|
if ( node.verbose ) {
|
|
24
25
|
sshparameters.push('-v');
|
|
@@ -36,6 +37,9 @@ module.exports = function(RED) {
|
|
|
36
37
|
|
|
37
38
|
sshprocess.stderr.on('data', (data) => {
|
|
38
39
|
logSSHBuffer(node, data, 'ssh process stderr');
|
|
40
|
+
if ( data.toString().includes('Connection timed out')) {
|
|
41
|
+
node.error(`SSH connection timeout. Please check if port 22 is open for outgoing connections.`);
|
|
42
|
+
}
|
|
39
43
|
});
|
|
40
44
|
|
|
41
45
|
sshprocess.on('close', (code, signal) => {
|
|
@@ -89,6 +93,11 @@ module.exports = function(RED) {
|
|
|
89
93
|
}
|
|
90
94
|
|
|
91
95
|
function requestInstanceSlot(node) {
|
|
96
|
+
// Is this instance banned?
|
|
97
|
+
if ( instanceIsBanned ) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
92
101
|
// Call API to retrive server and port.
|
|
93
102
|
const axiosInstance = commons.createAxiosInstance();
|
|
94
103
|
axiosInstance.post(`https://api-${node.confignode.server}/instanceSlotRequest`, {
|
|
@@ -105,10 +114,22 @@ module.exports = function(RED) {
|
|
|
105
114
|
startSSH(node, node.confignode.server, port);
|
|
106
115
|
})
|
|
107
116
|
.catch((error) => {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
117
|
+
// Log error
|
|
118
|
+
node.error('requestInstanceSlot: ' + commons.getNetworkErrorString(error))
|
|
119
|
+
if ( commons.getNetworkErrorCustomString(error) !== undefined) {
|
|
120
|
+
node.error(commons.getNetworkErrorCustomString(error));
|
|
111
121
|
}
|
|
122
|
+
|
|
123
|
+
// Wenn gebannt -> Merken
|
|
124
|
+
if ( error.response && error.response.status ) {
|
|
125
|
+
if ( error.response.status === 403 ) {
|
|
126
|
+
setStatus(node, {fill:"red",shape:"dot",text:"remote-access.status.banned"});
|
|
127
|
+
instanceIsBanned = true;
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Set status
|
|
112
133
|
setStatus(node, {fill:"red",shape:"dot",text:"remote-access.status.commerror"});
|
|
113
134
|
return;
|
|
114
135
|
});
|
|
@@ -183,10 +204,10 @@ module.exports = function(RED) {
|
|
|
183
204
|
}
|
|
184
205
|
})
|
|
185
206
|
.catch((error) => {
|
|
186
|
-
// Error on api call >
|
|
187
|
-
node.error('heartbeat: ' + error)
|
|
188
|
-
if (
|
|
189
|
-
node.error(
|
|
207
|
+
// Error on api call > Log error
|
|
208
|
+
node.error('heartbeat: ' + commons.getNetworkErrorString(error))
|
|
209
|
+
if ( commons.getNetworkErrorCustomString(error) !== undefined) {
|
|
210
|
+
node.error(commons.getNetworkErrorCustomString(error));
|
|
190
211
|
}
|
|
191
212
|
});
|
|
192
213
|
}
|
package/nodes/remote-commons.js
CHANGED
|
@@ -8,6 +8,7 @@ module.exports = {
|
|
|
8
8
|
createAxiosInstance: function() {
|
|
9
9
|
var filepath = path.join(__dirname, 'resources', 'ca.cer');
|
|
10
10
|
const httpsAgent = new https.Agent({
|
|
11
|
+
rejectUnauthorized: false,
|
|
11
12
|
ca: fs.readFileSync(filepath),
|
|
12
13
|
checkServerIdentity: function(host, cert) {
|
|
13
14
|
const pubkeyPinned = 'YHGEo54+LKxdpCuSAFt+Zwx/RVSHER96vM/Rh0/zcQ4=';
|
|
@@ -17,7 +18,7 @@ module.exports = {
|
|
|
17
18
|
}
|
|
18
19
|
}
|
|
19
20
|
});
|
|
20
|
-
return axios.create({ httpsAgent: httpsAgent });
|
|
21
|
+
return axios.create({ httpsAgent: httpsAgent, timeout: 5000 });
|
|
21
22
|
},
|
|
22
23
|
|
|
23
24
|
getNodeVersion: function() {
|
|
@@ -26,15 +27,40 @@ module.exports = {
|
|
|
26
27
|
return pjson.version;
|
|
27
28
|
},
|
|
28
29
|
|
|
29
|
-
evaluateValue: function(RED, value, type, node, msg) {
|
|
30
|
+
evaluateValue: function(RED, value, type, node, msg, tostring) {
|
|
30
31
|
// Evaluates the value
|
|
31
32
|
let evalValue = ''
|
|
32
33
|
try {
|
|
33
34
|
evalValue = RED.util.evaluateNodeProperty(value, type, node, msg);
|
|
35
|
+
if (tostring) {
|
|
36
|
+
if (evalValue == undefined) evalValue = '';
|
|
37
|
+
evalValue = String(evalValue);
|
|
38
|
+
}
|
|
34
39
|
} catch (e) {
|
|
35
40
|
node.error(`Error evaluating value: ${e}`)
|
|
36
41
|
}
|
|
37
42
|
return evalValue;
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
getNetworkErrorString: function(error) {
|
|
46
|
+
// Trys to get a error message
|
|
47
|
+
let errorString = `` + error;
|
|
48
|
+
if ( error.response && error.response.data && error.response.data.message ) {
|
|
49
|
+
errorString = `${error.response.data.message}`;
|
|
50
|
+
}
|
|
51
|
+
return errorString;
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
getNetworkErrorCustomString: function(error) {
|
|
55
|
+
// Custom error messages for common errors
|
|
56
|
+
let errorString = undefined;
|
|
57
|
+
if ( error.code === 'ECONNABORTED' ) {
|
|
58
|
+
errorString = `Error during https call. Please check Internet connection on your Node-RED server. Please check if a firewall blocks outgoing port 443.`;
|
|
59
|
+
}
|
|
60
|
+
if ( error.code === 'EAI_AGAIN' ) {
|
|
61
|
+
errorString = `Error during DNS queries. Please check Internet connection on your Node-RED server. Please check if a firewall blocks your DNS queries.`;
|
|
62
|
+
}
|
|
63
|
+
return errorString;
|
|
38
64
|
}
|
|
39
65
|
|
|
40
66
|
}
|
package/nodes/remote-config.html
CHANGED
|
@@ -103,6 +103,9 @@
|
|
|
103
103
|
} else {
|
|
104
104
|
// Show error
|
|
105
105
|
alert('Error while registering instance: ' + data.error);
|
|
106
|
+
|
|
107
|
+
// Enable button again
|
|
108
|
+
document.getElementById('registerRemoteAppButton').disabled = false;
|
|
106
109
|
}
|
|
107
110
|
});
|
|
108
111
|
}
|
|
@@ -214,6 +217,7 @@
|
|
|
214
217
|
<select id="node-config-input-region">
|
|
215
218
|
<option value="us" data-i18n="remote-config.label.region_us"></option>
|
|
216
219
|
<option value="de" data-i18n="remote-config.label.region_de"></option>
|
|
220
|
+
<option value="sg" data-i18n="remote-config.label.region_sg"></option>
|
|
217
221
|
<!-- <option value="dev" data-i18n="remote-config.label.region_dev"></option> -->
|
|
218
222
|
</select>
|
|
219
223
|
</div>
|
package/nodes/remote-config.js
CHANGED
|
@@ -27,7 +27,7 @@ module.exports = function(RED) {
|
|
|
27
27
|
// Return the internal IP and the mountpath
|
|
28
28
|
const ipData = {
|
|
29
29
|
'ipv4': internalIp.v4.sync(),
|
|
30
|
-
'baseurl': RED.httpNode.mountpath + ((RED.settings.ui !== undefined && RED.settings.ui.path !== undefined) ? RED.settings.ui.path : ''),
|
|
30
|
+
'baseurl': RED.httpNode.mountpath + ((RED.settings.ui !== undefined && RED.settings.ui.path !== undefined) ? RED.settings.ui.path : 'ui'),
|
|
31
31
|
'port': (RED.settings.uiPort !== undefined) ? String(RED.settings.uiPort) : '1880'
|
|
32
32
|
}
|
|
33
33
|
console.log(`${JSON.stringify(ipData)}`);
|
|
@@ -48,6 +48,9 @@ module.exports = function(RED) {
|
|
|
48
48
|
if ( error.response && error.response.data && error.response.data.message ) {
|
|
49
49
|
errorMessage = errorMessage + " / " + error.response.data.message;
|
|
50
50
|
}
|
|
51
|
+
if ( commons.getNetworkErrorCustomString(error) !== undefined) {
|
|
52
|
+
errorMessage = commons.getNetworkErrorCustomString(error);
|
|
53
|
+
}
|
|
51
54
|
res.json({ 'error': errorMessage });
|
|
52
55
|
});
|
|
53
56
|
});
|
|
@@ -97,6 +100,9 @@ module.exports = function(RED) {
|
|
|
97
100
|
if ( error.response && error.response.data && error.response.data.message ) {
|
|
98
101
|
errorMessage = errorMessage + " / " + error.response.data.message;
|
|
99
102
|
}
|
|
103
|
+
if ( commons.getNetworkErrorCustomString(error) !== undefined) {
|
|
104
|
+
errorMessage = commons.getNetworkErrorCustomString(error);
|
|
105
|
+
}
|
|
100
106
|
res.json({ 'error': errorMessage });
|
|
101
107
|
});
|
|
102
108
|
});
|
|
@@ -18,16 +18,14 @@ module.exports = function(RED) {
|
|
|
18
18
|
// Act on incomming messages
|
|
19
19
|
node.on('input', function(msg) {
|
|
20
20
|
if (node.confignode != undefined) {
|
|
21
|
-
if (msg.payload.send === false) {
|
|
21
|
+
if (msg.payload !== undefined && msg.payload.send === false) {
|
|
22
22
|
node.log(`Notification not send (msg.payload.send = false).`)
|
|
23
23
|
return;
|
|
24
24
|
}
|
|
25
25
|
node.limiter.removeTokens(1, function(err, remainingRequests) {
|
|
26
26
|
if (remainingRequests >= 0) {
|
|
27
|
-
let title = commons.evaluateValue(RED, config.notificationTitle, config.notificationTitleType, node, msg);
|
|
28
|
-
let body = commons.evaluateValue(RED, config.notificationBody, config.notificationBodyType, node, msg);
|
|
29
|
-
if (title == undefined) title = '';
|
|
30
|
-
if (body == undefined) body = '';
|
|
27
|
+
let title = commons.evaluateValue(RED, config.notificationTitle, config.notificationTitleType, node, msg, true);
|
|
28
|
+
let body = commons.evaluateValue(RED, config.notificationBody, config.notificationBodyType, node, msg, true);
|
|
31
29
|
const notificationEmpty = (title == '' && body == '');
|
|
32
30
|
if (!notificationEmpty) {
|
|
33
31
|
// Title and/or body are filled
|
|
@@ -40,7 +38,7 @@ module.exports = function(RED) {
|
|
|
40
38
|
// Sound configured or computed?
|
|
41
39
|
let sound = config.notificationSound
|
|
42
40
|
if (sound === 'computed') {
|
|
43
|
-
sound = commons.evaluateValue(RED, config.notificationSoundComputed, config.notificationSoundComputedType, node, msg);
|
|
41
|
+
sound = commons.evaluateValue(RED, config.notificationSoundComputed, config.notificationSoundComputedType, node, msg, true);
|
|
44
42
|
}
|
|
45
43
|
|
|
46
44
|
// Call API to send notification
|
|
@@ -63,7 +61,11 @@ module.exports = function(RED) {
|
|
|
63
61
|
}
|
|
64
62
|
})
|
|
65
63
|
.catch((error) => {
|
|
66
|
-
|
|
64
|
+
// Log error
|
|
65
|
+
node.error('sendNotification: ' + commons.getNetworkErrorString(error))
|
|
66
|
+
if ( commons.getNetworkErrorCustomString(error) !== undefined) {
|
|
67
|
+
node.error(commons.getNetworkErrorCustomString(error));
|
|
68
|
+
}
|
|
67
69
|
|
|
68
70
|
// Output status if configured so
|
|
69
71
|
if ( config.output == 2 ) {
|
|
@@ -73,7 +75,7 @@ module.exports = function(RED) {
|
|
|
73
75
|
});
|
|
74
76
|
} else {
|
|
75
77
|
// To big...
|
|
76
|
-
node.error("
|
|
78
|
+
node.error("xxxThe message exceeded 3600 bytes. Can´t send.");
|
|
77
79
|
|
|
78
80
|
// Output status if configured so
|
|
79
81
|
if ( config.output == 2 ) {
|
package/nodes/remote-question.js
CHANGED
|
@@ -18,16 +18,14 @@ module.exports = function(RED) {
|
|
|
18
18
|
// Act on incomming messages
|
|
19
19
|
node.on('input', function(msg) {
|
|
20
20
|
if (node.confignode != undefined) {
|
|
21
|
-
if (msg.payload.send === false) {
|
|
21
|
+
if (msg.payload !== undefined && msg.payload.send === false) {
|
|
22
22
|
node.log(`Question not send (msg.payload.send = false).`)
|
|
23
23
|
return;
|
|
24
24
|
}
|
|
25
25
|
node.limiter.removeTokens(1, function(err, remainingRequests) {
|
|
26
26
|
if (remainingRequests >= 0) {
|
|
27
|
-
let title = commons.evaluateValue(RED, config.questionTitle, config.questionTitleType, node, msg);
|
|
28
|
-
let body = commons.evaluateValue(RED, config.questionBody, config.questionBodyType, node, msg);
|
|
29
|
-
if (title == undefined) title = '';
|
|
30
|
-
if (body == undefined) body = '';
|
|
27
|
+
let title = commons.evaluateValue(RED, config.questionTitle, config.questionTitleType, node, msg, true);
|
|
28
|
+
let body = commons.evaluateValue(RED, config.questionBody, config.questionBodyType, node, msg, true);
|
|
31
29
|
const notificationEmpty = (title == '' && body == '');
|
|
32
30
|
if (!notificationEmpty) {
|
|
33
31
|
// Title and/or body are filled, generate question data
|
|
@@ -37,19 +35,20 @@ module.exports = function(RED) {
|
|
|
37
35
|
"questiontype" : 1,
|
|
38
36
|
"answers": [
|
|
39
37
|
{
|
|
40
|
-
"text": commons.evaluateValue(RED, config.questionAnswerOne, config.questionAnswerOneType, node, msg),
|
|
41
|
-
"value": commons.evaluateValue(RED, config.questionAnswerOneValue, config.questionAnswerOneValueType, node, msg)
|
|
38
|
+
"text": commons.evaluateValue(RED, config.questionAnswerOne, config.questionAnswerOneType, node, msg, true),
|
|
39
|
+
"value": commons.evaluateValue(RED, config.questionAnswerOneValue, config.questionAnswerOneValueType, node, msg, false)
|
|
42
40
|
},
|
|
43
41
|
{
|
|
44
|
-
"text": commons.evaluateValue(RED, config.questionAnswerTwo, config.questionAnswerTwoType, node, msg),
|
|
45
|
-
"value": commons.evaluateValue(RED, config.questionAnswerTwoValue, config.questionAnswerTwoValueType, node, msg)
|
|
42
|
+
"text": commons.evaluateValue(RED, config.questionAnswerTwo, config.questionAnswerTwoType, node, msg, true),
|
|
43
|
+
"value": commons.evaluateValue(RED, config.questionAnswerTwoValue, config.questionAnswerTwoValueType, node, msg, false)
|
|
46
44
|
},
|
|
47
45
|
{
|
|
48
|
-
"text": commons.evaluateValue(RED, config.questionAnswerThree, config.questionAnswerThreeType, node, msg),
|
|
49
|
-
"value": commons.evaluateValue(RED, config.questionAnswerThreeValue, config.questionAnswerThreeValueType, node, msg)
|
|
46
|
+
"text": commons.evaluateValue(RED, config.questionAnswerThree, config.questionAnswerThreeType, node, msg, true),
|
|
47
|
+
"value": commons.evaluateValue(RED, config.questionAnswerThreeValue, config.questionAnswerThreeValueType, node, msg, false)
|
|
50
48
|
}
|
|
51
49
|
]
|
|
52
50
|
};
|
|
51
|
+
node.log(`questionData: ${JSON.stringify(questionData)}`)
|
|
53
52
|
|
|
54
53
|
// Content smaller than 3600 bytes? FCM max size (complete payload) is 4000 bytes.
|
|
55
54
|
if (title.length + body.length + JSON.stringify(questionData).length <= 3600) {
|
|
@@ -59,7 +58,7 @@ module.exports = function(RED) {
|
|
|
59
58
|
// Sound configured or computed?
|
|
60
59
|
let sound = config.questionSound
|
|
61
60
|
if (sound === 'computed') {
|
|
62
|
-
sound = commons.evaluateValue(RED, config.questionSoundComputed, config.questionSoundComputedType, node, msg);
|
|
61
|
+
sound = commons.evaluateValue(RED, config.questionSoundComputed, config.questionSoundComputedType, node, msg, true);
|
|
63
62
|
}
|
|
64
63
|
|
|
65
64
|
// Call API to send notification
|
|
@@ -77,7 +76,11 @@ module.exports = function(RED) {
|
|
|
77
76
|
node.debug(`Question send successfull`)
|
|
78
77
|
})
|
|
79
78
|
.catch((error) => {
|
|
80
|
-
|
|
79
|
+
// Log error
|
|
80
|
+
node.error('sendNotification: ' + commons.getNetworkErrorString(error))
|
|
81
|
+
if ( commons.getNetworkErrorCustomString(error) !== undefined) {
|
|
82
|
+
node.error(commons.getNetworkErrorCustomString(error));
|
|
83
|
+
}
|
|
81
84
|
|
|
82
85
|
// Output Error
|
|
83
86
|
const msg = {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-red-contrib-remote",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Remote
|
|
3
|
+
"version": "1.5.1",
|
|
4
|
+
"description": "Remote-RED is an ecosystem to bring remote access, push notification and geofencing to Node-RED. There are also additional functions like directly answer on a notification and homescreen widgets.",
|
|
5
5
|
"author": "Thorsten Heilmann",
|
|
6
6
|
"license": "GPL-3.0",
|
|
7
7
|
"node-red": {
|