Tweeting via SMS using Bandwidth’s V2 Messaging API, NodeJS, the Twitter API, and secure callbacks

Bandwidth’s APIs are designed to integrate easily with other tools and APIs. Through the use of callbacks, call and text message information can be transferred from Bandwidth’s API to your server, and your server can use this information to interact with other APIs. Below is an example of combining Bandwidth’s Messaging V2 API with Twitter’s API in order to allow a user to tweet using only SMS.
Integrating an application with SMS as in this example is a fantastic way to provide content and utility to users without their having to download an app or access a website. Sending a text to interact with a service is fast, almost universally accessible in the United States, and doesn’t involve any downloads or mobile data usage. Ease of use and convenience are optimized.
Also discussed are secure callbacks, which allow you to use a username and password to ensure that only properly credentialled callbacks from Bandwidth reach your server.
This guide assumes you already have an account with Bandwidth configured to use V2 messaging. More information on Bandwidth’s V2 messaging can be found here.
The basic structure of this project is that we are going to set up a POST route on a server that receives callbacks from Bandwidth when an SMS message comes in. The server then takes the data from this callbacks and forward it to Twitter to create a tweet.
This project was designed to process only the text content of an SMS message. If you try to send MMS, the text content will go through, but this project is currently not designed to send any MMS media to Twitter.
Let’s dive in!
npm Packages
Once you initiate your package.json, you will need the following packages:
- encodeurl
- express
- express-basic-auth
- node-bandwidth
- request
Setting Up server.js with Basic Auth
Your server.js should look similar to the following:
//requirements
const express = require("express");
const bodyParser = require("body-parser");
const basicAuth = require("express-basic-auth");
//initialize app
const app = express();
const port = process.env.PORT || 3000;
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
//basic auth will go here in the next step
require("./routes/routes.js")(app);
//listen
app.listen(port, function() {
console.log("App listening on PORT " + port);
});
Setting Up Basic Auth for Secure Callbacks
The code to establish Basic Auth on your server using express-basic-auth looks like this:
app.use(basicAuth({
//here we set the credentials
users: { "{{USERNAME": "PASSWORD"},
//below is what the server does if the request does not have proper credentials, in this case we want to return the string "unauthorized". The express-basic-auth package takes care of sending the 401 HTTP error.
unauthorizedResponse: function doUnauthorizedResponse(req) {
return "unauthorized";
}
}));
To set up your V2 Application send callbacks with these Basic Auth credentials, refer to the diagram below showing what to do on the Application page:

Now your Application is set up to send callbacks accompanied by Basic Auth credentials. Any requests sent to your callback URL without these credentials will be met with a 401 Unauthorized response,
Skeleton of routes.js
Create a new folder called routes and in there, create routes.js (or whatever other file structure you want to use). The basic skeleton of routes.js will look like this:
//requirements
const bandwidth = require("node-bandwidth");
const request = require("request");
//initialize Bandiwdth client
const client = new bandwidth({
userId : "{{USER_ID}}",
apiToken : "{{TOKEN}}",
apiSecret : "{{SECRET}}"
});
module.exports = app => {
//this is where we will put our route for handling incoming messages
}
Creating a POST Route for Processing Callbacks
Here is a walkthrough of the POST route for V2 callbacks:
//create the POST route at whatever endpoint you choose
app.post("/{{CALLBACK_ENDPOINT}}", function(req, res) {
//create an if statement for messages from your phone number
if (req.body[0].message.from == "{{YOUR_NUMBER}}") {
//here we are creating a request to the Twitter API
request({
uri: "https://api.twitter.com/1.1/statuses/update.json",
headers: {
"authorization": //here put the oauth string needed for the Twitter API
},
method: "POST",
form: { status: req.body.text } //here we send the text content of the SMS to Twitter
}, function(error, response, body) {
//if the response from Twitter is a 200, then send a confirmation text
if (response.statusCode == 200) {
client.Message.send({
from: req.body.to,
to: req.body.from,
text: "Your tweet was tweeted, yay!"
});
//if response code isn’t 200, send an SMS response with the error details
} else {
client.Message.send({
from: req.body.to,
to: req.body.from,
text: "Error " + JSON.parse(response.body).errors[0].code + ": " + JSON.parse(response.body).errors[0].message
});
}
res.end();
});
//if the "from" number isn’t your number, nothing happens
} else {
res.end();
}
});
Conclusion
Once this server is live and you point your Application to the appropriate callback URL, you can tweet via SMS. With secure callbacks, only requests to your callback server with the Basic Auth credentials you specific on your Application page are able to get through, and the POST route for tweeting only forwards the message content to the Twitter API if the “from” number on the SMS is a number you specify.
This sample code is meant to demonstrate how Bandwidth’s V2 Messaging API can be integrated with other APIs. Please assess your own security and privacy needs before implementing a solution such as this that directly interacts with social media.