Retrieving my IP address Remotely

Retrieving my IP address Remotely

I posted a few years ago about using Twilio and Node-Red to send/receive SMS messages. Using that flow you gain the ability to text your server and have it read back values. Any values you want, as long as you have them stored as a global some where along the way. If you haven’t already done it toss $20 on an account at Twilio for a year and get to it, its so worth it! Here I am going to add a new reading to my setup.

There are occasions when I need to access my home network when I am, well, not home. Everyone screams use a VPN! Yeah, of course, I have one, and I use it. But my problem is I have a dynamic WAN IP and I am not paying for a static IP. It doesn’t change very often but it always seems to when I need to use it the most. Step in Node-Red and Twilio. With both of those at my disposal I can now send a text message to my home server and have it respond with my WAN IP address. I can then modify my VPN settings on my phone or whatever if needed. Fucking fantastic! I had been using Twilio/NR for sensor readings and alerts but I had never thought about using it to report my IP. Theres a few ways to do this.

Lets grab our IP (the flow)

(This flow grabs the WAN IP via an exec node)

First we use an inject node and set it to fire off once on start, this grabs the IP first thing and makes sure we have some data to work with. Then we move off to an execute node. We are gonna execute some command line code and echo it back, then we’ll save it in a file and as a global. This goes in the exec node:

wget -qO- http://bot.whatismyipaddress.com/ ; echo

This goes out to whatismyipaddress.com and echoes back our IP, simple and very fast. There are a few other sites that can be used also. Ifconfig.io and ipinfo.io both are alternative sites (you just have to change the truncation from 5 to 6 characters to drop the return sign in the following function node).

Alternatively, and preferably we can use an HTTP node instead of an exec node. What? Yeah I just found this out.

(This flow grabs the IP via an HTTP node)

That will get you your WAN IP quickly via an HTTP node formats it then saves it to a file. We have to comment out the substring trimming command if we use the HTTP node over the exec node. Ok no problem. Don’t forget.

After we grab the IP we need to format it and save it as a global for Twilio (and Alexa!).

This will trim the returned output from the website to 6 characters, dropping off anything extra. It also saves our trimmed value as a global. Then we slap on a debug node and a file node to save the IP to a file for later use. You don’t have to save the IP to a file, I just like to in the even the server is restarted/power loss.

Thats it! Once the IP has been picked up and set as a global you are good to go (as long as you followed the other flow for Twilio I posted previously).

 

It figures…

After typing this up and saving the draft I decided to update NPM/nodejs/Node-Red. Upon updating I came across a Node-Red node, node-red-contrib-ip.

A simple install via Palette Manager (which doesn’t work for me) or manually installed via npm install node-red-contrib-ip and you’re good. The node works simply, nothing to configure. Add an inject node to trigger it and it spits out your machines IPv4 and IPv6 address and well as your WAN IP address. Just have to format the data the way you want and boom. I did notice it is slow, painfully slow. It doesn’t need to be lightning quick but it is noticeable compared to the wget option above. Choose your weapon, either method works. Heres the flow for using the IP node.

(This flow grabs the WAN IP via the node red IP node)

After the IP node put a function node and fill it with this code

This drops all the other node info and just gives us the WAN IP. Easy as pie.

 

Lets get notified

So far we check our IP every 12hrs and write it to a file and a global for use. Thats great, we can take it one step further. Want to get a notification when the IP does change? Lets go.

(This flow grabs the IP via an HTTP node and checks if it has been updated, then sends a notification if it has)

  • Inject and repeat every 24hrs at a set time
  • Read the stored IP address by reading the file
  • Get the current IP address and set it as a global
  • Cross check to see if the new IP matches the old IP and save it to a file if it is newer.
  • Format the message payload and send a notification (however you like, pushbullet, email, Twilio etc)

 

Check out this site, its where I got the notifications from https://steve.zazeski.com/get-a-notification-when-your-wan-ip-changes/.

Node-Red IVR with Twilio

Twilio

A while back I posted about using Twilio and Node-Red to send/receive SMS messages. I was fiddling around with some older project stuff (uncompleted) earlier today and bounced into the IVR setup I had. Wondering if it was working I called it, and no it wasn’t. So I had to fix it. It took me a minute to come across all the related pages needed to get it working again so I decided to compile them here.

What is an IVR?

Well if you Google IVR you get: Interactive voice response (IVR) is a technology that allows a computer to interact with humans through the use of voice and DTMF tones input via keypad.

And that basically sums it up. It allows you the person, to call a computer and have the computer know what you want when pressing 1, or 5. Similar to a phone switching system but they are usually used to report some kind of information instead of route calls. IVRs basically cut out someones job once upon a time.

A better example is of a field technician calling an IVR system to read back what signals were received on the clients security system he just tested.

What we are doing here?

Were are going to get a basic IVR running on our Node-Red server to interact with and read back data or to activate/deactivate things over MQTT. If you would rather (and/or) use SMS to achieve kinda the same thing read here.

Prerequisites

 

The Flow!

the flow

Here is the glorious flow!

You will need to create a global and have its value set so the IVR can read it back (in this example).

Drop a line in the comments if you have a question.

 

What helped:

https://flows.nodered.org/node/node-red-node-twilio
old outdated flow https://flows.nodered.org/flow/637b5f6128a8d423503f
https://groups.google.com/d/topic/node-red/yAEx5k2UHJw/discussion


[{"id":"4868a284.66517c","type":"http response","z":"feaafa48.a34f88","name":"Send TwiML","x":870,"y":200,"wires":[]},{"id":"1444c0f8.9e1bff","type":"http in","z":"feaafa48.a34f88","name":"Incomming Twilio Call","url":"/twiliovoice","method":"post","upload":false,"swaggerDoc":"","x":316,"y":202,"wires":[["8cebf57a.769bc8","a77ee63.fbb7618"]]},{"id":"8cebf57a.769bc8","type":"function","z":"feaafa48.a34f88","name":"Process Call","func":"var twiml_response = \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\" standalone=\\\"yes\\\"?> \\\n <Response> \\\n <Gather action=\\\"https://yourserver.com/twilioivr\\\" numDigits=\\\"1\\\"> \\\n <Say voice=\\\"woman\\\">Welcome to Node-Red. For power usage press 1. To ring the bell press 2. For anything else press 3</Say> \\\n </Gather> \\\n <Say voice=\\\"woman\\\">Sorry, I didn't get your response.</Say> \\\n </Response>\";\nmsg.payload = twiml_response;\nreturn msg;","outputs":1,"noerr":0,"x":630,"y":200,"wires":[["4868a284.66517c","daf3c74e.9d90e8"]]},{"id":"2e446272.06064e","type":"http in","z":"feaafa48.a34f88","name":"IVR Data Call","url":"/twilioivr","method":"post","upload":false,"swaggerDoc":"","x":290,"y":280,"wires":[["f769d46d.3e7fc8","a306c4e8.68fd58"]]},{"id":"daf3c74e.9d90e8","type":"debug","z":"feaafa48.a34f88","name":"","active":true,"complete":false,"x":870,"y":280,"wires":[]},{"id":"f769d46d.3e7fc8","type":"debug","z":"feaafa48.a34f88","name":"","active":true,"complete":false,"x":630,"y":320,"wires":[]},{"id":"a77ee63.fbb7618","type":"debug","z":"feaafa48.a34f88","name":"","active":false,"console":false,"complete":"payload","x":630,"y":160,"wires":[]},{"id":"a306c4e8.68fd58","type":"function","z":"feaafa48.a34f88","name":"handleGather","func":"// Use 2 outputs, 2nd is for mqtt topic/payload combination\n// Could be useful to post other caller info to a topic\nvar mqttOut = null;\nvar responseMsg = \"\";\n\nvar name = \"wholehouse\";\nvar reading = context.global[name];\nvar digit = msg.payload.Digits;\nif( digit == \"1\" ) {\n var twiml_response = \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\" standalone=\\\"yes\\\"?> \\\n <Response> \\\n <Say voice=\\\"woman\\\">Power usage is \" + reading + \"</Say> \\\n </Response>\";\n msg.payload = twiml_response;\n} else if( digit == \"2\" ) {\n\tmqttOut = {topic: \"bellduino/ring\", payload: \"ringmybell\" };\n var twiml_response = \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\" standalone=\\\"yes\\\"?> \\\n <Response> \\\n <Say voice=\\\"woman\\\">Turing on the bell</Say> \\\n </Response>\";\n msg.payload = twiml_response;\n} else {\n\tresponseMsg = \"You pressed \" + digit;\n}\n\nreturn [msg, mqttOut];","outputs":"2","noerr":0,"x":640,"y":280,"wires":[["4868a284.66517c","daf3c74e.9d90e8"],["a023a81c.a3e318","442a4b04.0c3c64"]]},{"id":"413a0cf4.24b0e4","type":"globalGetSet","z":"feaafa48.a34f88","name":"Text Global","topic":"","context":"msg","variable":"payload","outContext":"global","outVar":"wholehouse","x":490,"y":380,"wires":[[]]},{"id":"390ea068.1c8f8","type":"inject","z":"feaafa48.a34f88","name":"","topic":"","payload":"42.1","payloadType":"num","repeat":"","crontab":"","once":true,"x":290,"y":380,"wires":[["413a0cf4.24b0e4"]]},{"id":"a023a81c.a3e318","type":"mqtt out","z":"feaafa48.a34f88","name":"","topic":"","qos":"","retain":"","broker":"bdbaaa3f.072c48","x":850,"y":400,"wires":[]},{"id":"442a4b04.0c3c64","type":"debug","z":"feaafa48.a34f88","name":"","active":true,"console":"false","complete":"true","x":850,"y":360,"wires":[]},{"id":"bdbaaa3f.072c48","type":"mqtt-broker","z":"","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"willTopic":"","willQos":"0","willPayload":"","birthTopic":"","birthQos":"0","birthPayload":""}]

 

SEND IT.

Receiving a Twilio SMS

Twilio

 

I use Node-Red for a lot of things and I have recently wanted to send notifications via SMS instead of an email, and I wanted to be able to receive SMS messages as well. I have had issues with the email node. It doesn’t always send for me (I’m using Google’s SMTP) and I don’t have a loud email notification on my phone. Because tons of emails thats why. But text messages on my phone have a very loud notification. I also wanted to be able to send messages to my Node-Red server, doing that via email is cumbersome. So texting it is. Plus sending/receiving an SMS is way cooler than a boring email. I know I can send texts to my phone via email (on most carriers) but that still requires using email and the email node. Don’t want to.

Enter Twilio. I have used Twilio before in the past with their free service tier and never got around to actually using it. The free service lets you do all the same stuff (I think) as the paid service but all the texts have a “This message was sent by Twilio – ” tag attached before every message. So I think thats why I never used it. Well I looked into it again and this time I just upgraded my account right away. Not fucking around. I just threw down $20 bucks. You buy a phone number for $1 per month and then you pay for all the messages you send. The cost per message (at this time) is somewhere around $0.0075 cents! Sweet! I figure I should be able to get a years worth of my number rental and a few messages off that $20 bucks.

So lets use Node-Red to send and receive an SMS with Twilio, it’s why you’re here right? Not for my ramblings.

To send an SMS from Node-Red is dead simple. Just install the Twilio node. It gives you a new output node. Just send you data to the node and off the SMS goes.

To be able to receive a message from Twilio your Node-Red needs to be accessible from the outside world. Twilio needs to be able to see the XML we are going to generate. In my searches for doing this I got a fucking headache. I found a few blogs out there with info on this but nothing concrete. It was actually pretty simple, at least for me. I have also already done this before in a previous post. I happen to run Apache for my web server, which is already setup and open to the world, DNS already setup. All I had to do was create a subdomain (not required) and point a the new vhost to my Node-Red server/install (via ProxyPass). Once this was done Twilio could access my Node-Red served pages. I also have (but I don’t think is required?) SSL already setup. I used Let’s Encrypt on my Apache server. However you do it is fine, you just need to be able to see at least 1-2 Node-Red generated pages from the web. I honestly found this to be one of the more pain in the ass tasks to deal with. Good luck.

Update: added a new post about reverse-proxy/SSL

 

Twilio Flow

The switch node checks msg.Body with   msg.req.query.Body for an incoming command. If the switch matches a command it routes it to a function node. If it matches a command it also checks that command for an ON or OFF and outputs the results as a 1 or 0 for you to do with what you like. So you would text your Twilio number “mySwitch on” or “mySwitch off” and bam! Otherwise it passes it off to a different function node to process the message further. That node checks the incoming message for a global. By this I mean you text your Twilio number “read mySensor” and this function node sees the “read” command and then checks for a sensor name (mySensor). It matches this name against a global you have saved and spits back the results after being XML’d. So when you text “read mySensor” it checks the mySensor global and texts you back with “mySensor: yourvalue”. Awesome.

Tip: the switch node is case sensitive, so be careful. The function nodes change everything to caps I assume to simplify stuff I dunno. I didn’t write it. Also when you change the sensor name make sure to edit the substr to match the character limit of your sensor name. Example: WEMO would be 4, MYSWITCH is 8 characters. Same thing if you change the READ query.

Here’s the flow, I included a testing global for you as well:

This is where I got the information on the Twilio node (from the creator it seems) and how to receive messages. But I found it about as clear as mud. (Note: the json2xml node doesn’t exist anymore. Just use the XML node now.)
http://blog.thiseldo.co.uk/?p=1090

Here is the original flow on flows.node.red.org, but its a little outdated.
http://flows.nodered.org/flow/d65e0c5e4f5fef767be2

 

Some other pages I found helpful along the way:
http://flows.nodered.org/flow/bce112d484f93a8c282a
https://groups.google.com/d/msg/node-red/YBVKXhJLI90/gUh3T-O6BAAJ
https://www.thethingsnetwork.org/forum/t/parse-data-with-node-red/835/9
http://noderedguide.com/node-red-lecture-3-basic-nodes-and-flows/
https://github.com/Leonidas-from-XIV/node-xml2js/issues/87
https://www.twilio.com/docs/api/twiml/sms/your_response

IVR with Twilio and Node-Red example flow
http://flows.nodered.org/flow/637b5f6128a8d423503f