Redact or Delete SMS Messages as They Arrive with Node.js

January 04, 2017
Written by
Phil Nash
Twilion

Keeping tabs on who has access to data in your application is hard when they exist in multiple places, like SMS messages in your app and within Twilio. Here’s how to redact or delete messages as soon you receive them with Node.js.

What you’ll need

To build this application to redact or delete SMS messages, you’ll need:

Got all that ready? Let’s see how to delete some messages.

Building a webhook endpoint

In order to delete or redact our messages as they arrive we need to get notified by Twilio that we have received a message. To receive these notifications we use a webhook. When our Twilio number receives a message Twilio will make an HTTP request to a URL we supply with all the details about the message.

On the command line, create a new folder for our application, change into that folder and initialise a new Node.js application.

$ mkdir self-destructing-messages
$ cd self-destructing-messages
$ npm init -y

We need to install a few libraries to get our application started.

$ npm install express body-parser twilio —save

Now create a file called index.js and open it in your favourite editor. Enter the following application boilerplate:

// index.js
const express = require('express');
const bodyParser = require('body-parser');

const app = new express();

app.use(bodyParser.urlencoded({ extended: false }));

// app goes here

app.listen(3000, () => {
  console.log('Your application has started on http://localhost:3000')
});

We need an endpoint that can receive POST requests from Twilio whenever our Twilio number receives a message. We’ll start simple and create one that logs out the incoming message. The message body is sent as the Body parameter in Twilio’s request to the application. Add a route for a POST request to /messages with the following code to log the message.

// index.js

app.use(bodyParser.urlencoded({ extended: false }));

app.post('/messages', (request, response) => {
  console.log(request.body.Body);
  response.send('<Response/>');
});

Start up the server:

$ node index.js

In another terminal get ngrok started as well:

$ ngrok http 3000

Copy your ngrok URL and open the Twilio console to edit your phone number. Enter the ngrok URL with a path to /messages in the Messaging config.

When editing the phone number in the Twilio console, find the messaging section and enter your ngrok URL into the field with the label 'A message comes in'

Now send your number a message and watch as the message is logged to the console! I sent myself a message that I knew wouldn’t be deleted.

The terminal shows the application starts and then prints out the message 'Hello, this message won't be deleted.'

And there’s the message in the Twilio console log.

In the Twilio log you can also see the message 'Hello, this message won't be deleted.'

Let’s get down to redacting that message body or deleting the message entirely.

Setting up the Twilio REST Client

To redact the text in a message or delete it completely we’re going to use the Twilio Node.js helper library to access the REST API. The library will need to use your Account SID and Auth Token so set them as the environment variables TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN. If you’re not sure how to set environment variables, take a look at this setup guide.

Now we need to require the Twilio module and set up a REST client to use to access the API.

// index.js
const express = require('express');
const bodyParser = require('body-parser');
const twilio = require('twilio');

const client = twilio(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);
const app = new express();

Redacting message bodies

To delete the text from a message we need to update the message resource by POSTing to it with a blank body. In your /messages route add the following code:

// index.js
app.post('/messages', (request, response) => {
  console.log(request.body.Body);
  client.messages(request.body.MessageSid).post({ body: '' })
    .then((message) => response.send('<Response/>'))
    .catch((err) => {
      console.error(err);
      response.send('<Response/>');
    });
});

Restart your server and send another message. You’ll see the body logged in the terminal, but when we inspect the Twilio console the message body will be gone.

This time in the Twilio log the message body appears empty, it has been redacted.

Deleting messages

We’ve managed to redact the body of the message, but what if we want to delete the message completely? We can perform a DELETE through the REST API. There is a slight problem here though. When the message arrives at our webhook, it may not have been marked as “received” within Twilio. We can’t delete the message until it is “received” so we keep checking the message until its status changes to “received”. Then we can delete it.

We first add a function to index.js which checks the message and its status and if it is “received” then deletes it, otherwise the application waits for 1 second and tries again.

// index.js
function tryDelete(messageSid) {
  client.messages(messageSid).get()
    .then((message) => {
      if (message.status === "received") {
        client.messages(messageSid).delete()
          .then(() => console.log("Message deleted"))
          .catch((err) => console.error(err));
      } else {
        setTimeout(() => tryDelete(messageSid), 1000);
      }
    })
    .catch((err) => console.error(err));
}

We don’t want the web request to be waiting around for the message to get deleted, so we return some empty TwiML first, then call on our tryDelete function.

// index.js
app.post('/messages', (request, response) => {
  console.log(request.body.Body);
  response.send('<Response/>')
  tryDelete(request.body.MessageSid);
});

Restart your server again and send in a message. It will get printed to the console, then you will see “Message deleted” printed and when you check the Twilio console it will be gone.

In the terminal the message is logged, shortly after the log 'Message deleted' is seen too. <title>An icon of a outbound link arrow</title> <path class="icon-stroke" d="M75.3037 3.98207L3 75.5935M75.3037 3.98207L76.0435 43.3021M75.3037 3.98207L35.951 3.59351" stroke="#F22F46" stroke-width="5.5" stroke-linecap="round" stroke-linejoin="round"/> </svg> "> Message privacy restored

So that’s all you need to do to redact or delete your received messages in Twilio using Node.js. I recommend that rather than just logging the received message, you store it in your own database so that you can control who can and can’t read it.

If you’ve got excited about deleting things from Twilio, there’s more!

  • If you also receive media messages, then watch out, you need to delete the media separate from the message text
  • If you have call logs, recordings or transcriptions you want to delete you can do that too

Do you use other techniques to keep your messages under the sole control of your system? Let me know in the comments or drop me an email at philnash@twilio.com.