How to Send a WhatsApp Message with Node.js (Tutorial)
Published on March 13, 2025

Introduction

In this tutorial, you’ll learn how to create an application that sends and receives messages using the Vonage Messages API, the Vonage Node SDK, and the WhatsApp Sandbox. The GitHub repository code for this project is located here

Prerequisites

To start sending WhatsApp messages with Node.js, you’ll need the following prerequisites:

  • Vonage API Account

    To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.

  • ngrok

  • Node.js Installed (version 20 or higher)

  • Optional - WhatsApp Business Account for additional features and functionality

Create a Vonage Application

The steps below show you how to create a new Vonage application from the dashboard. Alternatively, you can use the CLI to create an application.

Create a New Application

Go to 'Your Applications' in the Vonage dashboard and click to create a new application.

Generate Credentials 

Create a public/private key pair for API authentication. Click 'Generate public and private key’ to obtain the private key. The file will be downloaded to the location you set on your browser for downloaded files. Be sure to add that file to the project folder.

Messages API Capability

Start an ngrok Tunelling Instance

If you haven’t used ngrok before, you can start here. I’ve added the steps to run an instance below the image. 

Run the following command to start an ngrok tunneling instance.

ngrok http 8000

Output 

ngrok                                                                 (Ctrl+C to quit)
                                                                                                 
👋 Goodbye tunnels, hello Agent Endpoints: https://ngrok.com/r/aep                               
                                                                                                 
Session Status                online                                                             
Account                       plan name                                         
Version                       3.19.1                                                             
Region                        Europe (eu)                                                        
Latency                       31ms                                                               
Web Interface                 http://127.0.0.1:4040                                              
Forwarding                    https://xyz.ngrok.app -> http://localhost:8000            
                                                                                                 
Connections                   ttl     opn     rt1     rt5     p50     p90                        
                              14      0       0.03    0.03    6.10    7.79   

Configure Webhooks 

Back in the Vonage API Dashboard, under your Apps, toggle the Messages option under capabilities and set your server's public URL from ngrok as the endpoint for inbound messages and events. it should look like: https://xyz.ngrok.com/inbound for inbound and https://xyz.ngrok.com/status for status. If you’d like to learn more about webhooks, it’s on our Vonage documentation.

the inbound URL contains the ngrok URL with /inbound appended. The Status URL contains the ngrok URL with /status appended.Messages capability

Set Up the Vonage Messages API WhatsApp Sandbox

We will use theWhatsApp Sandboxfor this tutorial, which is a testing environment. You can use a WhatsApp business account once you are ready to put your application in production. Besides WhatsApp, you can integrate this application with channels such as Viber, Facebook Messenger, and Instagram with a few lines of code and setup adjustments.

Create a Messages API WhatsApp Sandbox

Navigate to the Vonage Messages API Sandbox page and set up your Messages API WhatsApp Sandbox.

Add WebHooks

Add the ngrok-generated URL to your application and the Messages API Sandbox, append /webhooks/inbound-message and /webhooks/message-status, respectively, and click 'Save webhooks.'

Two fields, one for inbound and outbound URLs.Webhooks

Environment Variables

We must create a .env file, and add the needed environment variables. We've generated some of these before, but I'll explain where to find each one.

# Vonage API keys

VONAGE_API_KEY=

VONAGE_API_SECRET=

VONAGE_APPLICATION_ID=

VONAGE_PRIVATE_KEY=

VONAGE_WHATSAPP_NUMBER=

VONAGE_API_SIGNATURE_SECRET=

# Server port (optional; default is 8000)

PORT=8000

Open your API dashboard to access your Vonage API Key and Secret. Both are found on the homepage, as shown in the screenshot below.

Screenshot of the Vonage API Dashboard. The main section welcomes the user, 'Welcome back, Diana,' and features the header 'Vonage API Dashboard.' Two fields are displayed: 'API Key,' showing 'Master (3e6287d2)' with a copy icon, and 'API Secret,' showing a masked value with eye and copy icons.API Key and API Secret

The VONAGE_WHATSAPP_NUMBER is on the Messages Sandbox Page. It is the number to which you will send a WhatsApp message. For sandbox testing, the number is 14157386102.

The VONAGE_APPLICATION_ID can be found within the application you’ve created.

Application ID found on the application.Application id

The VONAGE_PRIVATE_KEY is the path to the private.key file that was generated when you created your application.

VONAGE_API_SIGNATURE_SECRET is the secret used to sign the request that corresponds to the signature secret associated with the api_key included in the JWT claims. You can identify your signature secret on the Dashboard settings.

> NOTE: When entering a phone number, don't use a leading + or 00; start with the country code, such as16600700000.

The port is the one our express server will be running. I've set it to 8000, but feel free to change it.

Install the Dependencies

We will use the Vonage Server SDK, Vonage Messages SDK for Node.js, Vonage JWT SDK for Node.js, Express, and Dotenv. Install them with this command:

npm install @vonage/server-sdk @vonage/messages @vonage/jwt express dotenv

Implement the Code Logic

Create a server.js file.

Require and initialize the packages we will use for this project.

// src/server.js

require("dotenv").config();

const express = require("express");

const { Vonage } = require("@vonage/server-sdk");

const { WhatsAppText } = require("@vonage/messages");

const { verifySignature } = require("@vonage/jwt");

const app = express();

app.use(express.json());

Initialize a new Vonage Client; the values read from process.env are the environment variables you previously added to your .env file.

The apiHost provided is the sandbox environment URL for Vonage's messaging service.

const vonage = new Vonage(
 {
   apiKey: process.env.VONAGE_API_KEY,
   apiSecret: process.env.VONAGE_API_SECRET,
   applicationId: process.env.VONAGE_APPLICATION_ID,
   privateKey: process.env.VONAGE_PRIVATE_KEY,
 },
 {
   apiHost: "https://messages-sandbox.nexmo.com",
 }
);

We have a JWT verification function to verify if the incoming message came from Vonage. You can learn more about verifying the request

const verifyJWT = (req) => {
  // Verify if the incoming message came from Vonage
  const jwtToken = req.headers.authorization.split(" ")[1];
  if(!verifySignature(jwtToken, process.env.VONAGE_API_SIGNATURE_SECRET)) {
    console.error("Unauthorized request");
    throw new Error('Not a messages API request');
  }

  console.log('JWT verified');
}

The conversation will be initiated by the user sending a WhatsApp message. Let’s create a function to Send a WhatsApp Message back to the user with the text ‘Message received’.

// Function to send a message via Vonage

const sendMessage = async (to_number) => {

 const text = "Message received."; // The reply message

 try {

   const { messageUUID } = await vonage.messages.send(

     new WhatsAppText({

       from: process.env.VONAGE_WHATSAPP_NUMBER,

       to: to_number,

       text: text,

     })

   );

   console.log(`Message sent with messageUUID: ${messageUUID}`);

 } catch (error) {

   console.error(

     "Error sending message:",

     error.response ? error.response.body : error.message

   );

 }

};

Create an /inbound endpoint to handle the incoming message, the one added as a webhook in the Vonage dashboard. It logs when a message is received and sent back to the user allowed listed in the Sandbox saying: “Message received”.

app.post("/inbound", async (req, res) => {

 const { from: requesterNumber } = req.body;

 console.log(`Received message from ${requesterNumber}`);

 try {

   // Send the "Message received" reply

   await sendMessage(requesterNumber);

   res.status(200).send(); // Acknowledge the received message

 } catch (error) {

   console.error("Error handling incoming message:", error);

   res.status(500).send("An error occurred while processing the message.");

 }

});

Create a /status endpoint that logs the request data, checks if the user is authorized using a JWT, and then responds with a success message.

app.post('/status', (req, res) => {

  console.log(req.body);

  verifyJWT(req);

  console.log('Received status update');

  res.status(200).send();

});

The server listens on the specified port.

// Start the server

const PORT = process.env.PORT || 8000;

app.listen(PORT, () => {

 console.log(`Server is listening on port ${PORT}`);

});

Test Your Code

After that, you can test sending a message from your WhatsApp sandbox to your allowlisted WhatsApp number. From the directory where the file is saved, run:

> $ node src/server.js
Server is listening on port 8000
Received message from <Number>
JWT verified
Message sent with messageUUID: e295613c-a2fc-40f4-a9ae-fa16f5c685cf

At this point, the test message response should appear in WhatsApp on your allowed device. Now, you can test different types of messages and learn more about WhatsApp concepts.

Conclusion

WhatsApp is heavily used worldwide; I checked the Play Store on my Android phone, and it’s one of the most downloaded apps in the UK. As I was back in my home country in Brazil for vacation, I noticed how much it spread between businesses; I could buy açaí, contact customer support, check if places were open, and talk to friends and family. The possibilities of learning to send and receive via WhatsApp messages are endless. 

Got any questions or comments? Join our thriving Developer Community on Slack, follow us on X (formerly Twitter), or subscribe to our Developer Newsletter. Stay connected, share your progress, and keep up with the latest developer news, tips, and events!

Further Reading

https://a.storyblok.com/f/270183/400x400/3f6b0c045f/amanda-cavallaro.png
Amanda CavallaroDeveloper Advocate