Programmable SMS
Learn how to use Twilio's Programmable Messaging to send outbound SMS messages and respond to incoming messages.
Twilio provides various endpoints that allow us to build applications that send and receive text messages from a user. Let’s look at some of these endpoints in this lesson.
Send an SMS
Twilio allows us to send SMS messages to a specified phone number using the message endpoint. The base URL for this endpoint is as follows:
https://api.twilio.com/2010-04-01/Accounts/{{ACCOUNT_SID}}/Messages.json
Request parameters
We need to provide some mandatory and optional parameters to send an outbound SMS. The following table gives details about these parameters:
Name | Type | Category | Description |
| String | Mandatory | The Twilio phone number used to send the message. |
| String | Mandatory | The message we want to send. |
| String | Mandatory | The phone number we want to send the message to in the form “%2B [country code] [phone number].” Here, “%2B” is the code for the plus (+) sign. |
| String | Optional | The URL on which we want to `POST` the status of the message. |
| String | Optional | The ID of the application to which we want to `POST` the status of the message. |
| Float | Optional | The maximum price in US dollars we will pay for the message to be delivered. |
| Boolean | Optional | If set to |
| Integer | Optional | The total number of attempts made to send the message. |
| Integer | Optional | The total number of seconds the message can stay in the outgoing queue. After this time has expired, the message is discarded. Minimum value is |
| Enum | Optional | Indicates if we want to deliver the message at a specific time. Accepted input is |
| String | Optional | The date and time at which the message will be delivered. Given input should be in ISO 8601 format (YYYY-MM-DD HH:MM:SS). |
Note: If the phone number given in the
To
field is different than the number we used while creating the Twilio account, we need to verify that number. We can visit the Verified Caller IDs page to add our desired number to the verified caller IDs.
Click the "Run" button in the following widget to receive an SMS message on our phone number from our Twilio number.
import fetch from "node-fetch";//Define the header parametersconst header = {'Authorization': 'Basic ' + Buffer.from('{{ACCOUNT_SID}}'+':'+'{{AUTH_TOKEN}}').toString('base64'),'Content-Type': 'application/x-www-form-urlencoded',};//Define the endpoint URLconst url = new URL('https://api.twilio.com/2010-04-01/Accounts/{{ACCOUNT_SID}}/Messages.json');//Define the body parameterconst body = 'Body=Hi there&From={{TWILIO_PHONE_NUMBER}}&To={{YOUR_PHONE_NUMBER}}';//Setting API call optionsconst options = {method: 'POST',headers: header,body: body};async function SMSEndpoint() {try {const response = await fetch(url, options);// Custom function for printing the API responseprintResponse(response);} catch (error) {console.log(`Error: ${err}`);}}SMSEndpoint();
In the code above:
Line 1: We import the required library.
Lines 4–7: We define the header parameter, which includes the access tokens.
Line 10: We define the endpoint URL and provide the
ACCOUNT_SID
.Line 13: We define the body parameters and set the message body, source phone number, and destination phone number.
Lines 16–20: We define the options parameters and set the request type as
POST
.Lines 22–30: We define the function
SMSEndpoint
, which calls the endpoint.Line 32: We call the
SMSEndpoint
function.
Note: If we receive the error, “Unable to create record: Permission to send an SMS has not been enabled for the region indicated by the ‘To’ number,” we can visit Messaging Geographic Permissions to enable permission for that region.
Response fields
The following table provides attribute details given in the response object.
Name | Type | Description |
| String | The message sent. |
| String | The number of segments the message is divided into if the message body is too large to fit into one message. |
| Enum | The direction of the message. Possible output is |
| String | The phone number from which the message was sent. |
| String | The last date the message was updated. |
| String | The amount charged for sending the message. |
| String | The description of the error code, in case the message is not sent. |
| String | The URI of the message, relative to Twilio. |
| String | The SID of the account that sent the message. |
| String | The number of media files attached to the message. Maximum number of files we can attach is 10. |
| String | The phone number we sent the message to. |
| String | The date on which the message was created. |
| Enum | The status of the outbound message. |
| String | The ID associated with the message. |
| String | The date the message was received by the phone number defined in the |
| String | The SID of the service used. Null in case no service is used. |
| Integer | The error code in case the message is not delivered. |
| String | The currency in which the |
| String | The version of the Twilio API used. |
https://demo.twilio.com/welcome/sms/reply/
This URL points to some TwiML (Twilio Markup Language), which tells Twilio what to do next when it receives an incoming SMS message.
We’ll use the following Express application to provide instructions on how to respond to incoming SMS messages. To do this, we need to configure the webhook URL.
Configure the webhook URL
For Twilio to know where to look whenever it receives an SMS message, we need to configure our Twilio phone number to call our webhook URL. We’ll follow the below steps to configure the webhook URL:
Go to the Active Numbers page in our Twilio account dashboard.
Select the Twilio number to send an SMS to.
Scroll down to the “Messaging” section. In the “A MESSAGE COMES IN” section, select “Webhook” and paste in the URL we want to use. For now, we can put the URL that’s found against the “Your app can be found at:” field in the widget at the end of this lesson. We have given this URL separately below:
{{EDUCATIVE_LIVE_VM_URL}}
Click the “Save” button to update the webhook URL.
Now, we’ll test our implementation. Follow the steps below to see how Twilio responds to incoming SMS messages:
Click the “Run” button in the following widget to start the server.
When we see an output similar to
'Express server listening on port 3000'
in the terminal, it means that the server has started.Send an SMS from our phone number to the Twilio phone number.
After a while, we’ll receive a reply from our Twilio number containing the text we set up in the following widget in line 9.
const express = require('express'); const { MessagingResponse } = require('twilio').twiml; const app = express(); app.post('/', (req, res) => { const twiml = new MessagingResponse(); twiml.message('Message Received'); res.type('text/xml').send(twiml.toString()); }); app.listen(3000, () => { console.log('Express server listening on port 3000'); });
Custom responses
We discussed how to send replies to incoming SMS messages in the previous section. However, the Twilio number sends the same reply to all incoming messages. We can build custom responses using our application so that the Twilio phone number sends custom responses depending on the text of the incoming message.
We’ve built the custom responses in lines 12–20 in the following widget. Run the application and send 'Hello'
, 'Bye'
, or any other custom message we built. We should receive the corresponding custom response from our Twilio number.
const express = require('express'); const bodyParser = require('body-parser'); const { MessagingResponse } = require('twilio').twiml; const app = express(); app.use(bodyParser.urlencoded({ extended: false })); app.post('/', (req, res) => { const twiml = new MessagingResponse(); if (req.body.Body == 'Hello') { twiml.message('Hi!'); } else if (req.body.Body == 'Bye') { twiml.message('Goodbye'); } else { twiml.message( 'No Body param match, Twilio sends this in the request to your server.' ); } res.type('text/xml').send(twiml.toString()); }); app.listen(3000, () => { console.log('Express server listening on port 3000'); });