Alle Node-RED Tutorials
- Alexa Voice Control w/o Cloud
- Node-RED Alarm Ereigniszeitstrahl
- Node-RED and IFTTT
- Node-RED and MQTT
- Node-RED and ONVIF
- Node-RED and Alarmserver Queries
- Node-RED and the INSTAR Cloud Webhook
- Node-RED and SQL-Logging
- Node-RED Dashboard Live Video
- Node-RED in Docker
- Node-RED unter Android
- INSTAR MQTT - Node-RED
All Node-RED FAQs
Node-RED and IFTTT
Q: I am currently working through the Tutorial on Node-RED and IFTTT.
Unfortunately, I'm stuck at the point: IFTTT - contact to a Node-RED endpoint. During the execution I get the error messages: "IFTTT Read error" and "SyntaxError: Unexpected token o in JSON at position 1" Unfortunately I am still an absolute beginner in Node-Red, but I hope that you can help me.
A: First start importing the following Node-RED sequence:
[{"id":"b494a047.b16e1","type":"inject","z":"7daa2c74.0caa74","name":"","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":"","x":90,"y":60,"wires":[["dd733d09.e62"]]},{"id":"dd733d09.e62","type":"ifttt out","z":"7daa2c74.0caa74","eventName":"ifttt_webhook","key":"ed06780a.3466e8","x":234,"y":60,"wires":[]},{"id":"5ab42578.62ff9c","type":"http in","z":"7daa2c74.0caa74","name":"IFTTT POST Trigger","url":"/pushalarm/post/trigger/recording","method":"post","upload":false,"swaggerDoc":"","x":110,"y":160,"wires":[["6bc5487e.e34b78","6723978.979e168"]]},{"id":"6bc5487e.e34b78","type":"http response","z":"7daa2c74.0caa74","name":"Webhook","statusCode":"","headers":{"content-type":"application/json"},"x":296,"y":161,"wires":[]},{"id":"6723978.979e168","type":"debug","z":"7daa2c74.0caa74","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":310,"y":120,"wires":[]},{"id":"1fc3d4d.88f2a2b","type":"http in","z":"7daa2c74.0caa74","name":"IFTTT GET Trigger","url":"/pushalarm/get/trigger/recording","method":"get","upload":false,"swaggerDoc":"","x":110,"y":280,"wires":[["28ef78be.5ac678","725de5ab.46260c"]]},{"id":"28ef78be.5ac678","type":"http response","z":"7daa2c74.0caa74","name":"Webhook","statusCode":"","headers":{"content-type":"application/json"},"x":296,"y":281,"wires":[]},{"id":"725de5ab.46260c","type":"debug","z":"7daa2c74.0caa74","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":310,"y":240,"wires":[]},{"id":"ed06780a.3466e8","type":"ifttt-key","z":""}]
This has an Inject node to trigger an IFTTT webhook with the Event Name ifttt_webhook
- which we have to create later in the IFTTT interface (the naming here is arbitrary):
Don't forget to enter your IFTTT API key here, which you can look up in your IFTTT Account Settings.
In the following, we have created two webhooks in Node-RED - one for a POST and one for a GET request. You can decide later in the IFTTT configuration whether IFTTT uses POST or GET. We will test both here for now and decide later which one we want to use.
The POST webhook has the URL /pushalarm/post/trigger/recording
- that means if you want to call it on the local network, you would have to send a POST request to http://IP-der-Node-RED-Installation:1880/pushalarm/post/trigger/recording. This only works on the local network. For IFTTT you have to use a DDNS address - e.g. from an INSTAR IP camera in the same network - instead of the local IP address of Node-RED and an (external) port has to be forwarded to the internal port of your Node-RED installation:
You can directly forward port 1880 here or select another port as the external port.
The POST webhook has the URL /pushalarm/get/trigger/recording
- that means if you want to call it on the local network, you can call this URL http://IP-der-Node-RED-Installation:1880/pushalarm/get/trigger/recording directly in your browser. You will get an empty JSON response {}
here if everything is configured correctly.
This empty response is generated in the HTTP Response Node named as Webhook. You can leave everything blank here.
For the POST request, you must create the webhook in IFTTT as follows (the example uses the DDNS address of an AVM Fritzbox - an INSTAR DDNS address can also be used here). The port used here - separated from the DDNS address by a colon - must correspond to the port you have forwarded to the Node-RED installation in your router.
As you can see, we provide the JSON expression {"val": "on"}
as the body here. We want to use this later to switch on the motion detection areas.
For the GET request, simply select GET as the method and change the post
to a get
in the URL to be called.
You can now test the IFTT webhook by going to the following URL https://maker.ifttt.com/trigger/ifttt_webhook/with/key/c3oL9WnAbz8Z08KumJWS
. Here ifttt_webhook
is the name we gave the webhook and c3oL9WnAbz8Z08KumJWS
is your personal IFTTT API key (very important - do not share this key with anyone. It allows access to all webhooks you create in IFTTT).
Alternatively, you can trigger the node-red-contrib-ifttt node in the Node-RED sequence to contact the webhook.
Now for something practical. Copy the following flow into your Node-RED installation:
[{"id":"ead56e0c.9001","type":"http in","z":"7daa2c74.0caa74","name":"IFTTT Trigger","url":"/alarm/md/areas","method":"post","upload":false,"swaggerDoc":"","x":150,"y":539,"wires":[["db2cbc36.5d91e","6664558a.f6708c","dbe8067d.bb8a28"]]},{"id":"db2cbc36.5d91e","type":"http response","z":"7daa2c74.0caa74","name":"Webhook","statusCode":"","headers":{"content-type":"application/json"},"x":300,"y":500,"wires":[]},{"id":"ed404972.3504d8","type":"function","z":"7daa2c74.0caa74","name":"Enable Area 1","func":"var ip = \"192.168.2.165\";\nvar user = \"admin\";\nvar password = \"instar\";\n\n// Update the status with current timestamp\nvar now = new Date();\nvar yyyy = now.getFullYear();\nvar mm = now.getMonth() < 9 ? \"0\" + (now.getMonth() + 1) : (now.getMonth() + 1); // getMonth() is zero-based\nvar dd = now.getDate() < 10 ? \"0\" + now.getDate() : now.getDate();\nvar hh = now.getHours() < 10 ? \"0\" + now.getHours() : now.getHours();\nvar mmm = now.getMinutes() < 10 ? \"0\" + now.getMinutes() : now.getMinutes();\nvar ss = now.getSeconds() < 10 ? \"0\" + now.getSeconds() : now.getSeconds();\nvar currenttime= hh + \":\" + mmm + \":\" + ss;\nvar currentdate= dd + \".\" + mm + \".\" + yyyy;\n\nnode.status({fill:\"blue\",shape:\"ring\",text:\"Last updateChanged: \" + currentdate + \" - \" + currenttime});\n\nmsg.topic = \"area 1\";\nmsg.payload = ip+\"/param.cgi?cmd=setmdattr&-name=1&-enable=1&-usr=\"+user+\"&-pwd=\"+password;\nreturn msg;","outputs":1,"noerr":0,"x":535,"y":390,"wires":[["c2d5879e.abb308"]]},{"id":"2e3134ea.2896bc","type":"function","z":"7daa2c74.0caa74","name":"Disable Area 1","func":"var ip = \"192.168.2.165\";\nvar user = \"admin\";\nvar password = \"instar\";\n\n// Update the status with current timestamp\nvar now = new Date();\nvar yyyy = now.getFullYear();\nvar mm = now.getMonth() < 9 ? \"0\" + (now.getMonth() + 1) : (now.getMonth() + 1); // getMonth() is zero-based\nvar dd = now.getDate() < 10 ? \"0\" + now.getDate() : now.getDate();\nvar hh = now.getHours() < 10 ? \"0\" + now.getHours() : now.getHours();\nvar mmm = now.getMinutes() < 10 ? \"0\" + now.getMinutes() : now.getMinutes();\nvar ss = now.getSeconds() < 10 ? \"0\" + now.getSeconds() : now.getSeconds();\nvar currenttime= hh + \":\" + mmm + \":\" + ss;\nvar currentdate= dd + \".\" + mm + \".\" + yyyy;\n\nnode.status({fill:\"blue\",shape:\"ring\",text:\"Last updateChanged: \" + currentdate + \" - \" + currenttime});\n\nmsg.topic = \"area 1\";\nmsg.payload = ip+\"/param.cgi?cmd=setmdattr&-name=1&-enable=0&-usr=\"+user+\"&-pwd=\"+password;\nreturn msg;","outputs":1,"noerr":0,"x":535,"y":570,"wires":[["23d3f1c2.2207de"]]},{"id":"23d3f1c2.2207de","type":"change","z":"7daa2c74.0caa74","name":"Set URL","rules":[{"t":"set","p":"url","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":690,"y":570,"wires":[["ae6b249f.2bd9b8"]]},{"id":"c2d5879e.abb308","type":"change","z":"7daa2c74.0caa74","name":"Set URL","rules":[{"t":"set","p":"url","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":690,"y":390,"wires":[["d214ac4.329e15"]]},{"id":"ae6b249f.2bd9b8","type":"http request","z":"7daa2c74.0caa74","name":"m1_disable","method":"GET","ret":"txt","url":"","tls":"","x":834,"y":570,"wires":[["e46d691e.6c1a68"]]},{"id":"d214ac4.329e15","type":"http request","z":"7daa2c74.0caa74","name":"m1_enable","method":"GET","ret":"txt","paytoqs":false,"url":"","tls":"","persist":false,"proxy":"","authType":"","x":834,"y":390,"wires":[["e46d691e.6c1a68"]]},{"id":"6664558a.f6708c","type":"switch","z":"7daa2c74.0caa74","name":"Push","property":"payload.val","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"},{"t":"eq","v":"off","vt":"str"}],"checkall":"false","repair":false,"outputs":2,"x":330,"y":539,"wires":[["ed404972.3504d8","3ceb937e.88f20c","96be2992.947a38","93c60eb7.d9497"],["2e3134ea.2896bc","e3f362a8.041ef","26ac4b9c.4632e4","ed93967b.79c908"]]},{"id":"e46d691e.6c1a68","type":"debug","z":"7daa2c74.0caa74","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1039,"y":538,"wires":[]},{"id":"3ceb937e.88f20c","type":"function","z":"7daa2c74.0caa74","name":"Enable Area 2","func":"var ip = \"192.168.2.165\";\nvar user = \"admin\";\nvar password = \"instar\";\n\n// Update the status with current timestamp\nvar now = new Date();\nvar yyyy = now.getFullYear();\nvar mm = now.getMonth() < 9 ? \"0\" + (now.getMonth() + 1) : (now.getMonth() + 1); // getMonth() is zero-based\nvar dd = now.getDate() < 10 ? \"0\" + now.getDate() : now.getDate();\nvar hh = now.getHours() < 10 ? \"0\" + now.getHours() : now.getHours();\nvar mmm = now.getMinutes() < 10 ? \"0\" + now.getMinutes() : now.getMinutes();\nvar ss = now.getSeconds() < 10 ? \"0\" + now.getSeconds() : now.getSeconds();\nvar currenttime= hh + \":\" + mmm + \":\" + ss;\nvar currentdate= dd + \".\" + mm + \".\" + yyyy;\n\nnode.status({fill:\"blue\",shape:\"ring\",text:\"Last updateChanged: \" + currentdate + \" - \" + currenttime});\n\nmsg.topic = \"area 2\";\nmsg.payload = ip+\"/param.cgi?cmd=setmdattr&-name=2&-enable=1&-usr=\"+user+\"&-pwd=\"+password;\nreturn msg;","outputs":1,"noerr":0,"x":535,"y":432,"wires":[["98144281.8d951"]]},{"id":"98144281.8d951","type":"change","z":"7daa2c74.0caa74","name":"Set URL","rules":[{"t":"set","p":"url","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":690,"y":432,"wires":[["c7bfd8c6.b8f6e8"]]},{"id":"c7bfd8c6.b8f6e8","type":"http request","z":"7daa2c74.0caa74","name":"m1_enable","method":"GET","ret":"txt","url":"","tls":"","x":834,"y":432,"wires":[["e46d691e.6c1a68"]]},{"id":"96be2992.947a38","type":"function","z":"7daa2c74.0caa74","name":"Enable Area 3","func":"var ip = \"192.168.2.165\";\nvar user = \"admin\";\nvar password = \"instar\";\n\n// Update the status with current timestamp\nvar now = new Date();\nvar yyyy = now.getFullYear();\nvar mm = now.getMonth() < 9 ? \"0\" + (now.getMonth() + 1) : (now.getMonth() + 1); // getMonth() is zero-based\nvar dd = now.getDate() < 10 ? \"0\" + now.getDate() : now.getDate();\nvar hh = now.getHours() < 10 ? \"0\" + now.getHours() : now.getHours();\nvar mmm = now.getMinutes() < 10 ? \"0\" + now.getMinutes() : now.getMinutes();\nvar ss = now.getSeconds() < 10 ? \"0\" + now.getSeconds() : now.getSeconds();\nvar currenttime= hh + \":\" + mmm + \":\" + ss;\nvar currentdate= dd + \".\" + mm + \".\" + yyyy;\n\nnode.status({fill:\"blue\",shape:\"ring\",text:\"Last updateChanged: \" + currentdate + \" - \" + currenttime});\n\nmsg.topic = \"area 3\";\nmsg.payload = ip+\"/param.cgi?cmd=setmdattr&-name=3&-enable=1&-usr=\"+user+\"&-pwd=\"+password;\nreturn msg;","outputs":1,"noerr":0,"x":535,"y":472,"wires":[["a4c727eb.e93508"]]},{"id":"a4c727eb.e93508","type":"change","z":"7daa2c74.0caa74","name":"Set URL","rules":[{"t":"set","p":"url","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":690,"y":472,"wires":[["6cb7cabe.3103d4"]]},{"id":"6cb7cabe.3103d4","type":"http request","z":"7daa2c74.0caa74","name":"m1_enable","method":"GET","ret":"txt","url":"","tls":"","x":834,"y":472,"wires":[["e46d691e.6c1a68"]]},{"id":"93c60eb7.d9497","type":"function","z":"7daa2c74.0caa74","name":"Enable Area 4","func":"var ip = \"192.168.2.165\";\nvar user = \"admin\";\nvar password = \"instar\";\n\n// Update the status with current timestamp\nvar now = new Date();\nvar yyyy = now.getFullYear();\nvar mm = now.getMonth() < 9 ? \"0\" + (now.getMonth() + 1) : (now.getMonth() + 1); // getMonth() is zero-based\nvar dd = now.getDate() < 10 ? \"0\" + now.getDate() : now.getDate();\nvar hh = now.getHours() < 10 ? \"0\" + now.getHours() : now.getHours();\nvar mmm = now.getMinutes() < 10 ? \"0\" + now.getMinutes() : now.getMinutes();\nvar ss = now.getSeconds() < 10 ? \"0\" + now.getSeconds() : now.getSeconds();\nvar currenttime= hh + \":\" + mmm + \":\" + ss;\nvar currentdate= dd + \".\" + mm + \".\" + yyyy;\n\nnode.status({fill:\"blue\",shape:\"ring\",text:\"Last updateChanged: \" + currentdate + \" - \" + currenttime});\n\nmsg.topic = \"area 4\";\nmsg.payload = ip+\"/param.cgi?cmd=setmdattr&-name=4&-enable=1&-usr=\"+user+\"&-pwd=\"+password;\nreturn msg;","outputs":1,"noerr":0,"x":535,"y":512,"wires":[["d3c05e5.8e40da"]]},{"id":"d3c05e5.8e40da","type":"change","z":"7daa2c74.0caa74","name":"Set URL","rules":[{"t":"set","p":"url","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":690,"y":512,"wires":[["bd3b3647.c5a998"]]},{"id":"bd3b3647.c5a998","type":"http request","z":"7daa2c74.0caa74","name":"m1_enable","method":"GET","ret":"txt","url":"","tls":"","x":834,"y":512,"wires":[["e46d691e.6c1a68"]]},{"id":"e3f362a8.041ef","type":"function","z":"7daa2c74.0caa74","name":"Disable Area 2","func":"var ip = \"192.168.2.165\";\nvar user = \"admin\";\nvar password = \"instar\";\n\n// Update the status with current timestamp\nvar now = new Date();\nvar yyyy = now.getFullYear();\nvar mm = now.getMonth() < 9 ? \"0\" + (now.getMonth() + 1) : (now.getMonth() + 1); // getMonth() is zero-based\nvar dd = now.getDate() < 10 ? \"0\" + now.getDate() : now.getDate();\nvar hh = now.getHours() < 10 ? \"0\" + now.getHours() : now.getHours();\nvar mmm = now.getMinutes() < 10 ? \"0\" + now.getMinutes() : now.getMinutes();\nvar ss = now.getSeconds() < 10 ? \"0\" + now.getSeconds() : now.getSeconds();\nvar currenttime= hh + \":\" + mmm + \":\" + ss;\nvar currentdate= dd + \".\" + mm + \".\" + yyyy;\n\nnode.status({fill:\"blue\",shape:\"ring\",text:\"Last updateChanged: \" + currentdate + \" - \" + currenttime});\n\nmsg.topic = \"area 2\";\nmsg.payload = ip+\"/param.cgi?cmd=setmdattr&-name=2&-enable=0&-usr=\"+user+\"&-pwd=\"+password;\nreturn msg;","outputs":1,"noerr":0,"x":535,"y":612,"wires":[["9e948381.1b5bf"]]},{"id":"9e948381.1b5bf","type":"change","z":"7daa2c74.0caa74","name":"Set URL","rules":[{"t":"set","p":"url","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":690,"y":612,"wires":[["758ed212.5c8c6c"]]},{"id":"758ed212.5c8c6c","type":"http request","z":"7daa2c74.0caa74","name":"m1_disable","method":"GET","ret":"txt","url":"","tls":"","x":834,"y":612,"wires":[["e46d691e.6c1a68"]]},{"id":"26ac4b9c.4632e4","type":"function","z":"7daa2c74.0caa74","name":"Disable Area 3","func":"var ip = \"192.168.2.165\";\nvar user = \"admin\";\nvar password = \"instar\";\n\n// Update the status with current timestamp\nvar now = new Date();\nvar yyyy = now.getFullYear();\nvar mm = now.getMonth() < 9 ? \"0\" + (now.getMonth() + 1) : (now.getMonth() + 1); // getMonth() is zero-based\nvar dd = now.getDate() < 10 ? \"0\" + now.getDate() : now.getDate();\nvar hh = now.getHours() < 10 ? \"0\" + now.getHours() : now.getHours();\nvar mmm = now.getMinutes() < 10 ? \"0\" + now.getMinutes() : now.getMinutes();\nvar ss = now.getSeconds() < 10 ? \"0\" + now.getSeconds() : now.getSeconds();\nvar currenttime= hh + \":\" + mmm + \":\" + ss;\nvar currentdate= dd + \".\" + mm + \".\" + yyyy;\n\nnode.status({fill:\"blue\",shape:\"ring\",text:\"Last updateChanged: \" + currentdate + \" - \" + currenttime});\n\nmsg.topic = \"area 3\";\nmsg.payload = ip+\"/param.cgi?cmd=setmdattr&-name=3&-enable=0&-usr=\"+user+\"&-pwd=\"+password;\nreturn msg;","outputs":1,"noerr":0,"x":535,"y":652,"wires":[["b6569fcb.32091"]]},{"id":"b6569fcb.32091","type":"change","z":"7daa2c74.0caa74","name":"Set URL","rules":[{"t":"set","p":"url","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":690,"y":652,"wires":[["6676cfed.b231"]]},{"id":"6676cfed.b231","type":"http request","z":"7daa2c74.0caa74","name":"m1_disable","method":"GET","ret":"txt","url":"","tls":"","x":834,"y":652,"wires":[["e46d691e.6c1a68"]]},{"id":"ed93967b.79c908","type":"function","z":"7daa2c74.0caa74","name":"Disable Area 4","func":"var ip = \"192.168.2.165\";\nvar user = \"admin\";\nvar password = \"instar\";\n\n// Update the status with current timestamp\nvar now = new Date();\nvar yyyy = now.getFullYear();\nvar mm = now.getMonth() < 9 ? \"0\" + (now.getMonth() + 1) : (now.getMonth() + 1); // getMonth() is zero-based\nvar dd = now.getDate() < 10 ? \"0\" + now.getDate() : now.getDate();\nvar hh = now.getHours() < 10 ? \"0\" + now.getHours() : now.getHours();\nvar mmm = now.getMinutes() < 10 ? \"0\" + now.getMinutes() : now.getMinutes();\nvar ss = now.getSeconds() < 10 ? \"0\" + now.getSeconds() : now.getSeconds();\nvar currenttime= hh + \":\" + mmm + \":\" + ss;\nvar currentdate= dd + \".\" + mm + \".\" + yyyy;\n\nnode.status({fill:\"blue\",shape:\"ring\",text:\"Last updateChanged: \" + currentdate + \" - \" + currenttime});\n\nmsg.topic = \"area 4\";\nmsg.payload = ip+\"/param.cgi?cmd=setmdattr&-name=4&-enable=0&-usr=\"+user+\"&-pwd=\"+password;\nreturn msg;","outputs":1,"noerr":0,"x":535,"y":692,"wires":[["ed9704cc.f69a18"]]},{"id":"ed9704cc.f69a18","type":"change","z":"7daa2c74.0caa74","name":"Set URL","rules":[{"t":"set","p":"url","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":690,"y":692,"wires":[["bd53e77a.f197f8"]]},{"id":"bd53e77a.f197f8","type":"http request","z":"7daa2c74.0caa74","name":"m1_disable","method":"GET","ret":"txt","url":"","tls":"","x":834,"y":692,"wires":[["e46d691e.6c1a68"]]},{"id":"dbe8067d.bb8a28","type":"debug","z":"7daa2c74.0caa74","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":290,"y":580,"wires":[]}]
This sequence gives you a new POST webhook on the URL /alarm/md/areas
:
Sorts then whether a {"val": "on"}
or {"val": "off"}
was sent (we had set this in the IFTTT configuration):
In the following, the areas are then either switched on or off on the camera, which is set in the 8 Function Nodes: