Process Twilio SMS request

The Twilio node is not needed to handle SMS requests as this can be accomplished using regular HTTP input and output nodes. The way it works is that when a SMS is received on your Twilio number, the Twilio server will pass the information to you via the Messaging URL you define in your number setup. The Twilio requests require a response that is the TWiML payload. This can be a response to a request for information or just a simple 'OK' I've done it. The example flows use the HTTP input and output nodes to provide the link to Twilio.

My Node-RED flow listens for a /twiliosms url. This must be accessible from outside of your local network. I did this using my DynDNS pro account, which is set to not expire. My router then uses port forwarding to redirect the incoming request to my linux server running Node-RED . The external URL uses different ports to Node-RED and this is all catered for in the port forwarding on the router.

Your Twilio number needs to be have the correct Request URL and method setting up. This flow uses the GET method as this only seems to work for SMS, although voice works with POST. You can also set a fallback URL by selecting the Optional settings. This ideally would be a simple TWiML file located on an externally hosted URL to respond when your Node-RED system fails to respond for any reason.

The flows here demonstrate two uses, one to control a device, in this case my Wemo controlled lights. When it receives a message starting with WEMO followed by a space then either ON or OFF to turn the lights on or off. This also sends back a response to say its been done. The second example is to read a context variable to build up a custom message that is then returned. The example I use is that it returns the current power usage by sending the SMS "READ wholehouse".

The final part of the flows is to convert the created JSON body to the XML based TWiML response. This is done using the handy Json2XML node.

The flows can be further extended to handle specific commands by adding more conditions to the switch node. The main thing to remember is that the flows must return a valid TWiML response in the payload.

To aid in debugging this functionality, use the Twilio dev-tools menu to show any failures.

Your Twilio account has a lot of information that includes the dev tools plus what requests and responses have been processed.

[{"id":"1f11c5bb.e0ee3a","type":"http in","name":"TwilioSMS Web","url":"/twiliosms","method":"get","x":163,"y":395,"z":"22fdfba5.dd0204","wires":[["d552b695.2aad48"]]},{"id":"13f28111.ec0d7f","type":"function","name":"Process SMS","func":"// Process SMS request and create response\n// If SMS starts with READ (match is case insensitive) then use rest to access\n// a global context to read a previously stored value from a sensor\n// If READ not found then just returns what you sent\nvar responseMsg = \"\";\nvar smsMsg = msg.req.query.Body;\nif( smsMsg.substr(0,4).toUpperCase() == \"READ\" ) {\n\tvar name = smsMsg.substr(4).trim();\n\tvar reading =[name];\n\tresponseMsg = name + \": \" + reading;\n} else {\n\tresponseMsg = \"You sent: \" + msg.req.query.Body;\n}\n\n// Create JSON object for payload response\nvar messageObj = { \"Message\": responseMsg } ;\n\n// Need to return received msg object, but with new payload\nmsg.payload = messageObj;\nreturn msg;","outputs":"1","x":496,"y":429,"z":"22fdfba5.dd0204","wires":[["4a4ba74f.b5b458"]]},{"id":"4a4ba74f.b5b458","type":"json2xml","name":"J2XML TwiML Response","root":"Response","x":714,"y":430,"z":"22fdfba5.dd0204","wires":[["4de95001.b216b"]]},{"id":"4de95001.b216b","type":"http response","name":"Send TwiML","x":934,"y":431,"z":"22fdfba5.dd0204","wires":[]},{"id":"d552b695.2aad48","type":"switch","name":"Switch","property":"req.query.Body","rules":[{"t":"cont","v":"WEMO"},{"t":"nnull"}],"outputs":2,"x":319,"y":396,"z":"22fdfba5.dd0204","wires":[["ffd2c458.002d38"],["13f28111.ec0d7f"]]},{"id":"ffd2c458.002d38","type":"function","name":"Process WEMO","func":"// Setup WEMO message based on on/off received for wemo command\nvar smsMsg = msg.req.query.Body;\nif( smsMsg.substr(0,4).toUpperCase() == \"WEMO\" ) {\n\tvar status = smsMsg.substr(4).trim();\n\tif( status.toUpperCase() == \"ON\" )\n\t\tmsg.payload = \"1\";\n\telse\n\t\tmsg.payload = \"0\";\n}\n\nreturn msg;\n","outputs":1,"x":505,"y":360,"z":"22fdfba5.dd0204","wires":[["d1ec2f17.2e13d"]]},{"id":"d1ec2f17.2e13d","type":"wemo out","ipaddr":"","name":"Wemo Switch","x":725,"y":360,"z":"22fdfba5.dd0204","wires":[]}]

Flow Info

created 3 years, 5 months ago

Node Types

  • function (x2)
  • http in (x1)
  • http response (x1)
  • switch (x1)


  • Twilio
  • SMS
  • HTTP
  • Monitor
  • Control
  • TWiML
Copy this flow JSON to your clipboard and then import into Node-RED using the Import From > Clipboard (Ctrl-I) menu option