Using SMS API
There are many uses for SMS in modern websites and mobile apps. For example, you can:
- Send verification codes to new users after sign-up.
- Reminding visitors that their cart hasn’t been checked out.
- Letting existing customers know about upcoming promotions.
These are just some of the ways many businesses use SMS to enhance their product workflow and customer service. But SMS isn’t just for large corporations. When using the right APIs, anyone can use SMS.
In this tutorial, we’ll learn how to use SMS using Twilio SMS API and React, a popular web library.
What is React?
React is a popular JavaScript client-side library, used for rapid development of user interfaces (UIs). Simply put, you give React some data, and a function that tells it how to turn that data into a view, and React does the rest. In other words, React lets your view “react” to changes in your data.
This tutorial will show you how to use React to make an app that lets you send a text message, using Twilio SMS API, to your own mobile phone number. When we’re done, our app will look like this:
In this tutorial, we’re going to use JavaScript, React, React Hooks, and API calls. If you’d like more in-depth information on these topics, check out these excellent free resources:
- For a brief explanation of Endpoints, read What is an API Endpoint?
- New to JavaScript? Check out How To Use an API with JavaScript
- A great refresher on React can be found at How To Use an API with ReactJS
- If you’re new to hooks, read How to Fetch Data from an API with React Hooks
Exploring the Twilio SMS API
Step 1: Find the endpoints
For our SMS API, we’re going to use RapidAPI’s Twilio SMS API, which has all the endpoints we need:
- List available phone numbers
- Buy a phone number
- Send SMS Messages
- Delete the phone number
Step 2: Subscribe to the API for testing
Because this API provides so much convenience, there is a small fee. Before moving forward, make sure to click the “Pricing” tab and read the different pricing levels. The “Basic” level is very affordable, and will work perfectly for our small SMS API experiments.
After subscribing, your “Test Endpoint” button will now work as expected:
Step 3: Find the code snippets
Now we can start copying down our code snippets. Find all the following APIs:
- Fetch an Account Resource: This just returns the Account ID, which is needed for all the other calls. It doesn’t take any parameters.
- Available Local Phone Numbers: Given our account ID and a region, this will give us a list of available phone numbers that we can purchase.
- Buy a Phone Number: After we’ve found one, we can purchase it. This is needed to send SMS messages. This takes the number we want, and the account ID, and returns whether it succeeded.
- Send SMS (Create a Message Resource): This is the API call we ultimately want to make, and all the other ones are leading up to this. It takes the message text, the number to send the message to, the account ID, and the number we want to send from.
- Delete a Phone Number: Since we don’t want to have an extra phone number just lying around, or prevent others from using it, we’ll clean up our work by deleting the number now that we’re done with it.
Once you’ve found them:
- Find the Code Snippets tab on the right
- Choose the JavaScript drop-down
- Select the fetch option
This will give you the code snippets to use.
Note: For this tutorial, we already have the final transformed versions of these fetch calls, which have been transformed using async function syntax. So don’t worry about copying them right now. But it’s good to know how to find code snippets for Endpoints.
Step 4: Save your API key
For the code samples, we’re going to use a variable called “YOUR_RAPID_API_KEY_GOES_HERE”. You might want to save this code snippet now, so you can paste it later into the top of your React file.
const YOUR_RAPID_API_KEY_GOES_HERE = "a6s5dfi8as5df98a5sd8f5a964sf98asd5f08asd75f9a67s4d";
Using Twilio SMS API from JavaScript
Using API calls in React is very similar to using them from JavaScript. There are a few options of how we can call our functions:
- From Virtual DOM element callbacks, such as
onClick
oronSubmit
. - Inside a React Effect Hook, when the component mounts or a prop changes.
- Similarly, using class-based event methods, such as
componentDidMount
.
Step 1: Get Account ID
The first thing we want to do is get the Account ID. This just returns what Twilio’s API calls a “SID”, which is a unique ID representing this account. Our function is simple: make a GET request, get the JSON out of the body, and return the "sid"
property on the object it gives us.
Here’s the code we’re going to use in our React app. Copy and paste it into a temporary file for now, or mark this spot to come back to later.
async function getAccountId() { const response = await fetch("https://twilio-sms.p.rapidapi.com/2010-04-01/Account", { "method": "GET", "headers": { "x-rapidapi-host": "twilio-sms.p.rapidapi.com", "x-rapidapi-key": YOUR_RAPID_API_KEY_GOES_HERE } }); const body = await response.json(); console.log('getAccountId', body); return body.sid; }
Step 2: Get available local numbers
Next, we want to actually fetch a list of available numbers. We also make a GET request, giving it the account ID we got in the last method. We’ve hard-coded the country as “US” for testing, but you can change that to any other country code as needed.
But not all numbers have SMS capabilities, so we filter the list of numbers based on item.capabilities.SMS
.
At the end, we only return the two properties we need:
- number: this comes from
"item.phoneNumber"
but with the first character removed, since it comes in the format of “+15551231234” but we just need “15551231234” for other API calls. - display: we get this from
"item.friendlyName"
, which is in the format “(555) 123-1234”, which looks nicer in the logs that we show.
async function getAvailableNumbers(accountId) { const result = await fetch("https://twilio-sms.p.rapidapi.com/2010-04-01/Accounts/" + accountId + "/AvailablePhoneNumbers/us/Local.json", { "method": "GET", "headers": { "x-rapidapi-host": "twilio-sms.p.rapidapi.com", "x-rapidapi-key": YOUR_RAPID_API_KEY_GOES_HERE } }); const body = await result.json(); console.log('getAvailableNumbers', body); return body .filter(item => item.capabilities.SMS) .map(item => ({ number: item.phoneNumber.slice(1), display: item.friendlyName, })); }
Step 3: Buy phone number
Now that we have a list of available phone numbers, we can purchase one. This API call takes the account ID and the phone number in “15551231234” format, and returns the SID if it’s available.
Here we’re using the newer optional chaining JavaScript syntax in the line "return body.phoneNumber?.sid"
, which returns undefined if the "phoneNumber"
key is absent, otherwise returns the "sid"
key on the "phoneNumber"
object.
Note: This SID is the phone number’s unique ID, which is different from the SID representing the account ID.
async function buyPhoneNumber(accountId, number) { const result = await fetch("https://twilio-sms.p.rapidapi.com/2010-04-01/Accounts/" + accountId + "/IncomingPhoneNumbers.json?phoneNumber=" + number + "&phoneNumberType=local&countryCode=us", { "method": "POST", "headers": { "x-rapidapi-host": "twilio-sms.p.rapidapi.com", "x-rapidapi-key": YOUR_RAPID_API_KEY_GOES_HERE, "content-type": "application/x-www-form-urlencoded" }, }); const body = await result.json(); console.log('buyPhoneNumber', body); return body.phoneNumber?.sid; }
Step 4: Send SMS message
Now that we purchased a phone number, we can send a text message.
When given the “to” and “msg” fields, we sanitize them for the URL as query parameters using encodeURIComponent()
.
When we make this POST call, the response JSON will contain a "status"
key, letting us know whether it was sent or delivered. This will usually be the strings “sent” or “delivered”, or a number such as 400.
async function sendSMS(accountId, phoneId, to, msg) { to = encodeURIComponent(to); msg = encodeURIComponent(msg); const result = await fetch("https://twilio-sms.p.rapidapi.com/2010-04-01/Accounts/" + accountId + "/Messages.json?from=" + phoneId + "&body=" + msg + "&to=" + to, { "method": "POST", "headers": { "x-rapidapi-host": "twilio-sms.p.rapidapi.com", "x-rapidapi-key": YOUR_RAPID_API_KEY_GOES_HERE, "content-type": "application/x-www-form-urlencoded" }, }); const body = await result.json(); console.log('sendSMS', body); return body.status; }
Step 5: Delete phone number
To clean up after our example is done, we need to make a DELETE request for this phone number. All the parameters are provided in the URL, such as account ID and phone number ID (the SID we got when we purchased it). This call typically succeeds.
async function deletePhoneNumber(accountId, phoneNumberId) { const result = await fetch("https://twilio-sms.p.rapidapi.com/2010-04-01/Accounts/" + accountId + "/IncomingPhoneNumbers/" + phoneNumberId + ".json", { "method": "DELETE", "headers": { "x-rapidapi-host": "twilio-sms.p.rapidapi.com", "x-rapidapi-key": YOUR_RAPID_API_KEY_GOES_HERE } }); const body = await result.json(); console.log('deletePhoneNumber', body); }
Example: Send SMS from Twilio API in React
Now that we have a nice collection of async functions for each of our API calls, we can start creating our React app.
Step 1: Create React App
For convenience, we’re going to use the Create React App command line utility. This will get us a working React app with all the boilerplate taken care of for us, with only one command.
- Make sure you have NPM installed. We’ll need a recent version for the next command to work.
- Run
npx create-react-app react-sms-rapidapi --use-npm
- Go into the directory we just created, with
cd react-sms-rapidapi
- Open the directory in your favorite IDE. If you don’t have one, I recommend VS Code.
- Run
npm start
to run the React app. It’ll automatically open in your browser.
Step 2: Replace the App component’s JavaScript
Open the file src/App.jsx
and paste the following code into it:
function App() { const [to, setTo] = React.useState('15551231234'); const [msg, setMsg] = React.useState('Sending SMS from React using Twilio API!'); const [logs, setLogs] = React.useState([]); const addLog = (log) => { setLogs(prevLogs => [...prevLogs, log]); }; const sendMessage = async (e) => { /* ... */ }; return ( <div className="app"> <h2>SMS with Twilio in React</h2> <form onSubmit={sendMessage}> <label>Send To</label> <input value={to} onChange={e => setTo(e.target.value)} /> <label>Message</label> <textarea value={msg} onChange={e => setMsg(e.target.value)}></textarea> <span /> <button>Send SMS</button> </form> <h2>API Logs</h2> <ul> {logs.map((log, i) => ( <li key={i}>{log}</li> ))} </ul> </div> ); }
This is a very simple React app, but it does a few things we need to understand. We:
- Save our “to” and “msg” fields in state using React Hooks.
- Show a React form that contains input fields for “To” and “Message”.
- Connect our input fields to our Hook state using controlled components.
- Save an array of logged messages in React state, which starts empty.
- Show the event logs in an HTML list, mapping them to list items.
- Created a helper function
addLog()
, which just adds a new entry. - Make a
sendMessage()
function, which will call our API.
Step 3: Replace the App component’s CSS
Our form shows, but it doesn’t look that great. With modern CSS, we can make it look very nice, and with only a small amount of code.
So let’s paste the following CSS into the src/App.css
file:
body { background: #f7f7f7; } .app { width: 30em; margin: 2em; display: inline-grid; gap: 1em; padding: 1em; background: #fff; box-shadow: 0px 2px 6px 2px #0002; } .app * { margin: 0; } .app form { display: grid; grid-template-columns: auto 1fr; gap: 1em; align-items: baseline; } .app li:empty { list-style-type: none; height: 1em; } .app :read-write { border: 1px solid #999; border-radius: 3px; font: inherit; padding: 0.5em; outline: none; } .app :read-write:focus { outline: auto #17f; } .app button { background: #17f; color: #fff; font: inherit; border: none; border-radius: 3px; outline: none; padding: 0.5em 1.5em; } .app button:active { background-color: #05b; }
Check your browser. Now our little app should look like this:
Step 4: Make our API calls from React callback
You probably noticed that we left the implementation of sendMessage()
empty earlier. However, this is actually where most of the API call logic comes in.
So let’s replace our old function stub with this function definition:
const sendMessage = async (e) => { e.preventDefault(); addLog(`Getting account ID`); const accountId = await getAccountId(); addLog(`Got account ID: ${accountId}`); addLog(''); addLog(`Finding Phone Numbers`); const numbers = await getAvailableNumbers(accountId); addLog(`Got Phone Numbers`); addLog(''); let phone; for await (const { number, display } of numbers) { addLog(`Trying to purchase ${display}`); const phoneId = await buyPhoneNumber(accountId, number); if (phoneId) { addLog(`Number purchased.`); phone = { id: phoneId, number }; break; } else { addLog(`Number is unavailable, trying another.`); } } addLog(''); addLog(`Sending message`); const status = await sendSMS(accountId, phone.number, to, msg); addLog(`Status: ${status}`); addLog(''); addLog(`Deleting phone number`); await deletePhoneNumber(accountId, phone.id); addLog(`Deleted`); addLog(''); };
This looks like it’s doing a lot, but it’s actually very simple:
- First, we get the account ID by calling
await getAccountId()
. - Then, we get the list of numbers with
await getAvailableNumbers(accountId)
. - Now we can try buying them. Since they might fail, we do this in a loop:
- We call await
await buyPhoneNumber(accountId, number)
with the first number. - If it worked, we save the phone’s SID, and the number in “15551231234” format.
- Otherwise, we try again with each number in the list.
- When we finally succeed in buying one, we exit our async loop.
- We call await
- Now that we bought one, we make a call with
await sendSMS(...)
to try sending it! - Finally, we delete our number with
await deletePhoneNumber(accountId, phone.id)
.
Seem familiar? These are exactly the same steps as the API Endpoints we found earlier. With the exception of our loop, all we’re doing is calling them, one by one, in order, and using the results of each in the calls of the next ones.
Step 5: Try it out!
Here’s a video showing our brand new React SMS API app in action:
It works! Give yourself a nice pat on the back, you just sent an SMS using the Twilio API from React.
Conclusion
With just a few lines of JavaScript code in our React app, we were able to buy a phone number, and send a text to ourselves!
Using SMS can sound difficult, but it’s easy! All you need is the right API.
Curious what else you can do with SMS and React? Check out more SMS APIs at RapidAPI.com.
Leave a Reply