This tutorial is out of date and no longer maintained.
Short Message Service (SMS) is not a new technology, and has been around since even before World Wide Web was born. Now with APIs, you can easily integrate SMS with web technologies. With the SMS-enabled web, you can build a variety of products and services such as user authentication, alerts, notifications, general communication tools, and bots.
In this tutorial, I will walk you through how to build a simple web app that sends SMS messages using Node.js, Express, and Nexmo SMS API.
Additionally, to make the web app feel more interactive, let’s also implement W3C Web Notifications API for the front-end UI to display the SMS delivery confirmation message with using Socket.IO!
You can view the source code on GitHub and run the demo locally to see it in action!
You need to have Node.js installed on your machine to get started!
First, create your app directory then set up your app. On terminal:
Then follow the command line instruction to create a package.json
file, which defines your app.
Now you need to install the modules the app will depend upon. To build a core app, use npm to install nexmo-node, Express.js, body-parser, and ejs. For the additional feature, get Socket.IO too.
Create some directories for the files you are going to add. This is all up to you, but here is the example I am using in this tutorial:
├── public
│ ├── css
│ │ └── style.css
│ ├── images
│ │ └── icon-nexmo.png
│ └── js
│ └── app.js
├── server
│ └── index.js
└── views
│ └── index.html
└── package.json
Now, let’s set up an HTML web page that serves out a form with a phone number field and a message field using Express, which is a robust web application framework for Node.js.
Create an index.js
file:
Also, use body-parser (the middleware to parse form input onto a body
property of the request) and ejs (HTML templating tool) to configure the Express app:
Serving HTML:
Now create an index.html
under /views
to build the user interface. Make sure you include a JavaScript file, js/app.js
in <script>
.
In the HTML file, create a few form input fields with a button:
Notice the type attributes in each <input>
element- For phone number, use type="tel"
, and for the message text, use the regular type="text"
. By setting the proper input type, browsers on touch devices automatically pop up the proper type of keyboard for an improved user experience. For instance, when the browser sees type="tel"
, it serves as a number pad.
The entire HTML looks like this:
To see the entire markup and CSS, please refer to the source code on GitHub.
Create app.js
in /public/js
.
First, get the DOM object for each form input elements:
Note: Notice that I am using ES6 for Node.js while using ES5 for the front-end code, because not every ES6/ES2015 feature has been supported by modern browsers yet. If you would like to use ES6 all the way, I recommend Babel. However, I am not covering it in this article.
Then, listen to the events. Let’s make the form submittable by either hitting a Return key or pressing the button:
Now, let’s define the send
function to submit the input values to the Node code. First, grab the values from the inputs.
Next, post the values to the server using the Fetch API.
For the last decade or so, we have been using XMLHttpRequest for AJAX requests But now is the time to say good-bye to the good old XHR, and say hello to this shiny new Fetch API to make requests to your server!
Now, POST
the phone number and the message text as JSON using the Fetch API:
As of 2016, if you want to support Safari version 10 or older, you still need to use XHR as the fallback for now.
Now going back to the server-side index.js
, and add these lines of code to take the form input values from the request:
Let’s run this code once and see if this works fine.
Then, go to http://localhost:4000
in your browser. Try sending something.
Once the form is posted successfully, you should see the console.log
value like this on the terminal:
Next, let’s use Nexmo SMS API to actually send messages to the phone number!
The Nexmo SMS API allows you to send and receive a high volume of SMS anywhere in the world. Once you get your virtual phone number, you can use the API to manage outbound messages (“sending”) and inbound messages (“receiving”). In this app, the API will be used for outbound messages.
To get started with SMS, sign up for a Nexmo account to get your virtual number, as well as your API credentials. Once you signed up, go to your Dashboard to get your Nexmo virtual number on Numbers, and API key and secret on Settings section.
You should have nexmo-node
installed for your web app at the very beginning of this tutorial, but if not, install with npm.
In your index.js
, initialize with your credentials:
Then, in your POST
method route that you have defined earlier, grab a phone number and a message from the web form, and send an SMS to the number from your Nexmo virtual number (NUMBER
):
Now, try sending an SMS to a real phone number (or your Google Voice number) using your app! If everything works, you should receive SMS messages! Try emoji too. When you specify the SMS message type
to "unicode"
you are able to send and receive Unicode including emojis!
You can stop this tutorial right here, or proceed to add extra features!
The Nexmo SMS API returns a payload that indicates if the result of the request. Now, let’s add more features to display the sent status UI.
Note: This status indicates that the SMS is successfully sent by you via Nexmo, and not an actual delivery receipt from the recipient’s carrier. To access the actual delivery receipt, read the tutorial on Nexmo.com.
What you are going to do is:
To display the SMS confirmation sent from the server on the browser, you are going to use Socket.IO so that the server can talk to browsers. You need to use both server API and client API to be able to communicate in real-time.
You should have installed Socket.IO at the beginning of the tutorial so let’s go ahead and initialize a Socket.IO instance in index.js
:
Socket.IO lets you emit and receive any events you want. Let’s emit an event in the sendSms
callback, where you see the comment that says, // Optional
using emit(eventName, eventData)
:
In the code sample above, you are emitting the message-id
, an ID of the submitted SMS message, and the phone number your request was sent to. These data come from the Nexmo SMS API response, and the response also gives you more information on the status of the request and the costs of the SMS.
Now, you need to make browsers receive the event from the server. First, include the socket.io.js
in index.html
:
Then in the client, app.js, receive the smsStatus
event:
Next, write the displayStatus
function that displays the SMS callback data. You can just print it out as a simple HTML text in the browser, however, let’s display it as a desktop notification.
The W3C Web Notifications API allows web browsers to display notifications, even when the browser window is in the background. Since this feature is supported (or not) by browser vendors, each browser has a slightly different UI.
Each browser provides a built-in permission UI for the API so that the user can control which web pages can send them notifications. When the page is loaded for the first time, a browser asks a user for their permission. Your page can send notifications only after the user has granted permission.
To request permission, add these lines in your app.js,
Then create a displayStatus
function that passes the data received via Socket.IO. In the function, instantiate a new notification object with the contents including an icon:
The source code on GitHub includes the fallback, in case a user denied the permission.
Awesome! Now you have finished building a web app that allows you to send SMS messages, get the result callback from the server, and display it as a native web notification!
Also read more open-web articles at my personal site, Girliemac.com
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!