Build a WhatsApp Chatbot Voting Application Using NodeJs and Twilio

Nwachukwu Chibuike
Apr 8 · 9 min read

With the rate of technological advancement taking place in this century, we are always finding new ways to automate our tasks and make our lives better. Chatbots help us reduce our dependence on our manual ways of communication and also challenges our preconceived way of implementing solutions.

Photo by Owen Beard on Unsplash

What is a ChatBot?

In this tutorial, we would be embarking on a creativity journey by building a voting WhatsApp Chatbot with NodeJs using the Twilio Platform.

After successfully following this tutorial, you would have learned how to:

  1. respond to WhatsApp messages sent to your Twilio WhatsApp number
  2. develop a Rest API based voting application
  3. send free-form messages using the Twilio WhatsApp API


  • Basic knowledge of NodeJs
  • NodeJs and Npm installed on your machine
  • A WhatsApp enabled Twilio number
  • Twilio Account
  • An installation of ngrok

Setup and Installation

$ mkdir e-voting && cd e-voting

Then we initialize a node project by creating a package.json, the command allows the creation of the file without us entering prompt values. You can later change the values in this file.

$ npm init -y 

Next, we proceed to install the packages we would be using

$ npm i express twilio

Express — We use to set up our server

Twilio — The Twilio Library we would use to send messages

Now that we have our environment set up, let's proceed to our Twilio sandbox to set things up.

Setting up the WhatsApp Sandbox

However before we can start sending and receiving messages using the Twilio WhatsApp API in production, we must first get a WhatsApp Approved Twilio Number which will act as our WhatsApp number for sending and receiving messages. For this tutorial we would not involve ourselves in that process, we would rather leverage on a safe sandbox Twilio provides for development and testing purposes.

To begin using the Twilio WhatsApp Sandbox, we proceed to the WhatsApp section on the Twilio dashboard and send a message to the sandbox number provided; usually, +14155238886 with the provided code, which is in the format join-{unique word}:

You should receive a response similar to the one below once you join. If you didn't check the process you followed to make sure you didn't miss any step.

Building the App

The above simply uses express to spin up a server and uses a route file which was imported on line 2. We would later send all request to our server on the /vote route which points to this external route file.

Next, we proceed to create a routes.js which would hold the logic

I know this file looks quite a lot but with some explanation, you would see it's not that complex. To make the explanation easier I would be explaining section by section.

The First Section spans from Line1–5 is where we install helpers files and methods into our application. At Line 3, we installed the Twilio official NodeJs module which we would use to send back our response. Line 4 we imported our helper response module(this would help format our various responses). Line 5, sees us introduce our utility module where we store our helper functions.

The Second Section spans from Line 7–25 is where we define our file variables and default values, like votes and candidates.

The Third Section spans from Line 27–43 and only consists of one function, showCandidates, we simply use this to show our list of candidates once requested by the user.

The Fourth Section spans from Line 46–136 and consists of four functions which are in charge of actually accepting and validating users vote and showing the result to the user. The first two functions are the actual voting while the last two are for showing results. Here is how it works:

a) castVote(): It begins the voting process and also takes users vote. Once a user chooses to vote and this method is called for the first time through Line 218, it creates a tracker for that particular user in the server through Line 82, after it has performed a check to ascertain that there are candidates to be voted for(Line 81).

It then returns a response with the list of candidates with their id to enable the user to know how to vote for their chosen candidate in their next chat, it also includes a way to cancel the voting process and remove the tracker from the user end by appending the unique value(0) which should be used by the user to opt-out of the voting process (Line 83 which calls list_of_candidate accepts showCandidates function as a parameter).

When the user responds next with a chat, we then check by converting the chat value to a Number and check its value, if it's a 0, we know the user wants to cancel the voting process(Line 203), we then cancel the process and send a response to the user that we have. If the user rather sends any other value we then call castVote with the required parameters(Line 207).

When castVote is called and passed these values we then go to line 75 where we make sure the user hasn't voted before, then we proceed to Line 76 to recheck that the user has indeed begun the process of voting and lastly we proceed to confirm that there are actually candidates to be voted for in Line 77. After this, we call addVote in Line 78 with the provided parameters.

b) addVote(): This function is charged with the actual reception of users vote. Firstly we check at Line 58 to make sure that the value supplied by the user actually is an id of a Candidate. We then proceed to add that users vote, remove them from the voting process and send back a successful response (Line 61-63).

c) showResult(): We use this function to show the result to users. Line 118–119 is simply used to validate and make sure that votes and candidates exist respectively. At line 121 we group all votes by the candidate. Then at Line 122, we format the response we get from Line 121 in such a way we can show the user the name of each candidate, the total votes they amassed and their percentage of votes. Also, we show a winner or draw where applicable(the formatResult function at Line 95 helps us with this formatting and result response.

d)formatResponse(): Like said above, found at Line 95, it simply gets the grouped votes by their candidates, then it returns the names of each candidate, their votes count and percentage of votes. It also checks for a draw or winner and returns this formatted result as its response.

The Fifth Section spans from Line 139–191 and consists of display and default message and a footer which we include for every response. showDefaultMessage() is used at the beginning to show a list of actions that can be performed. showHelp() shows the help menu whenever it's called while the footer includes an additional message to all response.

The Sixth and Last Section which spans from Line 191–243 is where we accept the post request made to the server, parse the body content, process the user input and send a response. Line 197 simply gives us the user phone number, this is the unique identifier for each user. We use the switch statements to get users response and call the corresponding function.

That's basically what this file does, it serves as the engine of our chatbot.

Next, let's add the utility.js file that would hold our helper files

We have just 4 methods here that basically help us to perform various manipulations of data.

We also include our responses.js file

Now that we are done with the coding section, your project structure should look something like this:

Project Structure

We then have a functional server, we would now proceed to create a webhook that would allow us to redirect requests.

Create a Webhook

If you don't have ngrok, proceed here to see how to get and set it up to run in your system. We are going to use the URL provided by ngrok as our webhook URL.

But before we do that we need to start our server, let's open a terminal at the root of our project and run:

node index.js

This would spin up our server and expose it to a port. In our case, that port is 4000.

Next, we open a different terminal and run

ngrok http 4000

You should then see this on your terminal, Ngrok doing its job!

Port forwarding with Ngrok
Port forwarding with Ngrok
Port Forwarding with Ngrok

Though not needed we could go to the Web Interface URL( provided in the image to see requests as they are made to the endpoints:

Request Dashboard

Now update the webhook in Twilio to point to the exposed URL provided by Ngrok. This would redirect all messages from Twilio to our nodeJs server running locally on our system. Head over here and input the URL obtained from Ngrok and append it with /vote as this is our full endpoint. Then update the input field labelled “WHEN A MESSAGE COMES IN” with this value.

For our case, we would input

Twilio Sandbox Configuration
Twilio Sandbox Configuration
Twilio Sandbox Configuration


And when we send 3 to the bot, we get polling results back, it works!:

Shows Result



Technological advances have enabled us to live out our imaginations which we would have never thought possible in the previous century. I have just lived out one of mine! I can’t wait to see what you build!

Geek Culture

Proud to geek out.

Sign up for Geek Culture Hits

By Geek Culture

Subscribe to receive top 10 most read stories of Geek Culture — delivered straight into your inbox, once a week. Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Geek Culture

A new tech publication by Start it up (

Nwachukwu Chibuike

Written by

Full-stack developer, technical writer and lover of Jamstack. Passionate about lifelong learning.

Geek Culture

A new tech publication by Start it up (

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store