Track WhatsApp Message Status In Node.js and Twilio API for WhatsApp

January 31, 2020
Written by
Felistas Ngumi
Contributor
Opinions expressed by Twilio contributors are their own

Track WhatsApp Message Status In Node Js and Twilio API for WhatsApp.png

Over time, digital media outreach mediums have expanded from email and SMS to social media. It is estimated that the average user spends at least 2 hours and 22 minutes on social media and messaging platforms per day. In a world where almost everyone is connected, companies have jumped on this opportunity and used it to promote and campaign for their products and services. But what’s the point of sending promotional content if there is no way to track it? The Twilio API for WhatsApp recently added the read receipts feature where one can effectively measure if the recipient consumes the content sent to them. In this tutorial, I’m going to take you through on how you can obtain the status of a WhatsApp message sent via the Twilio API for WhatsApp.    

Prerequisites

To complete this tutorial you will need the following:

  1. Node.js Version 8 or above
  2. Twilio Account
  3. Mongo DB
  4. Ngrok

Getting Started

I have created an express app that follows the MVC pattern with only one route for sending WhatsApp messages. We will add its controllers as we progress in the tutorial. Follow the instructions below in your preferred terminal in order to set up your development environment:

mkdir demo && cd demo
git clone https://github.com/Felistas/whatsapp-status
cd whatsapp-status 
npm install
touch .env

Activating Twilio Sandbox for WhatsApp

After creating a free account and project on Twilio, head over to the “All Products & Services” tab on the console and select the “Programmable SMS” option. In the resulting dashboard, select “WhatsApp Beta” and follow the instructions to activate your sandbox. In my case, I’m supposed to send the code join smooth-took to +1 415 523 8886.

WhatsApp Sandbox in the Twilio console

After a  successful sandbox activation, you should receive a similar image as shown below:

WhatsApp conversation screen

In your favorite code editor, add the following lines of code in the app/message.controller.js file.

const axios = require("axios");
const dotenv = require("dotenv");

const Message = require("./message.model");
dotenv.config();

const authToken = process.env.ACCOUNT_TOKEN;
const authSID = process.env.ACCOUNT_SID;
const url = process.env.TWILIO_URL;

const messageBody = {
 Body: "50% off on burgers 🍔 for you today",
 From: "whatsapp:+14155238886",
 PersistentAction: "geo:-1.232453, 36.878987", 
 To: "whatsapp:+254712345678"

};

const messageController = (req, res) => {
 axios
   .post(url, new URLSearchParams(messageBody), {
     auth: {
       username: authSID,
       password: authToken
     }
   })
   .then(response => {
     const messageResponse = {
       msid: response.data.sid,
       mobileNo: response.data.to,
       whatsAppBody: response.data.body,
       whatsAppStatus: response.data.status
     };
     new Message(messageResponse).save();
     res.status(200).send("Message sent successfully");
   })
   .catch(error => {
     res
       .status(400)
       .send("Oops!, an error occurred while sending the request");
   });
};

const messageStatus = async (req, res) => {
 const message = await Message.find({ msid: req.body.MessageSid });
 if (!message) {
   res.send("Invalid message ID!");
 } else {
   await Message.findOneAndUpdate(
     {
       msid: req.body.MessageSid
     },
     { whatsAppStatus: req.body.MessageStatus }
   );
 }
};

module.exports = {
 messageController: messageController,
 messageStatus: messageStatus
};

NOTE: Be sure to replace the To key in the messageBody object with your own number.

The above code constructs a WhatsApp message body and uses Axios, a promise-based HTTP based client for the browser and client to send the message to the specified phone number. For record-keeping purposes, we are storing the WhatsApp status, message SID, mobile number, and WhatsApp body in our database.

In the .env file, add the following:

ACCOUNT_SID= your_twilio_SID
ACCOUNT_TOKEN= your_twilio_token
TWILIO_URL=https://api.twilio.com/2010-04-01/Accounts/your_account_SID/Messages.json

NOTE: Obtain the Twilio SID and auth token from your dashboard.

Next, paste the following lines of code in app/message.router.js.

const express = require("express");
const messageControllers = require("./message.controller");

const messageRouter = express.Router();

messageRouter.post("/whatsapp", (req, res) => {
 messageControllers.messageController(req, res);
});

messageRouter.post("/results", (req, res) => {
 messageControllers.messageStatus(req, res);
});

module.exports = messageRouter;

Testing

In a new terminal session run mongod and at the root of our project then run node index.js to start our application. Expect to see a similar screen as the output of your last command.

Node.js running

Next, we need to set up our webhook in the Twilio for WhatsApp dashboard in order to receive the various WhatsApp statuses. After downloading and configuring ngrok, run ./ngrok http 3000 to expose our localhost to the internet.

ngrok session

Copy the secure URL and append /results. Then paste in the WhatsApp sandbox configuration as shown below. The resulting URL as per my screen is: https://1993fac3.ngrok.io/results.

Twilio Sandbox for WhatsApp

Open your preferred REST client and paste the following URL http://localhost:3000/whatsapp. You should expect to receive a new WhatsApp message.

WhatsApp Messages

To ensure you are receiving the various WhatsApp statuses, run the following commands from your terminal.

$ mongo
$ use WhatsAppDb
$ db.messages.find({}).pretty()

Before you open the message, retrieve all messages using db.messages.find({}).pretty(). The whatsAppStatus will be delivered. Once, you open the message, the DB will be updated with the correct status which is read.

MongoDB log

Conclusion

In this tutorial, you have learned how to track WhatsApp messages sent to users. You can view the whole project code here. Happy hacking!

Additional Reading

If you would like to learn more about building a custom WhatsApp app, the following docs can assist: