Frequently Asked Questions
Use the Vonage Messages API with the Node.js SDK. After setting up a Vonage application and linking a number, initialize the Vonage client in your Node.js script. Then use vonage.messages.send() with the recipient's number, your Vonage number, and the message text. Ensure your API key and secret are stored securely in environment variables.
The Vonage Messages API is a unified platform for sending and receiving messages across multiple channels like SMS, WhatsApp, MMS, and more. It simplifies multi-channel messaging integration within applications and allows developers to manage all channels through a single interface.
Vonage uses webhooks to deliver inbound messages to your application in real-time. When a user sends a message to your Vonage number, Vonage forwards it to a pre-configured URL on your server via an HTTP POST request, ensuring your application receives messages instantly without constantly polling.
Use the Vonage WhatsApp Sandbox for testing and development of your WhatsApp integrations before going live. It allows you to test sending and receiving WhatsApp messages without needing a full WhatsApp Business Account initially, simply by joining the Sandbox and allowlisting your testing number.
Yes, you can send WhatsApp messages using Node.js, Express, and the Vonage Messages API. The Vonage Node.js SDK simplifies interaction with the API, and you can use new WhatsAppText({...}) with vonage.messages.send() within your Express server. Ensure you point to the Sandbox API host (https://messages-sandbox.nexmo.com) when initializing the Vonage client specifically for sending Sandbox messages.
Set up a webhook URL in your Vonage application settings and configure your Express server to listen for POST requests at that endpoint. Use express.json() middleware to parse incoming data. Vonage will send an HTTP POST request to your webhook URL whenever an SMS is received by your Vonage number.
Secure your Vonage webhooks using JWT signature verification. The Vonage Node.js SDK provides verifySignature to verify the signature of incoming webhook requests. Use a middleware function in Express to verify signatures, ensuring all webhook requests are authentic and originate from Vonage, blocking unauthorized access to sensitive data.
ngrok creates a secure tunnel that exposes your locally running Express server to the internet. This allows Vonage to deliver webhooks to your development environment during testing. ngrok provides an HTTPS URL that you configure as your webhook endpoint in your Vonage application settings.
Store your Vonage API Key, API Secret, Application ID, Private Key, and Signature Secret in a .env file. Use the dotenv package in Node.js to load these environment variables into process.env. Never commit the .env file to version control.
Within your inbound webhook handler, use vonage.messages.send() combined with new WhatsAppText({...}) to send a reply. Extract the sender's number and craft the reply message dynamically. Set the 'from' number to your Vonage Sandbox number. This allows your application to engage in two-way conversations with users.
A Vonage Application ID is a unique identifier assigned to each application you create within the Vonage platform. It's essential for authentication and associating your application with Vonage services, including configuring webhooks and managing API access.
You need a Vonage API account, Node.js and npm installed, ngrok for local testing, and a Vonage virtual number for sending SMS. An ngrok account is needed to expose your localhost during development. For WhatsApp, you need to enable the WhatsApp Sandbox and join it with your WhatsApp-enabled phone number.
Send and receive SMS & WhatsApp messages with Node.js, Express, and Vonage
Meta Description: Learn how to build a complete Node.js application with Express to send and receive SMS and WhatsApp messages using Vonage Messages API. Includes webhook handling, security, and production-ready code examples.
This guide provides a comprehensive walkthrough for building a Node.js application using the Express framework to send and receive both SMS and WhatsApp messages via the Vonage Messages API. You'll implement multi-channel messaging capabilities for notifications, alerts, customer support, or two-factor authentication using a unified API approach.
By the end of this tutorial, you will have a functional application capable of:
This guide solves the common need for applications to integrate multi-channel messaging capabilities for notifications, alerts, customer support, or two-factor authentication, leveraging the unified Vonage Messages API.
Technologies Used:
.envfile.How It Works:
POSTrequest.Prerequisites:
Final Outcome:
You will have two main scripts:
index.js: A standalone script to send an outbound SMS message.server.js: An Express server that listens for incoming SMS and WhatsApp messages via webhooks, logs them, and automatically replies to incoming WhatsApp messages.1. Node.js Project Setup for Vonage Messaging
Let's start by creating our project directory and initializing it as a Node.js project.
1. Create Project Directory:
Open your terminal or command prompt and create a new directory for your project.
2. Initialize Node.js Project:
Initialize the project using npm, which creates a
package.jsonfile.The
-yflag accepts the default settings.3. Install Dependencies:
Install the required npm packages for Vonage messaging, Express web framework, and environment configuration:
express: The web framework.@vonage/server-sdk: The core Vonage SDK.@vonage/messages: Specific helpers for the Messages API (likeWhatsAppText).@vonage/jwt: For verifying webhook signatures (important for security).dotenv: To manage environment variables securely.Install them using npm:
4. Create Project Structure:
For simplicity, we'll keep our code in the root directory for this example. Create the necessary files:
index.js: Will contain the code to send an SMS.server.js: Will contain the Express server to handle incoming webhooks..env: Will store our API keys and other configuration secrets. Never commit this file to version control..gitignore: Specifies intentionally untracked files that Git should ignore.5. Configure
.gitignore:Add
node_modulesand.envto your.gitignorefile to prevent committing dependencies and secrets.6. Set up Environment Variables (
.env):Open the
.envfile and add the following placeholders. We will fill these in during the Vonage configuration steps.Explanation of Configuration Choices:
.env: Using environment variables keeps sensitive credentials out of the codebase, enhancing security and making configuration easier across different environments (development, production)..gitignore: Essential for preventing accidental exposure of secrets (.env) and unnecessary bloating of the repository (node_modules).2. Vonage API Configuration and WhatsApp Sandbox Setup
Before writing code, we need to configure Vonage by creating an Application, setting up the WhatsApp Sandbox, and obtaining the necessary credentials.
1. Obtain API Key and Secret:
API keyandAPI secretare displayed prominently on the homepage..envfile forVONAGE_API_KEYandVONAGE_API_SECRET.2. Create a Vonage Application:
Vonage Applications act as containers for your communication settings, including webhook URLs and authentication keys.
private.keyfile. Save this file in the root of your project directory (vonage-node-messaging). The public key is stored by Vonage. Update theVONAGE_PRIVATE_KEYpath in your.envfile if you save it elsewhere (the default./private.keyassumes it's in the root).http://example.com/webhooks/inboundhttp://example.com/webhooks/status.envfile forVONAGE_APPLICATION_ID.3. Link a Vonage Number (for SMS):
To send and receive SMS, you need a Vonage virtual number linked to your application.
12015550123) and paste it into your.envfile forVONAGE_SMS_FROM_NUMBER.4. Set up the Messages API WhatsApp Sandbox:
The Sandbox provides a testing environment without needing a full WhatsApp Business Account initially.
+14157386102) to your WhatsApp contacts and send it a specific join message (e.g., "WhatsApp Sandbox"). Do this now from the phone number you want to use for testing. This "allowlists" your number.14157386102) is pre-filled in the.envfile forVONAGE_WHATSAPP_NUMBER.http://example.com/webhooks/inboundhttp://example.com/webhooks/status5. Obtain API Signature Secret (for Webhook Security):
Vonage signs incoming webhook requests with a JWT (JSON Web Token) using a secret key, allowing you to verify their authenticity.
.envfile forVONAGE_API_SIGNATURE_SECRET.6. Start ngrok:
To receive webhooks on your local machine, we need to expose your local server to the internet using ngrok.
8000in our.env).https://<unique-subdomain>.ngrok-free.app). Copy this HTTPS URL.7. Update Webhook URLs in Vonage:
Now, replace the placeholder URLs with your actual ngrok URL.
<your-ngrok-https-url>/webhooks/inbound<your-ngrok-https-url>/webhooks/status<your-ngrok-https-url>/webhooks/inbound<your-ngrok-https-url>/webhooks/statusYou have now fully configured Vonage and linked it to your local development environment via ngrok.
3. Implementing SMS and WhatsApp Message Handlers
Now let's write the Node.js code to send and receive messages.
Part 1: Sending an SMS (
index.js)This script demonstrates sending a single outbound SMS message using the credentials and Vonage number configured.
Explanation (
index.js):require('dotenv').config();: Loads environment variables from the.envfile intoprocess.env.process.envand performs basic checks to ensure they are present andTO_NUMBERis set. It also performs a simple regex check for phone number format. Note that this regex (/^\+?\d{1,15}$/) is a very basic check; it ensures the string contains only digits (optionally preceded by a+) and is within the typical length limits, but it doesn't rigorously enforce the full E.164 standard (e.g., specific country code rules). The error message guides the user towards the correct format.vonage.messages.send({...}): This is the core function call.message_type: 'text': Specifies a plain text message.text: The content of the message.to: The recipient's phone number (loaded from theTO_NUMBERconstant, with leading+removed for the API call). Crucially, replace the placeholder value.from: Your Vonage virtual number (loaded from.env, with leading+removed).channel: 'sms': Explicitly tells the Messages API to use the SMS channel.sendfunction returns a Promise, so we useasync/awaitfor cleaner handling. Atry...catchblock captures potential errors during the API call (e.g., network issues, invalid credentials, insufficient funds) and logs detailed information if available from the error response.sendSms()function to trigger the process.Part 2: Receiving Messages & Replying (WhatsApp) (
server.js)This script sets up an Express server to listen for incoming webhooks from Vonage for both SMS and WhatsApp messages. It includes JWT verification for security and demonstrates automatically replying to incoming WhatsApp messages.
Explanation (
server.js):dotenv,express, Vonage SDK components, and configuration variables. Includes validation.express.json(),express.urlencoded()) to parse incoming request bodies.{ apiHost: 'https://messages-sandbox.nexmo.com' }in the options. This directs API calls (specifically thesendWhatsAppReply) to the correct Sandbox endpoint. Important Limitation: Because thisapiHostis hardcoded, this specificvonageclient instance cannot be used to send production WhatsApp messages (which use the standardmessages.nexmo.comhost) or potentially SMS messages directly from the server without modification. For a production application sending multiple message types from the server, you might need separate client instances or logic to determine the correctapiHostbased on the message type or environment.verifyVonageSignatureMiddleware:/webhooks/inboundand/webhooks/status.Authorization: Bearer <token>header sent by Vonage.verifySignature(token, VONAGE_API_SIGNATURE_SECRET)from@vonage/jwtto check if the token's signature is valid using the secret stored in.env.401 Unauthorizedresponse and stops processing.next()to pass control to the actual webhook handler (app.post(...)). This is a critical security step to ensure webhooks genuinely originate from Vonage.sendWhatsAppReplyFunction:asyncfunction dedicated to sending replies via WhatsApp.vonage.messages.send()but wraps the message details innew WhatsAppText({...})provided by@vonage/messagesfor convenience.fromthe Sandbox numbertothe original sender (recipientNumber)./webhooks/inboundEndpoint:POSTrequests to this path (where Vonage sends incoming messages).verifyVonageSignaturemiddleware first.channel,from(sender number is extracted from thefromobject, e.g.,req.body.from.number),message_type,text. Includes a basic check to ensure the sender number was extracted.whatsappandsmschannels.sendWhatsAppReplyto send an automated response.res.status(200).send('OK');. This is vital. Vonage expects a 2xx response to confirm receipt; otherwise, it will retry sending the webhook, potentially causing duplicate processing./webhooks/statusEndpoint:POSTrequests for status updates (e.g., delivery confirmations).verifyVonageSignaturemiddleware.200 OK./healthEndpoint: A simpleGETendpoint useful for basic monitoring or load balancers to check if the server is running.app.listen: Starts the Express server, making it listen for connections on the configuredPORT.4. Testing SMS and WhatsApp Integration with Webhooks
Let's test both sending and receiving capabilities.
Ensure
ngrokis running and your Vonage webhook URLs are correctly updated.Test 1: Sending an Outbound SMS
Edit
index.js: Openindex.jsand replace'REPLACE_WITH_RECIPIENT_PHONE_NUMBER'with your actual mobile phone number in E.164 format (e.g.,14155550100or+14155550100). Save the file.Run the Script: In your terminal (the one not running ngrok), execute:
Check Output: You should see console output indicating the SMS was submitted successfully, including a
Message UUID.Check Your Phone: You should receive the SMS message ("Hello from Vonage and Node.js!") on the phone number you specified. Delivery might take a few seconds.
Test 2: Receiving Messages and WhatsApp Reply
Start the Server: In your terminal (the one not running ngrok, if you stopped it after sending SMS), start the Express server:
Check Server Logs: You should see "Server listening on port 8000...".
Receive an SMS:
VONAGE_SMS_FROM_NUMBERin.env).channel: 'sms'), your phone number, and the message text. The signature verification log should also appear.POST /webhooks/inbound 200 OKrequests in the ngrok terminal window.Receive a WhatsApp Message & Trigger Reply:
+14157386102).channel: 'whatsapp').POST /webhooks/inbound 200 OKrequests.Check Status Webhooks (Optional but Recommended):
index.js) and the WhatsApp reply (server.js), you should eventually see "--- Status Update Received ---" logs in yourserver.jsconsole as Vonage sends delivery confirmations (or failures) to the/webhooks/statusendpoint. This might take a few seconds to minutes depending on the network.5. Error Handling and Logging Best Practices
Our current implementation includes basic error handling and logging:
index.js,server.js):try...catchblocks wrapvonage.messages.send. Errors are logged to the console, including details from the error response if available (error.response.data).index.js,server.js): Basic checks for missing environment variables prevent the scripts from running without necessary config, exiting gracefully (process.exit(1)).server.js): TheverifyVonageSignaturemiddleware explicitly handles invalid or missing signatures, logging warnings/errors and returning401 Unauthorized.server.js):console.logis used to track incoming messages, status updates, signature verification results, and reply attempts. Timestamps are added for context.server.js): Sendingres.status(200).send('OK')prevents Vonage's retry mechanism from flooding the server if processing takes time or fails silently.Production Considerations:
While the current setup is functional for demonstration, a production environment requires more robustness:
async-retry) with exponential backoff if the initialvonage.messages.sendcall fails due to temporary network issues or API unavailability. Be cautious not to retry errors that are clearly permanent (like invalid numbers).6. Security Features for Production Deployment
Security is paramount, especially when handling communication and API keys.
.env): Keeping API keys, secrets, and application IDs out of source code (and using.gitignoreto exclude.env) is the most fundamental security practice.server.js): TheverifyVonageSignaturemiddleware is crucial. It ensures that incoming requests to your webhook endpoints genuinely originate from Vonage and haven't been tampered with or spoofed. Never disable this in production.ngrokprovides an HTTPS URL during development. In production, ensure your webhook endpoint is served over HTTPS (using a reverse proxy like Nginx or Caddy with SSL certificates, or platform-provided HTTPS like Heroku, Vercel, AWS Load Balancer). This encrypts the data in transit between Vonage and your server.TO_NUMBERformat), robust applications should validate all inputs more thoroughly, especially data coming from external sources (like webhook payloads or user input used in replies) to prevent injection attacks or unexpected behavior.express-rate-limit) to prevent abuse or denial-of-service attacks.