Pull request proposal - Confirmation before injecting

Hi folks,

I have a number of inject buttons in my flows, which I would like to secure for accidentally clicking them. Because some of those inject buttons trigger actions that could cause troubles, when being used at the wrong moments...

Therefore it would be nice if there was a confirmation popup, to have a reminder.

Some use cases:

Trigger action Confirmation label
Start cleaning pool Is the plastic cover removed?
Update geo-ip DB Continue? Because this will take 35 minutes...
Open garage door Do you really want to open the garage door?
Panic button Are you sure to trigger all alarms?
Cleanup video Do you really want to remove all video footage?
... ...

Until now I added Comment-nodes all across my flow, to have some kind of reminder.
But my flow is looking like a word document, and it still doesn't prevent me from accidentally clicking one of those buttons...

So I added a confirmation checkbox to the (old version of) Inject node:


When the inject button is now clicked, you will get a confirmation popup:


And it only triggers the message when you press the "OK" button.

P.S. I assume the suffix of the node name also has to be changed (e.g. with an extra ?) to visualize this in the flow editor?

Hopefully you like this idea,


I kind of like it (meaning that if it is there I would like it, but I would not miss it), but I can see people say "the editor is no dashboard" :slight_smile:

The buttons don't look very Node-RED like. Which CSS classes do you use?

I can also see people say that with the new outliner you can also just disable those inject nodes very easily and re-enable them if you need them


I was wondering who would be the first one to use those magic words :scream:
But the editor is also not a Word document, so I would like to get rid of all those warnings in my Comment-nodes :wink:

None for a couple of reasons:

  • I'm not a CSS specialist.
  • I don't want to spend too much time on a PR that might get rejected.
  • I don't want to get criticized that I have started developing, before we have agreed something.

This is a very basic implementation, just to explain the idea.
And creating a mockup in paint takes about as much time as changing the html immediately ...

I will certainly use that option for stuff I don't need currently or stuff that is not 100% fully operational. When I would use it also to remind me of something, that would be not my cup of tea...

Bart, let me be the second to add that comment, but rather than doing this through inject buttons in the flow, aren't these specific actions best handled on a dashboard or otherwise through confirmation added in your flow? For example have the flow first send a notification to your device that you have to interact with (say if you're using telegram nodes or similar send a text to your phone that you've to acknowledge before it continues). It's what I do in cases like this. The inject is good on non-dangerous aspects, but if there's a need for a confirmation I handle that through componenets in the flow.

1 Like

With 1.1.0 you'll be able to put those injects nodes into a group and make it bright red to alert you to the danger.

(Editor not a dashboard... Etc)


love it!


Hey Lena,
Yes of course in the dashboard I have more liberty, to secure those actions for my family. But since I spend most of my time myself in the flow editor, I wanted to have something similar. Recently I opened accidentally the garage door, while doing a test for somebody. That would have been covered very easily by a small checkbox...

Well if there was something in the flow editor - similar to the dashboard's socket id - then I would have immediately developed my own custom Confirmation-node, to avoid having to beg here for one extra small little feature in the Node-RED core...
But I don't think that the flow editor has something similar to the socket id, so I don't think I can handle this in a custom node. Indeed when you have N flow editors open simultaneously, you don't know on the server-side in which of those N editors somebody has pressed the Inject button. So you don't know to which client you have to push the confirmation request to show it. But perhaps I'm completely wrong...

could you elaborate a bit more what this confirmation node should do and where it should get its information from?

I think there is a way of sending something to a specific editor client, but the Node-RED chefs have to confirm that.

I can see your user-case, I have the same, but maybe such interactions should be restricted to the dashboard?
Having said that... I've created a 10 second delay to re-think certain actions, with an option to cancel.



Very smart - def worth adding to the flows site.
I guess you could also do a "confirm" version where you have to press two buttons to activate. (which is basically all that a popup is that doesn't need to pop-up...)


Could you post that flow here please?
(adding to existing post would be fine)

The other thing that I've done before is to actually cover the end of the inject node with a comment node. You have to move it out of the way to press the inject and can simply reload the page to put it back.

This is the exact equivalent of the "plastic shield" over a physical button.

I'd agree with others here that a purpose built UI is the safe, secure and easy way to create such an interface. Leaving the editor for actually editing flows.

In fact thinking about it, can't you also disable the node? So you could get even more protection by leaving it disabled most of the time.

1 Like

Hi guys,
Nice suggestions. Always nice to see how people become creative!!
But to me it seems I'm not the only one needing such a feature.
So I don't really understand why nobody wants a real solution then...
Seems like a lot of workarounds to solve a simple problem.

No I was wrong last night. I can never build such a node, even if I would have a socket_id. Would never work.

So end of this request. Case closed.

Here's 2 versions. The top flow will run the command if not cancelled within 10 seconds, and the bottom version will cancel the command in 10 seconds unless it has been confirmed.
To enable either flow, just reconnect the 'Command' exec node.
I'll add them to the flow library later...


[{"id":"d9792b68.171d18","type":"inject","z":"4487e413.bb781c","name":"Restart node-RED","topic":"nrRestart","payload":"node-red-restart","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":230,"y":1270,"wires":[["3516bc38.3395f4"]],"icon":"font-awesome/fa-refresh"},{"id":"3516bc38.3395f4","type":"function","z":"4487e413.bb781c","name":"Countdown","func":"let input = msg.payload;\nlet cancel = false;\nlet option = msg.topic;\nlet counter = 10;\nvar desc;\n\n// define the status messages\nif (option == \"nrRestart\"){\n        desc = \"Restarting node-RED\";\n    } else if (option == \"piRestart\"){\n        desc = \"Rebooting system\";\n    } else if (option == \"update\"){\n        desc = \"Updating Pi server\";\n    }\n    \n// enable user to cancel operation\nif (option == \"cancel\"){\n    flow.set(\"cancel\", true);\n    return;\n    } else {flow.set(\"cancel\", false);}\n\n// Run the countdown\nvar countdown = setInterval(function(){\n  node.status({text:(desc+\" in \"+counter+\" seconds\")});\n  counter--;\n  if (flow.get(\"cancel\")===true) {\n      clearInterval(countdown);\n      node.status({text:\"Request Cancelled\"});\n      flow.set(\"cancel\", false);\n  }\n  \n// When counter expires, update status & reset  \n  if (counter === -1) {\n    node.status({text:(desc+\" NOW!\")});\n    clearInterval(countdown);\n    node.send({\"payload\": input});\n  }\n}, 1000);","outputs":1,"noerr":0,"x":450,"y":1330,"wires":[[]],"icon":"font-awesome/fa-hourglass-1"},{"id":"609e311a.8302b","type":"inject","z":"4487e413.bb781c","name":"Cancel","topic":"cancel","payload":"cancel","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":"","x":270,"y":1390,"wires":[["3516bc38.3395f4"]],"icon":"font-awesome/fa-exclamation-triangle"},{"id":"f6ab5b46.514e08","type":"exec","z":"4487e413.bb781c","command":"","addpay":true,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"Command","x":630,"y":1320,"wires":[[],[],[]]},{"id":"ee6338f0.bdcfd8","type":"inject","z":"4487e413.bb781c","name":"Restart Pi","topic":"piRestart","payload":"sudo systemctl reboot","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":260,"y":1310,"wires":[["3516bc38.3395f4"]],"icon":"font-awesome/fa-refresh"},{"id":"d5bb979b.123548","type":"inject","z":"4487e413.bb781c","name":"Update Pi","topic":"update","payload":"sudo ~/update_server.sh","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":260,"y":1350,"wires":[["3516bc38.3395f4"]],"icon":"node-red/db.svg"},{"id":"b988f007.c6dd6","type":"inject","z":"4487e413.bb781c","name":"Restart node-RED","topic":"nrRestart","payload":"node-red-restart","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":240,"y":1450,"wires":[["418bf636.a88bd8"]],"icon":"font-awesome/fa-refresh"},{"id":"f48ec4b0.caab38","type":"inject","z":"4487e413.bb781c","name":"Confirm","topic":"confirm","payload":"confirm","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":"","x":280,"y":1570,"wires":[["418bf636.a88bd8"]],"icon":"font-awesome/fa-exclamation-triangle"},{"id":"97991ced.05158","type":"exec","z":"4487e413.bb781c","command":"","addpay":true,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"Command","x":630,"y":1500,"wires":[[],[],[]]},{"id":"3ad3fcb4.4d5684","type":"inject","z":"4487e413.bb781c","name":"Restart Pi","topic":"piRestart","payload":"sudo systemctl reboot","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":270,"y":1490,"wires":[["418bf636.a88bd8"]],"icon":"font-awesome/fa-refresh"},{"id":"88a2f64c.47de78","type":"inject","z":"4487e413.bb781c","name":"Update Pi","topic":"update","payload":"sudo ~/update_server.sh","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":270,"y":1530,"wires":[["418bf636.a88bd8"]],"icon":"node-red/db.svg"},{"id":"418bf636.a88bd8","type":"function","z":"4487e413.bb781c","name":"Countdown","func":"let input = msg.payload;\nlet option = msg.topic;\nlet confirm = false;\nlet counter = 10;\nvar desc;\n\n// define the status messages\n if (option == \"nrRestart\"){\n        desc = \"Confirm NR restart\";\n    } else if (option == \"piRestart\"){\n        desc = \"Confirm reboot\";\n    } else if (option == \"update\"){\n        desc = \"Confirm update\";\n    }\n    \n// enable user to confirm operation\nif (option == \"confirm\"){\n    flow.set(\"confirm\", true);\n    return;\n    } else {flow.set(\"confirm\", false);}\n  \n// Run the countdown\nvar countdown = setInterval(function(){\n  node.status({text:(desc+\" within \"+counter+\" seconds\")});\n  counter--;\n  if (flow.get(\"confirm\")===true) {\n      clearInterval(countdown);\n      node.status({text:\"Request Confirmed\"});\n      node.send({\"payload\": input});\n      flow.set(\"confirm\", false);\n  }\n  \n// When counter expires, update status & reset\n  if (counter === 0) {\n    node.status({text:(\"Request Cancelled!\")});\n    clearInterval(countdown);\n  }\n}, 1000);","outputs":1,"noerr":0,"x":460,"y":1510,"wires":[[]]},{"id":"24a0ce1e.4a4c42","type":"comment","z":"4487e413.bb781c","name":"Unless cancelled, command will be actioned","info":"","x":550,"y":1270,"wires":[]},{"id":"48618e90.16136","type":"comment","z":"4487e413.bb781c","name":"Unless confirmed, command will be cancelled","info":"","x":550,"y":1450,"wires":[]}]

Thanks :slight_smile:

Could I suggest you alter your posted code so that the Command blocks are disabled just in case someone imports and presses buttons without thinking things thru to their logical conclusion !

[edit] Done I see :slight_smile: [/edit]


or just remove the final wire...


Another thought - is it possible to access the RED pop-up API from a function node? I think that such pop-ups can have OK/Cancel buttons?

1 Like

No. The function node code runs in the runtime, not the editor.


This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.