Make a Phone Call With Voice Using Your ESP8266 and Arduino With Twilio’s API

As you probably know Twilio’s API only supports HTTPS (as it should), and the ESP8266 WiFi module doesn’t (even though it claims that it does in its API). To circumvent this “problem” I created a web service called IoT HTTPS Relay, and made the source code available. This web service simply receives your Twilio’s API credentials and makes an HTTPS request to Twilio’s API. I do not claim that this web service keeps your data secure, I simply made it because I wanted to see how far I can take my ESP8266 WiFi module, so use at your own risk.

You can see how the code works in the video below. There is currently a bug that makes the Arduino reset resulting in many calls, so if you find the solution create a pull request in my library

Step 1: Create a Twilio Account

Make a Twilio.com account and save your Account SID and Token as we’ll need it for the script.

Step 2: Send a POST Request to IoT HTTPS Relay

IoT HTTPS Relay is a Google App Engine app I created to use HTTPS APIs since the ESP8266 does not support SSL.

To make a call using IoT HTTPS Relay send the following POST request from your ESP8266:

POST /twilio/Calls.json HTTP/1.1 Host: iot-https-relay.appspot.com Connection: close Content-Type: application/x-www-form-urlencoded Content-Length: xxx token=xxxxxx&From=15558689998&To=19998675584&Body=myURLEncodedMessage&sid=xxxxxx

The token and sid parameters are your Twilio’s Token and Account SID. The From number can only be your Twilio’s given number. The To number can be any number if you are paying for Twilio’s service, or it can be your verified number if you are using the free account. The Body value will be played when the To phone number answers the phone.

Step 3: Install the Adafruit ESP8266 Arduino Library

Head over to GitHub and install my fork of the Adafruit ESP8266 Arduino library in your Arduino’s library folder.

Step 4: Make a Call With Your Arduino

Upload the code below to your Arduino. The phone call will be made during the setup() function execution. Open the serial monitor if you wish to debug the code. Please note that there is currently a bug in the script that causes the Arduino to reset, resulting in very many calls so be VERY CAREFUL if you are using a paid Twilio account.

/* * Visit http://iot-https-relay.appspot.com/ and http://allaboutee.com for more info on this script. * Warning! Please be sure to understand the security issues of using this relay app and use at your own risk * A sketch for sending text messages using IoT HTTPS Relay with Twilios API. Please note that there is a bug * where the Arduino keeps reseting resulting in many many calls. So be careful if you are using a * paid Twilio account. If are able to fix this bug though please create a pull request, thanks! */ /*------------------------------------------------------------------------ Requires SoftwareSerial and an ESP8266 that's been flashed with recent 'AT' firmware operating at 9600 baud. Only tested w/Adafruit-programmed modules: https://www.adafruit.com/product/2282 The ESP8266 is a 3.3V device. Safe operation with 5V devices (most Arduino boards) requires a logic-level shifter for TX and RX signals. ------------------------------------------------------------------------*/ #include <Adafruit_ESP8266.h> #include <SoftwareSerial.h> // Connect ESP TX pin to Arduino pin 3 #define ESP_RX 3 // Connect ESP RX pin to Arduino pin 4 #define ESP_TX 4 #define ESP_RST 8 SoftwareSerial softser(ESP_RX, ESP_TX); // Must declare output stream before Adafruit_ESP8266 constructor; can be // a SoftwareSerial stream, or Serial/Serial1/etc. for UART. Adafruit_ESP8266 wifi(&softser, &Serial, ESP_RST); // Must call begin() on the stream(s) before using Adafruit_ESP8266 object. #define ESP_SSID "xxx" // Your network name here #define ESP_PASS "xxxxxxx" // Your network password here const char PHONE_FROM[] = "xxxxxxxxxxx"; // Your Twilio's phone number, including country code const char PHONE_TO[] = "xxxxxxxxxxx"; // Any phone number including country code, BUT if you only have a free account this can only be your verified number const char TWILIO_ACCOUNT_SID[] = "xxxxxxxxxxxxxxx"; // Your Twilio's ACCOUNT SID const char TWILIO_TOKEN[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // Your Twilios TOKEN const char TEXT_MESSAGE_BODY[] = "Your+house+is+on+fire"; // URL encoded text message. char data[200]; // HTTP POST data string. Increase size as required. #define HOST "iot-https-relay.appspot.com" #define PORT 80 void setup() { char buffer[50]; // This might work with other firmware versions (no guarantees) // by providing a string to ID the tail end of the boot message: // comment/replace this if you are using something other than v 0.9.2.4! wifi.setBootMarker(F("Version:0.9.2.4]\r

\r

ready")); softser.begin(9600); // Soft serial connection to ESP8266 Serial.begin(57600); while(!Serial); // UART serial debug Serial.println(F("Adafruit ESP8266 Phone Call")); // Test if module is ready Serial.print(F("Hard reset...")); if(!wifi.hardReset()) { Serial.println(F("no response from module.")); for(;;); } Serial.println(F("OK.")); Serial.print(F("Soft reset...")); if(!wifi.softReset()) { Serial.println(F("no response from module.")); for(;;); } Serial.println(F("OK.")); Serial.print(F("Checking firmware version...")); wifi.println(F("AT+GMR")); if(wifi.readLine(buffer, sizeof(buffer))) { Serial.println(buffer); wifi.find(); // Discard the 'OK' that follows } else { Serial.println(F("error")); } Serial.print(F("Connecting to WiFi...")); if(wifi.connectToAP(F(ESP_SSID), F(ESP_PASS))) { // IP addr check isn't part of library yet, but // we can manually request and place in a string. Serial.print(F("OK

Checking IP addr...")); wifi.println(F("AT+CIFSR")); if(wifi.readLine(buffer, sizeof(buffer))) { Serial.println(buffer); wifi.find(); // Discard the 'OK' that follows Serial.print(F("Connecting to host...")); Serial.print("Connected.."); wifi.println("AT+CIPMUX=0"); // configure for single connection, //we should only be connected to one SMTP server wifi.find(); wifi.closeTCP(); // close any open TCP connections wifi.find(); if(wifi.connectTCP(F(HOST), PORT)) { Serial.print(F("OK

Requesting page...")); strcat(data,"From="); strcat(data,PHONE_FROM); strcat(data,"&"); strcat(data,"To="); strcat(data,PHONE_TO); strcat(data,"&"); strcat(data,"sid="); strcat(data,TWILIO_ACCOUNT_SID); strcat(data,"&"); strcat(data,"token="); strcat(data,TWILIO_TOKEN); strcat(data,"&"); strcat(data,"Body="); strcat(data,TEXT_MESSAGE_BODY); wifi.httpPost("iot-https-relay.appspot.com","/twilio/Calls.json",data); wifi.closeTCP(); while(1); } else { // TCP connect failed Serial.println(F("D'oh!")); } } else { // IP addr check failed Serial.println(F("error")); } } else { // WiFi connection failed Serial.println(F("FAIL")); } } void loop() { }

Send a Text Message

In line 26 simply change “Calls.json” to “Messages.json”.