Send SMS and MMS Messages From the ESP8266 in C++
Today we'll coax an ESP8266 to send MMS and SMS messages using C++ and the Arduino IDE. You'll need an ESP-8266 set up for the Arduino IDE, a serial connection (most likely with a serial to USB adapter or module on-board) and a friendly open, WEP or WPA (1 or 2) wireless network.
Read on, we're going to merge the Internet of Things with the Twilio API!
Sign Into - or Sign Up For - a Twilio Account
Either create a new Twilio account (sign up for a free Twilio trial here), or sign into your existing Twilio account.
Find or Purchase a SMS (and MMS) Capable Number
For this demo, you'll either need to use an SMS and MMS enabled number you own, or purchase a new one with the necessary capabilities.
First, enter the Twilio Console. Second, select the hash tag/Phone Numbers ('#') section on the left side, and navigate to your current active numbers.
Under 'Capabilities', you will see the functions you'll be able to use with your Twilio phone numbers. For this article, you'll need numbers with either SMS or both SMS and MMS capabilities.
If you don't currently have a number with SMS or MMS, you'll need to purchase one. After navigating to the 'Buy a Number' link, click the SMS - and optionally the MMS - checkbox.
Prerequisites for This ESP8266 MMS and SMS in C++ Guide
Espressif's ESP8266, sometimes found on boards costing as little as $2, is an amazing base for your IoT project. As it boasts TLS 1.2 support, we're excited to share an example of sending messages using the ESP8266 and the Twilio API.
Hardware development introduces many more variables than software development. We'll do our best to help guide you during the setup stage. While we unfortunately can't test every setup, please comment if you run into issues. We - and perhaps other readers - will do our best to help break through any roadblocks.
While it would be impossible to enumerate every ESP8266 board variation that would work with this guide, the repository for Arduino on ESP8266 has a nice list of tested boards. We'd suggest that you select one of those if you haven't yet picked a dev board. The ESP-8266 12-E variants such as this one work well.
When wwe first built this, we used a Sparkfun Thing and Sparkfun's Basic FTDI breakout for programming. The Thing overloads the DTR pin and won't work when programming and connected to the serial monitor. For most boards you don't need to touch the serial
#define s in the code.
But if you do: you can disable or enable software serial by changing the
USE_SOFTWARE_SERIAL in Twilio_ESP8266_Example.ino.
Using the Arduino IDE with the ESP8266 helps us eliminate some of the variables inherent in this type of project. The ESP-8266 Arduino tie-in includes the Xtensa gcc toolchain, provides the Arduino libraries, and makes it easy to program the ESP-8266.
If you choose to rewrite the code to forego the assumed Arduino environment (perhaps for Espressif's SDK), the most important steps will be to eliminate dependencies on Arduino Strings and making sure you connect to
api.twilio.com:443 using TLS 1.2. This is beyond the scope of this guide, but please share any success you have in the comments.
Building the ESP8266 MMS and SMS Example
(Note that this project has been extended in the receiving and replying to messages from the ESP8266 guide, here)
After cloning this project from our GitHub repository, you'll have to gather some credentials before you send your first message. At the top of Twilio_ESP8266_Example.ino we set up a number of globals for connecting to your WiFi network, verifying the SHA1 signature of api.twilio.com (we will be watching for CA verification on the ESP8266), and sending messages with your Twilio account.
Note that embedding your credentials on a hardware device is only acceptable for prototyping and when you will always retain physical possession of your device. If your device will be in the field, you must use revocable keys or other reversible authentication.
Here is the section you will need to edit:
After that, building the example should be as simple as hitting the 'Upload' button in the Arduino IDE.
If all goes well, you should get a text message with the content of the message_body variable. If all goes poorly, we've included sample code to debug with
SoftwareSerial; depending on your board and setup you will likely need to change it or use the defult
Serial library. Here are the first steps of an example (successful) debugging session with
Connected to WiFi, IP address: 192.168.1.155 Connecting to host api.twilio.com Certificate fingerprints match. Sending http POST: POST /2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXX/Messages HTTP/1.1 Authorization: Basic BASE64ENCODEDSTRINGHERE Host: api.twilio.com Cache-control: no-cache User-Agent: ESP8266 Twilio Example Content-Type: application/x-www-form-urlencoded Content-Length: 72 Connection: close To=+18005551212&From=+18005551212&Body=Hello+from+Twilio+and+the+ESP8266
If you are careful, the most common reason the message will fail is because the certificate is updated. This next section explains how to update the fingerprint.
Dealing with message failure
api.twilio.com refreshes its certificate – which means you have a new fingerprint to update. You can find the new fingerprint in a few ways, but two quick ones are using a browser or using
openssl in the command line of a *NIX system.
Find the api.twilio.com fingerprint from a web browser
To find the fingerprint from a web browser, from your computer or laptop visit api.twilio.com. Inspect the certificate for *.twilio.com, and scroll down to SHA-1 fingerprint.
Here is how it looks in Chrome (screenshot in July 2020):
Copy the hex characters and add them in the
const char fingerprint = line in the
Find the api.twilio.com fingerprint from the command line
Alternatively, if you have openssl on your system you can get the fingerprint without opening a browser. Run the following line on the command line:
openssl s_client -connect api.twilio.com:443 < /dev/null 2>/dev/null | openssl x509 -fingerprint -noout -in /dev/stdin | sed -En "s/SHA1 Fingerprint=//p" | sed "s/:/ /g"
The result you get will look like this:
BC B0 1A 32 80 5D E6 E4 A2 29 66 2B 08 C8 E0 4C 45 29 3F D0
Copy the hex characters and add them in the
const char fingerprint = line in the
Sending a Message with the ESP8266
Since we'll be hitting the Twilio REST API directly, this code has some superficial similarities to our SMS in C and C++ examples. Of course, without a library like libcurl abstracting away the finer details, we have to write some lower level code. You'll note that we've included code to connect to a WiFi network and verify the SHA1 signature of api.twilio.com.
Most starkly, however, we're crafting a HTTP POST manually:
We also need to do a number of other things not required (or abstracted away) on the desktop. You'll note that we've included code to base64 encode your
AUTH_TOKEN for HTTP Basic Authentication. Additionally, we've included Steve Nelson's URL encoding and decoding functions to escape special characters in the SMS or MMS body. Ensure that your eventual application has similar functions, and your own IoT Thing will work right the first time.
From the Internet of Things to the Pockets of Everyone with Twilio
The ESP8266 is a great chip which can act as the brain of your next IoT project, even without much external silicon. If you'd like to add telephone connectivity to your next project but a *NIX single board computer is too heavy, it's nice to know you've got alternatives.
For whatever you're building next - a monitoring tool, a must-buy wearable, a home automation product - add phone interoperability on the cheap (and with reasonable security) with ESP8266 and the Twilio API.
Need some help?
We all do sometimes; code is hard. Get help now from our support team, or lean on the wisdom of the crowd by visiting Twilio's Stack Overflow Collective or browsing the Twilio tag on Stack Overflow.